' . sprintf(__('Old post status: %s', 'publishpress'), $oldStatus->name) . '
';
+ $paramsString .= '
' . sprintf(__('Old post status: %s', 'publishpress'), $oldStatus->label) . '
';
}
if (is_object($newStatus)) {
- $paramsString .= '
' . sprintf(__('New post status: %s', 'publishpress'), $newStatus->name) . '
';
+ $paramsString .= '
' . sprintf(__('New post status: %s', 'publishpress'), $newStatus->label) . '
';
}
}
diff --git a/modules/calendar/calendar.php b/modules/calendar/calendar.php
index 121f42581..569b5f353 100644
--- a/modules/calendar/calendar.php
+++ b/modules/calendar/calendar.php
@@ -185,6 +185,7 @@ public function __construct()
],
'messages' => [
'post-date-updated' => __('Post date updated.', 'publishpress'),
+ 'status-updated' => __('Post status updated.', 'publishpress'),
'update-error' => __(
'There was an error updating the post. Please try again.',
'publishpress'
@@ -543,7 +544,7 @@ protected function getPostStatusOptions()
}
$postStatuses[] = [
'value' => esc_attr($status->slug),
- 'text' => esc_html($status->name),
+ 'text' => esc_html($status->label),
];
}
@@ -2309,7 +2310,6 @@ public function get_calendar_posts_for_week($args = [], $context = 'dashboard')
$args['post_status'] .= ', future';
}
}
-
// The WP functions for printing the category and author assign a value of 0 to the default
// options, but passing this to the query is bad (trashed and auto-draft posts appear!), so
// unset those arguments.
@@ -2661,9 +2661,11 @@ public function settings_ics_subscription_option()
*/
public function settings_show_posts_publish_time_option()
{
+ global $publishpress;
+
$field_name = esc_attr($this->module->options_group_name) . '[show_posts_publish_time]';
- $customStatuses = PP_Custom_Status::getCustomStatuses();
+ $customStatuses = (!empty($publishpress->custom_status)) ? $publishpress->custom_status->getPostStatuses([], 'object') : false;
if (empty($customStatuses)) {
$statuses = [
@@ -2674,7 +2676,7 @@ public function settings_show_posts_publish_time_option()
$statuses = [];
foreach ($customStatuses as $status) {
- $statuses[$status->slug] = $status->name;
+ $statuses[$status->slug] = ['title' => $status->label, 'status_obj' => $status];
}
}
@@ -2686,21 +2688,79 @@ public function settings_show_posts_publish_time_option()
];
}
- foreach ($statuses as $status => $title) {
- $id = esc_attr($status) . '-display-publish-time';
+ if (empty($customStatuses)) {
+ foreach ($statuses as $status) {
+ $id = esc_attr($status) . '-display-publish-time';
+
+ echo '
';
+
+ echo '
';
+ }
+ } else {
+ echo '';
+
+ echo '
';
+
+ foreach ($statuses as $status => $arr_status) {
+ $id = esc_attr($status) . '-display-publish-time';
+
+ echo '';
}
- // Defining post_type_supports in the functions.php file or similar should disable the checkbox
- disabled(post_type_supports($status, $this->module->post_type_support), true);
- echo ' type="checkbox" value="on" /> ' . esc_html($title) . '';
- echo ' ';
+ echo '
';
}
}
@@ -3361,7 +3421,7 @@ private function getPostStatusName($postStatusSlug)
foreach ($postStatuses as $postStatus) {
if ($postStatus->slug === $postStatusSlug) {
- return $postStatus->name;
+ return $postStatus->label;
}
}
@@ -3926,7 +3986,7 @@ public function calendar_filter_options($select_id, $select_name, $filters)
echo "';
+ ) . '>' . esc_html($post_status->label) . '';
}
?>
diff --git a/modules/content-overview/content-overview.php b/modules/content-overview/content-overview.php
index 49b3038ea..0de1d6c7a 100644
--- a/modules/content-overview/content-overview.php
+++ b/modules/content-overview/content-overview.php
@@ -325,7 +325,7 @@ public function settings_taxonomies_option()
$label = $taxonomy->label . ' (' . $value . ')';//some taxonomy can have same public name, so we should put unique name in bracket
//let skip status from filter list since we already have it seperately
- if ($value ==='post_status') {
+ if (in_array($value, ['post_status', 'post_status_core_wp_pp', 'post_visibility_pp'])) {
continue;
}
@@ -1235,7 +1235,7 @@ public function content_overview_filter_options($select_id, $select_name, $filte
echo "";
+ ) . ">" . esc_html($post_status->label) . "";
}
?>
diff --git a/modules/custom-status/custom-status.php b/modules/custom-status/custom-status.php
index 6c9eee88c..9292fd9a1 100644
--- a/modules/custom-status/custom-status.php
+++ b/modules/custom-status/custom-status.php
@@ -1,2983 +1,11 @@
.
- */
-use PublishPress\Notifications\Traits\Dependency_Injector;
-
-if (! class_exists('PP_Custom_Status')) {
- /**
- * class PP_Custom_Status
- * Custom statuses make it simple to define the different stages in your publishing workflow.
- *
- * @todo for v0.7
- * - Improve the copy
- * - Thoroughly test what happens when the default post statuses 'Draft' and 'Pending Review' no longer exist
- * - Ensure all of the form processing uses our messages functionality
- */
- #[\AllowDynamicProperties]
- class PP_Custom_Status extends PP_Module
- {
- use Dependency_Injector;
-
- const MODULE_NAME = 'custom_status';
-
- const SETTINGS_SLUG = 'pp-custom-status-settings';
-
- const STATUS_PUBLISH = 'publish';
-
- const STATUS_PRIVATE = 'private';
-
- const STATUS_SCHEDULED = 'future';
-
- const STATUS_PENDING = 'pending';
-
- const STATUS_DRAFT = 'draft';
-
- const DEFAULT_COLOR = '#655997';
-
- const DEFAULT_STATUS = 'draft';
-
- public $module;
-
- private $custom_statuses_cache = [];
-
- // This is taxonomy name used to store all our custom statuses
- const taxonomy_key = 'post_status';
-
- /**
- * Register the module with PublishPress but don't do anything else
- */
- public function __construct()
- {
- global $publishpress;
-
- $this->module_url = $this->get_module_url(__FILE__);
- // Register the module with PublishPress
- $args = [
- 'title' => __('Statuses', 'publishpress'),
- 'short_description' => false,
- 'extended_description' => false,
- 'module_url' => $this->module_url,
- 'icon_class' => 'dashicons dashicons-tag',
- 'slug' => 'custom-status',
- 'default_options' => [
- 'enabled' => 'on',
- 'always_show_dropdown' => 'on',
- 'post_types' => [
- 'post' => 'on',
- 'page' => 'on',
- ],
- ],
- 'post_type_support' => 'pp_custom_statuses', // This has been plural in all of our docs
- 'configure_page_cb' => 'print_configure_view',
- 'configure_link_text' => __('Edit Statuses', 'publishpress'),
- 'messages' => [
- 'status-added' => __('Post status created.', 'publishpress'),
- 'status-updated' => __('Post status updated.', 'publishpress'),
- 'status-missing' => __("Post status doesn't exist.", 'publishpress'),
- 'default-status-changed' => __('Default post status has been changed.', 'publishpress'),
- 'term-updated' => __("Post status updated.", 'publishpress'),
- 'status-deleted' => __('Post status deleted.', 'publishpress'),
- 'status-position-updated' => __("Status order updated.", 'publishpress'),
- ],
- 'autoload' => false,
- 'settings_help_tab' => [
- 'id' => 'pp-custom-status-overview',
- 'title' => __('Overview', 'publishpress'),
- 'content' => __(
- '
PublishPress’s custom statuses allow you to define the most important stages of your editorial workflow. Out of the box, WordPress only offers “Draft” and “Pending Review” as post states. With custom statuses, you can create your own post states like “In Progress”, “Pitch”, or “Waiting for Edit” and keep or delete the originals. You can also drag and drop statuses to set the best order for your workflow.
Custom statuses are fully integrated into the rest of PublishPress and the WordPress admin. On the calendar and content overview, you can filter your view to see only posts of a specific post state. Furthermore, email notifications can be sent to a specific group of users when a post changes state.
',
- 'publishpress'
- ),
- 'options_page' => true,
- ];
- $this->module = PublishPress()->register_module(self::MODULE_NAME, $args);
- }
-
- /**
- * Initialize the PP_Custom_Status class if the module is active
- */
- public function init()
- {
- global $publishpress;
-
- // Register custom statuses as a taxonomy
- $this->register_custom_statuses();
-
- if (is_admin()) {
- // Register our settings
- add_action('admin_init', [$this, 'register_settings']);
-
- // Load CSS and JS resources that we probably need
- add_action('admin_enqueue_scripts', [$this, 'action_admin_enqueue_scripts']);
- add_action('admin_notices', [$this, 'no_js_notice']);
- add_action('admin_print_scripts', [$this, 'post_admin_header']);
- add_action('enqueue_block_editor_assets', [$this, 'enqueue_block_editor_assets']);
-
- // Methods for handling the actions of creating, making default, and deleting post stati
- add_action('admin_init', [$this, 'handle_add_custom_status']);
- add_action('admin_init', [$this, 'handle_edit_custom_status']);
- add_action('admin_init', [$this, 'handle_delete_custom_status']);
- add_action('wp_ajax_update_status_positions', [$this, 'handle_ajax_update_status_positions']);
-
- // Hook to add the status column to Manage Posts
-
- add_filter('manage_posts_columns', [$this, '_filter_manage_posts_columns']);
- add_action('manage_posts_custom_column', [$this, '_filter_manage_posts_custom_column']);
-
- // We need these for pages (http://core.trac.wordpress.org/browser/tags/3.3.1/wp-admin/includes/class-wp-posts-list-table.php#L283)
- add_filter('manage_pages_columns', [$this, '_filter_manage_posts_columns']);
- add_action('manage_pages_custom_column', [$this, '_filter_manage_posts_custom_column']);
- }
-
- // These seven-ish methods are temporary fixes for solving bugs in WordPress core
- add_filter('preview_post_link', [$this, 'fix_preview_link_part_one']);
- add_filter('post_link', [$this, 'fix_preview_link_part_two'], 10, 3);
- add_filter('page_link', [$this, 'fix_preview_link_part_two'], 10, 3);
- add_filter('post_type_link', [$this, 'fix_preview_link_part_two'], 10, 3);
- add_filter('get_sample_permalink', [$this, 'fix_get_sample_permalink'], 10, 5);
- add_filter('get_sample_permalink_html', [$this, 'fix_get_sample_permalink_html'], 9, 5);
- add_filter('post_row_actions', [$this, 'fix_post_row_actions'], 10, 2);
- add_filter('page_row_actions', [$this, 'fix_post_row_actions'], 10, 2);
-
- add_filter('wp_insert_post_data', [$this, 'filter_insert_post_data'], 10, 2);
- }
-
- /**
- * Returns the list of default custom statuses.
- *
- * @return array
- */
- protected function get_default_terms()
- {
- return [
- 'pitch' => [
- 'term' => __('Pitch', 'publishpress'),
- 'args' => [
- 'slug' => 'pitch',
- 'description' => __('Idea proposed; waiting for acceptance.', 'publishpress'),
- 'position' => 1,
- 'color' => '#cc0000',
- 'icon' => 'dashicons-post-status',
- ],
- ],
- 'assigned' => [
- 'term' => __('Assigned', 'publishpress'),
- 'args' => [
- 'slug' => 'assigned',
- 'description' => __('Post idea assigned to writer.', 'publishpress'),
- 'position' => 2,
- 'color' => '#00bcc5',
- 'icon' => 'dashicons-admin-users',
- ],
- ],
- 'in-progress' => [
- 'term' => __('In Progress', 'publishpress'),
- 'args' => [
- 'slug' => 'in-progress',
- 'description' => __('Writer is working on the post.', 'publishpress'),
- 'position' => 3,
- 'color' => '#ccc500',
- 'icon' => 'dashicons-format-status',
- ],
- ]
- ];
- }
-
- /**
- * Create the default set of custom statuses the first time the module is loaded
- *
- * @since 0.7
- */
- public function install()
- {
- $default_terms = $this->get_default_terms();
- $roles = ['administrator', 'author', 'editor', 'contributor'];
-
- // Okay, now add the default statuses to the db if they don't already exist
- foreach ($default_terms as $term) {
- if (! term_exists($term['term'], self::taxonomy_key)) {
- $this->add_custom_status($term['term'], $term['args']);
- }
- }
-
- // Add basic capabilities for each post status
- $default_terms['publish'] = [];
- foreach ($default_terms as $termSlug => $data) {
- foreach ($roles as $roleName) {
- $role = get_role($roleName);
- if (! empty($role)) {
- $role->add_cap('status_change_' . str_replace('-', '_', $termSlug));
-
- if ('publish' === $termSlug) {
- $role->add_cap('status_change_private');
- $role->add_cap('status_change_future');
- }
- }
- }
- }
- }
-
- /**
- * Upgrade our data in case we need to
- *
- * @since 0.7
- */
- public function upgrade($previous_version)
- {
- global $publishpress;
-
- // Upgrade path to v0.7
- if (version_compare($previous_version, '0.7', '<')) {
- // Migrate dropdown visibility option
- if ($dropdown_visible = get_option('publishpress_status_dropdown_visible')) {
- $dropdown_visible = 'on';
- } else {
- $dropdown_visible = 'off';
- }
- $publishpress->update_module_option($this->module->name, 'always_show_dropdown', $dropdown_visible);
- delete_option('publishpress_status_dropdown_visible');
-
- // Technically we've run this code before so we don't want to auto-install new data
- $publishpress->update_module_option($this->module->name, 'loaded_once', true);
- }
-
- // Upgrade path to v0.7.4
- if (version_compare($previous_version, '0.7.4', '<')) {
- // Custom status descriptions become base64_encoded, instead of maybe json_encoded.
- $this->upgrade_074_term_descriptions(self::taxonomy_key);
- }
- }
-
- /**
- * Makes the call to register_post_status to register the user's custom statuses.
- * Also unregisters draft and pending, in case the user doesn't want them.
- *
- * @param array $args
- */
- public function register_custom_statuses($args = [])
- {
- global $wp_post_statuses;
-
- if ($this->disable_custom_statuses_for_post_type()) {
- return;
- }
-
- // Register new taxonomy so that we can store all our fancy new custom statuses (or is it stati?)
- if (! taxonomy_exists(self::taxonomy_key)) {
- register_taxonomy(
- self::taxonomy_key,
- 'post',
- [
- 'hierarchical' => false,
- 'update_count_callback' => '_update_post_term_count',
- 'label' => __('Statuses', 'publishpress'),
- 'query_var' => false,
- 'rewrite' => false,
- 'show_ui' => false,
- ]
- );
- }
-
- if (function_exists('register_post_status')) {
- $custom_statuses = $this->get_custom_statuses($args, ! is_admin());
-
- // 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) {
- // Ignore core statuses, defined as stdClass
- if ('stdClass' === get_class($status)) {
- continue;
- }
-
- $postStatusArgs = [
- 'label' => $status->name,
- 'protected' => true,
- 'date_floating' => true,
- '_builtin' => false,
- 'label_count' => _n_noop(
- "{$status->name} (%s)",
- "{$status->name} (%s)"
- ),
- ];
-
- $postStatusArgs = apply_filters('publishpress_new_custom_status_args', $postStatusArgs, $status);
-
- register_post_status($status->slug, $postStatusArgs);
- }
- }
- }
-
- /**
- * Whether custom post statuses should be disabled for this post type.
- * Used to stop custom statuses from being registered for post types that don't support them.
- *
- * @return bool
- * @since 0.7.5
- */
- public function disable_custom_statuses_for_post_type($post_type = null)
- {
- global $pagenow;
-
- // Only allow deregistering on 'edit.php' and 'post.php'
- if (! in_array($pagenow, ['edit.php', 'post.php', 'post-new.php'])) {
- return false;
- }
-
-
- if (is_null($post_type)) {
- $post_type = $this->get_current_post_type();
- }
-
- // Always allow for the notification workflows
- if (defined('PUBLISHPRESS_NOTIF_POST_TYPE_WORKFLOW')) {
- if (PUBLISHPRESS_NOTIF_POST_TYPE_WORKFLOW === $post_type) {
- return false;
- }
- }
-
- if ($post_type && ! in_array($post_type, $this->get_post_types_for_module($this->module))) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Enqueue Javascript resources that we need in the admin:
- * - Primary use of Javascript is to manipulate the post status dropdown on Edit Post and Manage Posts
- * - jQuery Sortable plugin is used for drag and dropping custom statuses
- * - We have other custom code for JS niceties
- */
- public function action_admin_enqueue_scripts()
- {
- global $publishpress;
-
-
- if ($this->disable_custom_statuses_for_post_type()) {
- return;
- }
-
- // Load Javascript we need to use on the configuration views (jQuery Sortable)
- if ($this->is_whitelisted_settings_view($this->module->name)) {
- wp_enqueue_script('jquery-ui-sortable');
- wp_enqueue_script(
- 'publishpress-custom-status-configure',
- $this->module_url . 'lib/custom-status-configure.js',
- ['jquery', 'jquery-ui-sortable'],
- PUBLISHPRESS_VERSION,
- true
- );
-
- wp_localize_script(
- 'publishpress-custom-status-configure',
- 'objectL10ncustomstatus',
- [
- 'pp_confirm_delete_status_string' => __(
- 'Are you sure you want to delete the post status? All posts with this status will be assigned to the default status.',
- 'publishpress'
- ),
- ]
- );
- wp_enqueue_script(
- 'publishpress-icon-preview',
- $this->module_url . 'lib/icon-picker.js',
- ['jquery'],
- PUBLISHPRESS_VERSION,
- true
- );
- wp_enqueue_style(
- 'publishpress-icon-preview',
- $this->module_url . 'lib/icon-picker.css',
- ['dashicons'],
- PUBLISHPRESS_VERSION,
- 'all'
- );
-
- wp_enqueue_style(
- 'publishpress-custom_status-admin',
- $this->module_url . 'lib/custom-status-admin.css',
- false,
- PUBLISHPRESS_VERSION,
- 'all'
- );
- }
-
- // Custom javascript to modify the post status dropdown where it shows up
- if ($this->is_whitelisted_page()) {
- wp_enqueue_script(
- 'publishpress-custom_status',
- $this->module_url . 'lib/custom-status.js',
- ['jquery'],
- PUBLISHPRESS_VERSION,
- true
- );
-
- if ($publishpress->isBlockEditorActive()) {
- wp_enqueue_style(
- 'publishpress-custom_status-block',
- $this->module_url . 'lib/custom-status-block-editor.css',
- false,
- PUBLISHPRESS_VERSION,
- 'all'
- );
- } else {
- wp_enqueue_style(
- 'publishpress-custom_status',
- $this->module_url . 'lib/custom-status.css',
- false,
- PUBLISHPRESS_VERSION,
- 'all'
- );
- }
- }
- }
-
- /**
- * Enqueue Gutenberg assets.
- */
- public function enqueue_block_editor_assets()
- {
- global $publishpress;
-
- if ($this->disable_custom_statuses_for_post_type()) {
- return;
- }
-
- wp_enqueue_script(
- 'pp-custom-status-block',
- $this->module_url . '/lib/custom-status-block.min.js',
- ['wp-blocks', 'wp-i18n', 'wp-element', 'wp-hooks'],
- PUBLISHPRESS_VERSION,
- true
- );
-
- $post = get_post();
-
- $statuses = apply_filters('pp_custom_status_list', $this->get_custom_statuses(), $post);
-
- wp_localize_script(
- 'pp-custom-status-block',
- 'PPCustomStatuses',
- array_values($statuses)
- );
- }
-
- /**
- * Displays a notice to users if they have JS disabled
- * Javascript is needed for custom statuses to be fully functional
- */
- public function no_js_notice()
- {
- if ($this->is_whitelisted_page()) :
- ?>
-
-
- Note: Your browser does not support JavaScript or has JavaScript disabled. You will not be able to access or change the post status.',
- 'publishpress'
- ); ?>
-
- field
- * $attributes Insert attributes different to name and class. For example: 'id="something"'
- */
- public function pp_color_picker($current_value = '', $fieldname = 'icon', $attributes = '')
- {
- // Load Color Picker
- if (is_admin()) {
- wp_enqueue_style('wp-color-picker');
- wp_enqueue_script(
- 'publishpress-color-picker',
- $this->module_url . 'lib/color-picker.js',
- ['wp-color-picker'],
- false,
- true
- );
- }
-
- // Set default value if empty
- if (! empty($current_value)) {
- $pp_color = $current_value;
- } else {
- $pp_color = self::DEFAULT_COLOR;
- }
-
- $color_picker = '';
-
- return $color_picker;
- }
-
- /**
- * Generate the dropdown for dashicons
- * $current_value Selected icon for the status
- * fieldname The name for the