Skip to content

PHPStan level 9 #536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
"wp-cli/extension-command": "^1.2 || ^2",
"wp-cli/media-command": "^1.1 || ^2",
"wp-cli/super-admin-command": "^1 || ^2",
"wp-cli/wp-cli-tests": "^4"
"wp-cli/wp-cli-tests": "dev-add/phpstan-enhancements"
},
"config": {
"process-timeout": 7200,
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"johnpbloch/wordpress-core-installer": true
"johnpbloch/wordpress-core-installer": true,
"phpstan/extension-installer": true
},
"lock": false
},
Expand Down Expand Up @@ -230,12 +231,14 @@
"behat-rerun": "rerun-behat-tests",
"lint": "run-linter-tests",
"phpcs": "run-phpcs-tests",
"phpstan": "run-phpstan-tests",
"phpunit": "run-php-unit-tests",
"phpcbf": "run-phpcbf-cleanup",
"prepare-tests": "install-package-tests",
"test": [
"@lint",
"@phpcs",
"@phpstan",
"@phpunit",
"@behat"
]
Expand Down
24 changes: 2 additions & 22 deletions entity-command.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,7 @@
);
WP_CLI::add_command( 'taxonomy', 'Taxonomy_Command' );
WP_CLI::add_command( 'term', 'Term_Command' );
WP_CLI::add_command(
'term meta',
'Term_Meta_Command',
array(
'before_invoke' => function () {
if ( Utils\wp_version_compare( '4.4', '<' ) ) {
WP_CLI::error( 'Requires WordPress 4.4 or greater.' );
}
},
)
);
WP_CLI::add_command( 'term meta', 'Term_Meta_Command' );
WP_CLI::add_command( 'user', 'User_Command' );
WP_CLI::add_command(
'user application-password',
Expand All @@ -84,17 +74,7 @@
)
);
WP_CLI::add_command( 'user meta', 'User_Meta_Command' );
WP_CLI::add_command(
'user session',
'User_Session_Command',
array(
'before_invoke' => function () {
if ( Utils\wp_version_compare( '4.0', '<' ) ) {
WP_CLI::error( 'Requires WordPress 4.0 or greater.' );
}
},
)
);
WP_CLI::add_command( 'user session', 'User_Session_Command' );
WP_CLI::add_command( 'user term', 'User_Term_Command' );

