*/ public static function abilities(): array { return [ new Ability( 'sarcio/comments-list', __('Look at comments', 'sarcio'), Ability::READ, 'Comments on the site: pending ones by default, or approved, spam or trash. Each with its id, who wrote it (name only), the post, the date and the first lines. Use the ids with comments-moderate.', [ 'properties' => [ 'limit' => ['maximum' => 50, 'minimum' => 1, 'type' => 'integer'], 'search' => ['maxLength' => 200, 'type' => 'string'], 'status' => ['enum' => ['pending', 'approved', 'spam', 'trash', 'all'], 'type' => 'string'], ], 'required' => [], 'type' => 'object', ], static fn (array $args): bool => current_user_can('moderate_comments'), static fn (array $args): array => self::list($args), ), new Ability( 'sarcio/comments-moderate', __('Approve, hold, spam or trash comments', 'sarcio'), Ability::WRITE, 'Set the status of one or more comments by id: approve, hold (unapprove), spam or trash. Made at once when the person confirms; undo puts each comment back to the status it had.', [ 'properties' => [ 'ids' => ['items' => ['minimum' => 1, 'type' => 'integer'], 'maxItems' => 50, 'minItems' => 1, 'type' => 'array'], 'status' => ['enum' => self::STATUSES, 'type' => 'string'], ], 'required' => ['ids', 'status'], 'type' => 'object', ], static fn (array $args): bool => current_user_can('moderate_comments'), static fn (array $args): array => self::moderate($args), null, static fn (array $before, array $after): array => self::restore($before), ), ]; } /** @param array $args */ private static function list(array $args): array { $status = (string) ($args['status'] ?? 'pending'); $query = [ 'number' => (int) ($args['limit'] ?? 20), 'orderby' => 'comment_date_gmt', 'order' => 'DESC', 'status' => match ($status) { 'pending' => 'hold', 'approved' => 'approve', 'all' => 'all', default => $status, }, ]; if (($args['search'] ?? '') !== '') { $query['search'] = (string) $args['search']; } $comments = get_comments($query); $out = []; foreach (is_array($comments) ? $comments : [] as $comment) { $out[] = self::describe($comment); } return ['comments' => $out, 'pending' => (int) (wp_count_comments()->moderated ?? 0)]; } public static function describe(object $comment): array { $id = (int) $comment->comment_ID; return [ 'author' => (string) $comment->comment_author, 'date' => (string) $comment->comment_date, 'excerpt' => mb_substr(trim(wp_strip_all_tags((string) $comment->comment_content)), 0, 240), 'id' => $id, 'post' => (string) get_the_title((int) $comment->comment_post_ID), 'postId' => (int) $comment->comment_post_ID, 'status' => self::statusOf($comment), 'type' => (string) $comment->comment_type, ]; } private static function statusOf(object $comment): string { $status = (string) wp_get_comment_status((int) $comment->comment_ID); return match ($status) { 'unapproved' => 'hold', 'approved' => 'approve', default => $status === '' ? 'hold' : $status, }; } /** @param array $args */ private static function moderate(array $args): array { $status = (string) $args['status']; $before = []; $changed = []; $missing = []; foreach ($args['ids'] as $id) { $comment = get_comment((int) $id); if ($comment === null) { $missing[] = (int) $id; continue; } $was = self::statusOf($comment); if ($was === $status) { continue; } if (!wp_set_comment_status((int) $id, $status)) { $missing[] = (int) $id; continue; } $before[(int) $id] = $was; $changed[] = (int) $id; } if ($changed === []) { return ['error' => $missing !== [] ? __('Those comments were not found.', 'sarcio') : __('Nothing would change.', 'sarcio')]; } $labels = ['approve' => __('Approved', 'sarcio'), 'hold' => __('Held', 'sarcio'), 'spam' => __('Marked as spam', 'sarcio'), 'trash' => __('Trashed', 'sarcio')]; return [ 'changed' => $changed, 'journal' => [ 'after' => ['ids' => $changed, 'status' => $status], 'before' => ['statuses' => $before], 'summary' => sprintf( /* translators: 1: what was done, 2: how many comments. */ _n('%1$s %2$d comment', '%1$s %2$d comments', count($changed), 'sarcio'), $labels[$status] ?? $status, count($changed), ), 'target' => 'comments:' . implode(',', $changed), ], 'notFound' => $missing, ]; } /** @param array $before */ private static function restore(array $before): array { $restored = 0; foreach ((array) ($before['statuses'] ?? []) as $id => $status) { if (get_comment((int) $id) !== null && wp_set_comment_status((int) $id, (string) $status)) { $restored++; } } return $restored > 0 ? ['restored' => $restored] : ['error' => __('Those comments are no longer there.', 'sarcio')]; } }