lipemat/phpstan-wordpress

Phpstan extension for working with WordPress

Fund package maintenance!
lipemat

Installs: 18 416

Dependents: 1

Suggesters: 0

Security: 0

Stars: 7

Watchers: 3

Forks: 0

Open Issues: 0

Type:phpstan-extension

3.4.2 2024-12-04 17:10 UTC

README

package version php version Packagist

Usage

Install via composer

composer require lipemat/phpstan-wordpress

Included Stubs

  1. The semi-official phpstan-wordpress stubs.
  2. Custom stubs
    1. wp.php some additional stubs for WordPress

Optional Stubs

  1. WP-CLI stubs.
  2. WP-CLI Tools Stubs.
  3. CMB2 stubs
  4. Genesis stubs
  5. VIP stubs some stubs for WP VIP environments.

These may be selectively added to your phpstan.neon or phpstan.neon.dist like so:

When using library as a global install

scanFiles:
  - %rootDir%/../../../stubs/cmb2/cmb2-3.10.php
  - %rootDir%/../../../stubs/genesis/genesis-3.4.php
  - %rootDir%/../../../stubs/wp-cli/php-cli-tools-0.11.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

When using library as composer dependency

scanFiles:
  - %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/wp-cli/php-cli-tools-0.11.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

Alternatively, 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

Utility Types

\AtLeast<T, U>

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<T, K>

Exclude the specified keys from an array shape.

/**
 * @phpstan-var \Exclude<array{a: string, b: string}, 'a'> $array
 *   // results: array{b: string}
 */

\Partial<T>

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<T, K>

Pick only the specified keys from an array shape.

/**
 * @phpstan-var \Pick<array{a: string, b: string}, 'a'> $array
 *   // results: array{a: string}
 */

\Required<T>

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}                                                  
 */

\Sarcastic<T>

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
 */

\Union<T, U, ...X>

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}
 */

Optional Included Rules

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 global install
  - %rootDir%/../../../rules.neon
# If you are using this library as a composer dependency
  - %rootDir%/../../lipemat/phpstan-wordpress/rules.neon
  
  1. Prevent using the compact function.
  2. Require all classes to be either abstract or final.
  3. Require a declare(strict_types=1) statement in every non-empty file.
  4. Prevent using default values in class constructors.
  5. Prevent declaring a method protected in a final class in favor of private.
  6. Prevent using the switch statement in favor of match.
  7. Require any concrete methods in abstract classes to be private or final.
  8. Prevent child classes from skipping parent parameter types.
  9. Prevent calls to methods on unknown classes.
  10. Prefer returning null over false unless boolean is expected.
  11. Prohibit using ArrayAccess to access class data.
  12. Require instance of instead of isset for object verification.

Distributed plugins or themes

Some rules assume you are working on a private project which will not be distributed to the community. If your project will be distributed, you may add the nonDistributed parameter to the lipemat parameter.

parameters:
    lipemat:
      nonDistributed: false

The nonDistributed set to false parameter will disable the following rules:

  1. Require all classes to be either abstract or final.
  2. Require a declare(strict_types=1) statement in every non-empty file.
  3. Require any concrete methods in abstract classes to be private or final.

Prevent any inheritance

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: true

You may omit the allowedToBeExtended parameter to prevent extending any abstract classes.