if ( class_exists( 'WP_CLI\Dispatcher\CommandNamespace' ) ) {
Expand Down
34 changes: 0 additions & 34 deletions features/post.feature
Original file line number Diff line number Diff line change
Expand Up @@ -451,40 +451,6 @@ Feature: Manage WordPress posts
Test Post
"""

@less-than-wp-4.4
Scenario: Creating/updating posts with meta keys for WP < 4.4 has no effect so should give warning
When I try `wp post create --post_title='Test Post' --post_content='Test post content' --meta_input='{"key1":"value1","key2":"value2"}' --porcelain`
Then the return code should be 0
And STDOUT should be a number
And save STDOUT as {POST_ID}
And STDERR should be:
"""
Warning: The 'meta_input' field was only introduced in WordPress 4.4 so will have no effect.
"""

When I run `wp post meta list {POST_ID} --format=count`
Then STDOUT should be:
"""
0
"""

When I try `wp post update {POST_ID} --meta_input='{"key2":"value2b","key3":"value3"}'`
Then the return code should be 0
And STDERR should be:
"""
Warning: The 'meta_input' field was only introduced in WordPress 4.4 so will have no effect.
"""
And STDOUT should be:
"""
Success: Updated post {POST_ID}.
"""

When I run `wp post meta list {POST_ID} --format=count`
Then STDOUT should be:
"""
0
"""

Scenario: Publishing a post and setting a date fails if the edit_date flag is not passed.
Given a WP install

Expand Down
16 changes: 16 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
parameters:
level: 9
paths:
- src
- entity-command.php
scanDirectories:
- vendor/wp-cli/wp-cli/php
- vendor/wp-cli/wp-cli-tests
scanFiles:
- vendor/php-stubs/wordpress-stubs/wordpress-stubs.php
treatPhpDocTypesAsCertain: false
ignoreErrors:
- identifier: missingType.iterableValue
- identifier: missingType.property
- identifier: missingType.parameter
- identifier: missingType.return
50 changes: 29 additions & 21 deletions src/Comment_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
]
);
if ( 'progress' === $format ) {
$notify->tick();

Check failure on line 193 in src/Comment_Command.php

View workflow job for this annotation

GitHub Actions / code-quality / PHPStan

Call to an undefined method cli\progress\Bar|WP_CLI\NoOp::tick().
} elseif ( 'ids' === $format ) {
echo $comment_id;
if ( $index < $limit - 1 ) {
Expand All @@ -200,7 +200,7 @@
}

if ( 'progress' === $format ) {
$notify->finish();

Check failure on line 203 in src/Comment_Command.php

View workflow job for this annotation

GitHub Actions / code-quality / PHPStan

Call to an undefined method cli\progress\Bar|WP_CLI\NoOp::finish().
}
}

Expand Down Expand Up @@ -243,6 +243,7 @@
}

if ( ! isset( $comment->url ) ) {
// @phpstan-ignore property.notFound
$comment->url = get_comment_link( $comment );
}

Expand Down Expand Up @@ -366,6 +367,8 @@
public function list_( $args, $assoc_args ) {
$formatter = $this->get_formatter( $assoc_args );

// To be fixed in wp-cli/wp-cli.
// @phpstan-ignore property.notFound
if ( 'ids' === $formatter->format ) {
$assoc_args['fields'] = 'comment_ID';
}
Expand All @@ -376,29 +379,27 @@
$assoc_args['count'] = true;
}

if ( ! empty( $assoc_args['comment__in'] )
&& ! empty( $assoc_args['orderby'] )
&& 'comment__in' === $assoc_args['orderby']
&& Utils\wp_version_compare( '4.4', '<' ) ) {
$comments = [];
foreach ( $assoc_args['comment__in'] as $comment_id ) {
$comment = get_comment( $comment_id );
if ( $comment ) {
$comments[] = $comment;
} else {
WP_CLI::warning( "Invalid comment {$comment_id}." );
}
}
} else {
$query = new WP_Comment_Query();
$comments = $query->query( $assoc_args );
}
$query = new WP_Comment_Query();
$comments = $query->query( $assoc_args );

if ( 'count' === $formatter->format ) {
/**
* @var int $comments
*/
echo $comments;
return;
} else {
/**
* @var array $comments
*/

if ( 'ids' === $formatter->format ) {
$comments = wp_list_pluck( $comments, 'comment_ID' );
/**
* @var \WP_Comment[] $comments
*/
$items = wp_list_pluck( $comments, 'comment_ID' );

$comments = $items;
} elseif ( is_array( $comments ) ) {
$comments = array_map(
function ( $comment ) {
Expand Down Expand Up @@ -439,7 +440,7 @@
$args,
$assoc_args,
function ( $comment_id, $assoc_args ) {
$force = Utils\get_flag_value( $assoc_args, 'force' );
$force = (bool) Utils\get_flag_value( $assoc_args, 'force' );

$status = wp_get_comment_status( $comment_id );
$result = wp_delete_comment( $comment_id, $force );
Expand All @@ -457,6 +458,9 @@
private function call( $args, $status, $success, $failure ) {
$comment_id = absint( $args );

/**
* @var callable $func
*/
$func = "wp_{$status}_comment";

if ( ! $func( $comment_id ) ) {
Expand Down Expand Up @@ -642,16 +646,17 @@
* total_comments: 19
*/
public function count( $args, $assoc_args ) {
$post_id = Utils\get_flag_value( $args, 0, 0 );
$post_id = $args[0] ?? null;

$count = wp_count_comments( $post_id );

// Move total_comments to the end of the object
$total = $count->total_comments;
unset( $count->total_comments );
// @phpstan-ignore assign.propertyReadOnly
$count->total_comments = $total;

foreach ( $count as $status => $count ) {
foreach ( (array) $count as $status => $count ) {
WP_CLI::line( str_pad( "$status:", 17 ) . $count );
}
}
Expand All @@ -673,6 +678,9 @@
public function recount( $args ) {
foreach ( $args as $id ) {
if ( wp_update_comment_count( $id ) ) {
/**
* @var \WP_Post $post
*/
$post = get_post( $id );
WP_CLI::log( "Updated post {$post->ID} comment count to {$post->comment_count}." );
} else {
Expand Down
5 changes: 3 additions & 2 deletions src/Comment_Meta_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
*
* @return mixed Single metadata value, or array of values.
*/
protected function get_metadata( $object_id, $meta_key = '', $single = false ) {

Check failure on line 80 in src/Comment_Meta_Command.php

View workflow job for this annotation

GitHub Actions / code-quality / PHPStan

Return type (mixed) of method Comment_Meta_Command::get_metadata() should be covariant with return type (($single is true ? string : array<string>)) of method WP_CLI\CommandWithMeta::get_metadata()
return get_comment_meta( $object_id, $meta_key, $single );
}

Expand All @@ -104,11 +104,12 @@
/**
* Check that the comment ID exists
*
* @param int
* @param string|int $object_id
* @return int|never
*/
protected function check_object_id( $object_id ) {
$fetcher = new CommentFetcher();
$comment = $fetcher->get_check( $object_id );
$comment = $fetcher->get_check( (string) $object_id );
return $comment->comment_ID;

Check failure on line 113 in src/Comment_Meta_Command.php

View workflow job for this annotation

GitHub Actions / code-quality / PHPStan

Cannot access property $comment_ID on mixed.
}
}
3 changes: 2 additions & 1 deletion src/Menu_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function create( $args, $assoc_args ) {

} elseif ( Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {

WP_CLI::line( $menu_id );
WP_CLI::line( (string) $menu_id );
} else {
WP_CLI::success( "Created menu {$menu_id}." );
}
Expand Down Expand Up @@ -166,6 +166,7 @@ public function list_( $args, $assoc_args ) {
$menu_locations = get_nav_menu_locations();
foreach ( $menus as &$menu ) {

// @phpstan-ignore property.notFound
$menu->locations = [];
foreach ( $menu_locations as $location => $term_id ) {

Expand Down
16 changes: 12 additions & 4 deletions src/Menu_Item_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
public function list_( $args, $assoc_args ) {

$items = wp_get_nav_menu_items( $args[0] );
if ( false === $items || is_wp_error( $items ) ) {
if ( false === $items ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it impossible here to end up with a WP_Error? Relying on the docblocks is not enough, and I'm seeing that multiple filters are involved... 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no code path in there that returns WP_Error, I already checked.

Filters can always be abused, but we can‘t check for every possible return value.

git blame was unfortunately not helpful here (mangled history)

WP_CLI::error( 'Invalid menu.' );
}

Expand Down Expand Up @@ -369,7 +369,7 @@

$post = get_post( $arg );
$menu_term = get_the_terms( $arg, 'nav_menu' );
$parent_menu_id = (int) get_post_meta( $arg, '_menu_item_menu_item_parent', true );

Check failure on line 372 in src/Menu_Item_Command.php

View workflow job for this annotation

GitHub Actions / code-quality / PHPStan

Cannot cast mixed to int.
$result = wp_delete_post( $arg, true );
if ( ! $result ) {
WP_CLI::warning( "Couldn't delete menu item {$arg}." );
Expand Down Expand Up @@ -408,10 +408,10 @@
private function add_or_update_item( $method, $type, $args, $assoc_args ) {

$menu = $args[0];
$menu_item_db_id = Utils\get_flag_value( $args, 1, 0 );
$menu_item_db_id = $args[1] ?? 0;

$menu = wp_get_nav_menu_object( $menu );
if ( ! $menu || is_wp_error( $menu ) ) {
if ( false === $menu ) {
Comment on lines -414 to +416
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here re. WP_Error. I'm assuming there was a reason why that particular check was in there?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so.

It was originally introduced in 246a8bc, but without any test coverage or so.

Like in the other cases, this function never returns a WP_Error

WP_CLI::error( 'Invalid menu.' );
}

Expand All @@ -422,6 +422,14 @@
if ( 'update' === $method ) {

$menu_item_obj = get_post( $menu_item_db_id );

if ( ! $menu_item_obj ) {
WP_CLI::error( 'Invalid menu.' );
}

/**
* @var object{title: string, url: string, description: string, object: string, object_id: int, menu_item_parent: int, attr_title: string, target: string, classes: string[], xfn: string, post_status: string, menu_order: int} $menu_item_obj
*/
$menu_item_obj = wp_setup_nav_menu_item( $menu_item_obj );

// Correct the menu position if this was the first item. See https://core.trac.wordpress.org/ticket/28140
Expand Down Expand Up @@ -502,7 +510,7 @@
}

if ( 'add' === $method && ! empty( $assoc_args['porcelain'] ) ) {
WP_CLI::line( $result );
WP_CLI::line( (string) $result );
} elseif ( 'add' === $method ) {
WP_CLI::success( 'Menu item added.' );
} elseif ( 'update' === $method ) {
Expand Down
10 changes: 8 additions & 2 deletions src/Menu_Location_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public function list_( $args, $assoc_args ) {

$formatter = new Formatter( $assoc_args, [ 'location', 'description' ] );

// To be fixed in wp-cli/wp-cli.
// @phpstan-ignore property.notFound
if ( 'ids' === $formatter->format ) {
$ids = array_map(
function ( $o ) {
Expand Down Expand Up @@ -107,6 +109,8 @@ function ( $o ) {
* Success: Assigned location primary to menu primary-menu.
*
* @subcommand assign
*
* @param array{string, string} $args
*/
public function assign( $args, $assoc_args ) {

Expand Down Expand Up @@ -147,18 +151,20 @@ public function assign( $args, $assoc_args ) {
* Success: Removed location from menu.
*
* @subcommand remove
*
* @param array{string, string} $args
*/
public function remove( $args, $assoc_args ) {

list( $menu, $location ) = $args;

$menu = wp_get_nav_menu_object( $menu );
if ( ! $menu || is_wp_error( $menu ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here re. WP_Error.

if ( false === $menu ) {
WP_CLI::error( 'Invalid menu.' );
}

$locations = get_nav_menu_locations();
if ( Utils\get_flag_value( $locations, $location ) !== $menu->term_id ) {
if ( ( $locations[ $location ] ?? null ) !== $menu->term_id ) {
WP_CLI::error( "Menu isn't assigned to location." );
}

Expand Down
Loading
Loading