Clone Posts - Version 2.0.3

Version Description

  • Ensure compatibility with WP 6.0.x
  • Remove jQuery and any dependencies
  • Add translation template
  • WP Coding Standards Compliant
Download this release

Release Info

Developer pattihis
Plugin Icon 128x128 Clone Posts
Version 2.0.3
Comparing to
See all releases

Code changes from version 2.0.2 to 2.0.3

README.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: lukaszwebmaster, pattihis
3
  Donate link: https://profiles.wordpress.org/pattihis/
4
  Tags: clone posts, clone pages, clone post, clone page, clone, page cloning, post cloning, posts cloning, pages cloning, page copy, page copy paste, post copy, posts copy paste, copy pages, copy posts, copy and paste posts, copy and paste pages, clone, cloning, copy and paste
5
  Requires at least: 5.0
6
- Tested up to: 5.9
7
  Requires PHP: 5.6
8
- Stable tag: 2.0.2
9
  License: GPL2
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -60,6 +60,12 @@ Of course! "Clone Posts" is compatible with any theme and plugin that follows Wo
60
 
61
  == Changelog ==
62
 
 
 
 
 
 
 
63
  = 2.0.2 =
64
  * Handle Warning about options not being an array
65
  * Resolve Notice about Undefined property
3
  Donate link: https://profiles.wordpress.org/pattihis/
4
  Tags: clone posts, clone pages, clone post, clone page, clone, page cloning, post cloning, posts cloning, pages cloning, page copy, page copy paste, post copy, posts copy paste, copy pages, copy posts, copy and paste posts, copy and paste pages, clone, cloning, copy and paste
5
  Requires at least: 5.0
6
+ Tested up to: 6.0
7
  Requires PHP: 5.6
8
+ Stable tag: 2.0.3
9
  License: GPL2
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
60
 
61
  == Changelog ==
62
 
63
+ = 2.0.3 =
64
+ * Ensure compatibility with WP 6.0.x
65
+ * Remove jQuery and any dependencies
66
+ * Add translation template
67
+ * WP Coding Standards Compliant
68
+
69
  = 2.0.2 =
70
  * Handle Warning about options not being an array
71
  * Resolve Notice about Undefined property
admin/class-clone-posts-admin.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * The admin-specific functionality of the plugin.
5
  *
@@ -13,8 +12,7 @@
13
  /**
14
  * The admin-specific functionality of the plugin.
15
  *
16
- * Defines the plugin name, version, and two examples hooks for how to
17
- * enqueue the admin-specific stylesheet and JavaScript.
18
  *
19
  * @package Clone_Posts
20
  * @subpackage Clone_Posts/admin
@@ -44,35 +42,13 @@ class Clone_Posts_Admin {
44
  * Initialize the class and set its properties.
45
  *
46
  * @since 2.0.0
47
- * @param string $plugin_name The name of this plugin.
48
- * @param string $version The version of this plugin.
49
  */
50
  public function __construct( $plugin_name, $version ) {
51
 
52
  $this->plugin_name = $plugin_name;
53
- $this->version = $version;
54
-
55
- }
56
-
57
- /**
58
- * Register the stylesheets for the admin area.
59
- *
60
- * @since 2.0.0
61
- */
62
- public function enqueue_styles() {
63
-
64
- wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/clone-posts-admin.css', array(), $this->version, 'all' );
65
-
66
- }
67
-
68
- /**
69
- * Register the JavaScript for the admin area.
70
- *
71
- * @since 2.0.0
72
- */
73
- public function enqueue_scripts() {
74
-
75
- wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/clone-posts-admin.js', array( 'jquery' ), $this->version, false );
76
 
77
  }
78
 
