php-stubs / wp-cli-stubs

WP-CLI function and class declaration stubs for static analysis.
https://packagist.org/packages/php-stubs/wp-cli-stubs
MIT License
23 stars 2 forks source link

PHPStan doesn't find the WP CLI stubs in scanFiles #8

Open devbanana opened 3 years ago

devbanana commented 3 years ago

The readme says to include wp-cli-stubs.php (and the other files) under scanFiles. I have this:

parameters:
    scanFiles:
        - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php
        - vendor/php-stubs/wp-cli-stubs/wp-cli-i18n-stubs.php
        - vendor/php-stubs/wp-cli-stubs/wp-cli-commands-stubs.php

But I have a class that extends WP_CLI_Command, and when analyzing that file I get:

Class WP_CLI_Command not found.

Only if I include it under bootstrapFiles does it work.

I'm not sure whether to report this on phpstan or here. Or if just something has changed not reflected in the documentation.

szepeviktor commented 3 years ago

Hello @devbanana ! Thank you for your report.

The root of the problem is that we need WP-CLI stubs at all. Normal packages and applications use Composer's autoloader thus PHPStan needs zero config to analyze them.

As WP-CLI is not an OOP project we need WP-CLI stubs. In general scanFiles: is enough when your PHPStan config does not run your code. I think something runs your code thus bootstrapFiles: has to execute the stubs to make classes available to PHP.

szepeviktor commented 3 years ago

BTW wp-cli-stubs.php may be enough for you, you do not need all three.

devbanana commented 3 years ago

Thank you for your reply. Very odd, any idea what would cause it to run my code? Our project is a bit legacy but we're using composer for autoloading. Any pointers of where to look would be appreciated.

szepeviktor commented 3 years ago

bootstrapFiles: starts your code! :) In composer.json autoload / files starts your code.

OR it could be that PHPStan analyzes your command class earlier than loading stubs with scanFiles: - which is strange.

szepeviktor commented 3 years ago

Please share your PHPStan configuration file if you need further help.

szepeviktor commented 3 years ago

+1 your code can be started when side-effects sit in a class file.

rosswintle commented 2 years ago

I'm seeing this too. Using bootstrapFiles fixes it. But thought I'd provide some more detail.

My phpstan.neon is:

includes:
    - vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
    level: 5
    paths:
        - local-config.php
        - app
        - public/wp-content/mu-plugins/
        - public/wp-content/themes/my-theme/
    scanFiles:
        - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php

It's definitely scanning the wp-cli-stubs.php because it reports:

Parameter #2 $callable of static method WP_CLI::add_command() expects callable(): mixed, '<some_other_file>' given.
rosswintle commented 2 years ago

Might be worth saying that I'm registering a command using the invokable syntax like this:

\WP_CLI::add_command( 'something docs', Command::class );

But I get the same if I do:

\WP_CLI::add_command( 'something docs', [ '<some namespace>\Command', '__invoke' ] );

The Command class looks like:

class Command extends \WP_CLI_Command {

    /**
     * @param array $args
     * @param array $assoc_args
     */
    public function __invoke( $args, $assoc_args ) {
        // Code
    }
}
szepeviktor commented 2 years ago

PHP is a tool for OOP code. In the OOP world you don't register functions nor methods. Ross! Try adding |class-string to add_command methods definition in WP-CLI stubs! https://github.com/wp-cli/wp-cli/blob/0c427c5f68f6265678e3db109d0a8f0e6f7887af/php/class-wp-cli.php#L467

rosswintle commented 2 years ago

Thanks. I know about OOP.

I think you've misunderstood though. Sorry if I wasn't clear.

When I mentioned:

Parameter #2 $callable of static method WP_CLI::add_command() expects callable(): mixed, '<some_other_file>' given.

it was to demonstrate that PHPStan is definitely scanning the wp-cli-stubs.php before the file being analyzed. If it wasn't then I wouldn't see this error.

The actual issue is the same one the OP had.

I have a class that extends WP_CLI_Command, and when analyzing that file I get:

Class WP_CLI_Command not found.

Only if I include it under bootstrapFiles does it work.

I was just providing more information about my case to see if it helped understand why using bootstrapFiles is required.

There might be something that you need to document here as the current instructions in the README don't seem to work for some cases.

P.S. Thanks for all you work making PHPStan work for WordPress 🙌