Timber
Timber

Reputation: 877

Resolve PhpStorm magic method and property warning using PHPDoc @property and @method for $this->stdout->styles

I'm trying to resolve

"Field 'stdout' not found in ..."

and

"Method ... not found in array"

warning using PHPDocumentor notations @property and @method on PhpStorm

enter image description here

I was able to resolve the warning for stdout using:

* @property array stdout

enter image description here

But now how do you resolve the Method 'styles' not found in array warning? (See screenshot above)


I made up this code to demonstrate what I'm trying to achieve:

* @method array $stdout->styles(array $name, array $items)

This is a CakePhp 2 project using CakePhp's Command Shell.

stdout->styles is declared in the framework.

For more context this is what my code looks like:

<?
class InvoiceShell extends AppShell {
    public $uses = array('Invoice', 'Request');

    public function main() {

        $this->stdout->styles('success', ['text' => 'green']);
        $this->stdout->styles('danger', ['text' => 'red']);
        $this->stdout->styles('bold', ['bold' => true]);

        .
        .
        .
    }
}

Upvotes: 4

Views: 1560

Answers (2)

Mert Aşan
Mert Aşan

Reputation: 436

Those with a similar problem can use this.

/** @var $items \Data\Items | mixed */

$items = new \Data\Items;

$items->method('data');
$items->item->method('data');

Upvotes: 0

David Harkness
David Harkness

Reputation: 36542

You need to tell PHPDoc/PhpStorm the correct type for stdout by replacing array with ConsoleOutput in your @property declaration.

/**
 * My cool class is cool.
 *
 * @property ConsoleOutput $stdout
 */

In cases where the object is a generic container with its own magic accessors, you can declare an interface solely for code completion by PhpStorm. Simply declare it in a file located in one of the Sources folders for your project.

/**
 * @method mixed styles(string, mixed)
 * @method ...
 */
interface FakeForCodeCompletion { }

Then reference FakeForCodeCompletion (preferably a descriptive name) in your class using @property as if it were a real class/interface.

Upvotes: 4

Related Questions