How to configure PhpStorm for autocompletion of the available methods and attributes of an object - annotations

How to configure PhpStorm for visualizing available methods and attributes of an object variable while typing?
I remembered having seeing that adding the #var annotations on the line above of the declared variable as
// #var \Drupal\Core\Entity\Plugin\DataType\EntityAdapter $entityAdapter
$entityAdapter = $entityReference->getTarget();
permits it but I do not know what does it do and how to use it.
An example of autocompletion:
annotating a local variable in php

Related

read out value of protected property TYPO3\CMS\Core\DataHandling\DataHandler::$historyRecords

I'm updating a TYPO3 installation from v6 to v7 and have a problem with class TYPO3\CMS\Core\DataHandling\DataHandler
(https://typo3.org/api/typo3cms/class_t_y_p_o3_1_1_c_m_s_1_1_core_1_1_data_handling_1_1_data_handler.html).
I get the following error:
Fatal error: Cannot access protected property
TYPO3\CMS\Core\DataHandling\DataHandler::$historyRecords ...
caused by the following call
public function processCmdmap_afterFinish(&$data)
{
$dataChanged = $data->historyRecords;
Can anyone tell me how in TYPO3 v7 you can get the value of historyRecords?
Thanks in advance!!!
DataHandler::$historyRecords was not defined as property in TYPO3 6.2 but was implicitly set by class member access inside DataHandler (see DataHandler of 6.2). In TYPO3 7.6 the property has been declared the first time and defined to be protected.
The $historyRecords array could be seen as change pattern, containing the oldRecord and newRecord for a particular invocation of the DataHandler. This could be seen as contents of a RecordDataChangedEvent - which does not exist in that way in TYPO3, yet. The information is collected in DataHandler::compareFieldArrayWithCurrentAndUnset().
To get access to the information you have three possibilities in TYPO3 7.6:
Overload DataHandler by XCLASSing and provide a getHistoryRecords() method
XCLASSing is basically a bad principle since you can override functionality
that might be changed in upstream versions. In this case it would be "okay"
since you just provide a new getter-method that did not exist before
find more details in the XCLASS documentation
Use hooks to collect and determine changes on your own
processDatamap_preProcessFieldArray($incomingFieldArray, $table, $id, DataHandler $dataHandler)
processDatamap_postProcessFieldArray($status, $table, $id, $fieldArray, DataHandler $dataHandler)
collect differences in a singleton object comparing $incomingFieldArray to $fieldArray for a combination of $table and $id
this however leaves out possible version and shadowing interactions that have been applied to the field-array in between
Retrieve from database table sys_history
see DataHandler::setHistory() and do the reverse look-up
at the time when your processCmdmap_afterFinish hook is called, this data has been written already
look-up a combination of the following criteria from sys_history
tstamp equals $GLOBALS['EXEC_TIME']
tablename equals $table AND recuid equals $id
the field history_data contains then a serialized representation of $historyRecords

Access Repository from Resource folder

I have a Typo3 Extension (Typo3 CMS 6.2) and I want to access the repository globalSettingsRepository from a PHP file which is located in /Resource/PHP/.
The dependency injection does not work although I cleared the cache:
/**
* globalSettingsRepository
*
* #var \TYPO3\Institutsvideoverwaltung\Domain\Repository\GlobalSettingsRepository
* #inject
*/
public $globalSettingsRepository = NULL;
The namespace of the PHP is the same as my controllers.
I have also tried this in order to create an instance of the globalSettingsRepository:
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
Which does not work either because /TYPO3/CMS/... was not found.
Does anyone have a solution? Is there even a way to access a repository from /Resources?
Thanks alot.
There are some things that should be fixed in your extension.
First of all, you should not use TYPO3 as vendor for your extension. This is only for the core and official extensions.
Second, you must stick to conventions.
\TYPO3\Institutsvideoverwaltung\Domain\Repository\GlobalSettingsRepository
This means that you must have a class called \TYPO3\Institutsvideoverwaltung\Domain\Repository\GlobalSettingsRepository at the following path: /typo3conf/ext/institutsvideoverwaltung/Classes/Domain/Repository/GlobalSettingsRepository.php.
It seems that you don't and instead put it in Resources/PHP.
If you want to use a class from Resources/PHP, you need to either include it manually using require_once() or you need to make sure that your class is autoloaded properly. The requirements for autoloading changed from version 6 to 7, so you need to state which version you're using. Nevertheless it doesn't make sense to break convention and then have a lot of effort of there is a simple way.

How can I add autocompletion for Flight PHP microframework in PHPStorm

I've started using Flight microframework, but all methods are hidden under the hood (not declared in the Flight class).
How can I configure PHPStorm or should I write new set of rules?
Update: use framework instance doesn't work
I've tried to use framework instance, but has no success — I have internal methods in the suggestion list:
Update: autocomplete implemented in the Flight framework
First of all: I'd suggest to submit new issue on their Issue Tracker asking to provide some sort of helper file (like below).. or implement it in any other way (e.g. via PHPDoc' #method for Flight class -- no helper needed and no changes in the actual code -- just PHPDoc) so that IDE (e.g. PhpStorm or Netbeans) would not complain for non-existing methods and you will have some code completion help from IDE.
Magic is good .. but not when whole interface is based on such magic.
On the actual question, which you can resolve yourself.
You will have to spend some time (half an hour or even less) and create some fake Flight class and put it anywhere in your IDE -- it will be used for code completion only. Yes, IDE may warn you about duplicate classes.. but that inspection can be turned off.
The idea is to create a class and declare all required methods as they should have been done if it would be an ordinary class. To start with (will resolve issues for first code example on their readme):
<?php
class Flight
{
/**
* Routes a URL to a callback function.
*
* #param string $pattern URL pattern to match
* #param callback $callback Callback function
* #param boolean $pass_route Pass the matching route object to the callback
*/
public static function route($pattern, $callback, $pass_route = false) {}
/**
* Starts the framework.
*/
public static function start() {}
}
Here is how it looks now:
As you can see Flight is underwaved -- IDE says that there is more than one class with such name in this project. Just tell PhpStorm to not to report such cases:
For adding methods to the original class via #method PHPDoc tags:
/**
* Bla-bla -- class description
*
* #method static void route(string $pattern, callback $callback, bool $pass_route = false) Routes a URL to a callback function
* #method static void start() Starts the framework
*/
class Flight
{
...
}

NetBeans autocompletion with Doctrine models?

I know it's possible to get IDE autocompletion from the *Table classes in Doctrine by doing things like this:
SomethingTable::getInstance()-><autocomplete>;
But the most important part is missing. I want autocomplete on the model classes themselves, not just the Table classes. It appears that Doctrine is not properly declaring the PHPdoc #return object types in the find and other standard model methods.
For example what I want to be able to do is this:
$something = SomethingTable::getInstance()->find($id);
$something-><autocomplete>
and have that pop up the methods and properties of the Something class.
I should mention too that I don't specifically care about using the SomethingTable::getInstance() syntax at all. ANY decent syntax that's standard Symfony is acceptable. Most of the time I'm fetching objects (or Doctrine_Collections) via custom queries like this:
$somethings = Doctrine_Query::create()
->from('Something s')
->leftJoin('s.SomethingElse s2')
->where(...);
By the way, in case it's not clear, I'm asking if there's any automatic solution to this with ANY of the various Doctrine find, fetch or query syntaxes. I'm NOT asking how to manually edit all the PHPdoc headers to cause the behavior I want.
I'm using NetBeans 6.9.1 and Symfony 1.4.12 with Doctrine, but not everyone working on the same code uses NetBeans.
The problem is that autogenerated *Table classes have the wrong phpdoc #return in the getInstance() method:
/**
* Returns an instance of this class.
*
* #return object MyModelTable
*/
public static function getInstance()
{
return Doctrine_Core::getTable('MyModel');
}
You just need to manually fix the #return line deleting the word "object":
* #return MyModelTable
And magically IDE autocompletion just works, giving you all the instance and static methods:
MyModelable::getInstance()->... //(you'll have autocompletion here)
I know, its a pain to have to manually fix this but at least it only have to be done once for each model *Table file.
In netbeans its quite easy:
$foo = ModelNameTable::getInstance()->find(1); /* #var $foo ModelName */
/* #var $foo ModelName */ tells netbeans to handle the variable $foo as a ModelName class.
just fix the generated model files by adding
/**
* #return ModelNameTable
*/
in the comment of the getInstance() method. This will provide autocomplete for the model file.
Regarding the find method, you can edit the comment of the class like this :
/**
* #method ModelName find()
*/
I think it might be possible for you to do this automatically by creating you own skeleton files.
Or not : Symfony Doctrine skeleton files
You could use sed to achieve this, or perhaps build your own task using the reflection api.

What is the phpdoc syntax to link $this to a specific class in Aptana?

I'm working on Magento templates, but this issue would apply to any template loading system.
As these templates are loaded by the template engine there's no way for the IDE (in this case Aptana) to know what object type $this is.
Potentially it could more than one object as a single template could be loaded by multiple objects, but ignoring this, what would the correct phpdoc syntax be to specify a specific class for the $this object?
You can define it like this:
/* #var $this type */
where type is a class name
To be clear, using $this should only ever indicate an object of the current class, right?
PhpDocumentor doesn't currently (v1.4.3) recognize $this as a specific keyword that should equate to a datatype of the class itself.
Only datatypes known by PHP and classes already parsed by PhpDocumentor are the proper datatype values to use with the #return tag. There is a feature request in to have some option available in PhpDocumtentor to aid in documenting fluent methods that always "return $this". [1]
In the case of the #var tag, I don't see how it would be feasible for a class variable to contain its own class instance. As such, I can't follow what "#var $this" should be saying.
If, however, your intention with $this is not for fluent methods that "return $this", and was simply to be some shortcut to PhpDocumentor and/or your IDE to magically guess what datatypes you might mean by using $this, I'd have to guess there's no way to do it. The closest suggestion I could make would be to use the name of a parent class that is a common parent to all the various child classes that this particular var/return might be at runtime, and then use the description part of the tag to have inline {#link} tags that list out the possible child classes that are possible.
Example: I have a Parent abstract class with Child1, Child2, and Child3 children that each could occur in my runtime Foo class.
So, Foo::_var could be any of those child class types at runtime, but how would I document this?
/**
* #var Parent this could be any child of {#link Parent}, {#link Child1}, {#link Child2}, or {#link Child3}...
*/
protected $_var;
Getting back to the "return $this" issue, I'd document things in a similar way:
/**
* a fluent method (i.e. it returns this class's instance object)
* #return Parent this could be any child of {#link Parent}, {#link Child1}, {#link Child2}, or {#link Child3}...
*/
public function foo() {
return $this;
}
Documenting this way at least allows your class doc to have links to the particular classes. What it fails to do is highlight the fluent 'ness. However, if your IDE is capable of recognizing the class names, then perhaps it will be able to do the necessary logical linking to those other classes. I think Eclipse is able to do this at least with popup help, if you hover over the class name in the tag's description. I do not think Eclipse can use this to then make the various child classes' methods available in code completion. It would know about the Parent methods for code completion, because the datatype I explicitly list is Parent, but that's as far as the IDE can go.
[1] -- http://pear.php.net/bugs/bug.php?id=16223
I have found that defining a type with #var for $this does not work - presumably because $this is special and is treated as such by Aptana. I have a similar need to the poster I think - it is in template files (in my case simply located and included by functions within the data class) that I wish to set a type for $this. As #ashnazg says, setting a type for $this within a class definition is not needed, because the type of $this is always the type of the class (up to inheritance).
There is, however, a workaround for template files. At the top of the template file simply put something like
/**
* #var My_Data_Model_Type
*/
$dataModel = &$this;
Then simply use $dataModel (or whatever you choose to call it - maybe something shorter) instead of $this in the template