IntelliJ/PhpStorm inline #var with magic fields - php

I am trying to define with a PHPDoc inline #var a magic field variable to set the correct type but the IDE is not auto-completing anything.
It is showing "Field accessed via magic method". I tried to remove it from the Inspections settings but then the warning is not showed and still it is not auto-completing.
I have tried different ways without success:
/** #var \NameSpace\SomeClass $this->field */
$this->field->someMethod(); // Not auto-completing
/** #var \NameSpace\SomeClass $this::field */
$this->field->someMethod(); // Not auto-completing
For other hand if I define a new variable it will work:
$field = $this->field;
/** #var \NameSpace\SomeClass $field */
$field->someMethod(); // Auto-completing correctly
Somebody knows how to do it to work the auto-completing feature without define a new variable? Is it possible?
UPDATE: I cannot use the #property attribute because $field is not always the same class in the main class.

It has to be done via #property tag at class-level PHPDoc comment.
/**
* My special class
*
* #property \NameSpace\SomeClass $field Optional my magical variable description
*/
class MySpecialClass {
....
https://docs.phpdoc.org/references/phpdoc/tags/property.html
/** #var \NameSpace\SomeClass $this->field */
This will never work -- you cannot provide typehint for 2nd level variable/element ($this->field) using inline #var. If anything: only first level entities can be typehinted.

It is not possible to provide typehint for 2nd level variable/element ($this->field) using inline #var (thank to #LazyOne).
So a possible solution would be set the #property with all classes using in the main class:
/**
* My special class
*
* #property \NameSpace\SomeClass|OtherSomeClass|OneMore $field
*/
class MySpecialClass {
By this way the magic field $field would be auto-completing with all method of all classes defined.

Related

Phpdoc documentation with php activerecord

I'm using php-activerecord for a short while now and i absolutely love it. Php-activerecord is an open source ORM library based on the ActiveRecord pattern. However, i also like phpdoc and use that to document my code. Therefore it's easy for my coworkers to understand the platform's i build. But with php-activerecord in use my Model classes now look like this:
/**
* The Company class.
*
* #since 1.0.0
*
*/
class Company extends \ActiveRecord\Model
{
/** explicit table name since our table is not "company" */
static $table_name = 'Company';
/** explicit pk since our pk is not "id" */
static $primary_key = 'companyId';
}
They work, but they used to look like this:
/**
* The Company class.
*
* #since 1.0.0
*
*/
class Company extends \ActiveRecord\Model
{
/** #var integer The company id. */
private $companyId;
/** #var string The company name. */
private $name;
}
Long story short
With php-activerecord in use there's no way to document my model attributes and update phpdoc. I want to be able to do this, in what direction should i look?
You can document all your "magic" properties as an #property! Say you have a table "Company" with fields "id, name, location", you would end up with:
**
* #property int $id
* #property string $name
* #property string $location
*/
class Company extends \ActiveRecord\Model
{
}
You can see in the documentation that there are some other tricks, like "property-read". I use those for any connections you might have, as you can read a has-one for instance, but cannot write models to those connections.
So if a Company has employees that you have defined as a $employees, you might add
* #property-read Employee[] $employees
and so on.

Is there a PHP equivalent to the C# summary tag?

Is there anyway to give text editors summary information in a tooltip for custom functions/classes etc. in the way that they can do for standard libraries while coding?
Failing this what is the standard way to highlight the purpose, required params etc. for a function/class in PHP.
Check out PHPDocumentor.
An example would be:
/**
* Set the data
*
* #access public
* #param string $field
* #param mixed $value
*/
public function __set($field, $value)
{
$this->_data[$field] = $value;
}
/**
* Get the data
*
* #access public
* #param string $field
* #return mixed
*/
public function __get($field)
{
return isset($this->_data[$field]) ? $this->_data[$field] : NULL;
}
As the comments self-explain, you use #access to show the visibility of the method (if the code being summarized is a method, of course), #paramto show each parameter, and #return to show the type of the data being returned. There are many different tags to document many different aspects of the code.
You can use the PHPDoc standard for letting your IDE give you hints about, for example, a function.
Just before a function declaration you could have:
/**
* This is a DocBlock comment
*/
function foo(){
//....
}
I've used it in Netbeans and can say that it works quite nicely.

How do I properly document an array property in a class for phpdocumentor?

I'm trying to find out how to properly document an array property in a class for phpdocumentor.
Ex:
<?php
class foo {
/**
* This holds something important
* #var string
*/
protected $junk;
/**
* This holds an important array of strings
* #var ???????
*/
protected $stuff = array();
// ...
}
?>
I couldn't find anything in the phpdoc manual about array properties.
/** #var array */ for your protected $stuff is the proper syntax. The phpDocumentor manual page for #var shows "The datatype should be a valid PHP type (int, string, bool, etc),", and "array" is such a valid PHP type.
Some IDEs have also begun recognizing /** #var ElementType[] */ to indicate "this is an array, whose elements are all of type ElementType". This syntax will be available in an upcoming version of phpDocumentor.

Auto-completion for Zend Form Elements

When creating form elements with Zend (using Zend Studio for Eclipse), I'd like some auto completion or hints. Here's what I'm thinking. I'm sure these exist, but I don't know how to get them.
I type createElement and auto-completes gives me the signature createElement($type, $name). Great, I select it.
but when I try to set the $type I don't get any hints like DateTextBox or ValidationTextBox. Being new, I see how this can be useful. What do you do to remember all the options?
for the array of attributes like require, invalidMessage, I'd like to get a list of those to choose from, and/or auto-complete when I start typing one.
// Date field
$date = $this->createElement('DateTextBox', 'date',
array('require' => 'true', 'invalidMessage' => 'Invalid date format')
);
$date->setLabel('date')->setRequired(true);
You have few options to help yourself, without waiting for any plugin:
learn it and remember ;)
extend your phpDoc blocks with all available options:
Example (to be honest I don't know if Eclipse supports html in phpDoc or even any text after variable name in #param, but it works fine in Netbeans):
/**
* [...]
* #param string $type Can be: <ul><li>DateTextBox</li><li>ValidationTextBox</li></ul>
* #param string $name Whatever
* #param array|Zend_Config $options Array with following keys: <ul><li>require</li><li>invalidMessage</li></ul>
* #return Zend_Form_Element
*/
public function createElement($type, $name, $options = null)
extend Zend class and create your own methods to simplify your work
Example:
class My_Zend_Form_Element extends Zend_Form_Element
{
public function createDateTextBox($name, $options = null)
{
return $this->createElement('DateTextBox', $name, $options);
}
}
declare some well named constants and provide some hint in phpDoc
Example: (type ZFE_OPTIONS and IDE should show hint with some constants to use as array keys)
/**
* Can be true or false
*/
define('ZFE_OPTIONS_REQUIRE','require');
create your own helper classes with methods to produce valid options array
Example:
class ZFE_Options
{
protected $opts = array();
/**
* #param bool $req
* #return ZFE_Options
*/
public function setRequired($req){
$this->opts['require'] = (bool)$req;
return $this;
}
/**
* #param string $txt
* #return ZFE_Options
*/
public function setInvalidMessage($txt){
$this->opts['invalidMessage'] = (string)$txt;
return $this;
}
/**
* #return array
*/
public function toArray(){
return $this->opts;
}
}
$zfe_options = new ZFE_Options();
$opts = $zfe_options
->setRequired(true)
->setInvalidMessage('Please provide valid email address')
->toArray();
That's not possible. It's not how autocompletion works. The hints you get are taken directly from ZF's code documentation. Nothing more, nothing less. Everything you see as hints is taken directly from the DocBlock and method signature, e.g.
/**
* Create an element
*
* Acts as a factory for creating elements. Elements created with this
* method will not be attached to the form, but will contain element
* settings as specified in the form object (including plugin loader
* prefix paths, default decorators, etc.).
*
* #param string $type
* #param string $name
* #param array|Zend_Config $options
* #return Zend_Form_Element
*/
public function createElement($type, $name, $options = null)
Eclipse can tell you to insert a string or an array and it will know that the method returns a Zend_Form_Element, but it cannot tell you what these strings should be.
The only place where I know something like what you describe exists is for CSS files. For some reason, when I type in display: it will give me an autocomplete box with possible values for this declaration. If you want more sophisticated autocomplete like this, consider filing this as a feature request to Zend.

How to document a method that modifies a protected attribute with phpdoc?

What's the best way to document a method that modifies a protected attribute with phpdoc?
For instance, what is the correct way of documenting the setVar() method below?
class Test {
protected $variables = array();
public function setVar($name, $value) {
$this->$variables[$name] = $value;
}
}
Thanks in advance,
.L.
I suppose it depends on why you are wanting to highlight that the method affects that protected attribute...
If you just want to "say" it, just say so in the description, with or without using an inline #link tag:
/**
* Setter for $variables or {#link Test::$variables}
* ...
By using the inline #link, a hyperlink to the $variables documentation is generated in the method's description.
You could use the #see tag to be a standalone reference to the attribute:
/**
* Setter
* #see Test::$variables
* ...
This also makes a hyperlink to the attribute's doc, but it's more prominent by having its own tag.
If you want to create a "pointer" from the method to the attribute, use the #uses tag:
/**
* Setter
* #uses Test::$variables
* ...
The #uses tag in the method here will automatically place a #usedby tag in the documentation for the $variables property... the result is a hyperlink from the method to the attribute in the method's doc, as well as a hyperlink from the attribute to the method in the attribute's doc. Think of it as analogous to the "secret passages" in the Clue board game that connect corner rooms to their opposite corner rooms.
Another intention that can be satisfied via the #uses tag is that the documentation for $variables will show a list of #usedby tags that show all methods that affect the attribute... assuming, of course, that you have been conscientious about putting #uses tags in those methods.
I usually use something akin to the following, although there is probably a better way.
class Test {
protected $variables = array();
//**
* Setter for $this->variables
*
* #var string
* #var string
* #returns void
*/
public function setVar($name, $value) {
$this->$variables[$name] = $value;
}
}

Categories