@@ -81,14 +57,14 @@ class Clone_Posts_Admin {
81
  *
82
  * @since 2.0.0
83
  */
84
- public function clonePosts_admin_page() {
85
 
86
  add_options_page(
87
  'Clone Posts Settings',
88
  'Clone Posts',
89
  'manage_options',
90
  'clone-posts-options',
91
- [$this,'clonePosts_admin_display'],
92
  null
93
  );
94
 
@@ -99,16 +75,16 @@ class Clone_Posts_Admin {
99
  *
100
  * @since 2.0.0
101
  */
102
- public function clonePosts_admin_display() {
103
  include_once 'partials/clone-posts-admin-display.php';
104
- }
105
 
106
  /**
107
  * Register the actual settings
108
  *
109
  * @since 2.0.0
110
  */
111
- public function clonePosts_register_setting() {
112
 
113
  add_settings_section(
114
  'clone_posts_settings_section',
@@ -126,12 +102,12 @@ class Clone_Posts_Admin {
126
  add_settings_field(
127
  'clone_posts_post_status',
128
  'Post Status',
129
- [$this,'clonePosts_option_post_status'],
130
  'clone-posts-options',
131
  'clone_posts_settings_section',
132
  array(
133
  'label_for' => 'clone_posts_post_status',
134
- 'class' => 'clone-posts',
135
  )
136
  );
137
 
@@ -144,30 +120,30 @@ class Clone_Posts_Admin {
144
  add_settings_field(
145
  'clone_posts_post_date',
146
  'Post Date',
147
- [$this,'clonePosts_option_post_date'],
148
  'clone-posts-options',
149
  'clone_posts_settings_section',
150
  array(
151
  'label_for' => 'clone_posts_post_date',
152
- 'class' => 'clone-posts',
153
  )
154
  );
155
 
156
  register_setting(
157
  'clone_post_settings',
158
  'clone_posts_post_type',
159
- [$this,'clonePosts_sanitize_array']
160
  );
161
 
162
  add_settings_field(
163
  'clone_posts_post_type',
164
  'Post Type',
165
- [$this,'clonePosts_option_post_type'],
166
  'clone-posts-options',
167
  'clone_posts_settings_section',
168
  array(
169
  'label_for' => 'clone_posts_post_type',
170
- 'class' => 'clone-posts',
171
  )
172
  );
173
 
@@ -178,14 +154,14 @@ class Clone_Posts_Admin {
178
  *
179
  * @since 2.0.0
180
  */
181
- public function clonePosts_option_post_status() {
182
- $option = get_option('clone_posts_post_status');
183
  ?>
184
  <select name="clone_posts_post_status" id="clone_posts_post_status">
185
- <option value="draft" <?php selected($option, 'draft'); ?>>Draft</option>
186
- <option value="publish" <?php selected($option, 'publish'); ?>>Publish</option>
187
- <option value="private" <?php selected($option, 'private'); ?>>Private</option>
188
- <option value="pending" <?php selected($option, 'pending'); ?>>Pending</option>
189
  </select>
190
  <p>Select the <a href="https://wordpress.org/support/article/post-status/#default-statuses" target="_blank">status</a> of the cloned post</p>
191
  <?php
@@ -196,12 +172,12 @@ class Clone_Posts_Admin {
196
  *
197
  * @since 2.0.0
198
  */
199
- public function clonePosts_option_post_date() {
200
- $option = get_option('clone_posts_post_date');
201
  ?>
202
  <select name="clone_posts_post_date" id="clone_posts_post_date">
203
- <option value="current" <?php selected($option, 'current'); ?>>Current Date/Time</option>
204
- <option value="original" <?php selected($option, 'original'); ?>>Original Post Date</option>
205
  </select>
206
  <p>Select if the cloned post will have the same date as the<br>original or if it will be assigned the current date/time</p>
207
  <?php
@@ -212,23 +188,23 @@ class Clone_Posts_Admin {
212
  *
213
  * @since 2.0.0
214
  */
215
- public function clonePosts_option_post_type() {
216
- $options = maybe_unserialize( get_option('clone_posts_post_type') );
217
- if ( !is_array($options) ) {
218
- $options = ['post', 'page'];
219
  }
220
- $exclude_cpt = ['attachment'];
221
- $post_types = get_post_types( array( 'public' => true, ), 'objects', 'and' );
222
  echo '<fieldset>';
223
  if ( $post_types ) {
224
  foreach ( $post_types as $post_type ) {
225
- if ( !in_array($post_type->name, $exclude_cpt) ) {
226
- ?>
227
  <div>
228
- <input type="checkbox" name="clone_posts_post_type[]" value="<?php echo $post_type->name ?>" id="post_type_<?php echo $post_type->name ?>" <?php checked( in_array( $post_type->name, $options ), 1 ); ?>>
229
- <label for="post_type_<?php echo $post_type->name; ?>"><?php echo $post_type->labels->name; ?></label>
230
  </div>
231
- <?php
232
  }
233
  }
234
  }
@@ -239,10 +215,10 @@ class Clone_Posts_Admin {
239
  * A custom sanitization function for arrays.
240
  *
241
  * @since 2.0.0
242
- * @param array $input The posted array.
243
- * @return array $output The array sanitized.
244
  */
245
- public function clonePosts_sanitize_array( $input ) {
246
  $output = array();
247
  foreach ( $input as $key => $val ) {
248
  $output[ $key ] = ( isset( $input[ $key ] ) ) ? sanitize_text_field( $val ) : '';
@@ -255,21 +231,21 @@ class Clone_Posts_Admin {
255
  *
256
  * @since 2.0.0
257
  */
258
- public function clonePosts_admin_footer() {
259
- $options = maybe_unserialize( get_option('clone_posts_post_type') );
260
 
261
- if ( !is_array($options) ) {
262
- $options = ['post', 'page'];
263
  }
264
 
265
- if ( !in_array( $GLOBALS['post_type'], $options ) ) {
266
- return;
267
  }
268
  ?>
269
  <script type="text/javascript">
270
  jQuery(function () {
271
- jQuery('<option>').val('clone').text('<?php _e('Clone')?>').appendTo("select[name='action']");
272
- jQuery('<option>').val('clone').text('<?php _e('Clone')?>').appendTo("select[name='action2']");
273
  });
274
  </script>
275
  <?php
@@ -280,69 +256,90 @@ class Clone_Posts_Admin {
280
  *
281
  * @since 2.0.0
282
  */
283
- public function clonePosts_bulk_action() {
284
  global $typenow;
285
  $post_type = $typenow;
286
- $plugin = new Clone_Posts;
287
 
288
- // get the action
289
- $wp_list_table = _get_list_table('WP_Posts_List_Table');
290
- $action = $wp_list_table->current_action();
291
 
292
- $allowed_actions = array("clone");
293
- if ( ! in_array( $action, $allowed_actions )) {
294
  return;
295
  }
296
 
297
- // security check
298
- check_admin_referer('bulk-posts');
299
 
300
- // make sure ids are submitted. depending on the resource type, this may be 'media' or 'ids'
301
- if ( isset( $_REQUEST['post'] )) {
302
  $post_ids = array_map( 'intval', $_REQUEST['post'] );
303
  }
304
 
305
- if ( empty( $post_ids )) {
306
  return;
307
  }
308
 
309
- // this is based on wp-admin/edit.php
310
  $sendback = remove_query_arg( array( 'cloned', 'untrashed', 'deleted', 'ids' ), wp_get_referer() );
311
  if ( ! $sendback ) {
312
  $sendback = admin_url( "edit.php?post_type=$post_type" );
313
  }
314
 
315
- $pagenum = $wp_list_table->get_pagenum();
316
  $sendback = add_query_arg( 'paged', $pagenum, $sendback );
317
 
318
  switch ( $action ) {
319
  case 'clone':
320
-
321
  $cloned = 0;
322
  foreach ( $post_ids as $post_id ) {
323
 
324
- if ( !current_user_can('edit_post', $post_id) ) {
325
- wp_die( __('You are not allowed to clone this post.', $plugin->get_plugin_name()) );
326
  }
327
 
328
- if ( ! $this->clonePosts_clone_single( $post_id )) {
329
- wp_die( __('Error cloning post.', $plugin->get_plugin_name()) );
330
  }
331
 
332
  $cloned++;
333
  }
334
 
335
- $sendback = add_query_arg( array( 'cloned' => $cloned, 'ids' => join(',', $post_ids) ), $sendback );
 
 
 
 
 
 
 
 
 
336
  break;
337
 
338
  default:
339
  return;
340
  }
341
 
342
- $sendback = remove_query_arg( array( 'action', 'action2', 'tags_input', 'post_author',
343
- 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), $sendback );
 
 
 
 
 
 
 
 
 
 
 
 
 
344
 
345
- wp_redirect($sendback);
346
  exit();
347
  }
348
 
@@ -351,19 +348,20 @@ class Clone_Posts_Admin {
351
  *
352
  * @since 2.0.0
353
  */
354
- function clonePosts_admin_notices() {
355
  global $pagenow;
356
 
357
- if ($pagenow == 'edit.php' && ! isset($_GET['trashed'] )) {
358
  $cloned = 0;
359
  if ( isset( $_REQUEST['cloned'] ) && (int) $_REQUEST['cloned'] ) {
360
  $cloned = (int) $_REQUEST['cloned'];
361
- } elseif ( isset($_GET['cloned']) && (int) $_GET['cloned'] ) {
362
  $cloned = (int) $_GET['cloned'];
363
  }
364
- if ($cloned) {
365
- $message = sprintf( _n( 'Post cloned.', '%s posts cloned.', $cloned ), number_format_i18n( $cloned ) );
366
- echo "<div class=\"updated\"><p>{$message}</p></div>";
 
367
  }
368
  }
369
  }
@@ -373,29 +371,48 @@ class Clone_Posts_Admin {
373
  *
374
  * @since 2.0.0
375
  */
376
- public function clonePosts_post_row_actions( $actions, $post ) {
377
  global $post_type;
378
- $plugin = new Clone_Posts;
379
 
380
- $options = maybe_unserialize( get_option('clone_posts_post_type') );
381
 
382
- if ( !is_array($options) ) {
383
- $options = ['post', 'page'];
384
  }
385
 
386
- if ( !in_array( $post_type, $options ) ) {
387
- return $actions;
388
  }
389
 
390
- $url = remove_query_arg( array( 'cloned', 'untrashed', 'deleted', 'ids' ), "" );
391
  if ( ! $url ) {
392
  $url = admin_url( "?post_type=$post_type" );
393
  }
394
- $url = remove_query_arg( array( 'action', 'action2', 'tags_input', 'post_author',
395
- 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), $url );
396
- $url = add_query_arg( array( 'action' => 'clone-single', 'post' => $post->ID, 'redirect' => $_SERVER['REQUEST_URI'] ), $url );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
 
398
- $actions['clone'] = '<a href=\''.$url.'\'>'.__('Clone', $plugin->get_plugin_name()).'</a>';
399
  return $actions;
400
  }
401
 
@@ -404,83 +421,84 @@ class Clone_Posts_Admin {
404
  *
405
  * @since 2.0.0
406
  */
407
- public function clonePosts_wp_loaded() {
408
  global $post_type;
409
- $plugin = new Clone_Posts;
410
 
411
- if ( ! isset($_GET['action']) || $_GET['action'] !== "clone-single") {
412
  return;
413
  }
414
 
415
  $post_id = (int) $_GET['post'];
416
 
417
- if ( !current_user_can('edit_post', $post_id )) {
418
- wp_die( __('You are not allowed to clone this post.', $plugin->get_plugin_name()) );
419
  }
420
 
421
- if ( !$this->clonePosts_clone_single( $post_id )) {
422
- wp_die( __('Error cloning post.', $plugin->get_plugin_name()) );
423
  }
424
 
425
- $sendback = remove_query_arg( array( 'cloned', 'untrashed', 'deleted', 'ids' ), $_GET['redirect'] );
426
  if ( ! $sendback ) {
427
  $sendback = admin_url( "edit.php?post_type=$post_type" );
428
  }
429
 
430
  $sendback = add_query_arg( array( 'cloned' => 1 ), $sendback );
431
- $sendback = remove_query_arg( array( 'action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), $sendback );
432
- wp_redirect($sendback);
433
  exit();
434
  }
435
 
436
  /**
437
  * Clone the Post
438
  *
 
439
  * @since 2.0.0
440
  */
441
- public function clonePosts_clone_single( $id ) {
442
- $p = get_post( $id );
443
- if ($p == null) return false;
444
- $plugin = new Clone_Posts;
 
445
 
446
  $newpost = array(
447
- 'post_name' => $p->post_name,
448
- 'post_type' => $p->post_type,
449
- 'ping_status' => $p->ping_status,
450
- 'post_parent' => $p->post_parent,
451
- 'menu_order' => $p->menu_order,
452
- 'post_password' => $p->post_password,
453
- 'post_excerpt' => $p->post_excerpt,
454
- 'comment_status' => $p->comment_status,
455
- 'post_title' => $p->post_title . __('- clone', $plugin->get_plugin_name()),
456
- 'post_content' => $p->post_content,
457
- 'post_author' => $p->post_author,
458
- 'to_ping' => $p->to_ping,
459
- 'pinged' => $p->pinged,
460
  'post_content_filtered' => $p->post_content_filtered,
461
- 'post_category' => $p->post_category,
462
- 'tags_input' => $p->tags_input,
463
- 'tax_input' => $p->tax_input,
464
- 'page_template' => $p->page_template,
465
  );
466
 
467
- $post_status = get_option('clone_posts_post_status');
468
- if ( $post_status !== 'draft' ) {
469
  $newpost['post_status'] = $post_status;
470
  }
471
 
472
- $date = get_option('clone_posts_post_date');
473
- if ( $date !== 'current' ) {
474
- $newpost['post_date'] = $p->post_date;
475
  $newpost['post_date_gmt'] = $p->post_date_gmt;
476
  }
477
 
478
- $newid = wp_insert_post($newpost);
479
- $format = get_post_format($id);
480
- set_post_format($newid, $format);
481
 
482
- $meta = get_post_meta($id);
483
- foreach($meta as $key=>$val) {
484
  update_post_meta( $newid, $key, $val[0] );
485
  }
486
 
1
  <?php
 
2
  /**
3
  * The admin-specific functionality of the plugin.
4
  *
12
  /**
13
  * The admin-specific functionality of the plugin.
14
  *
15
+ * Defines the plugin name and version
 
16
  *
17
  * @package Clone_Posts
18
  * @subpackage Clone_Posts/admin
42
  * Initialize the class and set its properties.
43
  *
44
  * @since 2.0.0
45
+ * @param string $plugin_name The name of this plugin.
46
+ * @param string $version The version of this plugin.
47
  */
48
  public function __construct( $plugin_name, $version ) {
49
 
50
  $this->plugin_name = $plugin_name;
51
+ $this->version = $version;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  }
54
 
57
  *
58
  * @since 2.0.0
59
  */
60
+ public function clone_posts_admin_page() {
61
 
62
  add_options_page(
63
  'Clone Posts Settings',
64
  'Clone Posts',
65
  'manage_options',
66
  'clone-posts-options',
67
+ array( $this, 'clone_posts_admin_display' ),
68
  null
69
  );
70
 
75
  *
76
  * @since 2.0.0
77
  */
78
+ public function clone_posts_admin_display() {
79
  include_once 'partials/clone-posts-admin-display.php';
80
+ }
81
 
82
  /**
83
  * Register the actual settings
84
  *
85
  * @since 2.0.0
86
  */
87
+ public function clone_posts_register_setting() {
88
 
89
  add_settings_section(
90
  'clone_posts_settings_section',
102
  add_settings_field(
103
  'clone_posts_post_status',
104
  'Post Status',
105
+ array( $this, 'clone_posts_option_post_status' ),
106
  'clone-posts-options',
107
  'clone_posts_settings_section',
108
  array(
109
  'label_for' => 'clone_posts_post_status',
110
+ 'class' => 'clone-posts',
111
  )
112
  );
113
 
120
  add_settings_field(
121
  'clone_posts_post_date',
122
  'Post Date',
123
+ array( $this, 'clone_posts_option_post_date' ),
124
  'clone-posts-options',
125
  'clone_posts_settings_section',
126
  array(
127
  'label_for' => 'clone_posts_post_date',
128
+ 'class' => 'clone-posts',
129
  )
130
  );
131
 
132
  register_setting(
133
  'clone_post_settings',
134
  'clone_posts_post_type',
135
+ array( $this, 'clone_posts_sanitize_array' )
136
  );
137
 
138
  add_settings_field(
139
  'clone_posts_post_type',
140
  'Post Type',
141
+ array( $this, 'clone_posts_option_post_type' ),
142
  'clone-posts-options',
143
  'clone_posts_settings_section',
144
  array(
145
  'label_for' => 'clone_posts_post_type',
146
+ 'class' => 'clone-posts',
147
  )
148
  );
149
 
154
  *
155
  * @since 2.0.0
156
  */
157
+ public function clone_posts_option_post_status() {
158
+ $option = get_option( 'clone_posts_post_status' );
159
  ?>
160
  <select name="clone_posts_post_status" id="clone_posts_post_status">
161
+ <option value="draft" <?php selected( $option, 'draft' ); ?>>Draft</option>
162
+ <option value="publish" <?php selected( $option, 'publish' ); ?>>Publish</option>
163
+ <option value="private" <?php selected( $option, 'private' ); ?>>Private</option>
164
+ <option value="pending" <?php selected( $option, 'pending' ); ?>>Pending</option>
165
  </select>
166
  <p>Select the <a href="https://wordpress.org/support/article/post-status/#default-statuses" target="_blank">status</a> of the cloned post</p>
167
  <?php
172
  *
173
  * @since 2.0.0
174
  */
175
+ public function clone_posts_option_post_date() {
176
+ $option = get_option( 'clone_posts_post_date' );
177
  ?>
178
  <select name="clone_posts_post_date" id="clone_posts_post_date">
179
+ <option value="current" <?php selected( $option, 'current' ); ?>>Current Date/Time</option>
180
+ <option value="original" <?php selected( $option, 'original' ); ?>>Original Post Date</option>
181
  </select>
182
  <p>Select if the cloned post will have the same date as the<br>original or if it will be assigned the current date/time</p>
183
  <?php
188
  *
189
  * @since 2.0.0
190
  */
191
+ public function clone_posts_option_post_type() {
192
+ $options = maybe_unserialize( get_option( 'clone_posts_post_type' ) );
193
+ if ( ! is_array( $options ) ) {
194
+ $options = array( 'post', 'page' );
195
  }
196
+ $exclude_cpt = array( 'attachment' );
197
+ $post_types = get_post_types( array( 'public' => true ), 'objects', 'and' );
198
  echo '<fieldset>';
199
  if ( $post_types ) {
200
  foreach ( $post_types as $post_type ) {
201
+ if ( ! in_array( $post_type->name, $exclude_cpt, true ) ) {
202
+ ?>
203
  <div>
204
+ <input type="checkbox" name="clone_posts_post_type[]" value="<?php echo esc_attr( $post_type->name ); ?>" id="post_type_<?php echo esc_attr( $post_type->name ); ?>" <?php checked( in_array( $post_type->name, $options, true ), 1 ); ?>>
205
+ <label for="post_type_<?php echo esc_attr( $post_type->name ); ?>"><?php echo esc_html( $post_type->labels->name ); ?></label>
206
  </div>
207
+ <?php
208
  }
209
  }
210
  }
215
  * A custom sanitization function for arrays.
216
  *
217
  * @since 2.0.0
218
+ * @param array $input The posted array.
219
+ * @return array $output The array sanitized.
220
  */
221
+ public function clone_posts_sanitize_array( $input ) {
222
  $output = array();
223
  foreach ( $input as $key => $val ) {
224
  $output[ $key ] = ( isset( $input[ $key ] ) ) ? sanitize_text_field( $val ) : '';
231
  *
232
  * @since 2.0.0
233
  */
234
+ public function clone_posts_admin_footer() {
235
+ $options = maybe_unserialize( get_option( 'clone_posts_post_type' ) );
236
 
237
+ if ( ! is_array( $options ) ) {
238
+ $options = array( 'post', 'page' );
239
  }
240
 
241
+ if ( ! in_array( $GLOBALS['post_type'], $options, true ) ) {
242
+ return;
243
  }
244
  ?>
245
  <script type="text/javascript">
246
  jQuery(function () {
247
+ jQuery('<option>').val('clone').text('<?php esc_html_e( 'Clone' ); ?>').appendTo("select[name='action']");
248
+ jQuery('<option>').val('clone').text('<?php esc_html_e( 'Clone' ); ?>').appendTo("select[name='action2']");
249
  });
250
  </script>
251
  <?php
256
  *
257
  * @since 2.0.0
258
  */
259
+ public function clone_posts_bulk_action() {
260
  global $typenow;
261
  $post_type = $typenow;
262
+ $plugin = new Clone_Posts();
263
 
264
+ // get the action.
265
+ $wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
266
+ $action = $wp_list_table->current_action();
267
 
268
+ $allowed_actions = array( 'clone' );
269
+ if ( ! in_array( $action, $allowed_actions, true ) ) {
270
  return;
271
  }
272
 
273
+ // security check.
274
+ check_admin_referer( 'bulk-posts' );
275
 
276
+ // make sure ids are submitted. depending on the resource type, this may be 'media' or 'ids'.
277
+ if ( isset( $_REQUEST['post'] ) ) {
278
  $post_ids = array_map( 'intval', $_REQUEST['post'] );
279
  }
280
 
281
+ if ( empty( $post_ids ) ) {
282
  return;
283
  }
284
 
285
+ // this is based on wp-admin/edit.php .
286
  $sendback = remove_query_arg( array( 'cloned', 'untrashed', 'deleted', 'ids' ), wp_get_referer() );
287
  if ( ! $sendback ) {
288
  $sendback = admin_url( "edit.php?post_type=$post_type" );
289
  }
290
 
291
+ $pagenum = $wp_list_table->get_pagenum();
292
  $sendback = add_query_arg( 'paged', $pagenum, $sendback );
293
 
294
  switch ( $action ) {
295
  case 'clone':
 
296
  $cloned = 0;
297
  foreach ( $post_ids as $post_id ) {
298
 
299
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
300
+ wp_die( esc_html__( 'You are not allowed to clone this post.', 'clone-posts' ) );
301
  }
302
 
303
+ if ( ! $this->clone_posts_clone_single( $post_id ) ) {
304
+ wp_die( esc_html__( 'Error cloning post.', 'clone-posts' ) );
305
  }
306
 
307
  $cloned++;
308
  }
309
 
310
+ $sendback = add_query_arg(
311
+ array(
312
+ 'cloned' => $cloned,
313
+ 'ids' => join(
314
+ ',',
315
+ $post_ids
316
+ ),
317
+ ),
318
+ $sendback
319
+ );
320
  break;
321
 
322
  default:
323
  return;
324
  }
325
 
326
+ $sendback = remove_query_arg(
327
+ array(
328
+ 'action',
329
+ 'action2',
330
+ 'tags_input',
331
+ 'post_author',
332
+ 'comment_status',
333
+ 'ping_status',
334
+ '_status',
335
+ 'post',
336
+ 'bulk_edit',
337
+ 'post_view',
338
+ ),
339
+ $sendback
340
+ );
341
 
342
+ wp_redirect( $sendback );
343
  exit();
344
  }
345
 
348
  *
349
  * @since 2.0.0
350
  */
351
+ public function clone_posts_admin_notices() {
352
  global $pagenow;
353
 
354
+ if ( 'edit.php' === $pagenow && ! isset( $_GET['trashed'] ) ) {
355
  $cloned = 0;
356
  if ( isset( $_REQUEST['cloned'] ) && (int) $_REQUEST['cloned'] ) {
357
  $cloned = (int) $_REQUEST['cloned'];
358
+ } elseif ( isset( $_GET['cloned'] ) && (int) $_GET['cloned'] ) {
359
  $cloned = (int) $_GET['cloned'];
360
  }
361
+ if ( $cloned ) {
362
+ /* translators: %s is the number of clomned posts. */
363
+ $message = sprintf( _n( '%s Post cloned.', '%s posts cloned.', $cloned ), number_format_i18n( $cloned ) );
364
+ echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( $message ) . '</p></div>';
365
  }
366
  }
367
  }
371
  *
372
  * @since 2.0.0
373
  */
374
+ public function clone_posts_post_row_actions( $actions, $post ) {
375
  global $post_type;
 
376
 
377
+ $options = maybe_unserialize( get_option( 'clone_posts_post_type' ) );
378
 
379
+ if ( ! is_array( $options ) ) {
380
+ $options = array( 'post', 'page' );
381
  }
382
 
383
+ if ( ! in_array( $post_type, $options, true ) ) {
384
+ return $actions;
385
  }
386
 
387
+ $url = remove_query_arg( array( 'cloned', 'untrashed', 'deleted', 'ids' ), '' );
388
  if ( ! $url ) {
389
  $url = admin_url( "?post_type=$post_type" );
390
  }
391
+ $url = remove_query_arg(
392
+ array(
393
+ 'action',
394
+ 'action2',
395
+ 'tags_input',
396
+ 'post_author',
397
+ 'comment_status',
398
+ 'ping_status',
399
+ '_status',
400
+ 'post',
401
+ 'bulk_edit',
402
+ 'post_view',
403
+ ),
404
+ $url
405
+ );
406
+ $url = add_query_arg(
407
+ array(
408
+ 'action' => 'clone-single',
409
+ 'post' => $post->ID,
410
+ 'redirect' => isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : get_home_url(),
411
+ ),
412
+ $url
413
+ );
414
 
415
+ $actions['clone'] = '<a href=\'' . $url . '\'>' . __( 'Clone', 'clone-posts' ) . '</a>';
416
  return $actions;
417
  }
418
 
421
  *
422
  * @since 2.0.0
423
  */
424
+ public function clone_posts_wp_loaded() {
425
  global $post_type;
 
426
 
427
+ if ( ! isset( $_GET['action'] ) || 'clone-single' !== $_GET['action'] || ! isset( $_GET['post'] ) || ! isset( $_GET['redirect'] ) ) {
428
  return;
429
  }
430
 
431
  $post_id = (int) $_GET['post'];
432
 
433
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
434
+ wp_die( esc_html__( 'You are not allowed to clone this post.', 'clone-posts' ) );
435
  }
436
 
437
+ if ( ! $this->clone_posts_clone_single( $post_id ) ) {
438
+ wp_die( esc_html__( 'Error cloning post.', 'clone-posts' ) );
439
  }
440
 
441
+ $sendback = remove_query_arg( array( 'cloned', 'untrashed', 'deleted', 'ids' ), esc_url_raw( wp_unslash( $_GET['redirect'] ) ) );
442
  if ( ! $sendback ) {
443
  $sendback = admin_url( "edit.php?post_type=$post_type" );
444
  }
445
 
446
  $sendback = add_query_arg( array( 'cloned' => 1 ), $sendback );
447
+ $sendback = remove_query_arg( array( 'action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view' ), $sendback );
448
+ wp_redirect( $sendback );
449
  exit();
450
  }
451
 
452
  /**
453
  * Clone the Post
454
  *
455
+ * @param int $id The Post ID.
456
  * @since 2.0.0
457
  */
458
+ public function clone_posts_clone_single( $id ) {
459
+ $p = get_post( $id );
460
+ if ( null === $p ) {
461
+ return false;
462
+ }
463
 
464
  $newpost = array(
465
+ 'post_name' => $p->post_name,
466
+ 'post_type' => $p->post_type,
467
+ 'ping_status' => $p->ping_status,
468
+ 'post_parent' => $p->post_parent,
469
+ 'menu_order' => $p->menu_order,
470
+ 'post_password' => $p->post_password,
471
+ 'post_excerpt' => $p->post_excerpt,
472
+ 'comment_status' => $p->comment_status,
473
+ 'post_title' => $p->post_title . __( ' - Clone', 'clone-posts' ),
474
+ 'post_content' => $p->post_content,
475
+ 'post_author' => $p->post_author,
476
+ 'to_ping' => $p->to_ping,
477
+ 'pinged' => $p->pinged,
478
  'post_content_filtered' => $p->post_content_filtered,
479
+ 'post_category' => $p->post_category,
480
+ 'tags_input' => $p->tags_input,
481
+ 'tax_input' => $p->tax_input,
482
+ 'page_template' => $p->page_template,
483
  );
484
 
485
+ $post_status = get_option( 'clone_posts_post_status' );
486
+ if ( 'draft' !== $post_status ) {
487
  $newpost['post_status'] = $post_status;
488
  }
489
 
490
+ $date = get_option( 'clone_posts_post_date' );
491
+ if ( 'current' !== $date ) {
492
+ $newpost['post_date'] = $p->post_date;
493
  $newpost['post_date_gmt'] = $p->post_date_gmt;
494
  }
495
 
496
+ $newid = wp_insert_post( $newpost );
497
+ $format = get_post_format( $id );
498
+ set_post_format( $newid, $format );
499
 
500
+ $meta = get_post_meta( $id );
501
+ foreach ( $meta as $key => $val ) {
502
  update_post_meta( $newid, $key, $val[0] );
503
  }
504
 
admin/css/clone-posts-admin.css DELETED
@@ -1,4 +0,0 @@
1
- /**
2
- * All of the CSS for your admin-specific functionality should be
3
- * included in this file.
4
- */
 
 
 
 
admin/js/clone-posts-admin.js DELETED
@@ -1,32 +0,0 @@
1
- (function( $ ) {
2
- 'use strict';
3
-
4
- /**
5
- * All of the code for your admin-facing JavaScript source
6
- * should reside in this file.
7
- *
8
- * Note: It has been assumed you will write jQuery code here, so the
9
- * $ function reference has been prepared for usage within the scope
10
- * of this function.
11
- *
12
- * This enables you to define handlers, for when the DOM is ready:
13
- *
14
- * $(function() {
15
- *
16
- * });
17
- *
18
- * When the window is loaded:
19
- *
20
- * $( window ).load(function() {
21
- *
22
- * });
23
- *
24
- * ...and/or other possibilities.
25
- *
26
- * Ideally, it is not considered best practise to attach more than a
27
- * single DOM-ready or window-load handler for a particular page.
28
- * Although scripts in the WordPress core, Plugins and Themes may be
29
- * practising this, we should strive to set a better example in our own work.
30
- */
31
-
32
- })( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/partials/clone-posts-admin-display.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Provide a admin area view for the plugin
5
  *
@@ -11,18 +10,19 @@
11
  * @package Clone_Posts
12
  * @subpackage Clone_Posts/admin/partials
13
  */
 
14
  ?>
15
 
16
  <div class="wrap">
17
- <h1>Clone Posts Settings</h1>
18
- <form method="post" action="options.php">
19
- <?php
20
- settings_fields( 'clone_post_settings' );
21
- do_settings_sections( 'clone-posts-options' );
22
- submit_button();
23
- ?>
24
- </form>
25
  </div>
26
  <div class="wrap">
27
- <p>If you find this free plugin useful then please <a target="_blank" href="https://wordpress.org/support/plugin/clone-posts/reviews/?rate=5#new-post" title="Rate the plugin">rate the plugin ★★★★★</a> to support us. Thank you!</p>
28
  </div>
1
  <?php
 
2
  /**
3
  * Provide a admin area view for the plugin
4
  *
10
  * @package Clone_Posts
11
  * @subpackage Clone_Posts/admin/partials
12
  */
13
+
14
  ?>
15
 
16
  <div class="wrap">
17
+ <h1>Clone Posts Settings</h1>
18
+ <form method="post" action="options.php">
19
+ <?php
20
+ settings_fields( 'clone_post_settings' );
21
+ do_settings_sections( 'clone-posts-options' );
22
+ submit_button();
23
+ ?>
24
+ </form>
25
  </div>
26
  <div class="wrap">
27
+ <p>If you find this free plugin useful then please <a target="_blank" href="https://wordpress.org/support/plugin/clone-posts/reviews/?rate=5#new-post" title="Rate the plugin">rate the plugin ★★★★★</a> to support us. Thank you!</p>
28
  </div>
clone-posts.php CHANGED
@@ -13,8 +13,9 @@
13
  * Plugin Name: Clone Posts
14
  * Plugin URI: http://wordpress.org/extend/plugins/clone-posts/
15
  * Description: Easily clone (duplicate) Posts, Pages and Custom Post Types, including their custom fields (post_meta).
16
- * Version: 2.0.2
17
  * Requires at least: 5.0
 
18
  * Requires PHP: 5.6
19
  * Author: George Pattihis
20
  * Author URI: https://profiles.wordpress.org/pattihis/
@@ -22,40 +23,41 @@
22
  * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
23
  * Text Domain: clone-posts
24
  * Domain Path: /languages
25
- *
26
  */
27
 
28
- /* Copyright 2014 Lukasz Kostrzewa (email : lukasz.webmaster@gmail.com)
29
-
30
- This program is free software; you can redistribute it and/or modify
31
- it under the terms of the GNU General Public License, version 2, as
32
- published by the Free Software Foundation.
33
-
34
- This program is distributed in the hope that it will be useful,
35
- but WITHOUT ANY WARRANTY; without even the implied warranty of
36
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37
- GNU General Public License for more details.
38
-
39
- You should have received a copy of the GNU General Public License
40
- along with this program; if not, write to the Free Software
41
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
42
- */
 
43
 
44
- /* Copyright 2021 George Pattihis (gpattihis@gmail.com)
 
45
 
46
- "Clone Posts" is free software: you can redistribute it and/or modify
47
- it under the terms of the GNU General Public License as published by
48
- the Free Software Foundation, either version 2 of the License, or
49
- any later version.
50
 
51
- "Clone Posts" is distributed in the hope that it will be useful,
52
- but WITHOUT ANY WARRANTY; without even the implied warranty of
53
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54
- GNU General Public License for more details.
55
 
56
- You should have received a copy of the GNU General Public License
57
- "along with Clone Posts". If not, see http://www.gnu.org/licenses/gpl-2.0.txt.
58
- */
59
 
60
  // If this file is called directly, abort.
61
  if ( ! defined( 'WPINC' ) ) {
@@ -65,7 +67,7 @@ if ( ! defined( 'WPINC' ) ) {
65
  /**
66
  * Current plugin version.
67
  */
68
- define( 'CLONE_POSTS_VERSION', '2.0.1' );
69
 
70
  /**
71
  * The code that runs during plugin activation.
13
  * Plugin Name: Clone Posts
14
  * Plugin URI: http://wordpress.org/extend/plugins/clone-posts/
15
  * Description: Easily clone (duplicate) Posts, Pages and Custom Post Types, including their custom fields (post_meta).
16
+ * Version: 2.0.3
17
  * Requires at least: 5.0
18
+ * Tested up to: 6.0
19
  * Requires PHP: 5.6
20
  * Author: George Pattihis
21
  * Author URI: https://profiles.wordpress.org/pattihis/
23
  * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
24
  * Text Domain: clone-posts
25
  * Domain Path: /languages
 
26
  */
27
 
28
+ /**
29
+ * Copyright 2014 Lukasz Kostrzewa (email : lukasz.webmaster@gmail.com)
30
+ *
31
+ * This program is free software; you can redistribute it and/or modify
32
+ * it under the terms of the GNU General Public License, version 2, as
33
+ * published by the Free Software Foundation.
34
+
35
+ * This program is distributed in the hope that it will be useful,
36
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38
+ * GNU General Public License for more details.
39
+
40
+ * You should have received a copy of the GNU General Public License
41
+ * along with this program; if not, write to the Free Software
42
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
43
+ */
44
 
45
+ /**
46
+ * Copyright 2021 George Pattihis (gpattihis@gmail.com)
47
 
48
+ * "Clone Posts" is free software: you can redistribute it and/or modify
49
+ * it under the terms of the GNU General Public License as published by
50
+ * the Free Software Foundation, either version 2 of the License, or
51
+ * any later version.
52
 
53
+ * "Clone Posts" is distributed in the hope that it will be useful,
54
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56
+ * GNU General Public License for more details.
57
 
58
+ * You should have received a copy of the GNU General Public License
59
+ * "along with Clone Posts". If not, see http://www.gnu.org/licenses/gpl-2.0.txt.
60
+ */
61
 
62
  // If this file is called directly, abort.
63
  if ( ! defined( 'WPINC' ) ) {
67
  /**
68
  * Current plugin version.
69
  */
70
+ define( 'CLONE_POSTS_VERSION', '2.0.3' );
71
 
72
  /**
73
  * The code that runs during plugin activation.
includes/class-clone-posts-activator.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Fired during plugin activation
5
  *
@@ -31,9 +30,9 @@ class Clone_Posts_Activator {
31
  */
32
  public static function activate() {
33
 
34
- update_option('clone_posts_post_status', 'draft');
35
- update_option('clone_posts_post_date', 'current');
36
- update_option('clone_posts_post_type', ['post']);
37
 
38
  }
39
 
1
  <?php
 
2
  /**
3
  * Fired during plugin activation
4
  *
30
  */
31
  public static function activate() {
32
 
33
+ update_option( 'clone_posts_post_status', 'draft' );
34
+ update_option( 'clone_posts_post_date', 'current' );
35
+ update_option( 'clone_posts_post_type', array( 'post' ) );
36
 
37
  }
38
 
includes/class-clone-posts-deactivator.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Fired during plugin deactivation
5
  *
@@ -23,9 +22,9 @@
23
  class Clone_Posts_Deactivator {
24
 
25
  /**
26
- * Short Description. (use period)
27
  *
28
- * Long Description.
29
  *
30
  * @since 2.0.0
31
  */
1
  <?php
 
2
  /**
3
  * Fired during plugin deactivation
4
  *
22
  class Clone_Posts_Deactivator {
23
 
24
  /**
25
+ * Fired during plugin deactivation.
26
  *
27
+ * This functions runs all code necessary for plugin's deactivation.
28
  *
29
  * @since 2.0.0
30
  */
includes/class-clone-posts-i18n.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Define the internationalization functionality
5
  *
@@ -24,7 +23,7 @@
24
  * @subpackage Clone_Posts/includes
25
  * @author George Pattihis <gpattihis@gmail.com>
26
  */
27
- class Clone_Posts_i18n {
28
 
29
 
30
  /**
1
  <?php
 
2
  /**
3
  * Define the internationalization functionality
4
  *
23
  * @subpackage Clone_Posts/includes
24
  * @author George Pattihis <gpattihis@gmail.com>
25
  */
26
+ class Clone_Posts_I18n {
27
 
28
 
29
  /**
includes/class-clone-posts-loader.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Register all actions and filters for the plugin
5
  *
@@ -57,11 +56,11 @@ class Clone_Posts_Loader {
57
  * Add a new action to the collection to be registered with WordPress.
58
  *
59
  * @since 2.0.0
60
- * @param string $hook The name of the WordPress action that is being registered.
61
- * @param object $component A reference to the instance of the object on which the action is defined.
62
- * @param string $callback The name of the function definition on the $component.
63
- * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
64
- * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
65
  */
66
  public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
67
  $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
@@ -71,11 +70,11 @@ class Clone_Posts_Loader {
71
  * Add a new filter to the collection to be registered with WordPress.
72
  *
73
  * @since 2.0.0
74
- * @param string $hook The name of the WordPress filter that is being registered.
75
- * @param object $component A reference to the instance of the object on which the filter is defined.
76
- * @param string $callback The name of the function definition on the $component.
77
- * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
78
- * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
79
  */
80
  public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
81
  $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
@@ -87,12 +86,12 @@ class Clone_Posts_Loader {
87
  *
88
  * @since 2.0.0
89
  * @access private
90
- * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
91
- * @param string $hook The name of the WordPress filter that is being registered.
92
- * @param object $component A reference to the instance of the object on which the filter is defined.
93
- * @param string $callback The name of the function definition on the $component.
94
- * @param int $priority The priority at which the function should be fired.
95
- * @param int $accepted_args The number of arguments that should be passed to the $callback.
96
  * @return array The collection of actions and filters registered with WordPress.
97
  */
98
  private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
@@ -102,7 +101,7 @@ class Clone_Posts_Loader {
102
  'component' => $component,
103
  'callback' => $callback,
104
  'priority' => $priority,
105
- 'accepted_args' => $accepted_args
106
  );
107
 
108
  return $hooks;
1
  <?php
 
2
  /**
3
  * Register all actions and filters for the plugin
4
  *
56
  * Add a new action to the collection to be registered with WordPress.
57
  *
58
  * @since 2.0.0
59
+ * @param string $hook The name of the WordPress action that is being registered.
60
+ * @param object $component A reference to the instance of the object on which the action is defined.
61
+ * @param string $callback The name of the function definition on the $component.
62
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
63
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
64
  */
65
  public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
66
  $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
70
  * Add a new filter to the collection to be registered with WordPress.
71
  *
72
  * @since 2.0.0
73
+ * @param string $hook The name of the WordPress filter that is being registered.
74
+ * @param object $component A reference to the instance of the object on which the filter is defined.
75
+ * @param string $callback The name of the function definition on the $component.
76
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
77
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
78
  */
79
  public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
80
  $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
86
  *
87
  * @since 2.0.0
88
  * @access private
89
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
90
+ * @param string $hook The name of the WordPress filter that is being registered.
91
+ * @param object $component A reference to the instance of the object on which the filter is defined.
92
+ * @param string $callback The name of the function definition on the $component.
93
+ * @param int $priority The priority at which the function should be fired.
94
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
95
  * @return array The collection of actions and filters registered with WordPress.
96
  */
97
  private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
101
  'component' => $component,
102
  'callback' => $callback,
103
  'priority' => $priority,
104
+ 'accepted_args' => $accepted_args,
105
  );
106
 
107
  return $hooks;
includes/class-clone-posts.php CHANGED
@@ -1,10 +1,8 @@
1
  <?php
2
-
3
  /**
4
  * The file that defines the core plugin class
5
  *
6
- * A class definition that includes attributes and functions used across both the
7
- * public-facing side of the site and the admin area.
8
  *
9
  * @link https://profiles.wordpress.org/pattihis/
10
  * @since 2.0.0
@@ -16,8 +14,7 @@
16
  /**
17
  * The core plugin class.
18
  *
19
- * This is used to define internationalization, admin-specific hooks, and
20
- * public-facing site hooks.
21
  *
22
  * Also maintains the unique identifier of this plugin as well as the current
23
  * version of the plugin.
@@ -61,8 +58,7 @@ class Clone_Posts {
61
  * Define the core functionality of the plugin.
62
  *
63
  * Set the plugin name and the plugin version that can be used throughout the plugin.
64
- * Load the dependencies, define the locale, and set the hooks for the admin area and
65
- * the public-facing side of the site.
66
  *
67
  * @since 2.0.0
68
  */
@@ -70,14 +66,13 @@ class Clone_Posts {
70
  if ( defined( 'CLONE_POSTS_VERSION' ) ) {
71
  $this->version = CLONE_POSTS_VERSION;
72
  } else {
73
- $this->version = '2.0.1';
74
  }
75
  $this->plugin_name = 'clone-posts';
76
 
77
  $this->load_dependencies();
78
  $this->set_locale();
79
  $this->define_admin_hooks();
80
- $this->define_public_hooks();
81
 
82
  }
83
 
@@ -87,9 +82,8 @@ class Clone_Posts {
87
  * Include the following files that make up the plugin:
88
  *
89
  * - Clone_Posts_Loader. Orchestrates the hooks of the plugin.
90
- * - Clone_Posts_i18n. Defines internationalization functionality.
91
  * - Clone_Posts_Admin. Defines all hooks for the admin area.
92
- * - Clone_Posts_Public. Defines all hooks for the public side of the site.
93
  *
94
  * Create an instance of the loader which will be used to register the hooks
95
  * with WordPress.
@@ -116,12 +110,6 @@ class Clone_Posts {
116
  */
117
  require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-clone-posts-admin.php';
118
 
119
- /**
120
- * The class responsible for defining all actions that occur in the public-facing
121
- * side of the site.
122
- */
123
- require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-clone-posts-public.php';
124
-
125
  $this->loader = new Clone_Posts_Loader();
126
 
127
  }
@@ -129,7 +117,7 @@ class Clone_Posts {
129
  /**
130
  * Define the locale for this plugin for internationalization.
131
  *
132
- * Uses the Clone_Posts_i18n class in order to set the domain and to register the hook
133
  * with WordPress.
134
  *
135
  * @since 2.0.0
@@ -137,7 +125,7 @@ class Clone_Posts {
137
  */
138
  private function set_locale() {
139
 
140
- $plugin_i18n = new Clone_Posts_i18n();
141
 
142
  $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
143
 
@@ -154,33 +142,14 @@ class Clone_Posts {
154
 
155
  $plugin_admin = new Clone_Posts_Admin( $this->get_plugin_name(), $this->get_version() );
156
 
157
- $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
158
- $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
159
-
160
- $this->loader->add_action( 'admin_init', $plugin_admin, 'clonePosts_register_setting' );
161
- $this->loader->add_action( 'admin_menu', $plugin_admin, 'clonePosts_admin_page' );
162
- $this->loader->add_action( 'admin_footer-edit.php', $plugin_admin, 'clonePosts_admin_footer' );
163
- $this->loader->add_action( 'load-edit.php', $plugin_admin, 'clonePosts_bulk_action' );
164
- $this->loader->add_action( 'admin_notices', $plugin_admin, 'clonePosts_admin_notices' );
165
- $this->loader->add_filter( 'post_row_actions', $plugin_admin, 'clonePosts_post_row_actions', 10, 2 );
166
- $this->loader->add_filter( 'page_row_actions', $plugin_admin, 'clonePosts_post_row_actions', 10, 2 );
167
- $this->loader->add_action( 'wp_loaded', $plugin_admin, 'clonePosts_wp_loaded' );
168
-
169
- }
170
-
171
- /**
172
- * Register all of the hooks related to the public-facing functionality
173
- * of the plugin.
174
- *
175
- * @since 2.0.0
176
- * @access private
177
- */
178
- private function define_public_hooks() {
179
-
180
- $plugin_public = new Clone_Posts_Public( $this->get_plugin_name(), $this->get_version() );
181
-
182
- $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
183
- $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
184
 
185
  }
186
 
1
  <?php
 
2
  /**
3
  * The file that defines the core plugin class
4
  *
5
+ * A class definition that includes attributes and functions used in the admin area.
 
6
  *
7
  * @link https://profiles.wordpress.org/pattihis/
8
  * @since 2.0.0
14
  /**
15
  * The core plugin class.
16
  *
17
+ * This is used to define internationalization and admin-specific hooks
 
18
  *
19
  * Also maintains the unique identifier of this plugin as well as the current
20
  * version of the plugin.
58
  * Define the core functionality of the plugin.
59
  *
60
  * Set the plugin name and the plugin version that can be used throughout the plugin.
61
+ * Load the dependencies, define the locale and set the hooks for the admin area.
 
62
  *
63
  * @since 2.0.0
64
  */
66
  if ( defined( 'CLONE_POSTS_VERSION' ) ) {
67
  $this->version = CLONE_POSTS_VERSION;
68
  } else {
69
+ $this->version = '2.0.3';
70
  }
71
  $this->plugin_name = 'clone-posts';
72
 
73
  $this->load_dependencies();
74
  $this->set_locale();
75
  $this->define_admin_hooks();
 
76
 
77
  }
78
 
82
  * Include the following files that make up the plugin:
83
  *
84
  * - Clone_Posts_Loader. Orchestrates the hooks of the plugin.
85
+ * - Clone_Posts_I18n. Defines internationalization functionality.
86
  * - Clone_Posts_Admin. Defines all hooks for the admin area.
 
87
  *
88
  * Create an instance of the loader which will be used to register the hooks
89
  * with WordPress.
110
  */
111
  require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-clone-posts-admin.php';
112
 
 
 
 
 
 
 
113
  $this->loader = new Clone_Posts_Loader();
114
 
115
  }
117
  /**
118
  * Define the locale for this plugin for internationalization.
119
  *
120
+ * Uses the Clone_Posts_I18n class in order to set the domain and to register the hook
121
  * with WordPress.
122
  *
123
  * @since 2.0.0
125
  */
126
  private function set_locale() {
127
 
128
+ $plugin_i18n = new Clone_Posts_I18n();
129
 
130
  $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
131
 
142
 
143
  $plugin_admin = new Clone_Posts_Admin( $this->get_plugin_name(), $this->get_version() );
144
 
145
+ $this->loader->add_action( 'admin_init', $plugin_admin, 'clone_posts_register_setting' );
146
+ $this->loader->add_action( 'admin_menu', $plugin_admin, 'clone_posts_admin_page' );
147
+ $this->loader->add_action( 'admin_footer-edit.php', $plugin_admin, 'clone_posts_admin_footer' );
148
+ $this->loader->add_action( 'load-edit.php', $plugin_admin, 'clone_posts_bulk_action' );
149
+ $this->loader->add_action( 'admin_notices', $plugin_admin, 'clone_posts_admin_notices' );
150
+ $this->loader->add_filter( 'post_row_actions', $plugin_admin, 'clone_posts_post_row_actions', 10, 2 );
151
+ $this->loader->add_filter( 'page_row_actions', $plugin_admin, 'clone_posts_post_row_actions', 10, 2 );
152
+ $this->loader->add_action( 'wp_loaded', $plugin_admin, 'clone_posts_wp_loaded' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
  }
155
 
public/class-clone-posts-public.php DELETED
@@ -1,79 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The public-facing functionality of the plugin.
5
- *
6
- * @link https://profiles.wordpress.org/pattihis/
7
- * @since 2.0.0
8
- *
9
- * @package Clone_Posts
10
- * @subpackage Clone_Posts/public
11
- */
12
-
13
- /**
14
- * The public-facing functionality of the plugin.
15
- *
16
- * Defines the plugin name, version, and two examples hooks for how to
17
- * enqueue the public-facing stylesheet and JavaScript.
18
- *
19
- * @package Clone_Posts
20
- * @subpackage Clone_Posts/public
21
- * @author George Pattihis <gpattihis@gmail.com>
22
- */
23
- class Clone_Posts_Public {
24
-
25
- /**
26
- * The ID of this plugin.
27
- *
28
- * @since 2.0.0
29
- * @access private
30
- * @var string $plugin_name The ID of this plugin.
31
- */
32
- private $plugin_name;
33
-
34
- /**
35
- * The version of this plugin.
36
- *
37
- * @since 2.0.0
38
- * @access private
39
- * @var string $version The current version of this plugin.
40
- */
41
- private $version;
42
-
43
- /**
44
- * Initialize the class and set its properties.
45
- *
46
- * @since 2.0.0
47
- * @param string $plugin_name The name of the plugin.
48
- * @param string $version The version of this plugin.
49
- */
50
- public function __construct( $plugin_name, $version ) {
51
-
52
- $this->plugin_name = $plugin_name;
53
- $this->version = $version;
54
-
55
- }
56
-
57
- /**
58
- * Register the stylesheets for the public-facing side of the site.
59
- *
60
- * @since 2.0.0
61
- */
62
- public function enqueue_styles() {
63
-
64
- wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/clone-posts-public.css', array(), $this->version, 'all' );
65
-
66
- }
67
-
68
- /**
69
- * Register the JavaScript for the public-facing side of the site.
70
- *
71
- * @since 2.0.0
72
- */
73
- public function enqueue_scripts() {
74
-
75
- wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/clone-posts-public.js', array( 'jquery' ), $this->version, false );
76
-
77
- }
78
-
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/css/clone-posts-public.css DELETED
@@ -1,4 +0,0 @@
1
- /**
2
- * All of the CSS for your public-facing functionality should be
3
- * included in this file.
4
- */
 
 
 
 
public/index.php DELETED
@@ -1 +0,0 @@
1
- <?php // Silence is golden
 
public/js/clone-posts-public.js DELETED
@@ -1,32 +0,0 @@
1
- (function( $ ) {
2
- 'use strict';
3
-
4
- /**
5
- * All of the code for your public-facing JavaScript source
6
- * should reside in this file.
7
- *
8
- * Note: It has been assumed you will write jQuery code here, so the
9
- * $ function reference has been prepared for usage within the scope
10
- * of this function.
11
- *
12
- * This enables you to define handlers, for when the DOM is ready:
13
- *
14
- * $(function() {
15
- *
16
- * });
17
- *
18
- * When the window is loaded:
19
- *
20
- * $( window ).load(function() {
21
- *
22
- * });
23
- *
24
- * ...and/or other possibilities.
25
- *
26
- * Ideally, it is not considered best practise to attach more than a
27
- * single DOM-ready or window-load handler for a particular page.
28
- * Although scripts in the WordPress core, Plugins and Themes may be
29
- * practising this, we should strive to set a better example in our own work.
30
- */
31
-
32
- })( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/partials/clone-posts-public-display.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Provide a public-facing view for the plugin
5
- *
6
- * This file is used to markup the public-facing aspects of the plugin.
7
- *
8
- * @link https://profiles.wordpress.org/pattihis/
9
- * @since 2.0.0
10
- *
11
- * @package Clone_Posts
12
- * @subpackage Clone_Posts/public/partials
13
- */
14
- ?>
15
-
16
- <!-- This file should primarily consist of HTML with a little bit of PHP. -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
uninstall.php CHANGED
@@ -1,9 +1,7 @@
1
  <?php
2
-
3
  /**
4
  * Fired when the plugin is uninstalled.
5
  *
6
- *
7
  * @link https://profiles.wordpress.org/pattihis/
8
  * @since 2.0.0
9
  *
@@ -15,29 +13,34 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
15
  exit;
16
  }
17
 
18
- // If we are on a multisite installation clean up all subsites
19
  if ( is_multisite() ) {
20
 
21
- foreach (get_sites(['fields'=>'ids']) as $blog_id) {
22
- switch_to_blog($blog_id);
23
- clonePosts_cleanup();
24
  restore_current_blog();
25
  }
26
-
27
  } else {
28
- clonePosts_cleanup();
29
  }
30
 
31
- function clonePosts_cleanup(){
 
 
 
 
 
 
32
 
33
- // Plugin options
34
  $options = array(
35
  'clone_posts_post_status',
36
  'clone_posts_post_date',
37
  'clone_posts_post_type',
38
  );
39
 
40
- // Loop through each option
41
  foreach ( $options as $option ) {
42
  delete_option( $option );
43
  }
1
  <?php
 
2
  /**
3
  * Fired when the plugin is uninstalled.
4
  *
 
5
  * @link https://profiles.wordpress.org/pattihis/
6
  * @since 2.0.0
7
  *
13
  exit;
14
  }
15
 
16
+ // If we are on a multisite installation clean up all subsites.
17
  if ( is_multisite() ) {
18
 
19
+ foreach ( get_sites( array( 'fields' => 'ids' ) ) as $blog_id_number ) {
20
+ switch_to_blog( $blog_id_number );
21
+ clone_posts_cleanup();
22
  restore_current_blog();
23
  }
 
24
  } else {
25
+ clone_posts_cleanup();
26
  }
27
 
28
+ /**
29
+ * Cleans up after plugin's uninstallation.
30
+ *
31
+ * @since 2.0.0
32
+ * @return void
33
+ */
34
+ function clone_posts_cleanup() {
35
 
36
+ // Plugin options.
37
  $options = array(
38
  'clone_posts_post_status',
39
  'clone_posts_post_date',
40
  'clone_posts_post_type',
41
  );
42
 
43
+ // Loop through each option.
44
  foreach ( $options as $option ) {
45
  delete_option( $option );
46
  }