multiple definitions exist for class - phpstorm

I'm using Kohana framework which allows for multiple class definitions (in application and system subfolders). I'm using phpstorm as an IDE which gives me messages multiple definitions exist for class . Is there any way to tell phpStorm which class definition is correct?

Is there any way to tell PhpStorm which class definition is correct?
You cannot, unfortunately.
https://youtrack.jetbrains.com/issue/WI-17646 -- watch this ticket (star/vote/comment) to get notified on any progress.
ATM you either just ignore the under-waving .. or you can configure that inspection to not to report such cases (Settings/Preferences | Editor | Inspections | PHP | Undefined | Undefined class, it has Don't report multiple class declaration potential problems checkbox).
Even with that inspection configured, IDE will still ask you what class declaration to jump to (and this is correct behaviour as IDE does not know if you want to see the original implementation or implement your own).
The only other way is to ensure that there is only one class with the same name in the project. For that you may use:
Mark whole folder as excluded
Mark individual file as Plain Text
Both are available via content menu in Project View and applicable to project files only (e.g. will be unavailable or will do nothing useful if tried to apply in Library scope).

You should just ignore the complete cache folder.
Go to Settings > Directories
Choose var\cache
Set it to 'Excluded'
From: https://github.com/Haehnchen/idea-php-symfony2-plugin/issues/301

I've found a possible solution to my problem - I can mark file as plain

As variant you can turn off inspection only for specific class. Put cursor inside underwaved class name, then Alt+Enter → Inspection options → Supress for statement
PHPStorm adds
/** #noinspection PhpUndefinedClassInspection */
above class declaration and class name is not underwaved anymore.

I've been around the web everywhere and not a single option worked for me... I've been struggling for months with it, and today I found a solution, so if none of the above works for you, try redefining the PHP Include Path List. under Settings > Languages & Frameworks > PHP, make sure only the folders containing paths to source used by your project or application is configured.
My scenario is that I do a lot of package development, and while my packages are all in one project, they are also "symlinked" in "vendor" in my composer configuration, so there is duplicated code found by PHPStorm, in the vendor folder and my packages folder. Similarly, if include paths are duplicated, or paths are configured to find code outside of your project, which is already part of the project, it will also find multiple definitions. So, excluding the symlinked folders in vendor, allows PHPStorm to only find one copy of the source to my packages, and if my packages contain vendor folders of their own, they will also show up as duplicated definitions. Remove anything in the Include Path list where it may find dipplication

Just some addition to the Andy White's comment:
Settings | Editor | Inspections | PHP | Undefined | Undefined class | Don't report multiple class declaration potential problems
I really couldn't find this config and thought it was no there now, but this is still there, but very well hidden)
It is a little counterintuitive and inconspicuous, but the needed checkbox is in the right panel, and appears only if you click on the Undefined class row:

Prolog
Guess there are several ways to solve this problem. Actually, it's just a warning and it says that phpstorm can't provide you with autocompletion so you have to work a bit harder :D
I had the same problem as many others here and solved it by ignoring unwanted.
Scenario
Had a git project with a vendor-folder after composer install. Also, there is a my-project.phar in this project that also contains some vendor stuff and this caused my warnings.
Solution
File > Preferences|Settings > Directories
There you have to possibility to exclude files and folders. In my case it's the .phar so it's a "file" and you can add it at the bottom of the settings-window.
PHPStorm will no longer see duplicates.
This is very project-specific and I guess most people have to find their own solution but pointing to this may help to find the problem easier.
Hope this helps someone :)

Somewhere in your project there are multiple definitions for the same class. I discovered I had backup copies in my project which caused this warning. I removed the backups from my Project (a good idea anyway) and it fixed the error.

