diff --git a/admin/admin-posts_rvy.php b/admin/admin-posts_rvy.php index ee2c85fb..56ff718a 100644 --- a/admin/admin-posts_rvy.php +++ b/admin/admin-posts_rvy.php @@ -85,9 +85,17 @@ public function fltAdminPostsListing() { if ($listed_ids) { $id_csv = implode("','", array_map('intval', $listed_ids)); - $revision_base_status_csv = implode("','", array_map('sanitize_key', rvy_revision_base_statuses())); $revision_status_csv = implode("','", array_map('sanitize_key', rvy_revision_statuses())); + $revision_base_statuses = array_map('sanitize_key', rvy_revision_base_statuses()); + + if (!rvy_get_option('pending_revision_unpublished')) { + $published_statuses = get_post_stati( ['public' => true, 'private' => true], 'names', 'or' ); + $revision_base_statuses = array_intersect($revision_base_statuses, $published_statuses); + } + + $revision_base_status_csv = implode("','", $revision_base_statuses); + $results = $wpdb->get_results( "SELECT comment_count AS published_post, COUNT(comment_count) AS num_revisions FROM $wpdb->posts WHERE comment_count IN ('$id_csv') AND post_status IN ('$revision_base_status_csv') AND post_mime_type IN ('$revision_status_csv') AND post_type != '' GROUP BY comment_count" ); @@ -169,7 +177,7 @@ function revisions_row_action_link($actions = array()) { if (!empty($this->post_revision_count[$post->ID])) { if ( 'trash' != $post->post_status && wp_check_post_lock( $post->ID ) === false ) { - $actions['revision_queue'] = "" . esc_html__('Revision Queue', 'revisionary') . ''; + $actions['revision_queue'] = "" . esc_html__('Revision Queue', 'revisionary') . ''; } } diff --git a/admin/history_rvy.php b/admin/history_rvy.php index e6bf530c..c1db01c6 100644 --- a/admin/history_rvy.php +++ b/admin/history_rvy.php @@ -1190,12 +1190,12 @@ function actPastRevisionDiffScripts() { if (rvyRevisionID != rvyLastID) { - var rvyPreviewURL = ''; + var rvyPreviewURL = ''; rvyPreviewURL = rvyPreviewURL.replace("page_id=" + , "page_id=" + rvyRevisionID); rvyPreviewURL = rvyPreviewURL.replace("p=" + , "p=" + rvyRevisionID); - var rvyManageURL = ''; + var rvyManageURL = ''; rvyManageURL = rvyManageURL.replace("revision=" + , "revision=" + rvyRevisionID); if(!$('span.rvy-compare-preview').length) { diff --git a/admin/revision-action_rvy.php b/admin/revision-action_rvy.php index e5b8ab8a..e2a0e833 100644 --- a/admin/revision-action_rvy.php +++ b/admin/revision-action_rvy.php @@ -956,6 +956,13 @@ function rvy_apply_revision( $revision_id, $actual_revision_status = '' ) { clean_post_cache($revision_id); clean_post_cache($published->ID); + if (defined('LSCWP_V')) { + do_action('litespeed_purge_post', $published->ID); + } + + // Passing ignore_revision_ids is not theoretically necessary here since this call occurs after deletion, but avoid any cache clearance timing issues. + revisionary_refresh_revision_flags($published->ID, ['ignore_revision_ids' => $revision_id]); + /** * Trigger after a revision has been applied. * @@ -1083,6 +1090,8 @@ function rvy_revision_bulk_delete() { $post_ids = []; foreach ($delete_revisions as $revision_id) { + $published_post_id = rvy_post_id(); + // this function is only used for past revisions (status=inherit) if ( ! $revision = wp_get_post_revision( $revision_id ) ) continue; @@ -1111,7 +1120,7 @@ function rvy_revision_bulk_delete() { wp_delete_post($revision_id, true); $delete_count++; - do_action('rvy_delete_revision', $revision_id); + do_action('rvy_delete_revision', $revision_id, $published_post_id); rvy_delete_past_revisions($revision_id); } diff --git a/admin/revision-queue_rvy.php b/admin/revision-queue_rvy.php index 6208ce3f..d9c32ebc 100644 --- a/admin/revision-queue_rvy.php +++ b/admin/revision-queue_rvy.php @@ -97,7 +97,7 @@ if (!empty($_REQUEST['post_status'])) { if ($status_obj = get_post_status_object(sanitize_key($_REQUEST['post_status']))) { - $filters['post_status'] = $status_obj->labels->plural; + $filters['post_status'] = (!empty($status_obj->labels->plural)) ? $status_obj->labels->plural : $status_obj->label; } } diff --git a/admin/revision-ui_rvy.php b/admin/revision-ui_rvy.php index ee0b0cee..b56852d3 100644 --- a/admin/revision-ui_rvy.php +++ b/admin/revision-ui_rvy.php @@ -244,7 +244,7 @@ function rvy_list_post_revisions( $post_id = 0, $status = '', $args = null ) { $datef = __awp( 'M j, Y @ g:i a' ); - $rows .= ""; if ( $post->ID != $revision->ID ) { if ('inherit' == $revision->post_status) { diff --git a/admin/revisions.php b/admin/revisions.php index 9dc643a9..b289e4cd 100644 --- a/admin/revisions.php +++ b/admin/revisions.php @@ -113,9 +113,14 @@ $delete_cap = $type_obj->cap->delete_post; } - $published_title = "$rvy_post->post_title"; ?> -

+

+ ID'>" . esc_html($rvy_post->post_title) . "" + ); + ?> +

$_revision_status) { - echo "
  • " - . sprintf( + echo "
  • "; + + $span_style = ('inherit' == $_revision_status) ? ' style="font-weight:bold"' : ''; + + printf( esc_html__( '%1$s %2$s (%3$s)%4$s', 'revisionary' ), - '', + "", esc_html($status_caption), esc_html(number_format_i18n( $num_revisions->$_revision_status )), '' - ) - . '
  • '; + ) ; + + echo '  '; } } else { echo "
  • " . esc_html($status_caption) . '
  • '; diff --git a/front_rvy.php b/front_rvy.php index 50fff573..6b06f37e 100644 --- a/front_rvy.php +++ b/front_rvy.php @@ -268,7 +268,7 @@ function act_template_redirect() { $published_url = ($published_post_id) ? get_permalink($published_post_id) : ''; $diff_url = rvy_admin_url("revision.php?revision=$revision_id"); - $queue_url = rvy_admin_url("admin.php?page=revisionary-q&published_post=$published_post_id"); + $queue_url = rvy_admin_url("admin.php?page=revisionary-q&published_post={$published_post_id}&all=1"); if ((!rvy_get_option('revisor_hide_others_revisions') && !empty($type_obj) && current_user_can($type_obj->cap->edit_posts)) || current_user_can('read_post', $revision_id)) { $view_published = ($published_url) diff --git a/readme.txt b/readme.txt index b204be43..17951f10 100644 --- a/readme.txt +++ b/readme.txt @@ -231,6 +231,14 @@ Divi is one of the most popular page-builders in WordPress, and it does integrat == Changelog == += 3.1.12 - 23 Mar 2023 = +* Fixed : Posts were left with invalid "Has Revision" links after publication or deletion of all their revisions +* Fixed : If Revision Submission for Unpublished Posts is disabled but revisions of draft posts were previously created, those caused a "Has Revisions" label without displaying the revisions in Queue +* Fixed : Links to Revision Queue for a specific published post (including "Has Revision" links from Posts listing) failed to list unsubmitted revisions +* Fixed : Revision Compare > Manage : Non-rendered html tags, incorrect table formatting +* Fixed : Compare Past Revisions - invalid link on Preview / Restore button +* Fixed : Request Deletion link was displayed even if revisions are not enabled for post type + = 3.1.11 - 9 Feb 2023 = * Fixed : Revision preview failure under some conditions * Fixed : Avoid PHP Warning on Revision Preview if requested revision cannot be loaded diff --git a/revision-workflow_rvy.php b/revision-workflow_rvy.php index b83e33e1..67f5a577 100644 --- a/revision-workflow_rvy.php +++ b/revision-workflow_rvy.php @@ -171,7 +171,7 @@ function do_notifications( $notification_type, $status, $post_arr, $args ) { $message .= esc_html__( 'Preview and Approval: ', 'revisionary' ) . $preview_link . "\r\n\r\n"; } - $message .= esc_html__( 'Revision Queue: ', 'revisionary' ) . rvy_admin_url("admin.php?page=revisionary-q&published_post={$published_post->ID}") . "\r\n\r\n"; + $message .= esc_html__( 'Revision Queue: ', 'revisionary' ) . rvy_admin_url("admin.php?page=revisionary-q&published_post={$published_post->ID}&all=1") . "\r\n\r\n"; $message .= sprintf(esc_html__( 'Edit %s: ', 'revisionary' ), pp_revisions_status_label('pending-revision', 'name')) . rvy_admin_url("post.php?action=edit&post={$revision_id}") . "\r\n"; } diff --git a/revisionary_main.php b/revisionary_main.php index 0815ffae..a962a262 100644 --- a/revisionary_main.php +++ b/revisionary_main.php @@ -434,6 +434,8 @@ function actDeletePost($post_id) { wp_delete_post($revision_id, true); } + revisionary_refresh_revision_flags($post_id, ['ignore_revision_ids' => $post_ids]); + $post = get_post($post_id); if ($post && rvy_in_revision_workflow($post)) { diff --git a/rvy_init.php b/rvy_init.php index 62252f3e..563594be 100644 --- a/rvy_init.php +++ b/rvy_init.php @@ -31,6 +31,23 @@ add_action("update_option_rvy_scheduled_publish_cron", '_rvy_existing_schedules_to_cron', 10, 2); +add_action('before_delete_post', + function($delete_post_id) { + if (rvy_in_revision_workflow($delete_post_id)) { + if ($published_post_id = rvy_post_id($delete_post_id)) { + _rvy_delete_revision($delete_post_id, $published_post_id); + } + } + } +); + +add_action('rvy_delete_revision', '_rvy_delete_revision', 999, 2); +add_action('untrash_post', + function($post_id) { + revisionary_refresh_revision_flags($post_id); + } +); + add_action('init', function() { global $kinsta_cache; @@ -97,6 +114,10 @@ function($intend_to_save, $indexable) { 10, 2); } +function _rvy_delete_revision($revision_id, $published_post_id) { + revisionary_refresh_revision_flags($published_post_id, ['ignore_revision_ids' => $revision_id]); +} + function _rvy_rest_prepare($response, $post, $request) { if (!rvy_in_revision_workflow($post)) { return $response; @@ -778,17 +799,28 @@ function revisionary_refresh_postmeta($post_id, $args = []) { revisionary_refresh_revision_flags(); } -function revisionary_refresh_revision_flags() { +function revisionary_refresh_revision_flags($published_post_id = 0, $args = []) { global $wpdb; + $ignore_revision_ids = (!empty($args['ignore_revision_ids'])) ? (array) $args['ignore_revision_ids'] : []; + $status_csv = implode("','", array_map('sanitize_key', rvy_filtered_statuses())); $revision_base_status_csv = implode("','", array_map('sanitize_key', rvy_revision_base_statuses())); $revision_status_csv = implode("','", array_map('sanitize_key', rvy_revision_statuses())); - $arr_have_revisions = $wpdb->get_col( - "SELECT r.comment_count FROM $wpdb->posts r INNER JOIN $wpdb->posts p ON r.comment_count = p.ID" - . " WHERE p.post_status IN ('$status_csv') AND r.post_status IN ('$revision_base_status_csv') AND r.post_mime_type IN ('$revision_status_csv')" - ); + $query = "SELECT r.comment_count FROM $wpdb->posts r INNER JOIN $wpdb->posts p ON r.comment_count = p.ID" + . " WHERE p.post_status IN ('$status_csv') AND r.post_status IN ('$revision_base_status_csv') AND r.post_mime_type IN ('$revision_status_csv')"; + + if ($published_post_id) { + $query = $wpdb->prepare("$query AND p.ID = %d", $published_post_id); + } + + if ($ignore_revision_ids) { + $ignore_revisions_csv = implode("','", array_map('sanitize_key', $ignore_revision_ids)); + $query .= " AND r.ID NOT IN ('$ignore_revisions_csv')"; + } + + $arr_have_revisions = $wpdb->get_col($query); $have_revisions = implode("','", array_map('intval', array_unique($arr_have_revisions))); @@ -797,13 +829,25 @@ function revisionary_refresh_revision_flags() { $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_id IN ('$id_csv')"); } - $have_flag_ids = $wpdb->get_col("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_rvy_has_revisions'"); + $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_rvy_has_revisions'"; + + if ($published_post_id) { + $query = $wpdb->prepare("$query AND post_id = %d", $published_post_id); + } + + $have_flag_ids = $wpdb->get_col($query); if ($posts_missing_flag = array_diff($arr_have_revisions, $have_flag_ids)) { foreach($posts_missing_flag as $post_id) { rvy_update_post_meta($post_id, '_rvy_has_revisions', true); } } + + if ($posts_invalid_flag = array_diff($have_flag_ids, $arr_have_revisions)) { + foreach($posts_missing_flag as $post_id) { + rvy_delete_post_meta($post_id, '_rvy_has_revisions'); + } + } } function rvy_refresh_options() { @@ -1388,16 +1432,16 @@ function rvy_preview_url($revision, $args = []) { if ('revision' == $post_type) { $post_type = get_post_field('post_type', $revision->post_parent); + } else { + if ($post_type_obj = get_post_type_object($revision->post_type)) { + if (empty($post_type_obj->public) && !defined('FL_BUILDER_VERSION') && !apply_filters('revisionary_private_type_use_preview_url', false, $revision)) { // For non-public types, preview is not available so default to Compare Revisions screen + return apply_filters('revisionary_preview_url', rvy_admin_url("revision.php?revision=$revision->ID"), $revision, $args); + } + } } $post_type = sanitize_key($post_type); - if ($post_type_obj = get_post_type_object($revision->post_type)) { - if (empty($post_type_obj->public) && !defined('FL_BUILDER_VERSION') && !apply_filters('revisionary_private_type_use_preview_url', false, $revision)) { // For non-public types, preview is not available so default to Compare Revisions screen - return apply_filters('revisionary_preview_url', rvy_admin_url("revision.php?revision=$revision->ID"), $revision, $args); - } - } - $link_type = rvy_get_option('preview_link_type'); $status_obj = get_post_status_object(get_post_field('post_status', rvy_post_id($revision->ID))); diff --git a/submittee_rvy.php b/submittee_rvy.php index 791dedde..6f63614d 100644 --- a/submittee_rvy.php +++ b/submittee_rvy.php @@ -64,9 +64,9 @@ function default_options( $sitewide = false, $customize_defaults = false ) { function update_sitewide() { check_admin_referer( 'rvy-update-options' ); - $reviewed_options = isset($_POST['rvy_all_movable_options']) ? array_map('sanitize_key', explode(',', sanitize_text_field($_POST['rvy_all_movable_options']))) : array(); + $reviewed_options = isset($_POST['rvy_all_movable_options']) ? array_map('sanitize_key', explode(',', $_POST['rvy_all_movable_options'])) : array(); - $options_sitewide = isset($_POST['rvy_options_sitewide']) ? array_map('sanitize_key', (array) sanitize_text_field($_POST['rvy_options_sitewide'])) : array(); + $options_sitewide = isset($_POST['rvy_options_sitewide']) ? array_map('sanitize_key', (array) $_POST['rvy_options_sitewide']) : array(); update_site_option( "rvy_options_sitewide_reviewed", $reviewed_options ); update_site_option( "rvy_options_sitewide", $options_sitewide );