diff --git a/includes.php b/includes.php index f4159436b..d39e99edd 100644 --- a/includes.php +++ b/includes.php @@ -40,7 +40,7 @@ ); // Define contants - define('PUBLISHPRESS_VERSION', '1.11.4'); + define('PUBLISHPRESS_VERSION', '1.12.0'); define('PUBLISHPRESS_BASE_PATH', __DIR__); define('PUBLISHPRESS_FILE_PATH', PUBLISHPRESS_BASE_PATH . '/' . basename(__FILE__)); define('PUBLISHPRESS_URL', plugins_url('/', __FILE__)); diff --git a/libraries/Notifications/Shortcodes.php b/libraries/Notifications/Shortcodes.php index 124fdc886..50c30bbfa 100644 --- a/libraries/Notifications/Shortcodes.php +++ b/libraries/Notifications/Shortcodes.php @@ -111,32 +111,20 @@ protected function get_actor() protected function get_user_data($user, $attrs) { // No attributes? Set the default one. - if (empty($attrs)) - { + if (empty($attrs)) { $attrs[] = 'display_name'; } // Set the separator - if (!isset($attrs['separator'])) - { + if (!isset($attrs['separator'])) { $attrs['separator'] = ', '; } // Get the user's info - $info = []; - $valid_attributes = [ - 'id', - 'login', - 'url', - 'display_name', - 'email', - 'separator', - ]; - - foreach ($attrs as $index => $item) - { - switch ($item) - { + $info = []; + + foreach ($attrs as $index => $item) { + switch ($item) { case 'id': $info[] = $user->ID; break; @@ -217,6 +205,7 @@ protected function get_post() * - old_status * - new_status * - separator + * - edit_link * * @param WP_Post $post * @param array $attrs @@ -227,34 +216,20 @@ protected function get_post_data($post, $attrs) $publishpress = $this->get_service('publishpress'); // No attributes? Set the default one. - if (empty($attrs)) - { - $attrs = array('title'); + if (empty($attrs)) { + $attrs = ['title']; } // Set the separator - if (!isset($attrs['separator'])) - { + if (!isset($attrs['separator'])) { $attrs['separator'] = ', '; } // Get the post's info - $info = []; - $valid_attributes = [ - 'id', - 'title', - 'permalink', - 'date', - 'time', - 'old_status', - 'new_status', - 'separator', - ]; - - foreach ($attrs as $index => $item) - { - switch ($item) - { + $info = []; + + foreach ($attrs as $index => $item) { + switch ($item) { case 'id': $info[] = $post->ID; break; @@ -264,7 +239,7 @@ protected function get_post_data($post, $attrs) break; case 'permalink': - $info[] = get_post_permalink($post->ID); + $info[] = get_permalink($post->ID); break; case 'date': @@ -282,14 +257,18 @@ protected function get_post_data($post, $attrs) $this->action_args[$item] ); - if (empty($status) || 'WP_Error' === get_class($status)) - { + if (empty($status) || 'WP_Error' === get_class($status)) { break; } $info[] = $status->name; break; + case 'edit_link': + $admin_path = 'post.php?post=' . $post->ID . '&action=edit'; + $info[] = htmlspecialchars_decode(admin_url($admin_path)); + break; + default: break; } @@ -318,29 +297,20 @@ public function handle_psppno_workflow($attrs) $post = $this->workflow_post; // No attributes? Set the default one. - if (empty($attrs)) - { + if (empty($attrs)) { $attrs[] = 'title'; } // Set the separator - if (!isset($attrs['separator'])) - { + if (!isset($attrs['separator'])) { $attrs['separator'] = ', '; } // Get the post's info - $info = []; - $valid_attributes = [ - 'id', - 'title', - 'separator', - ]; - - foreach ($attrs as $index => $item) - { - switch ($item) - { + $info = []; + + foreach ($attrs as $index => $item) { + switch ($item) { case 'id': $info[] = $post->ID; break; @@ -379,42 +349,27 @@ public function handle_psppno_workflow($attrs) */ public function handle_psppno_edcomment($attrs) { - if (!isset($this->action_args['comment'])) - { + if (!isset($this->action_args['comment'])) { return; } $comment = $this->action_args['comment']; // No attributes? Set the default one. - if (empty($attrs)) - { + if (empty($attrs)) { $attrs[] = 'content'; } // Set the separator - if (!isset($attrs['separator'])) - { + if (!isset($attrs['separator'])) { $attrs['separator'] = ', '; } // Get the post's info - $info = []; - $valid_attributes = [ - 'id', - 'content', - 'author', - 'author_email', - 'author_url', - 'author_ip', - 'date', - 'separator', - ]; - - foreach ($attrs as $index => $item) - { - switch ($item) - { + $info = []; + + foreach ($attrs as $index => $item) { + switch ($item) { case 'id': $info[] = $comment->comment_ID; break; diff --git a/libraries/Notifications/Traits/Dependency_Injector.php b/libraries/Notifications/Traits/Dependency_Injector.php index 04b9b3b90..fa4fc8638 100644 --- a/libraries/Notifications/Traits/Dependency_Injector.php +++ b/libraries/Notifications/Traits/Dependency_Injector.php @@ -24,6 +24,8 @@ trait Dependency_Injector * * @param string $service_name * + * @return mix + * * @throws \Exception */ public function get_service($service_name) diff --git a/libraries/Notifications/Workflow/Controller.php b/libraries/Notifications/Workflow/Controller.php index a73780149..6203730df 100644 --- a/libraries/Notifications/Workflow/Controller.php +++ b/libraries/Notifications/Workflow/Controller.php @@ -68,7 +68,7 @@ public function run_workflows($args) * @param array $args * @return array */ - protected function get_filtered_workflows($args) + public function get_filtered_workflows($args) { $workflows = []; diff --git a/libraries/Notifications/Workflow/Step/Base.php b/libraries/Notifications/Workflow/Step/Base.php index a989f84f0..863db984f 100644 --- a/libraries/Notifications/Workflow/Step/Base.php +++ b/libraries/Notifications/Workflow/Step/Base.php @@ -67,6 +67,10 @@ public function __construct() * Action to display the metabox * * @param string $html + * + * @return string + * + * @throws \Exception */ public function render_metabox_section($html) { diff --git a/libraries/Notifications/Workflow/Step/Event_Content/Filter/Category.php b/libraries/Notifications/Workflow/Step/Event_Content/Filter/Category.php index bb645a16e..1bd69b2f0 100644 --- a/libraries/Notifications/Workflow/Step/Event_Content/Filter/Category.php +++ b/libraries/Notifications/Workflow/Step/Event_Content/Filter/Category.php @@ -96,6 +96,10 @@ public function save_metabox_data($id, $post) */ public function get_run_workflow_query_args($query_args, $action_args) { + // If post is not set, we ignore. + if (!isset($action_args['post']) || !is_object($action_args['post'])) { + return parent::get_run_workflow_query_args($query_args, $action_args); + } $categories = wp_get_post_terms($action_args['post']->ID, 'category'); $category_ids = []; diff --git a/libraries/Notifications/Workflow/Step/Event_Content/Filter/Post_Type.php b/libraries/Notifications/Workflow/Step/Event_Content/Filter/Post_Type.php index 5b23ff86b..8acf974e2 100644 --- a/libraries/Notifications/Workflow/Step/Event_Content/Filter/Post_Type.php +++ b/libraries/Notifications/Workflow/Step/Event_Content/Filter/Post_Type.php @@ -90,7 +90,12 @@ public function save_metabox_data($id, $post) */ public function get_run_workflow_query_args($query_args, $action_args) { + // If post is not set, we ignore. + if (!isset($action_args['post']) || !is_object($action_args['post'])) { + return parent::get_run_workflow_query_args($query_args, $action_args); + } + // Add the filters $query_args['meta_query'][] = [ 'relation' => 'OR', // The filter is disabled diff --git a/libraries/Notifications/Workflow/Step/Event_Content/Post_Type.php b/libraries/Notifications/Workflow/Step/Event_Content/Post_Type.php index 376e46917..dcbe29178 100644 --- a/libraries/Notifications/Workflow/Step/Event_Content/Post_Type.php +++ b/libraries/Notifications/Workflow/Step/Event_Content/Post_Type.php @@ -58,7 +58,6 @@ protected function get_filters($filters = []) */ public function filter_run_workflow_query_args($query_args, $action_args) { - // Check the filters $filters = $this->get_filters(); diff --git a/libraries/Notifications/Workflow/Workflow.php b/libraries/Notifications/Workflow/Workflow.php index dd714f2fc..6903483cc 100644 --- a/libraries/Notifications/Workflow/Workflow.php +++ b/libraries/Notifications/Workflow/Workflow.php @@ -17,6 +17,8 @@ class Workflow use Dependency_Injector; + const NOTIFICATION_SCHEDULE_META_KEY = '_psppre_notification_scheduled'; + /** * The post of this workflow. * @@ -223,4 +225,61 @@ protected function filter_shortcodes($text) { return do_shortcode($text); } + + /** + * Get posts related to this workflow, applying the filters, in a reverse way, not founding a workflow related + * to the post. Used by add-ons like Reminders. + * + * @return array + */ + public function get_related_posts() + { + $posts = []; + + // Build the query + $query_args = [ + 'nopaging' => true, + 'post_status' => 'future', + 'no_found_rows' => true, + 'cache_results' => true, + 'meta_query' => [ + [ + 'key' => static::NOTIFICATION_SCHEDULE_META_KEY, + 'compare' => 'NOT EXISTS', + ], + ] + ]; + + // Check if the workflow filters by post type + $workflowPostTypes = get_post_meta( + $this->workflow_post->ID, + Step\Event_Content\Filter\Post_Type::META_KEY_POST_TYPE + ); + + if (!empty($workflowPostTypes)) { + $query_args['post_type'] = $workflowPostTypes; + } + + // Check if the workflow filters by category + $workflowCategories = get_post_meta( + $this->workflow_post->ID, + Step\Event_Content\Filter\Category::META_KEY_CATEGORY + ); + + if (!empty($workflowCategories)) { + $query_args['category__in'] = $workflowCategories; + } + + $query = new \WP_Query($query_args); + + if (!empty($query->posts)) + { + foreach ($query->posts as $post) + { + $posts[] = $post; + } + } + + return $posts; + } } diff --git a/modules/async-notifications/async-notifications.php b/modules/async-notifications/async-notifications.php index 7d3133b68..849429a08 100644 --- a/modules/async-notifications/async-notifications.php +++ b/modules/async-notifications/async-notifications.php @@ -74,8 +74,8 @@ public function __construct() // Register the module with PublishPress $args = [ 'title' => __('Async Notifications', 'publishpress'), - 'short_description' => __('Async notifications for PublishPress', 'publishpress'), - 'extended_description' => __('Async Notifications for PublishPress', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-feedback', 'slug' => 'async-notifications', diff --git a/modules/async-notifications/library/Queue/WPCron.php b/modules/async-notifications/library/Queue/WPCron.php index 609669aae..5cae910c9 100644 --- a/modules/async-notifications/library/Queue/WPCron.php +++ b/modules/async-notifications/library/Queue/WPCron.php @@ -71,6 +71,14 @@ public function enqueueNotification($workflowPost, $actionArgs, $receivers, $con $channel, ]; + $timestamp = apply_filters('publishpress_notif_async_timestamp', time(), $workflowPost->ID); + + if (false === $timestamp) { + // Abort. + error_log('PublishPress aborted a notification. Invalid timestamp for workflow ' . $workflowPost->ID); + return; + } + // Create one notification for each receiver in the queue foreach ($receivers as $receiver) { @@ -80,7 +88,7 @@ public function enqueueNotification($workflowPost, $actionArgs, $receivers, $con // Receiver $data[] = $receiver; - $this->scheduleEvent($data); + $this->scheduleEvent($data, $timestamp); } } } @@ -89,12 +97,14 @@ public function enqueueNotification($workflowPost, $actionArgs, $receivers, $con * Schedule the notification event. * * @param $data + * @param $timestamp + * * @throws \Exception */ - protected function scheduleEvent($data) + protected function scheduleEvent($data, $timestamp) { wp_schedule_single_event( - time() + 4, + $timestamp, 'publishpress_cron_notify', $data ); diff --git a/modules/calendar/calendar.php b/modules/calendar/calendar.php index add395a25..9a91e1247 100644 --- a/modules/calendar/calendar.php +++ b/modules/calendar/calendar.php @@ -125,8 +125,8 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('Calendar', 'publishpress'), - 'short_description' => __('The calendar lets you see your posts over a customizable date range.', 'publishpress'), - 'extended_description' => __('PublishPress’s calendar lets you see your posts over a customizable date range. Filter by status or click on the post title to see its details. Drag and drop posts between days to change their publication date.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-calendar-alt', 'slug' => 'calendar', diff --git a/modules/content-overview/content-overview.php b/modules/content-overview/content-overview.php index 8fa03858b..7a5efa16b 100644 --- a/modules/content-overview/content-overview.php +++ b/modules/content-overview/content-overview.php @@ -110,8 +110,8 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('Content Overview', 'publishpress'), - 'short_description' => __('Click here for a single screen that shows the publication status of all your content.', 'publishpress'), - 'extended_description' => __('Use the content overview to see how content on your site is progressing. Filter by specific categories or date ranges to see details about each post in progress.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-list-view', 'slug' => 'content-overview', diff --git a/modules/custom-status/custom-status.php b/modules/custom-status/custom-status.php index 24242fb7f..a4c8e7a54 100644 --- a/modules/custom-status/custom-status.php +++ b/modules/custom-status/custom-status.php @@ -59,8 +59,8 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('Statuses', 'publishpress'), - 'short_description' => __('Create custom post statuses to define the stages of your publishing workflow.', 'publishpress'), - 'extended_description' => __('Create your own post statuses to add structure your publishing workflow. You can change existing or add new ones anytime, and drag and drop to change their order.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-tag', 'slug' => 'custom-status', diff --git a/modules/dashboard/dashboard.php b/modules/dashboard/dashboard.php index 03b38469e..0fefa76a9 100644 --- a/modules/dashboard/dashboard.php +++ b/modules/dashboard/dashboard.php @@ -56,8 +56,8 @@ public function __construct() $this->module_url = $this->get_module_url(__FILE__); $args = array( 'title' => __('Dashboard', 'publishpress'), - 'short_description' => __('Track your content from the WordPress dashboard.', 'publishpress'), - 'extended_description' => __('Enable dashboard widgets to quickly get an overview of what state your content is in.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-layout', 'slug' => 'dashboard', diff --git a/modules/editorial-comments/editorial-comments.php b/modules/editorial-comments/editorial-comments.php index 687dde35b..d24aad363 100644 --- a/modules/editorial-comments/editorial-comments.php +++ b/modules/editorial-comments/editorial-comments.php @@ -47,8 +47,8 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('Editorial Comments', 'publishpress'), - 'short_description' => __('Share internal notes with your team.', 'publishpress'), - 'extended_description' => __('Use editorial comments to hold a private discussion about a post. Communicate directly with your writers or editors about what works and what needs to be improved for each piece.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-admin-comments', 'slug' => 'editorial-comments', diff --git a/modules/editorial-metadata/editorial-metadata.php b/modules/editorial-metadata/editorial-metadata.php index 4fa3163e3..6ee11c3c3 100644 --- a/modules/editorial-metadata/editorial-metadata.php +++ b/modules/editorial-metadata/editorial-metadata.php @@ -71,8 +71,8 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('Metadata', 'publishpress'), - 'short_description' => __('With Metadata you can customize the extra data that’s tracked for your content.', 'publishpress'), - 'extended_description' => __('Log details on every assignment using configurable editorial metadata. It’s completely customizable; create fields for everything from due date to location to contact information to role assignments.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-feedback', 'slug' => 'editorial-metadata', diff --git a/modules/improved-notifications/assets/js/workflow_form.js b/modules/improved-notifications/assets/js/workflow_form.js index 2b63e4bf6..e4a20748e 100644 --- a/modules/improved-notifications/assets/js/workflow_form.js +++ b/modules/improved-notifications/assets/js/workflow_form.js @@ -38,6 +38,9 @@ } } + // Make this method public for add-ons. + window.publishpressSetupFieldFilters = setupFieldFilters; + setupFieldFilters('event_post_save'); setupFieldFilters('event_content_post_type'); setupFieldFilters('event_content_category'); diff --git a/modules/improved-notifications/improved-notifications.php b/modules/improved-notifications/improved-notifications.php index e87a95bf1..efc2105bd 100644 --- a/modules/improved-notifications/improved-notifications.php +++ b/modules/improved-notifications/improved-notifications.php @@ -87,8 +87,8 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('Notification Workflows', 'publishpress'), - 'short_description' => __('Advanced notification workflows for PublishPress', 'publishpress'), - 'extended_description' => __('Advanced Notification workflows for PublishPress', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-feedback', 'slug' => 'improved-notifications', @@ -162,9 +162,6 @@ public function init() remove_all_actions('pp_send_notification_status_update'); remove_all_actions('pp_send_notification_comment'); - // Instantiate the controller of workflow's - $workflow_controller = $this->get_service('workflow_controller'); - $workflow_controller->load_workflow_steps(); // Add action to intercept transition between post status - post save add_action('transition_post_status', [$this, 'action_transition_post_status'], 999, 3); @@ -188,6 +185,8 @@ public function init() add_filter('pp_notification_send_email_message_headers', [$this, 'filter_send_email_message_headers'], 10, 3); add_filter('months_dropdown_results', [$this, 'hide_months_dropdown_filter'], 10, 2); + + add_action('pp_init', [$this, 'action_after_init']); } /** @@ -205,6 +204,19 @@ public function install() } } + /** + * Methods called after all modules where loaded and initialized, + * to make sure all hooks are set before we start some specific features. + */ + public function action_after_init() + { + // Instantiate the controller of workflow's + $workflow_controller = $this->get_service('workflow_controller'); + $workflow_controller->load_workflow_steps(); + + do_action('publishpress_workflow_steps_loaded'); + } + /** * Create default notification workflows based on current notification settings */ diff --git a/modules/modules-settings/modules-settings.php b/modules/modules-settings/modules-settings.php index 2b421ffdb..b51685643 100644 --- a/modules/modules-settings/modules-settings.php +++ b/modules/modules-settings/modules-settings.php @@ -46,7 +46,7 @@ public function __construct() // Register the module with PublishPress $args = array( 'title' => __('General', 'publishpress'), - 'short_description' => __('This tab contains settings for key features including notifications, dashboard widgets, and comments.', 'publishpress'), + 'short_description' => false, 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-admin-settings', diff --git a/modules/notifications/notifications.php b/modules/notifications/notifications.php index 99da77da0..4388d2db0 100644 --- a/modules/notifications/notifications.php +++ b/modules/notifications/notifications.php @@ -62,8 +62,8 @@ public function __construct() $this->module_url = $this->get_module_url(__FILE__); $args = array( 'title' => __('Default Notifications', 'publishpress'), - 'short_description' => __('With notifications, you can keep everyone updated about what’s happening with your content.', 'publishpress'), - 'extended_description' => __('With notifications, you can keep everyone updated about what’s happening with a given content. Each status change or editorial comment sends out a message to users subscribed to a post. Roles can be used to manage who receives notifications on what.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-email', 'slug' => 'notifications', @@ -1565,7 +1565,8 @@ public function send_notification_status_update($args) $body .= sprintf(__('Author: %1$s (%2$s )', 'publishpress'), $post_author->display_name, $post_author->user_email) . "\r\n"; } - $edit_link = htmlspecialchars_decode(get_edit_post_link($post_id)); + $admin_path = 'post.php?post=' . $post_id . '&action=edit'; + $edit_link = htmlspecialchars_decode(admin_url($admin_path)); if ($new_status != 'publish') { $view_link = add_query_arg(array('preview' => 'true'), wp_get_shortlink($post_id)); @@ -1604,7 +1605,8 @@ public function send_notification_comment($args) $body .= "\r\n--------------------\r\n"; - $edit_link = htmlspecialchars_decode(get_edit_post_link($args['post_id'])); + $admin_path = 'post.php?post=' . $args['post_id'] . '&action=edit'; + $edit_link = htmlspecialchars_decode(admin_url($admin_path)); $view_link = htmlspecialchars_decode(get_permalink($args['post_id'])); $body .= "\r\n"; diff --git a/modules/roles/roles.php b/modules/roles/roles.php index 1e7b874d3..a0f65ca19 100644 --- a/modules/roles/roles.php +++ b/modules/roles/roles.php @@ -151,7 +151,25 @@ public function init() add_action('profile_update', [$this, 'action_profile_update'], 10, 2); add_action('user_register', [$this, 'action_profile_update'], 10); - add_action('publishpress_migrate_groups_to_role', [$this, 'migrateUserGroupsToRoles']); + if ($this->wasPublishPressInstalledBefore()) { + add_action('publishpress_migrate_groups_to_role', [$this, 'migrateUserGroupsToRoles']); + } + } + + /** + * Detects if PublishPress was previously installed. + */ + public function wasPublishPressInstalledBefore() + { + $version = get_option('publishpress_version', false); + + $installed = !empty($version); + + if (PUBLISHPRESS_VERSION === $version) { + $installed = false; + } + + return $installed; } /** @@ -162,7 +180,10 @@ public function init() public function install() { $this->addCapabilitiesToAdmin(); - $this->scheduleUserGroupMigration(); + + if ($this->wasPublishPressInstalledBefore()) { + $this->scheduleUserGroupMigration(); + } } /*[$* @@ -201,7 +222,6 @@ protected function isUserGroupMigrationScheduled() public function scheduleUserGroupMigration() { // Check if the cron do not exists before schedule another one - if (!$this->isUserGroupMigrationScheduled()) { // Schedule for after 15 seconds. wp_schedule_single_event( diff --git a/modules/user-groups/user-groups.php b/modules/user-groups/user-groups.php index 3c3615d88..ddda0ff77 100644 --- a/modules/user-groups/user-groups.php +++ b/modules/user-groups/user-groups.php @@ -70,8 +70,8 @@ public function __construct() // Register the User Groups module with PublishPress $args = array( 'title' => __('User Groups', 'publishpress'), - 'short_description' => __('Organize your users into groups who can take different roles in your publishing workflow.', 'publishpress'), - 'extended_description' => __('Configure user groups to organize all of the users on your site. Each user can be in many user groups and you can change them at any time.', 'publishpress'), + 'short_description' => false, + 'extended_description' => false, 'module_url' => $this->module_url, 'icon_class' => 'dashicons dashicons-groups', 'slug' => 'user-groups', diff --git a/publishpress.php b/publishpress.php index f67e5ee10..10534c14d 100644 --- a/publishpress.php +++ b/publishpress.php @@ -5,7 +5,7 @@ * Description: The essential plugin for any WordPress site with multiple writers * Author: PublishPress * Author URI: https://publishpress.com - * Version: 1.11.4 + * Version: 1.12.0 * Text Domain: publishpress * Domain Path: /languages * diff --git a/readme.txt b/readme.txt index e0b1df109..fe959eaf3 100644 --- a/readme.txt +++ b/readme.txt @@ -6,7 +6,7 @@ Tags: Content Calendar, Editorial Calendar, workflow, checklist, permissions Requires at least: 4.6 Requires PHP: 5.4 Tested up to: 4.9.4 -Stable tag: 1.11.4 +Stable tag: 1.12.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -133,6 +133,21 @@ You can install PublishPress through your WordPress admin area: The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). += [1.12.0] - 2018-04-18 = + +*Added:* + +* Added option to display the edit link of the post in a notification's message; + +*Fixed:* + +* Fixed the warning about migration of legacy data in fresh installs; +* Fixed the post link on notifications; + +*Changed:* + +* Improved async notifications module for allowing extending workflows with add-ons (specially Reminders); + = [1.11.4] - 2018-04-05 = *Fixed:* diff --git a/twig/workflow_help.twig b/twig/workflow_help.twig index 4c977e100..441bf6997 100644 --- a/twig/workflow_help.twig +++ b/twig/workflow_help.twig @@ -4,7 +4,7 @@

{{ labels.content }}

[psppno_post]
-

{{ labels.available_fields }}: id, title, permalink, date, time, old_status, new_status

+

{{ labels.available_fields }}: id, title, permalink, date, time, old_status, new_status, edit_link

{{ labels.actor }}

[psppno_actor]