Onur Eren Elibol
Onur Eren Elibol

Reputation: 341

PhpStorm cannot autocomplete model attributes

simply I want PhpStorm autocomplete my model's attributes when I use find(), findAll(), findByAttributes() etc...

I have a model like:

/**
 * member model parameters:
 * @property integer $id
 * @property integer $city_id
 * @property string $e_mail
 */

    class Member extends CActiveRecord
    {
        /**
         * @static
         * @param string $className
         * @return Member
         */
        public static function model($className = __CLASS__)
        {
            return parent::model($className);
        }
...

When I use active record methods like:

$member = Member::model()->findByAttributes(array('e_mail'=>'Foo Bar'));

and try to autocomplete when I wrote this:

$member->

It only gives me CActiveRecord's parameters and methods in the list.

I tried to change

    /**
     * Finds a single active record that has the specified attribute values.
     * See {@link find()} for detailed explanation about $condition and $params.
     * @param array $attributes list of attribute values (indexed by attribute names) that the active records should match.
     * An attribute value can be an array which will be used to generate an IN condition.
     * @param mixed $condition query condition or criteria.
     * @param array $params parameters to be bound to an SQL statement.
     * @return CActiveRecord the record found. Null if none is found.
     */
    public function findByAttributes($attributes,$condition='',$params=array())
    {...

this method's return param from CActiveRecord to Member, self, parent, $this, child etc... Autocomplete only worked when it was "Member". But this method is used for all models not just the Member model so this is not a solution.

If anyone knows the solution (preferably without changing the framework core methods) I will be glad.

Upvotes: 3

Views: 2252

Answers (2)

lucifurious
lucifurious

Reputation: 640

NOTE: All of my awesome Yii code is freely available on bitbucket in the repositories here and here. If you hate Yii's verbosity, check out my Pii class. I think you'll totally dig it.

I've run into this and what I do is augment the phpdoc for the static model() method. This corrects the issue and the autocomplete works fine.

For instance:

class MyModel extends CActiveRecord {

         /**
         * @static
         * @param string $className
         * @return MyModel|CActiveRecord
         */    
         public static function model($className=__CLASS__) {
             .... yada yada yada ...
         }

}

Note the pipe and additional class added to the "@return". This tells PhpStorm to also include that class in the auto-complete lookups.

One additional note, if you're using namespaces, you may need a slash in front of some class names. Just depends on your project and includes.

=============== UPDATE: 2013-08-05 ===============

With PhpStorm v6 and up, it looks like you can use:

   *
   * @return $this
   *

And also get proper auto-completion.

On a side note, the whole static "model()" method thing is antiquated (like Yii) and I have a base model class that I use now for all projects. It contains the static model method; which is then no longer required in each of my subclasses. Here's an example...

<?php
namespace My\Awesome\Name\Space;

/**
 * MyBaseModel
 * etc.etc.
 */
class MyBaseModel extends \CActiveRecord
{
    /**
     * Returns the static model of the specified AR class.
     *
     * @param string $className
     *
     * @return $this
     */
    public static function model( $className = null )
    {
        return parent::model( $className ? : \get_called_class() );
    }

    //code code code code
}

/**
 * MySubModel
 */
class MySubModel extends MyBaseModel
{
    /**
     * {@InheritDoc}
     */
    public function tableName()
    {
        return 'my_sub_table';
    }
}

$_models = MySubModel::model()->findAll( 'xyz = :xyz', array( ':xyz' => 'abc' ) );

if ( !empty( $_models ) )
{
    foreach ( $_models as $_model )
    {
        //  Do awesome stuff...
    }
}

Autocomplete works fine for all the subclasses...

Just thought I'd update this and let y'all know.

Upvotes: 3

Alexey Prokhorov
Alexey Prokhorov

Reputation: 3931

You can use phpdoc @method. You can use this approach for frequently-used models or you can create new template for code generator.

    /**
     * @method Member findByPk($pk,$condition='',$params=array())
     */
    class Member extends CActiveRecord
    {

Upvotes: 0

Related Questions