From 086e8f9d00a761d8438a8260f9d6acc43b27615b Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Tue, 8 Oct 2024 14:02:30 +1100 Subject: [PATCH] Fix the default options not being set, the settings menu ordering, double status creations and the lack of settings updated message --- modules/custom-status/custom-status.php | 32 +++++++++++++----------- modules/settings/settings.php | 4 +-- modules/settings/views/settings.php | 8 +++++- modules/shared/php/options-utilities.php | 22 +++++++++++++++- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/modules/custom-status/custom-status.php b/modules/custom-status/custom-status.php index 16256a1..8119e47 100644 --- a/modules/custom-status/custom-status.php +++ b/modules/custom-status/custom-status.php @@ -127,17 +127,13 @@ public static function register_custom_status_taxonomy(): void { public static function register_custom_statuses(): void { global $wp_post_statuses; - // Users can delete the pending status if they want, so let's get rid of that - // It'll get re-added if the user hasn't "deleted" them - unset( $wp_post_statuses['pending'] ); - - $custom_statuses = self::get_custom_statuses(); + $custom_statuses = self::get_custom_statuses(); - // Unfortunately, register_post_status() doesn't accept a - // post type argument, so we have to register the post - // statuses for all post types. This results in - // all post statuses for a post type appearing at the top - // of manage posts if there is a post with the status + // Unfortunately, register_post_status() doesn't accept a + // post type argument, so we have to register the post + // statuses for all post types. This results in + // all post statuses for a post type appearing at the top + // of manage posts if there is a post with the status foreach ( $custom_statuses as $status ) { register_post_status( $status->slug, [ 'label' => $status->name, @@ -642,14 +638,17 @@ public static function update_custom_status( int $status_id, array $args = [] ): // Reset our internal object cache self::$custom_statuses_cache = []; + // Don't allow changing the name or slug of the Draft or pending status as they are core statuses + $banned_statuses = [ 'draft', 'pending' ]; + // Prevent user from changing draft name or slug - if ( 'draft' === $old_status->slug + if ( in_array( $old_status->slug, $banned_statuses ) && ( ( isset( $args['name'] ) && $args['name'] !== $old_status->name ) || ( isset( $args['slug'] ) && $args['slug'] !== $old_status->slug ) ) ) { - return new WP_Error( 'invalid', __( 'Changing the name and slug of "Draft" is not allowed', 'vip-workflow' ) ); + return new WP_Error( 'restricted', __( 'Changing the name and slug of a restricted status ', 'vip-workflow' ) . '(' . $old_status->name . ') is not allowed.' ); } // If the name was changed, we need to change the slug @@ -727,8 +726,11 @@ public static function delete_custom_status( int $status_id ): bool|WP_Error { $old_status_slug = $old_status->slug; - if ( self::is_restricted_status( $old_status_slug ) || 'draft' === $old_status_slug ) { - return new WP_Error( 'restricted', __( 'Restricted status ', 'vip-workflow' ) . '(' . $old_status->name . ')' ); + // Don't allow changing the name or slug of the Draft or pending status as they are core statuses + $banned_statuses = [ 'draft', 'pending' ]; + + if ( self::is_restricted_status( $old_status_slug ) || in_array( $old_status->slug, $banned_statuses ) ) { + return new WP_Error( 'restricted', __( 'Restricted status ', 'vip-workflow' ) . '(' . $old_status->name . ') cannot be deleted.' ); } // Reset our internal object cache @@ -736,7 +738,7 @@ public static function delete_custom_status( int $status_id ): bool|WP_Error { // Get the new status to reassign posts to, which would be the first custom status. // In the event that the first custom status is being deleted, we'll reassign to the second custom status. - // Since draft cannot be deleted, we don't need to worry about ever getting index out of bounds. + // Since draft and pending review cannot be deleted, we don't need to worry about ever getting index out of bounds. $custom_statuses = self::get_custom_statuses(); $new_status_slug = $custom_statuses[0]->slug; if ( $old_status_slug === $new_status_slug ) { diff --git a/modules/settings/settings.php b/modules/settings/settings.php index a91f8fc..1413603 100644 --- a/modules/settings/settings.php +++ b/modules/settings/settings.php @@ -17,7 +17,8 @@ class Settings { * Initialize the rest of the stuff in the class if the module is active */ public static function init(): void { - add_action( 'admin_menu', [ __CLASS__, 'add_admin_menu' ] ); + // Ensures that the settings page shows up at the bottom of the menu list + add_action( 'admin_menu', [ __CLASS__, 'add_admin_menu' ], 50 ); add_action( 'admin_init', [ __CLASS__, 'helper_settings_validate_and_save' ], 100 ); add_action( 'admin_init', [ __CLASS__, 'register_settings' ] ); @@ -218,7 +219,6 @@ public static function settings_validate( $new_options ): array { * This method is called automatically/ doesn't need to be registered anywhere */ public static function helper_settings_validate_and_save(): bool { - if ( ! isset( $_POST['action'], $_POST['_wpnonce'], $_POST['option_page'], $_POST['_wp_http_referer'], $_POST['submit'] ) || ! is_admin() ) { return false; } diff --git a/modules/settings/views/settings.php b/modules/settings/views/settings.php index fc9a721..7d23e62 100644 --- a/modules/settings/views/settings.php +++ b/modules/settings/views/settings.php @@ -21,7 +21,13 @@

- %s', esc_html( $messages[ $message_slug ] ) ); ?> + 'success', + 'dismissible' => true, + 'additional_classes' => [ 'inline', 'notice-alt' ], + ] ); + ?>

diff --git a/modules/shared/php/options-utilities.php b/modules/shared/php/options-utilities.php index e0a4933..b3497c7 100644 --- a/modules/shared/php/options-utilities.php +++ b/modules/shared/php/options-utilities.php @@ -13,6 +13,17 @@ class OptionsUtilities { const OPTIONS_GROUP = 'vip_workflow_'; const OPTIONS_GROUP_NAME = 'vip_workflow_options'; + // Its key to centralize these here, so we can easily update them in the future + private const DEFAULT_OPTIONS = [ + 'post_types' => [ + 'post' => 'on', + 'page' => 'on', + ], + 'publish_guard' => 'on', + 'email_address' => '', + 'webhook_url' => '', + ]; + /** * Given a module name, return a set of saved module options * @@ -21,7 +32,16 @@ class OptionsUtilities { */ public static function get_module_options( string $module_slug ): object|null { $module_options_key = self::get_module_options_key( $module_slug ); - return get_option( $module_options_key, new stdClass() ); + $module_options = get_option( $module_options_key, new stdClass() ); + + // Ensure all default options are set + foreach ( self::DEFAULT_OPTIONS as $key => $value ) { + if ( ! isset( $module_options->$key ) ) { + $module_options->$key = $value; + } + } + + return $module_options; } public static function get_module_option_by_key( string $module_slug, string $key ): string|array|bool|null {