diff --git a/features/comment.feature b/features/comment.feature index 290954e0..a1cc7c0b 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -55,6 +55,7 @@ Feature: Manage WordPress comments """ Success: Trashed comment 3. Success: Trashed comment 4. + Success: Deleted 2 comments. """ When I run `wp comment delete 3` @@ -472,3 +473,148 @@ Feature: Manage WordPress comments And I run `wp comment unspam {COMMENT_ID} --url=www.example.com` And I run `wp comment trash {COMMENT_ID} --url=www.example.com` And I run `wp comment untrash {COMMENT_ID} --url=www.example.com` + + Scenario: Delete all comments with --all flag + Given a WP install + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 1' --porcelain` + And save STDOUT as {COMMENT_ID_1} + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 2' --porcelain` + And save STDOUT as {COMMENT_ID_2} + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 3' --porcelain` + And save STDOUT as {COMMENT_ID_3} + + When I run `wp comment list --format=count` + Then STDOUT should be: + """ + 4 + """ + + When I run `wp comment delete --all` + Then STDOUT should contain: + """ + Success: Trashed comment 1. + """ + And STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_1}. + """ + And STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_2}. + """ + And STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_3}. + """ + + When I run `wp comment list --format=count` + Then STDOUT should be: + """ + 0 + """ + + Scenario: Delete all comments with --all flag and --force + Given a WP install + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 1' --porcelain` + And save STDOUT as {COMMENT_ID_1} + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 2' --porcelain` + And save STDOUT as {COMMENT_ID_2} + + When I run `wp comment list --format=count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp comment delete --all --force` + Then STDOUT should contain: + """ + Success: Deleted comment 1. + """ + And STDOUT should contain: + """ + Success: Deleted comment {COMMENT_ID_1}. + """ + And STDOUT should contain: + """ + Success: Deleted comment {COMMENT_ID_2}. + """ + + When I run `wp comment list --format=count` + Then STDOUT should be: + """ + 0 + """ + + Scenario: Delete all comments when no comments exist + Given a WP install + And I run `wp comment delete $(wp comment list --field=ID) --force` + + When I run `wp comment delete --all` + Then STDOUT should be: + """ + Success: No comments deleted. + """ + + Scenario: Delete multiple comments shows summary message + Given a WP install + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 1' --porcelain` + And save STDOUT as {COMMENT_ID_1} + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 2' --porcelain` + And save STDOUT as {COMMENT_ID_2} + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 3' --porcelain` + And save STDOUT as {COMMENT_ID_3} + + When I run `wp comment delete {COMMENT_ID_1} {COMMENT_ID_2} {COMMENT_ID_3}` + Then STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_1}. + """ + And STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_2}. + """ + And STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_3}. + """ + And STDOUT should contain: + """ + Success: Deleted 3 comments. + """ + + Scenario: Delete comments with mixed success and failure + Given a WP install + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 1' --porcelain` + And save STDOUT as {COMMENT_ID_1} + And I run `wp comment create --comment_post_ID=1 --comment_content='Comment 2' --porcelain` + And save STDOUT as {COMMENT_ID_2} + + When I try `wp comment delete {COMMENT_ID_1} {COMMENT_ID_2} 99999` + Then STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_1}. + """ + And STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID_2}. + """ + And STDERR should contain: + """ + Warning: Failed deleting comment 99999. + """ + And STDERR should contain: + """ + Error: Failed deleting 1 comments. + """ + And the return code should be 1 + + Scenario: Error when no comment IDs and no --all flag provided + Given a WP install + + When I try `wp comment delete` + Then STDERR should be: + """ + Error: Please specify one or more comment IDs, or use --all. + """ + And the return code should be 1 diff --git a/src/Comment_Command.php b/src/Comment_Command.php index 766e28a5..6806ed06 100644 --- a/src/Comment_Command.php +++ b/src/Comment_Command.php @@ -16,7 +16,7 @@ * # Update an existing comment. * $ wp comment update 123 --comment_author='That Guy' * Success: Updated comment 123. - * + * # Delete an existing comment. * $ wp comment delete 1337 --force * Success: Deleted comment 1337. @@ -416,9 +416,12 @@ function ( $comment ) { * * ## OPTIONS * - * ... + * [...] * : One or more IDs of comments to delete. * + * [--all] + * : If set, all comments will be deleted. + * * [--force] * : Skip the trash bin. * @@ -432,25 +435,65 @@ function ( $comment ) { * $ wp comment delete 1337 2341 --force * Success: Deleted comment 1337. * Success: Deleted comment 2341. + * + * # Delete all comments. + * $ wp comment delete --all --force + * Success: Deleted comment 1337. + * Success: Deleted comment 2341. + * Success: Deleted 2 of 2 comments. */ public function delete( $args, $assoc_args ) { - parent::_delete( - $args, - $assoc_args, - function ( $comment_id, $assoc_args ) { - $force = (bool) Utils\get_flag_value( $assoc_args, 'force' ); + $all = Utils\get_flag_value( $assoc_args, 'all', false ); - $status = wp_get_comment_status( $comment_id ); - $result = wp_delete_comment( $comment_id, $force ); + // Check if comment IDs or --all is passed. + $args = $this->check_optional_args_and_all( $args, $all, 'delete' ); + if ( ! $args ) { + return; + } - if ( ! $result ) { - return [ 'error', "Failed deleting comment {$comment_id}." ]; - } + $status = 0; - $verb = ( $force || 'trash' === $status ) ? 'Deleted' : 'Trashed'; - return [ 'success', "{$verb} comment {$comment_id}." ]; + $defer_term_counting = wp_defer_comment_counting(); + if ( $all ) { + wp_defer_term_counting( true ); + } + + $total = count( $args ); + $successfully_deleted = 0; + + $force = (bool) Utils\get_flag_value( $assoc_args, 'force' ); + + foreach ( $args as $comment_id ) { + + $comment_status = wp_get_comment_status( $comment_id ); + $result = wp_delete_comment( $comment_id, $force ); + + if ( ! $result ) { + $response = [ 'error', "Failed deleting comment {$comment_id}." ]; + $status = $this->success_or_failure( $response ); + // Keep status as 1 (error) if any deletion fails + } else { + $verb = ( $force || 'trash' === $comment_status ) ? 'Deleted' : 'Trashed'; + $response = [ 'success', "{$verb} comment {$comment_id}." ]; + $this->success_or_failure( $response ); + ++$successfully_deleted; } - ); + } + + if ( $all ) { + wp_defer_term_counting( $defer_term_counting ); + } + + if ( 0 === $status ) { + if ( $total > 1 ) { + WP_CLI::success( "Deleted {$successfully_deleted} comments." ); + } + } else { + $error_count = $total - $successfully_deleted; + WP_CLI::error( "Failed deleting {$error_count} comments." ); + } + + exit( $status ); } private function call( $args, $status, $success, $failure ) { @@ -734,4 +777,48 @@ public function exists( $args ) { WP_CLI::success( "Comment with ID {$args[0]} exists." ); } } + + /** + * If have optional args ([...]) and an all option, then check have something to do. + * + * @param array $args Passed-in arguments. + * @param bool $all All flag. + * @param string $verb Optional. Verb to use. Defaults to 'delete'. + * @return array Same as $args if not all, otherwise all comment IDs. + */ + private function check_optional_args_and_all( $args, $all, $verb = 'delete' ) { + if ( $all ) { + $args = $this->get_all_comment_ids(); + } + + if ( empty( $args ) ) { + if ( ! $all ) { + WP_CLI::error( 'Please specify one or more comment IDs, or use --all.' ); + } + + $past_tense_verb = Utils\past_tense_verb( $verb ); + WP_CLI::success( "No comments {$past_tense_verb}." ); + } + + return $args; + } + + /** + * Gets all available comment IDs. + */ + private function get_all_comment_ids(): array { + $query = new WP_Comment_Query(); + $comments = $query->query( + array( + 'fields' => 'ids', + 'number' => 0, // Get all comments + ) + ); + + if ( ! is_array( $comments ) ) { + return []; + } + + return $comments; + } }