Skip to content

Commit

Permalink
Refactor editorial metadata module (#34)
Browse files Browse the repository at this point in the history
- Migrate EditorialMetadata to static module (excluding install())
- Move page render logic into individual modules
- Move some functions out of shared Module to TaxonomyUtilities
- Rename EditEditorialMetadata to EditorialMetadataEndpoint
- Add functional modules for managing newly-installed data
- Fix PHPCS errors
- Add ToDo for moving the get_supported_post_types() function
  • Loading branch information
alecgeatches authored Sep 17, 2024
1 parent 084cb74 commit ec2a3de
Show file tree
Hide file tree
Showing 16 changed files with 470 additions and 376 deletions.
113 changes: 38 additions & 75 deletions class-workflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ private function setup_actions() {
add_action( 'init', [ $this, 'action_init_after' ], 1000 );

add_action( 'admin_init', [ $this, 'action_admin_init' ] );
add_action( 'admin_menu', [ $this, 'action_admin_menu' ] );
}

/**
Expand Down Expand Up @@ -173,76 +172,6 @@ public function action_admin_init() {
}
}

/**
* Add module pages to the admin menu
*/
public function action_admin_menu() {
$main_module = self::instance()->modules->custom_status;
$menu_title = __( 'VIP Workflow', 'vip-workflow' );

add_menu_page( $menu_title, $menu_title, 'manage_options', $main_module->settings_slug, function () use ( $main_module ) {
return $this->menu_controller( $main_module->settings_slug );
} );

foreach ( self::instance()->modules as $mod_name => $mod_data ) {
if ( $mod_data->configure_page_cb && $mod_name !== $main_module->name ) {
add_submenu_page( $main_module->settings_slug, $mod_data->title, $mod_data->title, 'manage_options', $mod_data->settings_slug, function () use ( $mod_data ) {
return $this->menu_controller( $mod_data->settings_slug );
} );
}
}
}

/**
* Handles all settings and configuration page requests. Required element for VIP Workflow
*/
public function menu_controller( $mod_slug ) {
$requested_module = self::instance()->get_module_by( 'settings_slug', $mod_slug );
if ( ! $requested_module ) {
wp_die( esc_html__( 'Not a registered VIP Workflow module', 'vip-workflow' ) );
}

$configure_callback = $requested_module->configure_page_cb;
$requested_module_name = $requested_module->name;

$this->print_default_header( $requested_module );
self::instance()->$requested_module_name->$configure_callback();
$this->print_default_footer();
}

/**
* Print the header on the top of each module page
*/
public function print_default_header( $current_module ) {
// If there's been a message, let's display it

// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Message slugs correspond to preset read-only strings and do not require nonce checks.
$message_slug = isset( $_REQUEST['message'] ) ? sanitize_title( $_REQUEST['message'] ) : false;

if ( $message_slug && isset( $current_module->messages[ $message_slug ] ) ) {
$display_text = sprintf( '<span class="vip-workflow-updated-message vip-workflow-message">%s</span>', esc_html( $current_module->messages[ $message_slug ] ) );
}

// If there's been an error, let's display it

// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Error slugs correspond to preset read-only strings and do not require nonce checks.
$error_slug = isset( $_REQUEST['error'] ) ? sanitize_title( $_REQUEST['error'] ) : false;

if ( $error_slug && isset( $current_module->messages[ $error_slug ] ) ) {
$display_text = sprintf( '<span class="vip-workflow-error-message vip-workflow-message">%s</span>', esc_html( $current_module->messages[ $error_slug ] ) );
}

include_once __DIR__ . '/modules/shared/php/views/module-header.php';
}

/**
* Print the footer for each module page
*/
public function print_default_footer() {
// End the wrap <div> started in the header
echo '</div>';
}

/**
* Register a new module
*/
Expand All @@ -263,10 +192,6 @@ public function register_module( $name, $args = [] ) {
'options' => false,
'configure_page_cb' => false,
'configure_link_text' => __( 'Configure', 'vip-workflow' ),
// These messages are applied to modules and can be overridden if custom messages are needed
'messages' => [
'settings-updated' => __( 'Settings updated.', 'vip-workflow' ),
],
'autoload' => true, // autoloading a module will remove the ability to enable or disable it
];
if ( isset( $args['messages'] ) ) {
Expand Down Expand Up @@ -372,6 +297,44 @@ public function update_all_module_options( $mod_name, $new_options ) {
$this->$mod_name->module = $this->modules->$mod_name;
return update_option( $this->options_group . $mod_name . '_options', $this->modules->$mod_name->options );
}


/**
* Collect all of the active post types
*
* @return array $post_types All of the post types that are 'on'
*/
public function get_supported_post_types(): array {
// ToDo: Move this function to a shared static helper after we've refactored into static modules

$post_types = [];
$post_types_options = $this->settings->module->options->post_types;

foreach ( $post_types_options as $post_type => $value ) {
if ( 'on' === $value ) {
$post_types[] = $post_type;
}
}

return $post_types;
}

/**
* Whether or not the current page is our settings view. Determination is based on $pagenow, $_GET['page'], and if it's settings module or not.
*
* @return bool $is_settings_view Return true if it is
*/
public static function is_settings_view_loaded( string $slug ): bool {
global $pagenow;

// All of the settings views are based on admin.php and a $_GET['page'] parameter
if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) ) {
return false;
}

// The current page better be in the array of registered settings view slugs
return $_GET['page'] === $slug;
}
}

