WP Revisions Control - Version 1.4

Version Description

  • Introduce block-editor (Gutenberg) sidebar component for supported post types.
Download this release

Release Info

Developer ethitter
Plugin Icon wp plugin WP Revisions Control
Version 1.4
Comparing to
See all releases

Code changes from version 1.3 to 1.4

assets/build/classic-editor.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array('jquery'), 'version' => '60fb0f1e9e40b24c7794');
assets/build/classic-editor.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(){"use strict";var t,e={n:function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,{a:n}),n},d:function(t,n){for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:function(t,e){return Object.prototype.hasOwnProperty.call(t,e)}},n=window.jQuery;(t=e.n(n)())(document).ready((function(){const e=t("#"+wp_revisions_control.namespace+" .button.purge");let n=null,o=null;function r(o){if(o.error)alert(o.error),t(e).text(n);else if(o.success){const n=t("ul.post-revisions > li");t(n).each((function(){t(this).text().match(wp_revisions_control.autosave)||t(this).slideUp("slow").remove()})),t(e).fadeOut("slow").after(wp_revisions_control.nothing_text)}}function s(){alert(wp_revisions_control.error),t(e).text(n)}n=t(e).text(),t(e).on("click",(function(){o=parseInt(t(this).data("postid")),t(e).text(wp_revisions_control.processing_text),confirm(wp_revisions_control.ays)&&o?t.ajax({url:ajaxurl,cache:!1,data:{action:wp_revisions_control.action_base+"_purge",post_id:o,nonce:t(this).data("nonce")},type:"post",dataType:"json",success:r,error:s}):t(e).text(n)}))}))}();
assets/build/gutenberg.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array('wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '7f1755eabefc886809fd');
assets/build/gutenberg.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ !function(){"use strict";var e={989:function(e){e.exports=window.wp.apiFetch},609:function(e){e.exports=window.wp.components},333:function(e){e.exports=window.wp.compose},818:function(e){e.exports=window.wp.data},67:function(e){e.exports=window.wp.editPost},307:function(e){e.exports=window.wp.element},736:function(e){e.exports=window.wp.i18n},817:function(e){e.exports=window.wp.plugins}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,o),i.exports}o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,{a:t}),t},o.d=function(e,t){for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e=o(307);const t=o(989),{Button:n,Modal:r,TextControl:i}=o(609),{compose:s}=o(333),{withSelect:l,withDispatch:c}=o(818),{PluginDocumentSettingPanel:a}=o(67),{useState:u}=o(307),{__:__,_n:_n,sprintf:p}=o(736),{registerPlugin:w}=o(817),d=window.wpRevisionsControlBlockEditorSettings.metaKey,v="wp-revisions-control",m=s([l((e=>{const{getCurrentPostRevisionsCount:t,getEditedPostAttribute:o}=e("core/editor"),n=t(),r=o("meta")[d];return{limit:r,showPurgeButton:Boolean(r)&&n>parseInt(r)}})),c(((e,o,n)=>{let{limit:r}=o,{select:i}=n;return{manualPurge:()=>{const o=i("core/editor").getCurrentPostId();t({path:`/wp-revisions-control/v1/schedule/${o}/${parseInt(r,10)}`,method:"PUT"}).then((t=>{let o,n;t?(o="success",n=__("Excess revisions scheduled for removal.","wp_revisions_control")):(o="error",n=__("Failed to schedule excess revisions for removal.","wp_revisions_control")),e("core/notices").createNotice(o,n,{id:"wp-revisions-control-scheduled-purge",isDismissible:!0,type:"snackbar"})}))},updateMeta:t=>{e("core/editor").editPost({meta:{[d]:t}})}}}))])((t=>{let{limit:o,manualPurge:s,showPurgeButton:l,updateMeta:c}=t;return(0,e.createElement)(a,{name:v,title:__("WP Revisions Control","wp_revisions_control"),className:v},(0,e.createElement)(i,{label:__("Number of revisions to retain:","wp_revisions_control"),help:__("Leave blank to keep all revisions.","wp_revisions_control"),value:o,onChange:c}),l&&((t,o)=>{const[i,s]=u(!1),l=()=>s(!1),c=parseInt(t,10),a=0===c?__("This will remove all revisions.","wp_revisions_control"):p(
2
+ /* translators: 1. Number of revisions to keep. */
3
+ _n("This will remove all but the most-recent revision.","This will remove all but the %1$d most-recent revisions.",c,"wp_revisions_control"),t);return(0,e.createElement)(e.Fragment,null,(0,e.createElement)(n,{isSecondary:!0,onClick:()=>s(!0)},__("Purge excess revisions","wp_revisions_control")),i&&(0,e.createElement)(r,{title:__("Purge excess revisions","wp_revisions_control"),contentLabel:a,onRequestClose:l},(0,e.createElement)("p",null,a),(0,e.createElement)(n,{isPrimary:!0,onClick:()=>{l(),o()}},__("Purge","wp_revisions_control"))," ",(0,e.createElement)(n,{isSecondary:!0,onClick:l},__("Cancel","wp_revisions_control"))))})(o,s))}));w(v,{render:m,icon:"backup"})}()}();
inc/class-block-editor.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Support block editor (Gutenberg).
4
+ *
5
+ * @package WP_Revisions_Control
6
+ */
7
+
8
+ namespace WP_Revisions_Control;
9
+
10
+ use WP_REST_Response;
11
+ use WP_REST_Request;
12
+ use WP_Revisions_Control;
13
+
14
+ /**
15
+ * Class Block_Editor.
16
+ */
17
+ class Block_Editor {
18
+ use Singleton;
19
+
20
+ /**
21
+ * Name of action used to clean up post's revisions via cron.
22
+ *
23
+ * @var string
24
+ */
25
+ private $cron_action = 'wp_revisions_control_cron_purge';
26
+
27
+ /**
28
+ * Prepare class.
29
+ *
30
+ * This is called at `init`, so cannot use that hook unless priority is
31
+ * greater than 10.
32
+ */
33
+ private function setup() {
34
+ add_action( 'rest_api_init', array( $this, 'action_rest_api_init' ) );
35
+ add_filter( 'is_protected_meta', array( $this, 'filter_is_protected_meta' ), 10, 2 );
36
+ add_action( $this->cron_action, array( WP_Revisions_Control::get_instance(), 'do_purge_excess' ), 10, 2 );
37
+ add_action( 'enqueue_block_editor_assets', array( $this, 'action_enqueue_block_editor_assets' ) );
38
+ }
39
+
40
+ /**
41
+ * Register REST API components for Gutenberg UI.
42
+ */
43
+ public function action_rest_api_init() {
44
+ if ( ! function_exists( 'register_rest_route' ) ) {
45
+ return;
46
+ }
47
+
48
+ foreach ( array_keys( WP_Revisions_Control::get_instance()->get_post_types() ) as $post_type ) {
49
+ register_meta(
50
+ 'post',
51
+ WP_REVISIONS_CONTROL_LIMIT_META_KEY,
52
+ array(
53
+ 'object_subtype' => $post_type,
54
+ 'type' => 'string', // Can be empty, so must be string.
55
+ 'default' => '',
56
+ 'single' => true,
57
+ 'show_in_rest' => true,
58
+ 'description' => __(
59
+ 'Number of revisions to retain.',
60
+ 'wp_revisions_control'
61
+ ),
62
+ )
63
+ );
64
+ }
65
+
66
+ register_rest_route(
67
+ 'wp-revisions-control/v1',
68
+ 'schedule/(?P<id>[\d]+)/(?P<limit_override>[\d]+)',
69
+ array(
70
+ 'methods' => 'PUT',
71
+ 'callback' => array( $this, 'rest_api_schedule_purge' ),
72
+ 'permission_callback' => array( $this, 'rest_api_permission_callback' ),
73
+ 'args' => array(
74
+ 'id' => array(
75
+ 'required' => true,
76
+ 'type' => 'integer',
77
+ 'validate_callback' => array( $this, 'rest_api_validate_id' ),
78
+ ),
79
+ 'limit_override' => array(
80
+ 'required' => false,
81
+ 'type' => 'integer',
82
+ 'default' => null,
83
+ 'validate_callback' => array( $this, 'rest_api_validate_id' ),
84
+ ),
85
+ ),
86
+ 'show_in_index' => false,
87
+ )
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Permissions callback for REST endpoint.
93
+ *
94
+ * @param WP_REST_Request $request Request object.
95
+ * @return bool
96
+ */
97
+ public function rest_api_permission_callback( $request ) {
98
+ return current_user_can(
99
+ 'edit_post',
100
+ $request->get_param( 'id' )
101
+ );
102
+ }
103
+
104
+ /**
105
+ * Validate post ID.
106
+ *
107
+ * @param int $input Post ID.
108
+ * @return bool
109
+ */
110
+ public function rest_api_validate_id( $input ) {
111
+ return is_numeric( $input );
112
+ }
113
+
114
+ /**
115
+ * Schedule cleanup of post's excess revisions.
116
+ *
117
+ * @param WP_REST_Request $request Request object.
118
+ * @return WP_REST_Response
119
+ */
120
+ public function rest_api_schedule_purge( $request ) {
121
+ $result = wp_schedule_single_event(
122
+ time() + 3,
123
+ $this->cron_action,
124
+ array(
125
+ $request->get_param( 'id' ),
126
+ $request->get_param( 'limit_override' ),
127
+ )
128
+ );
129
+
130
+ return rest_ensure_response( $result );
131
+ }
132
+
133
+ /**
134
+ * Allow our meta to be edited from Gutenberg.
135
+ *
136
+ * @param bool $protected If meta is protected.
137
+ * @param string $meta_key Meta key being checked.
138
+ * @return false
139
+ */
140
+ public function filter_is_protected_meta( $protected, $meta_key ) {
141
+ if ( WP_REVISIONS_CONTROL_LIMIT_META_KEY === $meta_key ) {
142
+ return false;
143
+ }
144
+
145
+ return $protected;
146
+ }
147
+
148
+ /**
149
+ * Register Gutenberg script.
150
+ */
151
+ public function action_enqueue_block_editor_assets() {
152
+ $handle = 'wp-revisions-control-block-editor';
153
+ $asset_data = require_once dirname( __DIR__ ) . '/assets/build/gutenberg.asset.php';
154
+
155
+ wp_enqueue_script(
156
+ $handle,
157
+ plugins_url(
158
+ 'assets/build/gutenberg.js',
159
+ __DIR__
160
+ ),
161
+ $asset_data['dependencies'],
162
+ $asset_data['version']
163
+ );
164
+
165
+ wp_localize_script(
166
+ $handle,
167
+ 'wpRevisionsControlBlockEditorSettings',
168
+ array(
169
+ 'metaKey' => WP_REVISIONS_CONTROL_LIMIT_META_KEY,
170
+ )
171
+ );
172
+ }
173
+ }
inc/class-wp-revisions-control-bulk-actions.php CHANGED
@@ -5,16 +5,13 @@
5
  * @package WP_Revisions_Control
6
  */
7
 
 
 
8
  /**
9
  * Class WP_Revisions_Control_Bulk_Actions.
10
  */
11
  class WP_Revisions_Control_Bulk_Actions {
12
- /**
13
- * Singleton.
14
- *
15
- * @var static
16
- */
17
- private static $__instance;
18
 
19
  /**
20
  * Supported post types.
@@ -37,38 +34,16 @@ class WP_Revisions_Control_Bulk_Actions {
37
  */
38
  protected $actions;
39
 
40
- /**
41
- * Silence is golden!
42
- */
43
- private function __construct() {}
44
-
45
- /**
46
- * Singleton implementation.
47
- *
48
- * @param array $post_types Supported post types, used only on instantiation.
49
- * @return static
50
- */
51
- public static function get_instance( $post_types = array() ) {
52
- if ( ! is_a( static::$__instance, __CLASS__ ) ) {
53
- static::$__instance = new self();
54
-
55
- static::$__instance->setup( $post_types );
56
- }
57
-
58
- return static::$__instance;
59
- }
60
-
61
  /**
62
  * One-time actions.
63
- *
64
- * @param array $post_types Supported post types.
65
  */
66
- public function setup( $post_types ) {
67
- if ( empty( $post_types ) || ! is_array( $post_types ) ) {
 
 
68
  return;
69
  }
70
 
71
- $this->post_types = $post_types;
72
  $this->register_actions();
73
 
74
  add_action( 'load-edit.php', array( $this, 'register_admin_hooks' ) );
@@ -104,9 +79,7 @@ class WP_Revisions_Control_Bulk_Actions {
104
  return;
105
  }
106
 
107
- $post_types = array_keys( $this->post_types );
108
-
109
- if ( ! in_array( $screen->post_type, $post_types, true ) ) {
110
  return;
111
  }
112
 
5
  * @package WP_Revisions_Control
6
  */
7
 
8
+ use WP_Revisions_Control\Singleton;
9
+
10
  /**
11
  * Class WP_Revisions_Control_Bulk_Actions.
12
  */
13
  class WP_Revisions_Control_Bulk_Actions {
14
+ use Singleton;
 
 
 
 
 
15
 
16
  /**
17
  * Supported post types.
34
  */
35
  protected $actions;
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * One-time actions.
 
 
39
  */
40
+ public function setup() {
41
+ $this->post_types = WP_Revisions_Control::get_instance()->get_post_types();
42
+
43
+ if ( empty( $this->post_types ) || ! is_array( $this->post_types ) ) {
44
  return;
45
  }
46
 
 
47
  $this->register_actions();
48
 
49
  add_action( 'load-edit.php', array( $this, 'register_admin_hooks' ) );
79
  return;
80
  }
81
 
82
+ if ( ! array_key_exists( $screen->post_type, $this->post_types ) ) {
 
 
83
  return;
84
  }
85
 
inc/class-wp-revisions-control.php CHANGED
@@ -5,16 +5,14 @@
5
  * @package WP_Revisions_Control
6
  */
7
 
 
 
 
8
  /**
9
  * Class WP_Revisions_Control.
10
  */
11
  class WP_Revisions_Control {
12
- /**
13
- * Singleton.
14
- *
15
- * @var static
16
- */
17
- private static $__instance;
18
 
19
  /**
20
  * Filter priority.
@@ -71,32 +69,14 @@ class WP_Revisions_Control {
71
  */
72
  private $meta_key_limit = '_wp_rev_ctl_limit';
73
 
74
- /**
75
- * Silence is golden!
76
- */
77
- private function __construct() {}
78
-
79
- /**
80
- * Singleton implementation.
81
- *
82
- * @return static
83
- */
84
- public static function get_instance() {
85
- if ( ! is_a( static::$__instance, __CLASS__ ) ) {
86
- static::$__instance = new self();
87
-
88
- static::$__instance->setup();
89
- }
90
-
91
- return static::$__instance;
92
- }
93
-
94
  /**
95
  * Register actions and filters at `init` so others can interact, if desired.
96
  */
97
  private function setup() {
98
  add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
99
  add_action( 'init', array( $this, 'action_init' ) );
 
 
100
  }
101
 
102
  /**
@@ -142,7 +122,7 @@ class WP_Revisions_Control {
142
  add_action( 'save_post', array( $this, 'action_save_post' ) );
143
 
144
  // Bulk actions.
145
- WP_Revisions_Control_Bulk_Actions::get_instance( $post_types );
146
  }
147
 
148
  /**
@@ -205,14 +185,14 @@ class WP_Revisions_Control {
205
  $type_length = strlen( $to_keep );
206
 
207
  if ( 0 === $type_length ) {
208
- $to_keep = -1;
209
  } else {
210
  $to_keep = (int) $to_keep;
211
  }
212
 
213
  // Lowest possible value is -1, used to indicate infinite revisions are stored.
214
- if ( -1 > $to_keep ) {
215
- $to_keep = -1;
216
  }
217
 
218
  $options_sanitized[ $post_type ] = $to_keep;
@@ -252,7 +232,7 @@ class WP_Revisions_Control {
252
  * @return int
253
  */
254
  public function filter_wp_revisions_to_keep( $qty, $post ) {
255
- $post_limit = get_post_meta( $post->ID, $this->meta_key_limit, true );
256
 
257
  if ( 0 < strlen( $post_limit ) ) {
258
  $qty = $post_limit;
@@ -275,48 +255,68 @@ class WP_Revisions_Control {
275
  /**
276
  * Override Core's revisions metabox.
277
  *
278
- * @param string $post_type Post type.
279
- * @param object $post Post object.
280
  */
281
  public function action_add_meta_boxes( $post_type, $post ) {
282
- if ( post_type_supports( $post_type, 'revisions' ) && 'auto-draft' !== get_post_status() && count( wp_get_post_revisions( $post ) ) > 1 ) {
283
- // Replace the metabox.
284
- remove_meta_box( 'revisionsdiv', null, 'normal' );
285
- add_meta_box(
286
- 'revisionsdiv-wp-rev-ctl',
287
- __(
288
- 'Revisions',
289
- 'wp_revisions_control'
290
- ),
291
- array(
292
- $this,
293
- 'revisions_meta_box',
294
- ),
295
- null,
296
- 'normal',
297
- 'core'
298
- );
299
 
300
- // A bit of JS for us.
301
- $handle = 'wp-revisions-control-post';
302
- wp_enqueue_script( $handle, plugins_url( 'js/post.js', __DIR__ ), array( 'jquery' ), '20131205', true );
303
- wp_localize_script(
304
- $handle,
305
- $this->settings_section,
306
- array(
307
- 'namespace' => $this->settings_section,
308
- 'action_base' => $this->settings_section,
309
- 'processing_text' => __( 'Processing&hellip;', 'wp_revisions_control' ),
310
- 'ays' => __( 'Are you sure you want to remove revisions from this post?', 'wp_revisions_control' ),
311
- 'autosave' => __( 'Autosave', 'wp_revisions_control' ),
312
- 'nothing_text' => wpautop( __( 'There are no revisions to remove.', 'wp_revisions_control' ) ),
313
- 'error' => __( 'An error occurred. Please refresh the page and try again.', 'wp_revisions_control' ),
314
- )
315
- );
316
 
317
- // Add some styling to our metabox additions.
318
- add_action( 'admin_head', array( $this, 'action_admin_head' ), 999 );
319
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  }
321
 
322
  /**
@@ -413,15 +413,19 @@ class WP_Revisions_Control {
413
  /**
414
  * Remove any revisions in excess of a post's limit.
415
  *
416
- * @param int $post_id Post ID to purge of excess revisions.
 
 
417
  * @return array
418
  */
419
- public function do_purge_excess( $post_id ) {
420
  $response = array(
421
  'count' => 0,
422
  );
423
 
424
- $to_keep = wp_revisions_to_keep( get_post( $post_id ) );
 
 
425
 
426
  if ( $to_keep < 0 ) {
427
  $response['success'] = __(
@@ -467,9 +471,9 @@ class WP_Revisions_Control {
467
  $limit = (int) $_POST[ $qty ];
468
 
469
  if ( -1 === $limit || empty( $limit ) ) {
470
- delete_post_meta( $post_id, $this->meta_key_limit );
471
  } else {
472
- update_post_meta( $post_id, $this->meta_key_limit, absint( $limit ) );
473
  }
474
  }
475
  }
@@ -549,7 +553,7 @@ class WP_Revisions_Control {
549
  *
550
  * @return array
551
  */
552
- private function get_post_types() {
553
  if ( empty( self::$post_types ) ) {
554
  foreach ( get_post_types() as $type ) {
555
  if ( post_type_supports( $type, 'revisions' ) ) {
@@ -600,7 +604,7 @@ class WP_Revisions_Control {
600
  * @return int|string
601
  */
602
  private function get_post_revisions_to_keep( $post_id ) {
603
- $to_keep = get_post_meta( $post_id, $this->meta_key_limit, true );
604
 
605
  if ( empty( $to_keep ) || -1 === $to_keep || '-1' === $to_keep ) {
606
  $to_keep = '';
5
  * @package WP_Revisions_Control
6
  */
7
 
8
+ use WP_Revisions_Control\Block_Editor;
9
+ use WP_Revisions_Control\Singleton;
10
+
11
  /**
12
  * Class WP_Revisions_Control.
13
  */
14
  class WP_Revisions_Control {
15
+ use Singleton;
 
 
 
 
 
16
 
17
  /**
18
  * Filter priority.
69
  */
70
  private $meta_key_limit = '_wp_rev_ctl_limit';
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  /**
73
  * Register actions and filters at `init` so others can interact, if desired.
74
  */
75
  private function setup() {
76
  add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
77
  add_action( 'init', array( $this, 'action_init' ) );
78
+
79
+ Block_Editor::get_instance();
80
  }
81
 
82
  /**
122
  add_action( 'save_post', array( $this, 'action_save_post' ) );
123
 
124
  // Bulk actions.
125
+ WP_Revisions_Control_Bulk_Actions::get_instance();
126
  }
127
 
128
  /**
185
  $type_length = strlen( $to_keep );
186
 
187
  if ( 0 === $type_length ) {
188
+ $to_keep = - 1;
189
  } else {
190
  $to_keep = (int) $to_keep;
191
  }
192
 
193
  // Lowest possible value is -1, used to indicate infinite revisions are stored.
194
+ if ( - 1 > $to_keep ) {
195
+ $to_keep = - 1;
196
  }
197
 
198
  $options_sanitized[ $post_type ] = $to_keep;
232
  * @return int
233
  */
234
  public function filter_wp_revisions_to_keep( $qty, $post ) {
235
+ $post_limit = get_post_meta( $post->ID, WP_REVISIONS_CONTROL_LIMIT_META_KEY, true );
236
 
237
  if ( 0 < strlen( $post_limit ) ) {
238
  $qty = $post_limit;
255
  /**
256
  * Override Core's revisions metabox.
257
  *
258
+ * @param string $post_type Post type.
259
+ * @param WP_Post $post Post object.
260
  */
261
  public function action_add_meta_boxes( $post_type, $post ) {
262
+ if (
263
+ ! post_type_supports( $post_type, 'revisions' )
264
+ || 'auto-draft' === get_post_status()
265
+ || (
266
+ function_exists( 'use_block_editor_for_post' )
267
+ && use_block_editor_for_post( $post )
268
+ )
269
+ || count( wp_get_post_revisions( $post ) ) < 1
270
+ ) {
271
+ return;
272
+ }
 
 
 
 
 
 
273
 
274
+ // Replace the metabox.
275
+ remove_meta_box( 'revisionsdiv', null, 'normal' );
276
+ add_meta_box(
277
+ 'revisionsdiv-wp-rev-ctl',
278
+ __(
279
+ 'Revisions',
280
+ 'wp_revisions_control'
281
+ ),
282
+ array(
283
+ $this,
284
+ 'revisions_meta_box',
285
+ ),
286
+ null,
287
+ 'normal',
288
+ 'core'
289
+ );
290
 
291
+ // A bit of JS for us.
292
+ $handle = 'wp-revisions-control-post';
293
+ $asset_data = require_once dirname( __DIR__ ) . '/assets/build/classic-editor.asset.php';
294
+ wp_enqueue_script(
295
+ $handle,
296
+ plugins_url(
297
+ 'assets/build/classic-editor.js',
298
+ __DIR__
299
+ ),
300
+ $asset_data['dependencies'],
301
+ $asset_data['version'],
302
+ true
303
+ );
304
+ wp_localize_script(
305
+ $handle,
306
+ $this->settings_section,
307
+ array(
308
+ 'namespace' => $this->settings_section,
309
+ 'action_base' => $this->settings_section,
310
+ 'processing_text' => __( 'Processing&hellip;', 'wp_revisions_control' ),
311
+ 'ays' => __( 'Are you sure you want to remove revisions from this post?', 'wp_revisions_control' ),
312
+ 'autosave' => __( 'Autosave', 'wp_revisions_control' ),
313
+ 'nothing_text' => wpautop( __( 'There are no revisions to remove.', 'wp_revisions_control' ) ),
314
+ 'error' => __( 'An error occurred. Please refresh the page and try again.', 'wp_revisions_control' ),
315
+ )
316
+ );
317
+
318
+ // Add some styling to our metabox additions.
319
+ add_action( 'admin_head', array( $this, 'action_admin_head' ), 999 );
320
  }
321
 
322
  /**
413
  /**
414
  * Remove any revisions in excess of a post's limit.
415
  *
416
+ * @param int $post_id Post ID to purge of excess revisions.
417
+ * @param int|null $limit_override Optional. Override post's revisions
418
+ * limit.
419
  * @return array
420
  */
421
+ public function do_purge_excess( $post_id, $limit_override = null ) {
422
  $response = array(
423
  'count' => 0,
424
  );
425
 
426
+ $to_keep = null !== $limit_override
427
+ ? $limit_override
428
+ : wp_revisions_to_keep( get_post( $post_id ) );
429
 
430
  if ( $to_keep < 0 ) {
431
  $response['success'] = __(
471
  $limit = (int) $_POST[ $qty ];
472
 
473
  if ( -1 === $limit || empty( $limit ) ) {
474
+ delete_post_meta( $post_id, WP_REVISIONS_CONTROL_LIMIT_META_KEY );
475
  } else {
476
+ update_post_meta( $post_id, WP_REVISIONS_CONTROL_LIMIT_META_KEY, absint( $limit ) );
477
  }
478
  }
479
  }
553
  *
554
  * @return array
555
  */
556
+ public function get_post_types() {
557
  if ( empty( self::$post_types ) ) {
558
  foreach ( get_post_types() as $type ) {
559
  if ( post_type_supports( $type, 'revisions' ) ) {
604
  * @return int|string
605
  */
606
  private function get_post_revisions_to_keep( $post_id ) {
607
+ $to_keep = get_post_meta( $post_id, WP_REVISIONS_CONTROL_LIMIT_META_KEY, true );
608
 
609
  if ( empty( $to_keep ) || -1 === $to_keep || '-1' === $to_keep ) {
610
  $to_keep = '';
inc/trait-singleton.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reusable singleton.
4
+ *
5
+ * @package WP_Revisions_Control
6
+ */
7
+
8
+ namespace WP_Revisions_Control;
9
+
10
+ /**
11
+ * Trait Singleton.
12
+ */
13
+ trait Singleton {
14
+ /**
15
+ * Singleton.
16
+ *
17
+ * @var static
18
+ */
19
+ private static $__instance;
20
+
21
+ /**
22
+ * Silence is golden!
23
+ */
24
+ final private function __construct() {}
25
+
26
+ /**
27
+ * Singleton implementation.
28
+ *
29
+ * @return static
30
+ */
31
+ final public static function get_instance() {
32
+ if ( ! is_a( static::$__instance, __CLASS__ ) ) {
33
+ static::$__instance = new self();
34
+
35
+ static::$__instance->setup();
36
+ }
37
+
38
+ return static::$__instance;
39
+ }
40
+
41
+ /**
42
+ * Prepare class.
43
+ */
44
+ abstract public function setup();
45
+ }
js/post.js DELETED
@@ -1,73 +0,0 @@
1
- ( function( $ ) {
2
- $( document ).ready( function() {
3
- var purge_button = $( '#' + wp_revisions_control.namespace + ' .button.purge' ),
4
- post_id = null,
5
- nonce = null,
6
- button_text = null;
7
-
8
- button_text = $( purge_button ).text();
9
-
10
- $( purge_button ).on( 'click', click_handler_purge );
11
-
12
- /**
13
- * Click handler for purging a post's revisions
14
- */
15
- function click_handler_purge() {
16
- post_id = parseInt( $( this ).data( 'postid' ) );
17
-
18
- $( purge_button ).text( wp_revisions_control.processing_text );
19
-
20
- var confirmed = confirm( wp_revisions_control.ays );
21
-
22
- if ( confirmed && post_id ) {
23
- $.ajax({
24
- url: ajaxurl,
25
- cache: false,
26
- data: {
27
- action: wp_revisions_control.action_base + '_purge',
28
- post_id: post_id,
29
- nonce: $( this ).data( 'nonce' )
30
- },
31
- type: 'post',
32
- dataType: 'json',
33
- success: ajax_purge_request_success,
34
- error: ajax_purge_request_error
35
- });
36
- } else {
37
- $( purge_button ).text( button_text );
38
- }
39
- }
40
-
41
- /**
42
- * User feedback when Ajax request succeeds
43
- * Does not indicate that purge request succeeded
44
- */
45
- function ajax_purge_request_success( response ) {
46
- if ( response.error ) {
47
- alert( response.error );
48
-
49
- $( purge_button ).text( button_text );
50
- } else if ( response.success ) {
51
- var list_table = $( 'ul.post-revisions > li' );
52
-
53
- $( list_table ).each( function() {
54
- var autosave = $( this ).text().match( wp_revisions_control.autosave );
55
-
56
- if ( ! autosave )
57
- $( this ).slideUp( 'slow' ).remove();
58
- } );
59
-
60
- $( purge_button ).fadeOut( 'slow' ).after( wp_revisions_control.nothing_text );
61
- }
62
- }
63
-
64
- /**
65
- * Return a generic error when the Ajax request fails
66
- */
67
- function ajax_purge_request_error() {
68
- alert( wp_revisions_control.error );
69
-
70
- $( purge_button ).text( button_text );
71
- }
72
- } );
73
- } )( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/wp-revisions-control.pot CHANGED
@@ -1,61 +1,65 @@
1
- # Copyright (C) 2021 Erick Hitter
2
  # This file is distributed under the same license as the WP Revisions Control package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WP Revisions Control 1.3\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/wp-revisions-control\n"
8
- "POT-Creation-Date: 2021-03-27 21:26:05+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2021-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
- "X-Generator: grunt-wp-i18n 0.5.4\n"
16
- "X-Poedit-KeywordsList: "
17
- "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
18
- "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
19
  "Language: en\n"
20
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
21
  "X-Poedit-Country: United States\n"
22
  "X-Poedit-SourceCharset: UTF-8\n"
 
 
 
23
  "X-Poedit-Basepath: ../\n"
24
  "X-Poedit-SearchPath-0: .\n"
25
  "X-Poedit-Bookmarks: \n"
26
  "X-Textdomain-Support: yes\n"
 
 
 
 
 
27
 
28
- #: inc/class-wp-revisions-control-bulk-actions.php:84
29
  msgid "Purge excess revisions"
30
  msgstr ""
31
 
32
- #: inc/class-wp-revisions-control-bulk-actions.php:89
33
  msgid "Purge ALL revisions"
34
  msgstr ""
35
 
36
- #: inc/class-wp-revisions-control-bulk-actions.php:269
37
  msgid "Purged all revisions."
38
  msgstr ""
39
 
40
- #: inc/class-wp-revisions-control-bulk-actions.php:276
41
  msgid "Purged excess revisions."
42
  msgstr ""
43
 
44
- #: inc/class-wp-revisions-control-bulk-actions.php:287
45
  msgid "WP Revisions Control encountered an unspecified error."
46
  msgstr ""
47
 
48
- #: inc/class-wp-revisions-control.php:158
49
  msgid ""
50
  "Set the number of revisions to save for each post type listed. To retain "
51
  "all revisions for a given post type, leave the field empty."
52
  msgstr ""
53
 
54
- #: inc/class-wp-revisions-control.php:159
55
  msgid "If a post type isn't listed, revisions are not enabled for that post type."
56
  msgstr ""
57
 
58
- #: inc/class-wp-revisions-control.php:170
59
  #. translators: 1. Filter tag.
60
  msgid ""
61
  "A local change is causing this plugin's functionality to run at a priority "
@@ -63,27 +67,27 @@ msgid ""
63
  "please unhook any functions from the %1$s filter."
64
  msgstr ""
65
 
66
- #: inc/class-wp-revisions-control.php:287
67
  msgid "Revisions"
68
  msgstr ""
69
 
70
- #: inc/class-wp-revisions-control.php:309
71
  msgid "Processing&hellip;"
72
  msgstr ""
73
 
74
- #: inc/class-wp-revisions-control.php:310
75
  msgid "Are you sure you want to remove revisions from this post?"
76
  msgstr ""
77
 
78
- #: inc/class-wp-revisions-control.php:311
79
  msgid "Autosave"
80
  msgstr ""
81
 
82
- #: inc/class-wp-revisions-control.php:312
83
  msgid "There are no revisions to remove."
84
  msgstr ""
85
 
86
- #: inc/class-wp-revisions-control.php:313
87
  msgid "An error occurred. Please refresh the page and try again."
88
  msgstr ""
89
 
@@ -115,8 +119,8 @@ msgstr ""
115
  msgid "Removed %1$s revisions associated with this post."
116
  msgstr ""
117
 
118
- #: inc/class-wp-revisions-control.php:427
119
- #: inc/class-wp-revisions-control.php:439
120
  msgid "No revisions to remove."
121
  msgstr ""
122
 
1
+ # Copyright (C) 2022 Erick Hitter
2
  # This file is distributed under the same license as the WP Revisions Control package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WP Revisions Control 1.4\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/wp-revisions-control\n"
8
+ "POT-Creation-Date: 2022-06-05 23:17:47+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2022-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
 
 
 
 
15
  "Language: en\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
  "X-Poedit-Country: United States\n"
18
  "X-Poedit-SourceCharset: UTF-8\n"
19
+ "X-Poedit-KeywordsList: "
20
+ "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
21
+ "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
22
  "X-Poedit-Basepath: ../\n"
23
  "X-Poedit-SearchPath-0: .\n"
24
  "X-Poedit-Bookmarks: \n"
25
  "X-Textdomain-Support: yes\n"
26
+ "X-Generator: grunt-wp-i18n 1.0.3\n"
27
+
28
+ #: inc/class-block-editor.php:58
29
+ msgid "Number of revisions to retain."
30
+ msgstr ""
31
 
32
+ #: inc/class-wp-revisions-control-bulk-actions.php:59
33
  msgid "Purge excess revisions"
34
  msgstr ""
35
 
36
+ #: inc/class-wp-revisions-control-bulk-actions.php:64
37
  msgid "Purge ALL revisions"
38
  msgstr ""
39
 
40
+ #: inc/class-wp-revisions-control-bulk-actions.php:242
41
  msgid "Purged all revisions."
42
  msgstr ""
43
 
44
+ #: inc/class-wp-revisions-control-bulk-actions.php:249
45
  msgid "Purged excess revisions."
46
  msgstr ""
47
 
48
+ #: inc/class-wp-revisions-control-bulk-actions.php:260
49
  msgid "WP Revisions Control encountered an unspecified error."
50
  msgstr ""
51
 
52
+ #: inc/class-wp-revisions-control.php:138
53
  msgid ""
54
  "Set the number of revisions to save for each post type listed. To retain "
55
  "all revisions for a given post type, leave the field empty."
56
  msgstr ""
57
 
58
+ #: inc/class-wp-revisions-control.php:139
59
  msgid "If a post type isn't listed, revisions are not enabled for that post type."
60
  msgstr ""
61
 
62
+ #: inc/class-wp-revisions-control.php:150
63
  #. translators: 1. Filter tag.
64
  msgid ""
65
  "A local change is causing this plugin's functionality to run at a priority "
67
  "please unhook any functions from the %1$s filter."
68
  msgstr ""
69
 
70
+ #: inc/class-wp-revisions-control.php:278
71
  msgid "Revisions"
72
  msgstr ""
73
 
74
+ #: inc/class-wp-revisions-control.php:310
75
  msgid "Processing&hellip;"
76
  msgstr ""
77
 
78
+ #: inc/class-wp-revisions-control.php:311
79
  msgid "Are you sure you want to remove revisions from this post?"
80
  msgstr ""
81
 
82
+ #: inc/class-wp-revisions-control.php:312
83
  msgid "Autosave"
84
  msgstr ""
85
 
86
+ #: inc/class-wp-revisions-control.php:313
87
  msgid "There are no revisions to remove."
88
  msgstr ""
89
 
90
+ #: inc/class-wp-revisions-control.php:314
91
  msgid "An error occurred. Please refresh the page and try again."
92
  msgstr ""
93
 
119
  msgid "Removed %1$s revisions associated with this post."
120
  msgstr ""
121
 
122
+ #: inc/class-wp-revisions-control.php:431
123
+ #: inc/class-wp-revisions-control.php:443
124
  msgid "No revisions to remove."
125
  msgstr ""
126
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: ethitter
3
  Donate link: https://ethitter.com/donate/
4
  Tags: revision, revisions, admin
5
  Requires at least: 3.6
6
- Tested up to: 5.9
7
- Stable tag: 1.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -35,6 +35,9 @@ Navigate to **Settings > Writing** in your WordPress Dashboard, and look for the
35
 
36
  == Changelog ==
37
 
 
 
 
38
  = 1.3 =
39
  * Add bulk actions to purge excess or all revisions.
40
  * Introduce unit tests.
@@ -51,6 +54,9 @@ Navigate to **Settings > Writing** in your WordPress Dashboard, and look for the
51
 
52
  == Upgrade Notice ==
53
 
 
 
 
54
  = 1.3 =
55
  Introduces bulk actions for purging revisions, along with unit tests. The plugin also conforms to coding standards.
56
 
@@ -63,4 +69,5 @@ For any post type that supports revisions, you can now limit the number of revis
63
  == Screenshots ==
64
 
65
  1. The plugin's settings section, found under **Settings > Writing**.
66
- 2. The post-level controls provided in version 1.2.
 
3
  Donate link: https://ethitter.com/donate/
4
  Tags: revision, revisions, admin
5
  Requires at least: 3.6
6
+ Tested up to: 6.0
7
+ Stable tag: 1.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
35
 
36
  == Changelog ==
37
 
38
+ = 1.4 =
39
+ * Introduce block-editor (Gutenberg) sidebar component for supported post types.
40
+
41
  = 1.3 =
42
  * Add bulk actions to purge excess or all revisions.
43
  * Introduce unit tests.
54
 
55
  == Upgrade Notice ==
56
 
57
+ = 1.4 =
58
+ Introduces block-editor (Gutenberg) sidebar component for supported post types.
59
+
60
  = 1.3 =
61
  Introduces bulk actions for purging revisions, along with unit tests. The plugin also conforms to coding standards.
62
 
69
  == Screenshots ==
70
 
71
  1. The plugin's settings section, found under **Settings > Writing**.
72
+ 2. The post-level controls for the Classic Editor provided in version 1.2.
73
+ 3. The post-level controls for the Block Editor provided in version 1.4.
wp-revisions-control.php CHANGED
@@ -1,20 +1,16 @@
1
  <?php
2
- /**
3
- * Load plugin.
4
- *
5
- * @package WP_Revisions_Control
6
- */
7
-
8
  /**
9
  * Plugin Name: WP Revisions Control
10
  * Plugin URI: https://ethitter.com/plugins/wp-revisions-control/
11
  * Description: Control how many revisions are stored for each post type
12
  * Author: Erick Hitter
13
- * Version: 1.3
14
  * Author URI: https://ethitter.com/
15
  * Text Domain: wp_revisions_control
16
  * Domain Path: /languages/
17
  *
 
 
18
  * This program is free software; you can redistribute it and/or modify
19
  * it under the terms of the GNU General Public License as published by
20
  * the Free Software Foundation; either version 2 of the License, or
@@ -30,5 +26,9 @@
30
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31
  */
32
 
 
 
 
 
33
  require_once __DIR__ . '/inc/class-wp-revisions-control-bulk-actions.php';
34
  require_once __DIR__ . '/inc/class-wp-revisions-control.php';
1
  <?php
 
 
 
 
 
 
2
  /**
3
  * Plugin Name: WP Revisions Control
4
  * Plugin URI: https://ethitter.com/plugins/wp-revisions-control/
5
  * Description: Control how many revisions are stored for each post type
6
  * Author: Erick Hitter
7
+ * Version: 1.4
8
  * Author URI: https://ethitter.com/
9
  * Text Domain: wp_revisions_control
10
  * Domain Path: /languages/
11
  *
12
+ * @package WP_Revisions_Control
13
+ *
14
  * This program is free software; you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License as published by
16
  * the Free Software Foundation; either version 2 of the License, or
26
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
+ define( 'WP_REVISIONS_CONTROL_LIMIT_META_KEY', '_wp_rev_ctl_limit' );
30
+
31
+ require_once __DIR__ . '/inc/trait-singleton.php';
32
+ require_once __DIR__ . '/inc/class-block-editor.php';
33
  require_once __DIR__ . '/inc/class-wp-revisions-control-bulk-actions.php';
34
  require_once __DIR__ . '/inc/class-wp-revisions-control.php';