I don't know how you created the other definition, but if you or anyone has this issue due to calling class_alias(), then you can solve this issue quickly.
Consider
class_alias(
'The\AliasClass',
'My\RealClass',
true
);
and
class_alias(
'The\AliasClass',
'My\Real'.'Class', // <-- break up the string
true
);
With the latter, PhpStorm will not pick up the My\RealClass and your "multiple definition" warning will cease. This is an ancient JavaScript trick to embed HTML in a string literal, by the way.

This warning has annoyed me for a long time. I believe the answers here saying there is a duplicate file somewhere is correct. The reason I am getting the warnings are due to the autocomplete file to give phpStorm a hint on how to find codeIgniter functions. If you are doing this also that is the reason for some of the warnings. The autocomplete file makes phpStorm think there are two different definitions. However, I like autocomplete more than I dislike the warnings so I guess I have to live with them.
This is the autocomplete I'm referring to:
IntelliJ IDEA 12 not finding CodeIgniter classes, throwing errors

Alternatives that work after a fashion, but aren't so good
marking the file B you don't want to be used by autocomplete as "plain" or excluded, leaving file A active: this will disable notifications in the file C, but will also make autocompletion no longer work for whatever is in file B. So if somewhere else you use something that's rightly in B, and maybe there you want to exclude A from autocompletion, you can't do that.
disable the inspection: this will also disable undefined class warnings, so if I make any typos in any class name, I'll only discover this after deployment (or from the fact that autocomplete stops working for that object).
"Don't report multiple class declaration potential problems" - this is very nearly good, but I don't like having "potential problems" ignored; what if I create a class with an unwittingly duplicated name that is in use somewhere else? Granted that I'll catch it (or phpunit will), but still.
The best I've found so far
The way to go for now, at least until a more focused configuration is available for PHPStorm (e.g. "Alternative Classes"), is to mark those notifications - and only those - as ignorable:
/* #noinspection PhpUndefinedClassInspection */
/**
* Verify an existing contract. Requires agent and supervisor.
*
* #param array $data
* #param Cliente $cli
* #param User $age
* #param User $sup
* #return Contratto
*/
private function contratto(
array $data,
/* #noinspection PhpUndefinedClassInspection */
Cliente $cli,
/* #noinspection PhpUndefinedClassInspection */
User $age,
/* #noinspection PhpUndefinedClassInspection */
User $sup
) {
Note that to disable notifications in the PHPDoc comment I had to add a directive before the comment; this did not disable the notifications for the three parameters.
In the future, I wish to be able to specify those in PHPStorm as
* #param array $data raw data for the contract
* #param \local\foobar\Cliente $cli customer opening the contract
private function contratto(
array $data,
/*\local\foobar\*/Cliente $cli,
or better still, explicitly use a new PHPdoc tag such as "#replaces". So PHPStorm would know that my class is the one not replaced. I'll also have to decorate my use's to specify the class I'll be actually using.
And run a search for "#noinspection PhpUndefinedClassInspection" throughout my code.
Another way
The above problems stem from the fact that I have a "master" Customer class which is overridden by a "local" modification for the foobar client, whose Customers have (say) a special method.
The "correct" way of doing this should be to declare a FoobarCustomer which is only employed by foobar's code, and is a child class of Customer. Of course this is only possible if the child class is in my code, not in the framework's, and also I may need some methods in the parent class to be protected rather than private, which may make this solution either impossible or needful of Reflection:
/**
* Verify an existing contract. Requires agent and supervisor.
*
* #param array $data
* #param FoobarCliente $cli
* #param FoobarUser $age
* #param FoobarUser $sup
* #return Contratto
*/
private function contratto(array $data, FoobarCliente $cli, FoobarUser $age...

I had similar problem and it was quite annoying one. I was using Yii2 framework and as it turned out at the end I have accidentally created en extra "vendor" folder and composer.json in the root of the project (not in the root of the app) so I ended up with that warning as phpStorm was confused which extension folder is the right one.
I've deleted extra vendor folder and it solved the problem.

Try delete duplicate declared libraries
Settings -> Languages & Frameworks -> PHP -> Include Path

I resolved this in my case by removing a more specific entry in my composer.json that included code by another more general entry

Related

Telling PhpStorm where a class is located so it can use autocomplete

I'm using WordPress and using a plugin called Timber, which basically helps you to utilise the Twig templating engine in WordPress.
Anyway, I am trying to do this in one of my files:
Timber::render('welcome.twig');
PhpStorm is reporting that Timber is an unrecognized class, because it doesn't see where I have included it; I assume it is being auto-loaded somewhere?
Now, I did a search around and came across answers about using PHPDoc such as this, however I'm not sure how to apply that to my situation, I tried:
/** #var \Timber\Timber */
...but it didn't seem to work.
If I can somehow do this globally that would be great, so I don't have to do it in every file I need to use Timber in.

Disable import of classes for PHPDoc

One thing I love about PhpStorm is the easy import of classes (adding the use statement for you). However, the annoyance with this is when you don't actually want it to import the class. For example, when I'm documenting a method's return value as another class.
Is there any way to disable PhpStorm's import of classes only when annotating in PHPDoc blocks?
If I understand your request correctly...
Settings/Preferences
Editor | Code Style | PHP
PHPDoc tab
There is Use fully-qualified class names under Generated Doc Blocks
That option does the job when completing not-yet-imported class in #return (should do the same for #param and others -- have not tested other tags myself -- only checked on #return).
On related note: this ticket is asking to have an ability to always use FQN in PHPDoc blocks (implemented as Inspection .. so can be turned on or off). Might be useful for you -- consider voting.
https://youtrack.jetbrains.com/issue/WI-28591

How to tell the PhpStorm IDE that a constant exists?

The IDE (PS-117.65) is complaining that some of constants aren't defined.
I've defined them in a loop in another file. Can I put a doc comment at the top of this file to inform it about the constants? The usual /** #var and #global syntax doesn't seem to work for constants.
There is no known to me PHPDoc comment to do that.
But you can "fake" them -- create some const.php file and place it anywhere in a project (you can even place it in separate folder outside the project and attach it as External Library or as separate Content Root).
In this file -- define those constants with in a normal way: define("CONST_NAME", "value"); The "value" part can be anything (as long as types are matching -- useful for inspections/code analysis) -- it really depends where those constant will be used (e.g. if they are used in include/require statements, then it may be beneficial to have some real (or close to it) values there).

How to override a Magento function in app/code/core/Mage/Core/functions.php

I need to override a function in this file:
app/code/core/Mage/Core/functions.php
The problem is that this is so core that there’s no class associated to it, probably because Core isn’t even a module. Does anybody know how to override a function in the file without a class?
Any help would be appreciated.
Copying the file to app/code/local/Mage/Core/functions.php should not be used because of the following reasons:
The entire file has to be copied over making it harder for us to identify what changes have been made.
Future upgrades could introduce new features that would not be available unless it is remembered to copy across the new version of that file and implement the changes again.
Future upgrades could address bugs with core that we would miss unless it is remembered to copy across the new version of that file and implement the changes again.
In respect to points 2 & 3 each upgrade could change the way things work that means revisiting what changes we need to make. In some cases this will be true for overriden methods as well but at least we can easily identify where those changes effect us.
What do you do if another person wants to use the same technique? Being able to identify what is core code and what is ours becomes more and more complex.
Keeping our code together as a “module” becomes more difficult as by copying in the core file means that we have effectively locked it into being “guaranteed” to run on the version of the software that we have copied the original code from. It also means reusing this work is a lot more difficult to do.
Identifying why the code was changed it much harder as it is outside our namespacing, ie all development related to “Example_Module” is in the namespace:
/app/code/core/local/Example/Module
whereas code copied to app/code/core/local/Mage only indicates that we have made a change to support an unknown feature etc.
Also Magento occasionally release patches which fixes bugs – these will only patch files inside core leaving your copied file without the patch.
What I would suggest instead is that you write your own function to do what you want and override the function to call your new function instead.
Maybe I did not understood your question right but why not just copy this file into
app/code/**local**/Mage/Core/functions.php
and modify it there in any way you want?
As mentioned by #tweakmag the disadvantages of creating a folder structure and copying the entire Model or controller for a single function override, most important being,
"Future upgrades could introduce new features that would not be
available unless it is remembered to copy across the new version of
that file and implement the changes again."
Thus a solution can be, to extend the core class (Model or controller) and just write the method you want to override, instead of copying all the methods.
For example, if you want to say, override a method getProductCollection in Mage_Catalog_Model_Category, here will be the steps:
Create a Custom Namespace/Module folder with etc folder in it
Register the module in app/etc folder by creating Namespace_Module.xml
setup the config.xml in Namespace/Module/etc/ :
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Module>
<version>1.0</version>
</Namespace_Module>
</modules>
<global>
<models>
<catalog>
<rewrite>
<category>Namespace_Module_Model_Category</category>
</rewrite>
</catalog>
</models>
</global>
</config>
create Model folder in Namespace_Module and a Php File Category.php
Now the main difference here is we extend the Magento's core class instead of writing all the methods
<?php
/**
* Catalog category model
*/
class Namespace_Module_Model_Category extends Mage_Catalog_Model_Category
{
public function getProductCollection()
{
// Include your custom code here!
$collection = Mage::getResourceModel('catalog/product_collection')
->setStoreId($this->getStoreId())
->addCategoryFilter($this);
return $collection;
}
}
The getProductCollection method is overridden so it'll be called instead of the method defined in the core model class.
Also an important point is:
When you override any methods in models, you should make sure that the data type of the return value of that method matches with the data type of the base class method. Since model methods are called from several core modules, we should make sure that it doesn't break other features!
This link gives a step by step approach to it
1. UOPZ
There's a way to do it without having to copy and maintain functions.php file from core, but it involves extension uopz (pecl install uopz), then you can rename magento's function (from foo to foo_uopzOLD for example) and define your own (https://secure.php.net/uopz)
It works and is very useful for magento - usually you'll bump into something you can not change. Uopz is very helpful in such cases.
pros: works ;), you don't have to redo it everytime you update Magento (if you do it right, because inside you still can call foo_uopzOLD so you can assure some backward compatibility... in some cases).
cons: it's little bit implicit
2. Composer post-install-cmd
If you don't like the above, but you use composer you can patch any file you want:
"scripts": {
"post-install-cmd": "patch -p0 < change-core-functions.patch"
}
pros: explicit (when patch fail - composer install fails), and since it's explicit - you can revisit and fix the patch every time you upgrade magento
cons: you have modified core file, so you probably would want to add it to .gitignore
3. Ugly solution (uglier than those above)
If none of the above is possible for you (really, give it a try with composer - there's no excuse for not using it). But when you really can not the only way I can think of
- create app/local/Mage/Core/functions.php
- define this one function you need
- load original /app/core/Mage/Core/functions.php
- surround every function foo() {...} with
if(!function_exists("foo"){
function foo() {...}
}
hold on to your chair and
eval this SOB ;)

Fixing broken paths in ASDoc?

This question concerns using ASDoc to create documentation from AS3. I'm not doing this from Flex or anything, just using the command line, and though everything works fine and ASDoc doesn't return any errors, some of the links in the resulting documentation are broken.
Specifically, in all the places where there are links to properties or methods in other parts of the documentation (including in the same class), the link winds up doubling the folder corresponding to the package.
For example, say I'm documenting myPackage.MyClass. If MyClass has a property called MyProperty, and somewhere in my docs I include a line like this:
#see #MyProperty
then the docs are parsed correctly and the "See also:" link is correctly created, but it winds up pointing to
.../output_directory/myPackage/myPackage/MyClass.html#MyProperty
where of course, in the actual file system there is only one myPackage folder.
The relevant part of my ASDoc command looks like this:
asdoc
-source-path .
-doc-sources myPackage
-output D:\dev\repository\docs\myPackage_docs
-external-library-path "C:\Progra~1\Adobe\flex_sdk_3\frameworks\libs\player\10\playerglobal.swc"
Am I perhaps missing some ASDoc argument that would specify the base URL for links, or something along those lines? If this was a plain bug it would be apparent to many, but I can't find any google results for the problem, so my working hypothesis is that it doesn't happen to people running ASDoc from Flex, perhaps because of some setting I've omitted.
Thanks for any help!
On the suggestion of TypeOneError, I tried different kinds of #see links. I found that these work fine:
#see some.package
#see ClassName
#see ClassName#property
while these do not work:
#see #property
#see full.package.ClassName
#see full.package.ClassName#property
What's a bit worse is, although all the navigational links work, the same doubled path occurs in automatically generated type links. For example, where it shows each method's signature, when the method returns a class that's in the documentation, that link is broken.
I also had a look at the HTML, and found that the problem doesn't appear to be with the page's base URL or anything, it's just inconsistent links. So in a row of consecutive #see links, some of them link to ClassName.html and some link to package/ClassName.html, by the rules shown above. All of this, by the way, is true regardless of whether the pages are viewed in frames or not.
More info if I figure anything out, but ideas for workarounds are most welcome.
Update: A few more details: I'm not sure of my exact SDK version, except that it accompanied Flex 3, but if I run ASDoc without arguments, it reports: Adobe ASDoc Version 3.3.0 build 4852. I'm running this all on Windows XP, from a batch file placed in the classpath directory.
Partial solution: all but one of my issues were resolved by upgrading to the 4.0.0.7219 beta release of the Flex 4 SDK (and using the ASDoc distributed therein). Now, all my #see tags work as expected. The only remaining problem is that, wherever I have a method that returns a class that is part of my documentation, ASDoc simply mangles the link. For example, if I have a method whose signature is ClassA#getB():ClassB, then where that is shown in the docs, the text "ClassB" links to "packageName:ClassB.html" instead of "packageName/ClassB.html". This would appear to be a simple bug. Bleh.
ASDoc is frustrating to no end. Have you tried explicitly adding the full package/class name to the #see, i.e:
#see myPackage.myClass#MyProperty
To see if that makes a difference?
Edit
I ran a few tests based on your findings and the internal property marker is working for me. i.e.
#see #_dispatcher
Links directly to that property on the page (no double sub-folder). I think maybe you need to rethink how you're running the command. For instance, my codebase is set up thusly:
/src
/com
/bkwld
/fetch
I typically run asdoc inside "src":
asdoc -source-path . -doc-classes com/bkwld/fetch/Fetch
I tried all of these in Fetch.as and they all worked as expected:
* #see FetchItem
* #see com.bkwld.utils.Logger
* #see #_dispatcher
First took me to the FetchItem page, second took me to the Logger page in a different package, and third jumped up the page to the protected methods of Fetch.
Just out of curiosity...what version of the sdk are you using?
I'd guess the problem is your line
-doc-sources myPackage
Specifying '.' there instead of 'myPackage' should get it fixed (so make it identical to your source path)
I have written a simple Python script that fixes the paths incorrectly generated by asdoc in the case mentioned mentioned above. Namely, if there is a method myMethod(v:MyClass,...)
asdoc incorrectly generates the link href="../mypackage:Myclass"
The script will fix this replacing the : by a /
I should notice that the docs I am generating have a pretty "flat" structure, that is, a single package with a bunch of classes. I have no idea if the fix works with more complex documentation structures.
Anyway, if anyone wants to try the script, I'll be glad to send it.