VIP_Workflow::instance();
60 changes: 36 additions & 24 deletions modules/custom-status/custom-status.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use VIPWorkflow\VIP_Workflow;
use VIPWorkflow\Modules\Shared\PHP\Module;
use VIPWorkflow\Modules\CustomStatus\REST\EditStatus;
use VIPWorkflow\Modules\Shared\PHP\TaxonomyUtilities;
use WP_Error;
use WP_Query;
use function VIPWorkflow\Modules\Shared\PHP\_vw_wp_link_page;
Expand All @@ -24,6 +25,8 @@ class Custom_Status extends Module {
// This is taxonomy name used to store all our custom statuses
const TAXONOMY_KEY = 'post_status';

const SETTINGS_SLUG = 'vw-custom-status';

/**
* Register the module with VIP Workflow but don't do anything else
*/
Expand All @@ -33,8 +36,6 @@ public function __construct() {
// Register the module with VIP Workflow
$args = [
'title' => __( 'Workflow Config', 'vip-workflow' ),
'short_description' => __( 'Configure your editorial workflow.', 'vip-workflow' ),
'extended_description' => __( 'Starting from the top, each post status represents the publishing worklow to be followed. This workflow can be configured by re-ordering statuses as well as editing/deleting and creating new ones.', 'vip-workflow' ),
'module_url' => $this->module_url,
'slug' => 'custom-status',
'configure_page_cb' => 'print_configure_view',
Expand All @@ -51,7 +52,7 @@ public function init() {

// Register our settings
if ( ! $this->disable_custom_statuses_for_post_type() ) {
// Load CSS and JS resources that we probably need in the admin page
// Load CSS and JS resources for the admin page
add_action( 'admin_enqueue_scripts', [ $this, 'action_admin_enqueue_scripts' ] );

// Assets for block editor UI.
Expand All @@ -66,6 +67,9 @@ public function init() {
// Add custom statuses to the post states.
add_filter( 'display_post_states', [ $this, 'add_status_to_post_states' ], 10, 2 );

// Register sidebar menu
add_action( 'admin_menu', [ $this, 'add_admin_menu' ], 6 /* Prior to default registration of sub-pages */ );

// These seven-ish methods are hacks for fixing bugs in WordPress core
add_action( 'admin_init', [ $this, 'check_timestamp_on_publish' ] );
add_filter( 'wp_insert_post_data', [ $this, 'fix_custom_status_timestamp' ], 10, 2 );
Expand Down Expand Up @@ -214,13 +218,21 @@ public function disable_custom_statuses_for_post_type( $post_type = null ) {
$post_type = $this->get_current_post_type();
}

if ( $post_type && ! in_array( $post_type, $this->get_supported_post_types() ) ) {
$supported_post_types = VIP_Workflow::instance()->get_supported_post_types();

if ( $post_type && ! in_array( $post_type, $supported_post_types ) ) {
return true;
}

return false;
}

public function add_admin_menu() {
$menu_title = __( 'VIP Workflow', 'vip-workflow' );

add_menu_page( $menu_title, $menu_title, 'manage_options', self::SETTINGS_SLUG, [ $this, 'render_settings_view' ] );
}

public function configure_page_cb() {
// do nothing
}
Expand All @@ -230,7 +242,7 @@ public function configure_page_cb() {
*/
public function action_admin_enqueue_scripts() {
// Load Javascript we need to use on the configuration views
if ( $this->is_whitelisted_settings_view() ) {
if ( VIP_Workflow::is_settings_view_loaded( self::SETTINGS_SLUG ) ) {
$asset_file = include VIP_WORKFLOW_ROOT . '/dist/modules/custom-status/custom-status-configure.asset.php';
wp_enqueue_script( 'vip-workflow-custom-status-configure', VIP_WORKFLOW_URL . 'dist/modules/custom-status/custom-status-configure.js', $asset_file['dependencies'], $asset_file['version'], true );
wp_enqueue_style( 'vip-workflow-custom-status-styles', VIP_WORKFLOW_URL . 'dist/modules/custom-status/custom-status-configure.css', [ 'wp-components' ], $asset_file['version'] );
Expand Down Expand Up @@ -269,14 +281,14 @@ public function load_scripts_for_block_editor() {
wp_localize_script( 'vip-workflow-block-custom-status-script', 'VW_CUSTOM_STATUSES', [
'is_publish_guard_enabled' => $publish_guard_enabled,
'status_terms' => $this->get_custom_statuses(),
'supported_post_types' => $this->get_supported_post_types(),
'supported_post_types' => VIP_Workflow::instance()->get_supported_post_types(),
] );
}

public function load_styles_for_block_editor() {
$asset_file = include VIP_WORKFLOW_ROOT . '/dist/modules/custom-status/custom-status-block.asset.php';

wp_enqueue_style( 'vip-workflow-manager-styles', VIP_WORKFLOW_URL . 'dist/modules/custom-status/custom-status-block.css', [ 'wp-components' ], $asset_file['version'] );
wp_enqueue_style( 'vip-workflow-custom-status-styles', VIP_WORKFLOW_URL . 'dist/modules/custom-status/custom-status-block.css', [], $asset_file['version'] );
}

/**
Expand All @@ -287,7 +299,7 @@ public function load_styles_for_block_editor() {
public function is_whitelisted_page() {
global $pagenow;

if ( ! in_array( $this->get_current_post_type(), $this->get_supported_post_types() ) ) {
if ( ! in_array( $this->get_current_post_type(), VIP_Workflow::instance()->get_supported_post_types() ) ) {
return false;
}

Expand Down Expand Up @@ -406,7 +418,7 @@ public function remove_or_add_publish_capability_for_user( $allcaps, $cap, $args
}

// Bail early if the post type is not supported or if its a not supported capability for this guard
if ( ! in_array( $post->post_type, $this->get_supported_post_types() ) || ! isset( $supported_publish_caps_map[ $post->post_type ] ) ) {
if ( ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() ) || ! isset( $supported_publish_caps_map[ $post->post_type ] ) ) {
return $allcaps;
}

Expand Down Expand Up @@ -466,7 +478,7 @@ public function add_custom_status( $term, $args = [] ) {
$args['position'] = $default_position;
}

$encoded_description = $this->get_encoded_description( $args );
$encoded_description = TaxonomyUtilities::get_encoded_description( $args );

$inserted_term = wp_insert_term( $term, self::TAXONOMY_KEY, [
'slug' => $slug,
Expand Down Expand Up @@ -530,7 +542,7 @@ public function update_custom_status( $status_id, $args = [] ) {
$args_to_encode = [];
$args_to_encode['description'] = ( isset( $args['description'] ) ) ? $args['description'] : $old_status->description;
$args_to_encode['position'] = ( isset( $args['position'] ) ) ? $args['position'] : $old_status->position;
$encoded_description = $this->get_encoded_description( $args_to_encode );
$encoded_description = TaxonomyUtilities::get_encoded_description( $args_to_encode );
$args['description'] = $encoded_description;

$updated_status = wp_update_term( $status_id, self::TAXONOMY_KEY, $args );
Expand Down Expand Up @@ -640,7 +652,7 @@ public function get_custom_statuses() {
$hold_to_end = [];
foreach ( $statuses as $key => $status ) {
// Unencode and set all of our psuedo term meta because we need the position if it exists
$unencoded_description = $this->get_unencoded_description( $status->description );
$unencoded_description = TaxonomyUtilities::get_unencoded_description( $status->description );
if ( is_array( $unencoded_description ) ) {
foreach ( $unencoded_description as $key => $value ) {
$status->$key = $value;
Expand Down Expand Up @@ -707,7 +719,7 @@ public function get_custom_status_by( $field, $value ) {
*/
public function reassign_post_status( $old_status, $new_status ) {
$old_status_post_ids = ( new WP_Query( [
'post_type' => $this->get_supported_post_types(),
'post_type' => VIP_Workflow::instance()->get_supported_post_types(),
'post_status' => $old_status,
'posts_per_page' => -1,
'fields' => 'ids',
Expand Down Expand Up @@ -757,7 +769,7 @@ public function reassign_post_status( $old_status, $new_status ) {
* @return array $post_states
*/
public function add_status_to_post_states( $post_states, $post ) {
if ( ! in_array( $post->post_type, $this->get_supported_post_types(), true ) ) {
if ( ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types(), true ) ) {
// Return early if this post type doesn't support custom statuses.
return $post_states;
}
Expand Down Expand Up @@ -811,7 +823,7 @@ public function is_restricted_status( $slug ) {
/**
* Primary configuration page for custom status class, which is also the main entry point for configuring the plugin
*/
public function print_configure_view() {
public function render_settings_view() {
include_once __DIR__ . '/views/manage-workflow.php';
}

Expand All @@ -831,7 +843,7 @@ public function workflow_is_publish_blocked( $post_id ) {
$custom_statuses = $this->get_custom_statuses();
$status_slugs = wp_list_pluck( $custom_statuses, 'slug' );

if ( ! in_array( $post->post_status, $status_slugs ) || ! in_array( $post->post_type, $this->get_supported_post_types() ) ) {
if ( ! in_array( $post->post_status, $status_slugs ) || ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() ) ) {
// Post is not using a custom status, or is not a supported post type
return false;
}
Expand Down Expand Up @@ -859,7 +871,7 @@ public function is_post_using_custom_status( $post_id ) {
return false;
}

$custom_post_types = $this->get_supported_post_types();
$custom_post_types = VIP_Workflow::instance()->get_supported_post_types();
$custom_statuses = $this->get_custom_statuses();
$status_slugs = wp_list_pluck( $custom_statuses, 'slug' );

Expand Down Expand Up @@ -985,7 +997,7 @@ public function maybe_keep_post_name_empty( $data, $postarr ) {

// Ignore if it's not a post status and post type we support
if ( ! in_array( $data['post_status'], $status_slugs )
|| ! in_array( $data['post_type'], $this->get_supported_post_types() ) ) {
|| ! in_array( $data['post_type'], VIP_Workflow::instance()->get_supported_post_types() ) ) {
return $data;
}

Expand Down Expand Up @@ -1013,7 +1025,7 @@ public function fix_unique_post_slug( $override_slug, $slug, $post_ID, $post_sta
$status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' );

if ( ! in_array( $post_status, $status_slugs )
|| ! in_array( $post_type, $this->get_supported_post_types() ) ) {
|| ! in_array( $post_type, VIP_Workflow::instance()->get_supported_post_types() ) ) {
return null;
}

Expand Down Expand Up @@ -1047,7 +1059,7 @@ public function fix_preview_link_part_one( $preview_link ) {
|| ! is_admin()
|| 'post.php' != $pagenow
|| ! in_array( $post->post_status, $status_slugs )
|| ! in_array( $post->post_type, $this->get_supported_post_types() )
|| ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() )
|| strpos( $preview_link, 'preview_id' ) !== false
|| 'sample' === $post->filter ) {
return $preview_link;
Expand All @@ -1072,7 +1084,7 @@ public function fix_preview_link_part_two( $permalink, $post, $sample ) {
}

//Should we be doing anything at all?
if ( ! in_array( $post->post_type, $this->get_supported_post_types() ) ) {
if ( ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() ) ) {
return $permalink;
}

Expand Down Expand Up @@ -1141,7 +1153,7 @@ public function fix_get_sample_permalink( $permalink, $post_id, $title, $name, $
$status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' );

if ( ! in_array( $post->post_status, $status_slugs )
|| ! in_array( $post->post_type, $this->get_supported_post_types() ) ) {
|| ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() ) ) {
return $permalink;
}

Expand Down Expand Up @@ -1183,7 +1195,7 @@ public function fix_get_sample_permalink_html( $permalink, $post_id, $new_title,
$status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' );

if ( ! in_array( $post->post_status, $status_slugs )
|| ! in_array( $post->post_type, $this->get_supported_post_types() ) ) {
|| ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() ) ) {
return $permalink;
}

Expand Down Expand Up @@ -1275,7 +1287,7 @@ public function fix_post_row_actions( $actions, $post ) {
$status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' );
if ( 'edit.php' != $pagenow
|| ! in_array( $post->post_status, $status_slugs )
|| ! in_array( $post->post_type, $this->get_supported_post_types() ) ) {
|| ! in_array( $post->post_type, VIP_Workflow::instance()->get_supported_post_types() ) ) {
return $actions;
}

Expand Down
Loading

0 comments on commit ec2a3de

Please sign in to comment.