Install via composer
composer require lipemat/phpstan-wordpress- The semi-official phpstan-wordpress stubs.
- Custom stubs
wp.phpsome additional stubs for WordPress
- WP-CLI stubs.
WP-CLI Tools Stubs.Included in the wp-cli-stubs package since version 2.11.0.- CMB2 stubs
- Genesis stubs
- VIP stubs some stubs for WP VIP environments.
These may be selectively added to your phpstan.neon or phpstan.neon.dist like so:
scanFiles:
- %rootDir%/../../../stubs/cmb2/cmb2-3.10.php
- %rootDir%/../../../stubs/genesis/genesis-3.4.php
- %rootDir%/../../../stubs/vip.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-stubs.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-commands-stubs.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-i18n-stubs.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-tools-stubs.phpscanFiles:
- %rootDir%/../../lipemat/phpstan-wordpress/stubs/cmb2/cmb2-3.10.php
- %rootDir%/../../lipemat/phpstan-wordpress/stubs/genesis/genesis-3.4.php
- %rootDir%/../../lipemat/phpstan-wordpress/stubs/vip.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-stubs.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-commands-stubs.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-i18n-stubs.php
- %rootDir%/../../php-stubs/wp-cli-stubs/wp-cli-tools-stubs.phpAlternatively, you may replace %rootDir%/../../ with the relative path to your vendor directory.
Example wp-content/plugins/core/vendor/lipemat/phpstan-wordpress/stubs/cmb2/cmb2-3.10.php
Mark a set of array shape keys as required while making the rest optional.
/**
* @phpstan-var \AtLeast<array{a?: string, b?: string}, 'a'> $array
* // results: array{a: string, b?: string}
*/Exclude the specified keys from an array shape.
/**
* @phpstan-var \Exclude<array{a: string, b: string}, 'a'> $array
* // results: array{b: string}
*/Mark either all or specified keys in an array shape as optional.
\Partial<T>: Mark all keys as optional.\Partial<T, K>: Mark only the specified keys as optional.
/**
* @phpstan-var \Optional<array{a: string, b: string}> $array
* // results: array{a?: string, b?: string}
*
* @phpstan-var \Optional<array{a: string, b: string}, 'b'> $array
* // results: array{a: string, b?: string}
*/Pick only the specified keys from an array shape.
/**
* @phpstan-var \Pick<array{a: string, b: string}, 'a'> $array
* // results: array{a: string}
*/Mark either all or specified keys in an array shape as required.
\Required<T>: Mark all keys as required.\Required<T, K>: Mark only the specified keys as required.
/**
* @phpstan-var \Required<array{a?: string, b?: string}> $array
* // results: array{a: string, b: string}
*
* @phpstan-var \Required<array{a?: string, b?: string}, 'b'> $array
* // results: array{a?: string, b: string}
*/Mark a type as an unpredictable random value.
This utility is extremely useful in everyday projects.
/**
* @phpstan-var \Sarcastic<string> $string
* // results: anyone's guess
*/Combine two or more array shapes as if you were using array_merge with the second array overwriting the first.
/**
* @phpstan-var \Union<array{a: string}, array{b: string}> $array
* // results: array{a: string, b: string}
*/As we move toward a world where we use composition over inheritance, we need to be more strict about how we write our code. These optional rules do not get us all the way there, but they are a step in the right direction while still being viable for a WordPress project.
Enable in your phpstan.neon or phpstan.neon.dist like so:
includes:
# If you are using this library as a globally installed library.
- %rootDir%/../../../rules.neon
# If you are using this library as a composer dependency.
- %rootDir%/../../lipemat/phpstan-wordpress/rules.neon
- Prevent using the
compactfunction. - Prevent using the
extractfunction. - Require all classes to be either abstract or final.
- Require a
declare(strict_types=1)statement in every non-empty file. - Prevent using default values in class constructors.
- Prevent declaring a method
protectedin a final class in favor ofprivate.- Rule is now disabled by default but may be enabled manually.
- Prevent using the
switchstatement in favor ofmatch. - Require any concrete methods in abstract classes to be
privateorfinal. - Prevent child classes from skipping parent parameter types.
- Prevent calls to methods on unknown classes.
- Prefer returning null over false unless boolean is expected.
- Prohibit using
ArrayAccessto access class data. - Require
instance ofinstead ofissetfor object verification.
Some rules assume you are working on a private project which will not be distributed to the community.
If your project is distributed, you may add the nonDistributed parameter to the lipemat parameter.
parameters:
lipemat:
nonDistributed: falseThe nonDistributed set to false parameter will disable the following rules:
- Require all classes to be either abstract or final.
- Require a
declare(strict_types=1)statement in every non-empty file. - Require any concrete methods in abstract classes to be
privateorfinal.
Adding the noExtends parameter to the lipemat parameter will prevent having or extending any unlisted abstract classes.
parameters:
lipemat:
allowedToBeExtended:
- Lipe\Project\SomeAbstractClass
- Lipe\Project\SomeOtherAbstractClass
noExtends: trueYou may omit the allowedToBeExtended parameter to prevent extending any abstract classes.