Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Added

* feat(custom-status): add status migration tool and WP-CLI commands by @GaryJones in [#859](https://github.com/Automattic/Edit-Flow/pull/859)
* feat(notifications): add Post Author and Auto-subscribed badges by @GaryJones in [#847](https://github.com/Automattic/Edit-Flow/pull/847)
* feat(story-budget): improve UX with Screen Options and collapsible categories by @GaryJones in [#846](https://github.com/Automattic/Edit-Flow/pull/846)

Expand Down
82 changes: 81 additions & 1 deletion modules/custom-status/custom-status.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function __construct() {
'term-updated' => __( 'Post status updated.', 'edit-flow' ),
'status-deleted' => __( 'Post status deleted.', 'edit-flow' ),
'status-position-updated' => __( 'Status order updated.', 'edit-flow' ),
'status-migrated' => __( 'Posts migrated successfully.', 'edit-flow' ),
],
'autoload' => false,
'settings_help_tab' => [
Expand All @@ -72,6 +73,11 @@ public function __construct() {
public function init() {
global $edit_flow;

// Load WP-CLI commands.
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once __DIR__ . '/lib/class-cli.php';
}

// Register custom statuses as a taxonomy
$this->register_custom_statuses();

Expand Down Expand Up @@ -100,6 +106,7 @@ public function init() {
add_action( 'admin_init', [ $this, 'handle_edit_custom_status' ] );
add_action( 'admin_init', [ $this, 'handle_make_default_custom_status' ] );
add_action( 'admin_init', [ $this, 'handle_delete_custom_status' ] );
add_action( 'admin_init', [ $this, 'handle_migrate_status' ] );
add_action( 'wp_ajax_update_status_positions', [ $this, 'handle_ajax_update_status_positions' ] );
add_action( 'wp_ajax_inline_save_status', [ $this, 'ajax_inline_save_status' ] );

Expand Down Expand Up @@ -1051,6 +1058,79 @@ public function handle_delete_custom_status() {
wp_die();
}

/**
* Handle a POST request to migrate posts between statuses.
*
* @since 0.9.10
*/
public function handle_migrate_status() {
// Check that this is our POST request.
if ( ! isset( $_POST['action'] ) || 'migrate' !== $_POST['action'] ) {
return;
}

// Verify the page.
if ( ! isset( $_GET['page'] ) || $_GET['page'] !== $this->module->settings_slug ) {
return;
}

// Check for proper nonce.
if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'custom-status-migrate-nonce' ) ) {
wp_die( esc_html__( 'Invalid nonce for submission.', 'edit-flow' ) );
}

// Only allow users with the proper caps.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'Sorry, you do not have permission to migrate posts.', 'edit-flow' ) );
}

$from_status = isset( $_POST['migrate_from'] ) ? sanitize_key( $_POST['migrate_from'] ) : '';
$to_status = isset( $_POST['migrate_to'] ) ? sanitize_key( $_POST['migrate_to'] ) : '';

// Validate inputs.
if ( empty( $from_status ) || empty( $to_status ) ) {
wp_die( esc_html__( 'Please select both a source and target status.', 'edit-flow' ) );
}

if ( $from_status === $to_status ) {
wp_die( esc_html__( 'Source and target status cannot be the same.', 'edit-flow' ) );
}

// Perform the migration.
$this->reassign_post_status( $from_status, $to_status );

// Clear caches.
wp_cache_flush();

$redirect_url = $this->get_link(
[
'action' => 'migrate-status',
'message' => 'status-migrated',
]
);
wp_redirect( $redirect_url );
exit;
}

/**
* Get count of posts with a specific status.
*
* @since 0.9.10
*
* @param string $status The status slug.
* @return int The number of posts with this status.
*/
public function get_post_count_for_status( $status ) {
global $wpdb;

return (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = %s",
$status
)
);
}

/**
* Generate a link to one of the custom status actions
*
Expand Down Expand Up @@ -1261,7 +1341,7 @@ public function settings_validate( $new_options ) {
*/
public function print_configure_view() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- No verification required for unprivileged URL check.
$action = isset( $_GET['action'] ) && in_array( $_GET['action'], [ 'edit-status', 'change-options' ] ) ? $_GET['action'] : '';
$action = isset( $_GET['action'] ) && in_array( $_GET['action'], [ 'edit-status', 'change-options', 'migrate-status' ] ) ? $_GET['action'] : '';

// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No verification required for unprivileged URL check.
$term_id = isset( $_GET['term-id'] ) ? absint( $_GET['term-id'] ) : false;
Expand Down
Loading
Loading