Almost level 7

This commit is contained in:
Pascal Birchler 2025-05-19 10:49:35 +02:00
parent db4f48e5c6
commit 99de66ce62
No known key found for this signature in database
GPG key ID: 0DECE73DD74E8B2F
11 changed files with 90 additions and 89 deletions

View file

@ -60,17 +60,7 @@ WP_CLI::add_command(
); );
WP_CLI::add_command( 'taxonomy', 'Taxonomy_Command' ); WP_CLI::add_command( 'taxonomy', 'Taxonomy_Command' );
WP_CLI::add_command( 'term', 'Term_Command' ); WP_CLI::add_command( 'term', 'Term_Command' );
WP_CLI::add_command( WP_CLI::add_command( 'term meta', 'Term_Meta_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( 'user', 'User_Command' ); WP_CLI::add_command( 'user', 'User_Command' );
WP_CLI::add_command( WP_CLI::add_command(
'user application-password', 'user application-password',
@ -84,17 +74,7 @@ WP_CLI::add_command(
) )
); );
WP_CLI::add_command( 'user meta', 'User_Meta_Command' ); WP_CLI::add_command( 'user meta', 'User_Meta_Command' );
WP_CLI::add_command( WP_CLI::add_command( 'user session', 'User_Session_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 term', 'User_Term_Command' ); WP_CLI::add_command( 'user term', 'User_Term_Command' );


if ( class_exists( 'WP_CLI\Dispatcher\CommandNamespace' ) ) { if ( class_exists( 'WP_CLI\Dispatcher\CommandNamespace' ) ) {

View file

@ -379,29 +379,22 @@ class Comment_Command extends CommandWithDBObject {
$assoc_args['count'] = true; $assoc_args['count'] = true;
} }


if ( ! empty( $assoc_args['comment__in'] ) $query = new WP_Comment_Query();
&& ! empty( $assoc_args['orderby'] ) $comments = $query->query( $assoc_args );
&& '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 );
}


if ( 'count' === $formatter->format ) { if ( 'count' === $formatter->format ) {
/**
* @var int $comments
*/
echo $comments; echo $comments;
} else { } else {
if ( 'ids' === $formatter->format ) { 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 ) ) { } elseif ( is_array( $comments ) ) {
$comments = array_map( $comments = array_map(
function ( $comment ) { function ( $comment ) {
@ -460,6 +453,9 @@ class Comment_Command extends CommandWithDBObject {
private function call( $args, $status, $success, $failure ) { private function call( $args, $status, $success, $failure ) {
$comment_id = absint( $args ); $comment_id = absint( $args );


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


if ( ! $func( $comment_id ) ) { if ( ! $func( $comment_id ) ) {

View file

@ -422,6 +422,10 @@ class Menu_Item_Command extends WP_CLI_Command {
if ( 'update' === $method ) { if ( 'update' === $method ) {


$menu_item_obj = get_post( $menu_item_db_id ); $menu_item_obj = get_post( $menu_item_db_id );

/**
* @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 ); $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 // Correct the menu position if this was the first item. See https://core.trac.wordpress.org/ticket/28140

View file

@ -746,17 +746,11 @@ class Option_Command extends WP_CLI_Command {
} }


private static function esc_like( $old ) { private static function esc_like( $old ) {
/**
* @var \wpdb $wpdb
*/
global $wpdb; global $wpdb;


// Remove notices in 4.0 and support backwards compatibility return $wpdb->esc_like( $old );
if ( method_exists( $wpdb, 'esc_like' ) ) {
// 4.0
$old = $wpdb->esc_like( $old );
} else {
// phpcs:ignore WordPress.WP.DeprecatedFunctions.like_escapeFound -- called in WordPress 3.9 or less.
$old = like_escape( esc_sql( $old ) );
}

return $old;
} }
} }

View file

@ -933,7 +933,7 @@ class Post_Command extends CommandWithDBObject {
} else { } else {
$readfile = 'php://stdin'; $readfile = 'php://stdin';
} }
return file_get_contents( $readfile ); return (string) file_get_contents( $readfile );
} }


/** /**
@ -1010,7 +1010,7 @@ class Post_Command extends CommandWithDBObject {
private function get_tags( $post_id ) { private function get_tags( $post_id ) {
$tag_data = get_the_tags( $post_id ); $tag_data = get_the_tags( $post_id );
$tag_arr = []; $tag_arr = [];
if ( $tag_data ) { if ( $tag_data && ! is_wp_error( $tag_data ) ) {
foreach ( $tag_data as $tag ) { foreach ( $tag_data as $tag ) {
array_push( $tag_arr, $tag->slug ); array_push( $tag_arr, $tag->slug );
} }

View file

@ -29,6 +29,8 @@ use WP_CLI\Fetchers\User as UserFetcher;
* Success: The site at 'http://www.example.com/example' was deleted. * Success: The site at 'http://www.example.com/example' was deleted.
* *
* @package wp-cli * @package wp-cli
*
* @phpstan-type UserSite object{userblog_id: int, blogname: string, domain: string, path: string, site_id: int, siteurl: string, archived: int, spam: int, deleted: int}
*/ */
class Site_Command extends CommandWithDBObject { class Site_Command extends CommandWithDBObject {


@ -809,6 +811,9 @@ class Site_Command extends CommandWithDBObject {
$user = ( new UserFetcher() )->get_check( $assoc_args['site_user'] ); $user = ( new UserFetcher() )->get_check( $assoc_args['site_user'] );


if ( $user ) { if ( $user ) {
/**
* @phpstan-var UserSite[] $blogs
*/
$blogs = get_blogs_of_user( $user->ID ); $blogs = get_blogs_of_user( $user->ID );


foreach ( $blogs as $blog ) { foreach ( $blogs as $blog ) {

View file

@ -406,17 +406,11 @@ class Site_Option_Command extends WP_CLI_Command {
} }


private static function esc_like( $old ) { private static function esc_like( $old ) {
/**
* @var \wpdb $wpdb
*/
global $wpdb; global $wpdb;


// Remove notices in 4.0 and support backwards compatibility return $wpdb->esc_like( $old );
if ( method_exists( $wpdb, 'esc_like' ) ) {
// 4.0
$old = $wpdb->esc_like( $old );
} else {
// phpcs:ignore WordPress.WP.DeprecatedFunctions.like_escapeFound -- called in WordPress 3.9 or less.
$old = like_escape( esc_sql( $old ) );
}

return $old;
} }
} }

View file

@ -223,11 +223,6 @@ class Term_Command extends WP_CLI_Command {
$porcelain = Utils\get_flag_value( $assoc_args, 'porcelain' ); $porcelain = Utils\get_flag_value( $assoc_args, 'porcelain' );
unset( $assoc_args['porcelain'] ); unset( $assoc_args['porcelain'] );


// Compatibility for < WP 4.0
if ( $assoc_args['parent'] > 0 && ! term_exists( (int) $assoc_args['parent'] ) ) {
WP_CLI::error( 'Parent term does not exist.' );
}

$assoc_args = wp_slash( $assoc_args ); $assoc_args = wp_slash( $assoc_args );
$term = wp_slash( $term ); $term = wp_slash( $term );
$result = wp_insert_term( $term, $taxonomy, $assoc_args ); $result = wp_insert_term( $term, $taxonomy, $assoc_args );
@ -537,10 +532,13 @@ class Term_Command extends WP_CLI_Command {
WP_CLI::error( "'{$taxonomy}' is not a registered taxonomy." ); WP_CLI::error( "'{$taxonomy}' is not a registered taxonomy." );
} }


$label = get_taxonomy( $taxonomy )->labels->singular_name; /**
$slug = sanitize_title_with_dashes( $label ); * @var \WP_Taxonomy $tax
*/
$tax = get_taxonomy( $taxonomy );


$hierarchical = get_taxonomy( $taxonomy )->hierarchical; $label = $tax->labels->singular_name;
$slug = sanitize_title_with_dashes( $label );


$format = Utils\get_flag_value( $assoc_args, 'format', 'progress' ); $format = Utils\get_flag_value( $assoc_args, 'format', 'progress' );


@ -560,7 +558,7 @@ class Term_Command extends WP_CLI_Command {


for ( $index = $max_id + 1; $index <= $max_id + $count; $index++ ) { for ( $index = $max_id + 1; $index <= $max_id + $count; $index++ ) {


if ( $hierarchical ) { if ( $tax->hierarchical ) {


if ( $previous_term_id && $this->maybe_make_child() && $current_depth < $max_depth ) { if ( $previous_term_id && $this->maybe_make_child() && $current_depth < $max_depth ) {


@ -645,6 +643,10 @@ class Term_Command extends WP_CLI_Command {
WP_CLI::warning( "Taxonomy {$taxonomy} does not exist." ); WP_CLI::warning( "Taxonomy {$taxonomy} does not exist." );
} else { } else {


/**
* @var \WP_Term[] $terms
*/

// phpcs:ignore WordPress.WP.DeprecatedParameters.Get_termsParam2Found -- Required for backward compatibility. // phpcs:ignore WordPress.WP.DeprecatedParameters.Get_termsParam2Found -- Required for backward compatibility.
$terms = get_terms( $taxonomy, [ 'hide_empty' => false ] ); $terms = get_terms( $taxonomy, [ 'hide_empty' => false ] );
$term_taxonomy_ids = wp_list_pluck( $terms, 'term_taxonomy_id' ); $term_taxonomy_ids = wp_list_pluck( $terms, 'term_taxonomy_id' );
@ -699,7 +701,11 @@ class Term_Command extends WP_CLI_Command {
WP_CLI::error( "Taxonomy term '{$term_reference}' for taxonomy '{$original_taxonomy}' doesn't exist." ); WP_CLI::error( "Taxonomy term '{$term_reference}' for taxonomy '{$original_taxonomy}' doesn't exist." );
} }


$original_taxonomy = get_taxonomy( $original_taxonomy ); $tax = get_taxonomy( $original_taxonomy );

if ( ! $tax ) {
WP_CLI::error( "Taxonomy '{$original_taxonomy}' doesn't exist." );
}


$id = wp_insert_term( $id = wp_insert_term(
$term->name, $term->name,
@ -715,11 +721,14 @@ class Term_Command extends WP_CLI_Command {
WP_CLI::error( $id->get_error_message() ); WP_CLI::error( $id->get_error_message() );
} }


$post_ids = get_objects_in_term( $term->term_id, $original_taxonomy->name ); /**
* @var string[] $post_ids
*/
$post_ids = get_objects_in_term( $term->term_id, $tax->name );


foreach ( $post_ids as $post_id ) { foreach ( $post_ids as $post_id ) {
$type = get_post_type( (int) $post_id ); $type = get_post_type( (int) $post_id );
if ( in_array( $type, $original_taxonomy->object_type, true ) ) { if ( in_array( $type, $tax->object_type, true ) ) {
$term_taxonomy_id = wp_set_object_terms( (int) $post_id, $id['term_id'], $destination_taxonomy, true ); $term_taxonomy_id = wp_set_object_terms( (int) $post_id, $id['term_id'], $destination_taxonomy, true );


if ( is_wp_error( $term_taxonomy_id ) ) { if ( is_wp_error( $term_taxonomy_id ) ) {
@ -736,7 +745,7 @@ class Term_Command extends WP_CLI_Command {


WP_CLI::log( "Term '{$term->slug}' migrated." ); WP_CLI::log( "Term '{$term->slug}' migrated." );


$del = wp_delete_term( $term->term_id, $original_taxonomy->name ); $del = wp_delete_term( $term->term_id, $tax->name );


if ( is_wp_error( $del ) ) { if ( is_wp_error( $del ) ) {
WP_CLI::error( "Failed to delete the term '{$term->slug}'. Reason: " . $del->get_error_message() ); WP_CLI::error( "Failed to delete the term '{$term->slug}'. Reason: " . $del->get_error_message() );
@ -745,7 +754,7 @@ class Term_Command extends WP_CLI_Command {
WP_CLI::log( "Old instance of term '{$term->slug}' removed from its original taxonomy." ); WP_CLI::log( "Old instance of term '{$term->slug}' removed from its original taxonomy." );
$post_count = count( $post_ids ); $post_count = count( $post_ids );
$post_plural = Utils\pluralize( 'post', $post_count ); $post_plural = Utils\pluralize( 'post', $post_count );
WP_CLI::success( "Migrated the term '{$term->slug}' from taxonomy '{$original_taxonomy->name}' to taxonomy '{$destination_taxonomy}' for {$post_count} {$post_plural}." ); WP_CLI::success( "Migrated the term '{$term->slug}' from taxonomy '{$tax->name}' to taxonomy '{$destination_taxonomy}' for {$post_count} {$post_plural}." );
} }


private function maybe_make_child() { private function maybe_make_child() {

View file

@ -33,7 +33,7 @@ class Term_Meta_Command extends CommandWithMeta {
*/ */
protected function check_object_id( $object_id ) { protected function check_object_id( $object_id ) {
$term = get_term( $object_id ); $term = get_term( $object_id );
if ( ! $term ) { if ( ! $term || is_wp_error( $term ) ) {
WP_CLI::error( "Could not find the term with ID {$object_id}." ); WP_CLI::error( "Could not find the term with ID {$object_id}." );
} }
return $term->term_id; return $term->term_id;
@ -52,7 +52,7 @@ class Term_Meta_Command extends CommandWithMeta {
* value for the specified metadata key, no change * value for the specified metadata key, no change
* will be made. * will be made.
* *
* @return int|false The meta ID on success, false on failure. * @return int|false|WP_Error The meta ID on success, false on failure, WP_Error when term_id is ambiguous between taxonomies.
*/ */
protected function add_metadata( $object_id, $meta_key, $meta_value, $unique = false ) { protected function add_metadata( $object_id, $meta_key, $meta_value, $unique = false ) {
return add_term_meta( $object_id, $meta_key, $meta_value, $unique ); return add_term_meta( $object_id, $meta_key, $meta_value, $unique );
@ -69,8 +69,8 @@ class Term_Meta_Command extends CommandWithMeta {
* metadata entries with the specified value. * metadata entries with the specified value.
* Otherwise, update all entries. * Otherwise, update all entries.
* *
* @return int|bool Meta ID if the key didn't exist, true on successful * @return int|bool|WP_Error Meta ID if the key didn't exist, true on successful
* update, false on failure. * update, false on failure, WP_Error when term_id is ambiguous between taxonomies.
*/ */
protected function update_metadata( $object_id, $meta_key, $meta_value, $prev_value = '' ) { protected function update_metadata( $object_id, $meta_key, $meta_value, $prev_value = '' ) {
return update_term_meta( $object_id, $meta_key, $meta_value, $prev_value ); return update_term_meta( $object_id, $meta_key, $meta_value, $prev_value );

View file

@ -31,6 +31,8 @@ use WP_CLI\Utils;
* Success: Removed user 123 from http://example.com. * Success: Removed user 123 from http://example.com.
* *
* @package wp-cli * @package wp-cli
*
* @phpstan-import-type UserSite from Site_Command
*/ */
class User_Command extends CommandWithDBObject { class User_Command extends CommandWithDBObject {


@ -645,7 +647,7 @@ class User_Command extends CommandWithDBObject {
] ]
); );


if ( false === $role ) { if ( false === $role && ! is_wp_error( $user_id ) ) {
delete_user_option( $user_id, 'capabilities' ); delete_user_option( $user_id, 'capabilities' );
delete_user_option( $user_id, 'user_level' ); delete_user_option( $user_id, 'user_level' );
} }
@ -653,7 +655,10 @@ class User_Command extends CommandWithDBObject {
if ( 'progress' === $format ) { if ( 'progress' === $format ) {
$notify->tick(); $notify->tick();
} elseif ( 'ids' === $format ) { } elseif ( 'ids' === $format ) {
echo $user_id; if ( ! is_wp_error( $user_id ) ) {
echo $user_id;
}

if ( $index < $limit - 1 ) { if ( $index < $limit - 1 ) {
echo ' '; echo ' ';
} }
@ -1164,6 +1169,11 @@ class User_Command extends CommandWithDBObject {
WP_CLI::log( "{$existing_user->user_login} added as {$new_user['role']}." ); WP_CLI::log( "{$existing_user->user_login} added as {$new_user['role']}." );
} }


if ( is_wp_error( $user_id ) ) {
WP_CLI::warning( $user_id );
continue;
}

// Create the user // Create the user
} else { } else {
unset( $new_user['ID'] ); // Unset else it will just return the ID unset( $new_user['ID'] ); // Unset else it will just return the ID
@ -1189,22 +1199,24 @@ class User_Command extends CommandWithDBObject {
$user_id = wp_insert_user( $new_user ); $user_id = wp_insert_user( $new_user );
} }


if ( is_wp_error( $user_id ) ) {
WP_CLI::warning( $user_id );
continue;
}

if ( Utils\get_flag_value( $assoc_args, 'send-email' ) ) { if ( Utils\get_flag_value( $assoc_args, 'send-email' ) ) {
self::wp_new_user_notification( $user_id, $new_user['user_pass'] ); self::wp_new_user_notification( $user_id, $new_user['user_pass'] );
} }
} }


if ( is_wp_error( $user_id ) ) {
WP_CLI::warning( $user_id );
continue;

}

if ( false === $new_user['role'] ) { if ( false === $new_user['role'] ) {
delete_user_option( $user_id, 'capabilities' ); delete_user_option( $user_id, 'capabilities' );
delete_user_option( $user_id, 'user_level' ); delete_user_option( $user_id, 'user_level' );
} }


/**
* @var \WP_User $user
*/
$user = get_user_by( 'id', $user_id ); $user = get_user_by( 'id', $user_id );
foreach ( $secondary_roles as $secondary_role ) { foreach ( $secondary_roles as $secondary_role ) {
$user->add_role( $secondary_role ); $user->add_role( $secondary_role );
@ -1332,7 +1344,7 @@ class User_Command extends CommandWithDBObject {
* @param mixed $password * @param mixed $password
*/ */
public static function wp_new_user_notification( $user_id, $password ) { public static function wp_new_user_notification( $user_id, $password ) {
wp_new_user_notification( $user_id, null, 'both' ); wp_new_user_notification( (int) $user_id, null, 'both' );
} }


/** /**
@ -1414,6 +1426,10 @@ class User_Command extends CommandWithDBObject {
} }


// Make that user's blog as spam too. // Make that user's blog as spam too.

/**
* @phpstan-var UserSite[] $blogs
*/
$blogs = (array) get_blogs_of_user( $user_id, true ); $blogs = (array) get_blogs_of_user( $user_id, true );
foreach ( $blogs as $details ) { foreach ( $blogs as $details ) {
// Only mark site as spam if not main site. // Only mark site as spam if not main site.

View file

@ -103,6 +103,9 @@ abstract class CommandWithTerms extends WP_CLI_Command {
$taxonomy_args['fields'] = 'ids'; $taxonomy_args['fields'] = 'ids';
} }


/**
* @var \WP_Term[] $items
*/
$items = wp_get_object_terms( $object_id, $taxonomy_names, $taxonomy_args ); $items = wp_get_object_terms( $object_id, $taxonomy_names, $taxonomy_args );


$formatter = $this->get_formatter( $assoc_args ); $formatter = $this->get_formatter( $assoc_args );