Duplicate Post - Version 3.1

Version Description

Bulk clone + custom field wildcards + other features + bugfixes

Download this release

Release Info

Developer lopo
Plugin Icon 128x128 Duplicate Post
Version 3.1
Comparing to
See all releases

Code changes from version 3.0.3 to 3.1

duplicate-post-admin.php CHANGED
@@ -26,110 +26,101 @@ add_action('admin_init','duplicate_post_plugin_upgrade');
26
 
27
  function duplicate_post_plugin_upgrade() {
28
  $installed_version = duplicate_post_get_installed_version();
 
 
 
29
 
30
- if (empty($installed_version)) { // first install
31
-
32
- // Add capability to admin and editors
33
-
34
  // Get default roles
35
- $default_roles = array(
36
  3 => 'editor',
37
  8 => 'administrator',
38
  );
39
-
40
  // Cycle all roles and assign capability if its level >= duplicate_post_copy_user_level
41
  foreach ($default_roles as $level => $name){
42
  $role = get_role($name);
43
  if(!empty($role)) $role->add_cap( 'copy_posts' );
44
  }
 
 
45
 
46
- add_option('duplicate_post_copytitle','1');
47
- add_option('duplicate_post_copydate','0');
48
- add_option('duplicate_post_copystatus','0');
49
- add_option('duplicate_post_copyslug','1');
50
- add_option('duplicate_post_copyexcerpt','1');
51
- add_option('duplicate_post_copycontent','1');
52
- add_option('duplicate_post_copypassword','0');
53
- add_option('duplicate_post_copyattachments','0');
54
- add_option('duplicate_post_copychildren','0');
55
- add_option('duplicate_post_copycomments','0');
56
- add_option('duplicate_post_taxonomies_blacklist',array());
57
- add_option('duplicate_post_blacklist','');
58
- add_option('duplicate_post_types_enabled',array('post', 'page'));
59
- add_option('duplicate_post_show_row','1');
60
- add_option('duplicate_post_show_adminbar','1');
61
- add_option('duplicate_post_show_submitbox','1');
62
- } else if ( $installed_version==duplicate_post_get_current_version() ) { //re-install
63
- // do nothing
64
- } else { //upgrade form previous version
65
- // delete old, obsolete options
66
- delete_option('duplicate_post_admin_user_level');
67
- delete_option('duplicate_post_create_user_level');
68
- delete_option('duplicate_post_view_user_level');
69
- delete_option('dp_notice');
70
-
71
- $installed_version_numbers = explode('.', $installed_version);
72
-
73
- if($installed_version_numbers[0] == 2){ // upgrading from 2.*
74
- /*
75
- * Convert old userlevel option to new capability scheme
76
- */
77
-
78
- // Get old duplicate_post_copy_user_level option
79
- $min_user_level = get_option('duplicate_post_copy_user_level');
80
-
81
- if (!empty($min_user_level)){
82
- // Get default roles
83
- $default_roles = array(
84
- 1 => 'contributor',
85
- 2 => 'author',
86
- 3 => 'editor',
87
- 8 => 'administrator',
88
- );
89
-
90
- // Cycle all roles and assign capability if its level >= duplicate_post_copy_user_level
91
- foreach ($default_roles as $level => $name){
92
- $role = get_role($name);
93
- if ($role && $min_user_level <= $level)
94
- $role->add_cap( 'copy_posts' );
95
- }
96
-
97
- // delete old option
98
- delete_option('duplicate_post_copy_user_level');
99
  }
100
-
101
- add_option('duplicate_post_copytitle','1');
102
- add_option('duplicate_post_copydate','0');
103
- add_option('duplicate_post_copystatus','0');
104
- add_option('duplicate_post_copyslug','1');
105
- add_option('duplicate_post_copyexcerpt','1');
106
- add_option('duplicate_post_copycontent','1');
107
- add_option('duplicate_post_copypassword','0');
108
- add_option('duplicate_post_copyattachments','0');
109
- add_option('duplicate_post_copychildren','0');
110
- add_option('duplicate_post_copycomments','0');
111
- add_option('duplicate_post_taxonomies_blacklist',array());
112
- add_option('duplicate_post_blacklist','');
113
- add_option('duplicate_post_types_enabled',array('post', 'page'));
114
- add_option('duplicate_post_show_row','1');
115
- add_option('duplicate_post_show_adminbar','1');
116
- add_option('duplicate_post_show_submitbox','1');
117
-
118
- // show notice about new features
119
- add_site_option('duplicate_post_show_notice','1');
120
-
121
- } else if($installed_version_numbers[0] == 3){ // upgrading from 3.*
122
- // hide notice, we assume people already know of new features
123
- delete_option('duplicate_post_show_notice', 0);
124
- update_site_option('duplicate_post_show_notice', 0);
125
  }
 
126
 
127
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  }
129
- // Update version number
 
 
 
 
 
 
130
  delete_option('duplicate_post_version');
131
  update_site_option( 'duplicate_post_version', duplicate_post_get_current_version() );
132
-
 
 
 
133
  }
134
 
135
  if (get_option('duplicate_post_show_row') == 1){
@@ -145,9 +136,14 @@ if (get_site_option('duplicate_post_show_notice') == 1){
145
  function duplicate_post_show_update_notice() {
146
  if(!current_user_can( 'manage_options')) return;
147
  $class = 'notice is-dismissible';
148
- $message = sprintf(__('<strong>Duplicate Post has been greatly redesigned in its options page.</strong> Please <a href="%s">review the settings</a> to make sure it works as you expect.', 'duplicate-post'), admin_url('options-general.php?page=duplicatepost'));
149
- $message .= '<br/>';
150
- $message .= '<a href="http://lopo.it/duplicate-post-plugin">'.__('Donate', 'duplicate-post').' (10¢) </a> | <a id="duplicate-post-dismiss-notice" href="javascript:duplicate_post_dismiss_notice();">'.__('Dismiss this notice.').'</a>';
 
 
 
 
 
151
  echo '<div id="duplicate-post-notice" class="'.$class.'"><p>'.$message.'</p></div>';
152
  echo "<script>
153
  function duplicate_post_dismiss_notice(){
@@ -168,7 +164,11 @@ if (get_site_option('duplicate_post_show_notice') == 1){
168
  </script>";
169
  }
170
 
171
- add_action( 'admin_notices', 'duplicate_post_show_update_notice' );
 
 
 
 
172
  add_action( 'wp_ajax_duplicate_post_dismiss_notice', 'duplicate_post_dismiss_notice' );
173
 
174
  function duplicate_post_dismiss_notice() {
@@ -184,11 +184,11 @@ if (get_site_option('duplicate_post_show_notice') == 1){
184
  function duplicate_post_make_duplicate_link_row($actions, $post) {
185
  if (duplicate_post_is_current_user_allowed_to_copy() && duplicate_post_is_post_type_enabled($post->post_type)) {
186
  $actions['clone'] = '<a href="'.duplicate_post_get_clone_post_link( $post->ID , 'display', false).'" title="'
187
- . esc_attr(__("Clone this item", 'duplicate-post'))
188
- . '">' . __('Clone', 'duplicate-post') . '</a>';
189
  $actions['edit_as_new_draft'] = '<a href="'. duplicate_post_get_clone_post_link( $post->ID ) .'" title="'
190
- . esc_attr(__('Copy to a new draft', 'duplicate-post'))
191
- . '">' . __('New Draft', 'duplicate-post') . '</a>';
192
  }
193
  return $actions;
194
  }
@@ -208,7 +208,7 @@ function duplicate_post_add_duplicate_post_button() {
208
  ?>
209
  <div id="duplicate-action">
210
  <a class="submitduplicate duplication"
211
- href="<?php echo duplicate_post_get_clone_post_link( $_GET['post'] ) ?>"><?php _e('Copy to a new draft', 'duplicate-post'); ?>
212
  </a>
213
  </div>
214
  <?php
@@ -243,7 +243,7 @@ function duplicate_post_add_removable_query_arg( $removable_query_args ){
243
  */
244
  function duplicate_post_save_as_new_post($status = ''){
245
  if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_post' == $_REQUEST['action'] ) ) ) {
246
- wp_die(__('No post to duplicate has been supplied!', 'duplicate-post'));
247
  }
248
 
249
  // Get the original post
@@ -253,9 +253,9 @@ function duplicate_post_save_as_new_post($status = ''){
253
  // Copy the post and insert it
254
  if (isset($post) && $post!=null) {
255
  $new_id = duplicate_post_create_duplicate($post, $status);
256
-
257
  if ($status == ''){
258
- $sendback = remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'cloned', 'ids'), wp_get_referer() );
259
  // Redirect to the post list screen
260
  wp_redirect( add_query_arg( array( 'cloned' => 1, 'ids' => $post->ID), $sendback ) );
261
  } else {
@@ -265,7 +265,7 @@ function duplicate_post_save_as_new_post($status = ''){
265
  exit;
266
 
267
  } else {
268
- wp_die(__('Copy creation failed, could not find original:', 'duplicate-post') . ' ' . htmlspecialchars($id));
269
  }
270
  }
271
 
@@ -279,8 +279,16 @@ function duplicate_post_copy_post_taxonomies($new_id, $post) {
279
  wp_set_object_terms( $new_id, NULL, 'category' );
280
 
281
  $post_taxonomies = get_object_taxonomies($post->post_type);
 
 
 
 
 
282
  $taxonomies_blacklist = get_option('duplicate_post_taxonomies_blacklist');
283
  if ($taxonomies_blacklist == "") $taxonomies_blacklist = array();
 
 
 
284
  $taxonomies = array_diff($post_taxonomies, $taxonomies_blacklist);
285
  foreach ($taxonomies as $taxonomy) {
286
  $post_terms = wp_get_object_terms($post->ID, $taxonomy, array( 'orderby' => 'term_order' ));
@@ -307,17 +315,54 @@ function duplicate_post_copy_post_meta_info($new_id, $post) {
307
  $meta_blacklist[] = '_wpas_mess'; //Jetpack Publicize
308
  $meta_blacklist[] = '_edit_lock'; // edit lock
309
  $meta_blacklist[] = '_edit_last'; // edit lock
310
- $meta_keys = array_diff($post_meta_keys, $meta_blacklist);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
 
312
  foreach ($meta_keys as $meta_key) {
313
  $meta_values = get_post_custom_values($meta_key, $post->ID);
314
  foreach ($meta_values as $meta_value) {
315
  $meta_value = maybe_unserialize($meta_value);
316
- add_post_meta($new_id, $meta_key, $meta_value);
317
  }
318
  }
319
  }
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  /**
322
  * Copy the attachments
323
  */
@@ -337,7 +382,7 @@ function duplicate_post_copy_attachments($new_id, $post){
337
  continue;
338
  }
339
 
340
- $desc = addslashes($child->post_content);
341
 
342
  $file_array = array();
343
  $file_array['name'] = basename($url);
@@ -352,17 +397,17 @@ function duplicate_post_copy_attachments($new_id, $post){
352
  $new_post_author = wp_get_current_user();
353
  $cloned_child = array(
354
  'ID' => $new_attachment_id,
355
- 'post_title' => addslashes($child->post_title),
356
- 'post_exceprt' => addslashes($child->post_title),
357
  'post_author' => $new_post_author->ID
358
  );
359
- wp_update_post( $cloned_child );
360
 
361
  $alt_title = get_post_meta($child->ID, '_wp_attachment_image_alt', true);
362
- if($alt_title) update_post_meta($new_attachment_id, '_wp_attachment_image_alt', $alt_title);
363
 
364
  // if we have cloned the post thumbnail, set the copy as the thumbnail for the new post
365
- if($old_thumbnail_id == $child->ID){
366
  set_post_thumbnail($new_id, $new_attachment_id);
367
  }
368
 
@@ -447,10 +492,14 @@ add_action('dp_duplicate_page', 'duplicate_post_copy_post_taxonomies', 50, 2);
447
  * Create a duplicate from a post
448
  */
449
  function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
 
 
450
 
451
  if (!duplicate_post_is_post_type_enabled($post->post_type) && $post->post_type != 'attachment')
452
- wp_die(__('Copy features for this post type are not enabled in options page', 'duplicate-post'));
453
 
 
 
454
  if ($post->post_type != 'attachment'){
455
  $prefix = sanitize_text_field(get_option('duplicate_post_title_prefix'));
456
  $suffix = sanitize_text_field(get_option('duplicate_post_title_suffix'));
@@ -468,13 +517,40 @@ function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
468
  // empty title
469
  $title = __('Untitled');
470
  }
471
-
472
-
473
- if (get_option('duplicate_post_copystatus') == 0) $status = 'draft';
474
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
  $new_post_author = wp_get_current_user();
 
 
 
 
 
 
 
 
 
 
 
 
 
476
 
477
- $menu_order = $post->menu_order;
478
  $increase_menu_order_by = get_option('duplicate_post_increase_menu_order_by');
479
  if(!empty($increase_menu_order_by) && is_numeric($increase_menu_order_by)){
480
  $menu_order += intval($increase_menu_order_by);
@@ -484,15 +560,15 @@ function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
484
  'menu_order' => $menu_order,
485
  'comment_status' => $post->comment_status,
486
  'ping_status' => $post->ping_status,
487
- 'post_author' => $new_post_author->ID,
488
- 'post_content' => (get_option('duplicate_post_copycontent') == '1') ? addslashes($post->post_content) : "" ,
489
- 'post_content_filtered' => (get_option('duplicate_post_copycontent') == '1') ? addslashes($post->post_content_filtered) : "" ,
490
- 'post_excerpt' => (get_option('duplicate_post_copyexcerpt') == '1') ? addslashes($post->post_excerpt) : "",
491
  'post_mime_type' => $post->post_mime_type,
492
  'post_parent' => $new_post_parent = empty($parent_id)? $post->post_parent : $parent_id,
493
  'post_password' => (get_option('duplicate_post_copypassword') == '1') ? $post->post_password: "",
494
- 'post_status' => $new_post_status = (empty($status))? $post->post_status: $status,
495
- 'post_title' => addslashes($title),
496
  'post_type' => $post->post_type,
497
  );
498
 
@@ -501,7 +577,7 @@ function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
501
  $new_post['post_date_gmt'] = get_gmt_from_date($new_post_date);
502
  }
503
 
504
- $new_post_id = wp_insert_post($new_post);
505
 
506
  // If the copy is published or scheduled, we have to set a proper slug.
507
  if ($new_post_status == 'publish' || $new_post_status == 'future'){
@@ -516,12 +592,12 @@ function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
516
  $new_post['post_name'] = $post_name;
517
 
518
  // Update the post into the database
519
- wp_update_post( $new_post );
520
  }
521
 
522
  // If you have written a plugin which uses non-WP database tables to save
523
  // information about a post you can hook this action to dupe that data.
524
- if ($post->post_type == 'page' || (function_exists('is_post_type_hierarchical') && is_post_type_hierarchical( $post->post_type )))
525
  do_action( 'dp_duplicate_page', $new_post_id, $post );
526
  else
527
  do_action( 'dp_duplicate_post', $new_post_id, $post );
@@ -529,6 +605,8 @@ function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
529
  delete_post_meta($new_post_id, '_dp_original');
530
  add_post_meta($new_post_id, '_dp_original', $post->ID);
531
 
 
 
532
  return $new_post_id;
533
  }
534
 
@@ -537,12 +615,14 @@ add_filter('plugin_row_meta', 'duplicate_post_add_plugin_links', 10, 2);
537
 
538
  function duplicate_post_add_plugin_links($links, $file) {
539
  if ( $file == plugin_basename(dirname(__FILE__).'/duplicate-post.php') ) {
540
- $links[] = '<a href="http://lopo.it/duplicate-post-plugin">' . __('Donate', 'duplicate-post') . '</a>';
541
- $links[] = '<a href="https://translate.wordpress.org/projects/wp-plugins/duplicate-post">' . __('Translate', 'duplicate-post') . '</a>';
542
  }
543
  return $links;
544
  }
545
 
 
 
546
  add_action( 'admin_notices', 'duplicate_post_action_admin_notice' );
547
 
548
  function duplicate_post_action_admin_notice() {
@@ -557,3 +637,55 @@ function duplicate_post_action_admin_notice() {
557
  remove_query_arg( 'cloned' );
558
  }
559
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  function duplicate_post_plugin_upgrade() {
28
  $installed_version = duplicate_post_get_installed_version();
29
+
30
+ if ( $installed_version==duplicate_post_get_current_version() )
31
+ return;
32
 
33
+
34
+ if (empty($installed_version)) {
 
 
35
  // Get default roles
36
+ $default_roles = array(
37
  3 => 'editor',
38
  8 => 'administrator',
39
  );
40
+
41
  // Cycle all roles and assign capability if its level >= duplicate_post_copy_user_level
42
  foreach ($default_roles as $level => $name){
43
  $role = get_role($name);
44
  if(!empty($role)) $role->add_cap( 'copy_posts' );
45
  }
46
+ } else {
47
+ $min_user_level = get_option('duplicate_post_copy_user_level');
48
 
49
+ if (!empty($min_user_level)){
50
+ // Get default roles
51
+ $default_roles = array(
52
+ 1 => 'contributor',
53
+ 2 => 'author',
54
+ 3 => 'editor',
55
+ 8 => 'administrator',
56
+ );
57
+
58
+ // Cycle all roles and assign capability if its level >= duplicate_post_copy_user_level
59
+ foreach ($default_roles as $level => $name){
60
+ $role = get_role($name);
61
+ if ($role && $min_user_level <= $level)
62
+ $role->add_cap( 'copy_posts' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
+ delete_option('duplicate_post_copy_user_level');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
66
+ }
67
 
68
+
69
+ add_option('duplicate_post_copytitle','1');
70
+ add_option('duplicate_post_copydate','0');
71
+ add_option('duplicate_post_copystatus','0');
72
+ add_option('duplicate_post_copyslug','1');
73
+ add_option('duplicate_post_copyexcerpt','1');
74
+ add_option('duplicate_post_copycontent','1');
75
+ add_option('duplicate_post_copythumbnail','1');
76
+ add_option('duplicate_post_copytemplate','1');
77
+ add_option('duplicate_post_copyformat','1');
78
+ add_option('duplicate_post_copyauthor','0');
79
+ add_option('duplicate_post_copypassword','0');
80
+ add_option('duplicate_post_copyattachments','0');
81
+ add_option('duplicate_post_copychildren','0');
82
+ add_option('duplicate_post_copycomments','0');
83
+ add_option('duplicate_post_copymenuorder','1');
84
+ add_option('duplicate_post_taxonomies_blacklist',array());
85
+ add_option('duplicate_post_blacklist','');
86
+ add_option('duplicate_post_types_enabled',array('post', 'page'));
87
+ add_option('duplicate_post_show_row','1');
88
+ add_option('duplicate_post_show_adminbar','1');
89
+ add_option('duplicate_post_show_submitbox','1');
90
+ add_option('duplicate_post_show_bulkactions','1');
91
+
92
+ $taxonomies_blacklist = get_option('duplicate_post_taxonomies_blacklist');
93
+ if ($taxonomies_blacklist == "") $taxonomies_blacklist = array();
94
+ if(in_array('post_format',$taxonomies_blacklist)){
95
+ update_option('duplicate_post_copyformat', 0);
96
+ $taxonomies_blacklist = array_diff($taxonomies_blacklist, array('post_format'));
97
+ update_option('duplicate_post_taxonomies_blacklist', $taxonomies_blacklist);
98
+ }
99
+
100
+ $meta_blacklist = explode(",",get_option('duplicate_post_blacklist'));
101
+ if ($meta_blacklist == "") $meta_blacklist = array();
102
+ $meta_blacklist = array_map('trim', $meta_blacklist);
103
+ if(in_array('_wp_page_template', $meta_blacklist)){
104
+ update_option('duplicate_post_copytemplate', 0);
105
+ $meta_blacklist = array_diff($meta_blacklist, array('_wp_page_template'));
106
+ }
107
+ if(in_array('_thumbnail_id', $meta_blacklist)){
108
+ update_option('duplicate_post_copythumbnail', 0);
109
+ $meta_blacklist = array_diff($meta_blacklist, array('_thumbnail_id'));
110
  }
111
+ update_option('duplicate_post_blacklist', implode(',',$meta_blacklist));
112
+
113
+ delete_option('duplicate_post_admin_user_level');
114
+ delete_option('duplicate_post_create_user_level');
115
+ delete_option('duplicate_post_view_user_level');
116
+ delete_option('dp_notice');
117
+
118
  delete_option('duplicate_post_version');
119
  update_site_option( 'duplicate_post_version', duplicate_post_get_current_version() );
120
+
121
+ delete_option('duplicate_post_show_notice', 0);
122
+ update_site_option('duplicate_post_show_notice', 1);
123
+
124
  }
125
 
126
  if (get_option('duplicate_post_show_row') == 1){
136
  function duplicate_post_show_update_notice() {
137
  if(!current_user_can( 'manage_options')) return;
138
  $class = 'notice is-dismissible';
139
+ $message = '<strong>'.esc_html__('Duplicate Post has new features!', 'duplicate-post').'</strong><br/>';
140
+ $message .= '<em>'.esc_html__('Clone posts in bulk (WP 4.7+)', 'duplicate-post').' — '.esc_html__('Wildcards in custom field names', 'duplicate-post').' — '.esc_html__('Options for thumbnail, post format, post template, author, menu order', 'duplicate-post').'</em><br/>';
141
+ $message .= sprintf(__('Please <a href="%s">review the settings</a> to make sure it works as you expect.', 'duplicate-post'), admin_url('options-general.php?page=duplicatepost')).'<br/>';
142
+ $message .= '<strong>'.__('Help me develop the plugin and provide support by <a href="http://lopo.it/duplicate-post-plugin">donating even a small sum</a>.', 'duplicate-post').'</strong>';
143
+ global $wp_version;
144
+ if( version_compare($wp_version, '4.2') < 0 ){
145
+ $message .= ' | <a id="duplicate-post-dismiss-notice" href="javascript:duplicate_post_dismiss_notice();">'.__('Dismiss this notice.').'</a>';
146
+ }
147
  echo '<div id="duplicate-post-notice" class="'.$class.'"><p>'.$message.'</p></div>';
148
  echo "<script>
149
  function duplicate_post_dismiss_notice(){
164
  </script>";
165
  }
166
 
167
+ if(is_multisite()){
168
+ add_action( 'network_admin_notices', 'duplicate_post_show_update_notice' );
169
+ } else {
170
+ add_action( 'admin_notices', 'duplicate_post_show_update_notice' );
171
+ }
172
  add_action( 'wp_ajax_duplicate_post_dismiss_notice', 'duplicate_post_dismiss_notice' );
173
 
174
  function duplicate_post_dismiss_notice() {
184
  function duplicate_post_make_duplicate_link_row($actions, $post) {
185
  if (duplicate_post_is_current_user_allowed_to_copy() && duplicate_post_is_post_type_enabled($post->post_type)) {
186
  $actions['clone'] = '<a href="'.duplicate_post_get_clone_post_link( $post->ID , 'display', false).'" title="'
187
+ . esc_attr__("Clone this item", 'duplicate-post')
188
+ . '">' . esc_html__('Clone', 'duplicate-post') . '</a>';
189
  $actions['edit_as_new_draft'] = '<a href="'. duplicate_post_get_clone_post_link( $post->ID ) .'" title="'
190
+ . esc_attr__('Copy to a new draft', 'duplicate-post')
191
+ . '">' . esc_html__('New Draft', 'duplicate-post') . '</a>';
192
  }
193
  return $actions;
194
  }
208
  ?>
209
  <div id="duplicate-action">
210
  <a class="submitduplicate duplication"
211
+ href="<?php echo duplicate_post_get_clone_post_link( $_GET['post'] ) ?>"><?php esc_html_e('Copy to a new draft', 'duplicate-post'); ?>
212
  </a>
213
  </div>
214
  <?php
243
  */
244
  function duplicate_post_save_as_new_post($status = ''){
245
  if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_post' == $_REQUEST['action'] ) ) ) {
246
+ wp_die(esc_html__('No post to duplicate has been supplied!', 'duplicate-post'));
247
  }
248
 
249
  // Get the original post
253
  // Copy the post and insert it
254
  if (isset($post) && $post!=null) {
255
  $new_id = duplicate_post_create_duplicate($post, $status);
256
+
257
  if ($status == ''){
258
+ $sendback = remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'cloned', 'ids'), admin_url( 'edit.php?post_type='.$post->post_type) );
259
  // Redirect to the post list screen
260
  wp_redirect( add_query_arg( array( 'cloned' => 1, 'ids' => $post->ID), $sendback ) );
261
  } else {
265
  exit;
266
 
267
  } else {
268
+ wp_die(esc_html__('Copy creation failed, could not find original:', 'duplicate-post') . ' ' . htmlspecialchars($id));
269
  }
270
  }
271
 
279
  wp_set_object_terms( $new_id, NULL, 'category' );
280
 
281
  $post_taxonomies = get_object_taxonomies($post->post_type);
282
+ // severl plugins just add support to post-formats but don't register post_format taxonomy
283
+ if(post_type_supports($post->post_type, 'post-formats') && !in_array('post_format', $post_taxonomies)){
284
+ $post_taxonomies[] = 'post_format';
285
+ }
286
+
287
  $taxonomies_blacklist = get_option('duplicate_post_taxonomies_blacklist');
288
  if ($taxonomies_blacklist == "") $taxonomies_blacklist = array();
289
+ if(get_option('duplicate_post_copyformat') == 0){
290
+ $taxonomies_blacklist[] = 'post_format';
291
+ }
292
  $taxonomies = array_diff($post_taxonomies, $taxonomies_blacklist);
293
  foreach ($taxonomies as $taxonomy) {
294
  $post_terms = wp_get_object_terms($post->ID, $taxonomy, array( 'orderby' => 'term_order' ));
315
  $meta_blacklist[] = '_wpas_mess'; //Jetpack Publicize
316
  $meta_blacklist[] = '_edit_lock'; // edit lock
317
  $meta_blacklist[] = '_edit_last'; // edit lock
318
+ if(get_option('duplicate_post_copytemplate') == 0){
319
+ $meta_blacklist[] = '_wp_page_template';
320
+ }
321
+ if(get_option('duplicate_post_copythumbnail') == 0){
322
+ $meta_blacklist[] = '_thumbnail_id';
323
+ }
324
+ //$meta_keys = array_diff($post_meta_keys, $meta_blacklist);
325
+ $meta_blacklist_string = '('.implode(')|(',$meta_blacklist).')';
326
+ $meta_blacklist_string = str_replace(array('*'), array('[a-zA-Z0-9_]*'), $meta_blacklist_string);
327
+
328
+ $meta_keys = array();
329
+ foreach($post_meta_keys as $meta_key){
330
+ if(!preg_match('#^'.$meta_blacklist_string.'$#', $meta_key))
331
+ $meta_keys[] = $meta_key;
332
+ }
333
 
334
+ $meta_keys = apply_filters( 'dp_meta_keys', $meta_keys );
335
  foreach ($meta_keys as $meta_key) {
336
  $meta_values = get_post_custom_values($meta_key, $post->ID);
337
  foreach ($meta_values as $meta_value) {
338
  $meta_value = maybe_unserialize($meta_value);
339
+ add_post_meta($new_id, $meta_key, duplicate_post_wp_slash($meta_value));
340
  }
341
  }
342
  }
343
 
344
+ /*
345
+ * Workaround for inconsistent wp_slash.
346
+ * Works only with WP 4.4+ (map_deep)
347
+ */
348
+ function duplicate_post_addslashes_deep( $value ) {
349
+ if (function_exists('map_deep')){
350
+ return map_deep( $value, 'duplicate_post_addslashes_to_strings_only' );
351
+ } else {
352
+ return wp_slash( $value );
353
+ }
354
+ }
355
+
356
+ function duplicate_post_addslashes_to_strings_only( $value ) {
357
+ return is_string( $value ) ? addslashes( $value ) : $value;
358
+ }
359
+
360
+ function duplicate_post_wp_slash( $value ) {
361
+ return duplicate_post_addslashes_deep( $value );
362
+ }
363
+
364
+
365
+
366
  /**
367
  * Copy the attachments
368
  */
382
  continue;
383
  }
384
 
385
+ $desc = wp_slash($child->post_content);
386
 
387
  $file_array = array();
388
  $file_array['name'] = basename($url);
397
  $new_post_author = wp_get_current_user();
398
  $cloned_child = array(
399
  'ID' => $new_attachment_id,
400
+ 'post_title' => $child->post_title,
401
+ 'post_exceprt' => $child->post_title,
402
  'post_author' => $new_post_author->ID
403
  );
404
+ wp_update_post( wp_slash($cloned_child) );
405
 
406
  $alt_title = get_post_meta($child->ID, '_wp_attachment_image_alt', true);
407
+ if($alt_title) update_post_meta($new_attachment_id, '_wp_attachment_image_alt', wp_slash($alt_title));
408
 
409
  // if we have cloned the post thumbnail, set the copy as the thumbnail for the new post
410
+ if(get_option('duplicate_post_copythumbnail') == 1 && $old_thumbnail_id == $child->ID){
411
  set_post_thumbnail($new_id, $new_attachment_id);
412
  }
413
 
492
  * Create a duplicate from a post
493
  */
494
  function duplicate_post_create_duplicate($post, $status = '', $parent_id = '') {
495
+
496
+ do_action('duplicate_post_pre_copy');
497
 
498
  if (!duplicate_post_is_post_type_enabled($post->post_type) && $post->post_type != 'attachment')
499
+ wp_die(esc_html__('Copy features for this post type are not enabled in options page', 'duplicate-post'));
500
 
501
+ $new_post_status = (empty($status))? $post->post_status: $status;
502
+
503
  if ($post->post_type != 'attachment'){
504
  $prefix = sanitize_text_field(get_option('duplicate_post_title_prefix'));
505
  $suffix = sanitize_text_field(get_option('duplicate_post_title_suffix'));
517
  // empty title
518
  $title = __('Untitled');
519
  }
520
+ if (get_option('duplicate_post_copystatus') == 0){
521
+ $new_post_status = 'draft';
522
+ } else {
523
+ if ( 'publish' == $new_post_status || 'future' == $new_post_status ){
524
+ // check if the user has the right capability
525
+ if(is_post_type_hierarchical( $post->post_type )){
526
+ if(!current_user_can('publish_pages')){
527
+ $new_post_status = 'pending';
528
+ }
529
+ } else {
530
+ if(!current_user_can('publish_posts')){
531
+ $new_post_status = 'pending';
532
+ }
533
+ }
534
+ }
535
+ }
536
+ }
537
+
538
  $new_post_author = wp_get_current_user();
539
+ $new_post_author_id = $new_post_author->ID;
540
+ if ( get_option('duplicate_post_copyauthor') == '1' ){
541
+ // check if the user has the right capability
542
+ if(is_post_type_hierarchical( $post->post_type )){
543
+ if(current_user_can('edit_others_pages')){
544
+ $new_post_author_id = $post->post_author;
545
+ }
546
+ } else {
547
+ if(current_user_can('edit_others_posts')){
548
+ $new_post_author_id = $post->post_author;
549
+ }
550
+ }
551
+ }
552
 
553
+ $menu_order = (get_option('duplicate_post_copymenuorder') == '1') ? $post->menu_order : 0;
554
  $increase_menu_order_by = get_option('duplicate_post_increase_menu_order_by');
555
  if(!empty($increase_menu_order_by) && is_numeric($increase_menu_order_by)){
556
  $menu_order += intval($increase_menu_order_by);
560
  'menu_order' => $menu_order,
561
  'comment_status' => $post->comment_status,
562
  'ping_status' => $post->ping_status,
563
+ 'post_author' => $new_post_author_id,
564
+ 'post_content' => (get_option('duplicate_post_copycontent') == '1') ? $post->post_content : "" ,
565
+ 'post_content_filtered' => (get_option('duplicate_post_copycontent') == '1') ? $post->post_content_filtered : "" ,
566
+ 'post_excerpt' => (get_option('duplicate_post_copyexcerpt') == '1') ? $post->post_excerpt : "",
567
  'post_mime_type' => $post->post_mime_type,
568
  'post_parent' => $new_post_parent = empty($parent_id)? $post->post_parent : $parent_id,
569
  'post_password' => (get_option('duplicate_post_copypassword') == '1') ? $post->post_password: "",
570
+ 'post_status' => $new_post_status,
571
+ 'post_title' => $title,
572
  'post_type' => $post->post_type,
573
  );
574
 
577
  $new_post['post_date_gmt'] = get_gmt_from_date($new_post_date);
578
  }
579
 
580
+ $new_post_id = wp_insert_post(wp_slash($new_post));
581
 
582
  // If the copy is published or scheduled, we have to set a proper slug.
583
  if ($new_post_status == 'publish' || $new_post_status == 'future'){
592
  $new_post['post_name'] = $post_name;
593
 
594
  // Update the post into the database
595
+ wp_update_post( wp_slash($new_post) );
596
  }
597
 
598
  // If you have written a plugin which uses non-WP database tables to save
599
  // information about a post you can hook this action to dupe that data.
600
+ if ($post->post_type == 'page' || is_post_type_hierarchical( $post->post_type ))
601
  do_action( 'dp_duplicate_page', $new_post_id, $post );
602
  else
603
  do_action( 'dp_duplicate_post', $new_post_id, $post );
605
  delete_post_meta($new_post_id, '_dp_original');
606
  add_post_meta($new_post_id, '_dp_original', $post->ID);
607
 
608
+ do_action('duplicate_post_post_copy');
609
+
610
  return $new_post_id;
611
  }
612
 
615
 
616
  function duplicate_post_add_plugin_links($links, $file) {
617
  if ( $file == plugin_basename(dirname(__FILE__).'/duplicate-post.php') ) {
618
+ $links[] = '<a href="http://lopo.it/duplicate-post-plugin">' . esc_html__('Donate', 'duplicate-post') . '</a>';
619
+ $links[] = '<a href="https://translate.wordpress.org/projects/wp-plugins/duplicate-post">' . esc_html__('Translate', 'duplicate-post') . '</a>';
620
  }
621
  return $links;
622
  }
623
 
624
+ /*** NOTICES ***/
625
+
626
  add_action( 'admin_notices', 'duplicate_post_action_admin_notice' );
627
 
628
  function duplicate_post_action_admin_notice() {
637
  remove_query_arg( 'cloned' );
638
  }
639
  }
640
+
641
+
642
+ /*** BULK ACTIONS ***/
643
+
644
+ add_action('admin_init', 'duplicate_post_add_bulk_filters_for_enabled_post_types');
645
+
646
+ function duplicate_post_add_bulk_filters_for_enabled_post_types(){
647
+ if(get_option('duplicate_post_show_bulkactions') != 1) return;
648
+ $duplicate_post_types_enabled = get_option('duplicate_post_types_enabled', array ('post', 'page'));
649
+ if(!is_array($duplicate_post_types_enabled)) $duplicate_post_types_enabled = array($duplicate_post_types_enabled);
650
+ foreach($duplicate_post_types_enabled as $duplicate_post_type_enabled){
651
+ add_filter( "bulk_actions-edit-{$duplicate_post_type_enabled}", 'duplicate_post_register_bulk_action' );
652
+ add_filter( "handle_bulk_actions-edit-{$duplicate_post_type_enabled}", 'duplicate_post_action_handler', 10, 3 );
653
+ }
654
+ }
655
+
656
+ function duplicate_post_register_bulk_action($bulk_actions) {
657
+ $bulk_actions['duplicate_post_clone'] = esc_html__( 'Clone', 'duplicate-post');
658
+ return $bulk_actions;
659
+ }
660
+
661
+ function duplicate_post_action_handler( $redirect_to, $doaction, $post_ids ) {
662
+ if ( $doaction !== 'duplicate_post_clone' ) {
663
+ return $redirect_to;
664
+ }
665
+ $counter = 0;
666
+ foreach ( $post_ids as $post_id ) {
667
+ $post = get_post($post_id);
668
+ if(!empty($post)){
669
+ if( get_option('duplicate_post_copychildren') != 1
670
+ || !is_post_type_hierarchical( $post->post_type )
671
+ || (is_post_type_hierarchical( $post->post_type ) && !duplicate_post_has_ancestors_marked($post, $post_ids))){
672
+ if(duplicate_post_create_duplicate($post)){
673
+ $counter++;
674
+ }
675
+ }
676
+ }
677
+ }
678
+ $redirect_to = add_query_arg( 'cloned', $counter, $redirect_to );
679
+ return $redirect_to;
680
+ }
681
+
682
+ function duplicate_post_has_ancestors_marked($post, $post_ids){
683
+ $ancestors_in_array = 0;
684
+ $parent = $post->ID;
685
+ while ($parent = wp_get_post_parent_id($parent)){
686
+ if(in_array($parent, $post_ids)){
687
+ $ancestors_in_array++;
688
+ }
689
+ }
690
+ return ($ancestors_in_array !== 0);
691
+ }
duplicate-post-common.php CHANGED
@@ -12,6 +12,7 @@ function duplicate_post_is_current_user_allowed_to_copy() {
12
  */
13
  function duplicate_post_is_post_type_enabled($post_type){
14
  $duplicate_post_types_enabled = get_option('duplicate_post_types_enabled', array ('post', 'page'));
 
15
  return in_array($post_type, $duplicate_post_types_enabled);
16
  }
17
 
@@ -74,10 +75,10 @@ function duplicate_post_clone_post_link( $link = null, $before = '', $after = ''
74
  return;
75
 
76
  if ( null === $link )
77
- $link = __('Copy to a new draft', 'duplicate-post');
78
 
79
  $link = '<a class="post-clone-link" href="' . $url . '" title="'
80
- . esc_attr(__("Copy to a new draft", 'duplicate-post'))
81
  .'">' . $link . '</a>';
82
  echo $before . apply_filters( 'duplicate_post_clone_post_link', $link, $post->ID ) . $after;
83
  }
@@ -99,6 +100,7 @@ function duplicate_post_get_original($id = 0 , $output = OBJECT){
99
 
100
  // Admin bar
101
  function duplicate_post_admin_bar_render() {
 
102
  global $wp_admin_bar;
103
  $current_object = get_queried_object();
104
  if ( empty($current_object) )
@@ -111,13 +113,14 @@ function duplicate_post_admin_bar_render() {
111
  {
112
  $wp_admin_bar->add_menu( array(
113
  'id' => 'new_draft',
114
- 'title' => __("Copy to a new draft", 'duplicate-post'),
115
  'href' => duplicate_post_get_clone_post_link( $current_object->ID )
116
  ) );
117
  }
118
  }
119
 
120
  function duplicate_post_add_css() {
 
121
  $current_object = get_queried_object();
122
  if ( empty($current_object) )
123
  return;
12
  */
13
  function duplicate_post_is_post_type_enabled($post_type){
14
  $duplicate_post_types_enabled = get_option('duplicate_post_types_enabled', array ('post', 'page'));
15
+ if(!is_array($duplicate_post_types_enabled)) $duplicate_post_types_enabled = array($duplicate_post_types_enabled);
16
  return in_array($post_type, $duplicate_post_types_enabled);
17
  }
18
 
75
  return;
76
 
77
  if ( null === $link )
78
+ $link = esc_html__('Copy to a new draft', 'duplicate-post');
79
 
80
  $link = '<a class="post-clone-link" href="' . $url . '" title="'
81
+ . esc_attr__("Copy to a new draft", 'duplicate-post')
82
  .'">' . $link . '</a>';
83
  echo $before . apply_filters( 'duplicate_post_clone_post_link', $link, $post->ID ) . $after;
84
  }
100
 
101
  // Admin bar
102
  function duplicate_post_admin_bar_render() {
103
+ if(!is_admin_bar_showing()) return;
104
  global $wp_admin_bar;
105
  $current_object = get_queried_object();
106
  if ( empty($current_object) )
113
  {
114
  $wp_admin_bar->add_menu( array(
115
  'id' => 'new_draft',
116
+ 'title' => esc_attr__("Copy to a new draft", 'duplicate-post'),
117
  'href' => duplicate_post_get_clone_post_link( $current_object->ID )
118
  ) );
119
  }
120
  }
121
 
122
  function duplicate_post_add_css() {
123
+ if(!is_admin_bar_showing()) return;
124
  $current_object = get_queried_object();
125
  if ( empty($current_object) )
126
  return;
duplicate-post-options.php CHANGED
@@ -18,10 +18,15 @@ function duplicate_post_register_settings() { // whitelist options
18
  register_setting( 'duplicate_post_group', 'duplicate_post_copyslug');
19
  register_setting( 'duplicate_post_group', 'duplicate_post_copyexcerpt');
20
  register_setting( 'duplicate_post_group', 'duplicate_post_copycontent');
 
 
 
 
21
  register_setting( 'duplicate_post_group', 'duplicate_post_copypassword');
22
  register_setting( 'duplicate_post_group', 'duplicate_post_copyattachments');
23
  register_setting( 'duplicate_post_group', 'duplicate_post_copychildren');
24
  register_setting( 'duplicate_post_group', 'duplicate_post_copycomments');
 
25
  register_setting( 'duplicate_post_group', 'duplicate_post_blacklist');
26
  register_setting( 'duplicate_post_group', 'duplicate_post_taxonomies_blacklist');
27
  register_setting( 'duplicate_post_group', 'duplicate_post_title_prefix');
@@ -32,6 +37,7 @@ function duplicate_post_register_settings() { // whitelist options
32
  register_setting( 'duplicate_post_group', 'duplicate_post_show_row');
33
  register_setting( 'duplicate_post_group', 'duplicate_post_show_adminbar');
34
  register_setting( 'duplicate_post_group', 'duplicate_post_show_submitbox');
 
35
  }
36
 
37
 
@@ -69,19 +75,25 @@ function duplicate_post_options() {
69
  <br>
70
  </div>
71
  <h1>
72
- <?php _e("Duplicate Post Options", 'duplicate-post'); ?>
73
  </h1>
74
-
75
  <div
76
- style="margin: 9px 15px 4px 0; padding: 5px; text-align: center; font-weight: bold; float: left;">
77
- <a href="http://lopo.it/duplicate-post-plugin"><?php _e('Visit plugin site'); ?></a>
78
- - <a href="https://translate.wordpress.org/projects/wp-plugins/duplicate-post"><?php _e('Translate', 'duplicate-post'); ?></a>
79
- - <a href="https://wordpress.org/plugins/duplicate-post/faq/"><?php _e('FAQ', 'duplicate-post'); ?></a>
80
- - <a href="http://lopo.it/duplicate-post-plugin"><?php _e('Donate', 'duplicate-post'); ?> (10¢)</a>
81
- <a href="http://lopo.it/duplicate-post-plugin"><img id="donate-button" src="<?php echo plugins_url( 'donate.png', __FILE__ ); ?>" alt="Donate"/></a>
82
-
83
-
 
 
 
 
 
84
  </div>
 
85
 
86
  <script>
87
  jQuery(document).on( 'click', '.nav-tab-wrapper a', function() {
@@ -91,12 +103,14 @@ function duplicate_post_options() {
91
  jQuery('section').eq(jQuery(this).index()).show();
92
  return false;
93
  });
94
-
95
  function toggle_private_taxonomies(){
96
- jQuery('.taxonomy_private').toggle();
97
  }
 
 
98
  jQuery(function(){
99
- jQuery('.taxonomy_private').hide();
100
  });
101
 
102
  </script>
@@ -169,11 +183,11 @@ img#donate-button{
169
 
170
  <h2 class="nav-tab-wrapper">
171
  <a class="nav-tab nav-tab-active"
172
- href="<?php echo admin_url() ?>/index.php?page=duplicate-post-what"><?php _e('What to copy', 'duplicate-post'); ?>
173
  </a> <a class="nav-tab"
174
- href="<?php echo admin_url() ?>/index.php?page=duplicate-post-who"><?php _e('Permissions', 'duplicate-post'); ?>
175
  </a> <a class="nav-tab"
176
- href="<?php echo admin_url() ?>/index.php?page=duplicate-post-where"><?php _e('Display', 'duplicate-post'); ?>
177
  </a>
178
  </h2>
179
 
@@ -181,99 +195,118 @@ img#donate-button{
181
 
182
  <table class="form-table">
183
  <tr valign="top">
184
- <th scope="row"><?php _e('Post/page elements to copy', 'duplicate-post'); ?>
185
  </th>
186
  <td colspan="2"><label> <input type="checkbox"
187
  name="duplicate_post_copytitle" value="1" <?php if(get_option('duplicate_post_copytitle') == 1) echo 'checked="checked"'; ?>"/>
188
- <?php _e("Title", 'default'); ?>
189
  </label> <label> <input type="checkbox"
190
  name="duplicate_post_copydate" value="1" <?php if(get_option('duplicate_post_copydate') == 1) echo 'checked="checked"'; ?>"/>
191
- <?php _e("Date", 'default'); ?>
192
  </label> <label> <input type="checkbox"
193
  name="duplicate_post_copystatus" value="1" <?php if(get_option('duplicate_post_copystatus') == 1) echo 'checked="checked"'; ?>"/>
194
- <?php _e("Status", 'default'); ?>
195
  </label> <label> <input type="checkbox"
196
  name="duplicate_post_copyslug" value="1" <?php if(get_option('duplicate_post_copyslug') == 1) echo 'checked="checked"'; ?>"/>
197
- <?php _e("Slug", 'default'); ?>
198
  </label> <label> <input type="checkbox"
199
  name="duplicate_post_copyexcerpt" value="1" <?php if(get_option('duplicate_post_copyexcerpt') == 1) echo 'checked="checked"'; ?>"/>
200
- <?php _e("Excerpt", 'default'); ?>
201
  </label> <label> <input type="checkbox"
202
  name="duplicate_post_copycontent" value="1" <?php if(get_option('duplicate_post_copycontent') == 1) echo 'checked="checked"'; ?>"/>
203
- <?php _e("Content", 'default'); ?>
 
 
 
 
 
 
 
 
 
 
 
 
204
  </label> <label> <input type="checkbox"
205
  name="duplicate_post_copypassword" value="1" <?php if(get_option('duplicate_post_copypassword') == 1) echo 'checked="checked"'; ?>"/>
206
- <?php _e("Password", 'default'); ?>
207
  </label> <label> <input type="checkbox"
208
  name="duplicate_post_copyattachments" value="1" <?php if(get_option('duplicate_post_copyattachments') == 1) echo 'checked="checked"'; ?>"/>
209
- <?php _e("Attachments", 'duplicate-post'); ?>
210
  </label> <label> <input type="checkbox"
211
  name="duplicate_post_copychildren" value="1" <?php if(get_option('duplicate_post_copychildren') == 1) echo 'checked="checked"'; ?>"/>
212
- <?php _e("Children", 'duplicate-post'); ?>
213
  </label> <label> <input type="checkbox"
214
  name="duplicate_post_copycomments" value="1" <?php if(get_option('duplicate_post_copycomments') == 1) echo 'checked="checked"'; ?>"/>
215
- <?php _e("Comments", 'default'); ?> (<?php _e("except pingbacks and trackbacks", 'duplicate-post'); ?>)
 
 
 
216
  </label>
217
  </td>
218
  </tr>
219
  <tr valign="top">
220
- <th scope="row"><?php _e("Title prefix", 'duplicate-post'); ?>
221
  </th>
222
  <td><input type="text" name="duplicate_post_title_prefix"
223
  value="<?php echo get_option('duplicate_post_title_prefix'); ?>" />
224
  </td>
225
- <td><span class="description"><?php _e("Prefix to be added before the title, e.g. \"Copy of\" (blank for no prefix)", 'duplicate-post'); ?>
226
  </span>
227
  </td>
228
  </tr>
229
  <tr valign="top">
230
- <th scope="row"><?php _e("Title suffix", 'duplicate-post'); ?>
231
  </th>
232
  <td><input type="text" name="duplicate_post_title_suffix"
233
  value="<?php echo get_option('duplicate_post_title_suffix'); ?>" />
234
  </td>
235
- <td><span class="description"><?php _e("Suffix to be added after the title, e.g. \"(dup)\" (blank for no suffix)", 'duplicate-post'); ?>
236
  </span>
237
  </td>
238
  </tr>
239
  <tr valign="top">
240
- <th scope="row"><?php _e("Increase menu order by", 'duplicate-post'); ?>
241
  </th>
242
  <td><input type="text" name="duplicate_post_increase_menu_order_by"
243
  value="<?php echo get_option('duplicate_post_increase_menu_order_by'); ?>" />
244
  </td>
245
- <td><span class="description"><?php _e("Add this number to the original menu order (blank or zero to retain the value)", 'duplicate-post'); ?>
246
  </span>
247
  </td>
248
  </tr>
249
  <tr valign="top">
250
- <th scope="row"><?php _e("Do not copy these fields", 'duplicate-post'); ?>
251
  </th>
252
  <td id="textfield"><input type="text"
253
  name="duplicate_post_blacklist"
254
  value="<?php echo get_option('duplicate_post_blacklist'); ?>" /></td>
255
- <td><span class="description"><?php _e("Comma-separated list of meta fields that must not be copied", 'duplicate-post'); ?><br />
256
- <small><?php _e("Add <code>_thumbnail_id</code> to prevent featured images to be copied", 'duplicate-post'); ?>
257
  </small> </span>
258
  </td>
259
  </tr>
260
  <tr valign="top">
261
- <th scope="row"><?php _e("Do not copy these taxonomies", 'duplicate-post'); ?><br />
262
  <a class="toggle_link" href="#"
263
- onclick="toggle_private_taxonomies();return false;"><?php _e('Show/hide private taxonomies', 'duplicate-post');?>
264
  </a>
265
  </th>
266
  <td colspan="2"><?php $taxonomies=get_taxonomies(array(),'objects'); usort($taxonomies, 'duplicate_post_tax_obj_cmp');
267
  $taxonomies_blacklist = get_option('duplicate_post_taxonomies_blacklist');
268
  if ($taxonomies_blacklist == "") $taxonomies_blacklist = array();
269
- foreach ($taxonomies as $taxonomy ) : ?> <label
 
 
 
 
270
  class="taxonomy_<?php echo ($taxonomy->public)?'public':'private';?>">
271
  <input type="checkbox"
272
  name="duplicate_post_taxonomies_blacklist[]"
273
  value="<?php echo $taxonomy->name?>"
274
  <?php if(in_array($taxonomy->name, $taxonomies_blacklist)) echo 'checked="checked"'?> />
275
  <?php echo $taxonomy->labels->name.' ['.$taxonomy->name.']'; ?>
276
- </label> <?php endforeach; ?> <span class="description"><?php _e("Select the taxonomies you don't want to be copied", 'duplicate-post'); ?>
277
  </span>
278
  </td>
279
  </tr>
@@ -283,7 +316,7 @@ img#donate-button{
283
  <table class="form-table">
284
  <?php if ( current_user_can( 'promote_users' ) ){ ?>
285
  <tr valign="top">
286
- <th scope="row"><?php _e("Roles allowed to copy", 'duplicate-post'); ?>
287
  </th>
288
  <td><?php global $wp_roles;
289
  $roles = $wp_roles->get_names();
@@ -293,14 +326,14 @@ img#donate-button{
293
  value="<?php echo $name ?>"
294
  <?php if($role->has_cap('copy_posts')) echo 'checked="checked"'?> />
295
  <?php echo translate_user_role($display_name); ?>
296
- </label> <?php endforeach; ?> <span class="description"><?php _e("Warning: users will be able to copy all posts, even those of other users", 'duplicate-post'); ?><br />
297
- <?php _e("Passwords and contents of password-protected posts may become visible to undesired users and visitors", 'duplicate-post'); ?>
298
  </span>
299
  </td>
300
  </tr>
301
  <?php } ?>
302
  <tr valign="top">
303
- <th scope="row"><?php _e("Enable for these post types", 'duplicate-post'); ?>
304
  </th>
305
  <td><?php $post_types = get_post_types(array('show_ui' => true),'objects');
306
  foreach ($post_types as $post_type_object ) :
@@ -309,8 +342,8 @@ img#donate-button{
309
  value="<?php echo $post_type_object->name?>"
310
  <?php if(duplicate_post_is_post_type_enabled($post_type_object->name)) echo 'checked="checked"'?> />
311
  <?php echo $post_type_object->labels->name?>
312
- </label> <?php endforeach; ?> <span class="description"><?php _e("Select the post types you want the plugin to be enabled", 'duplicate-post'); ?>
313
- <br /> <?php _e("Whether the links are displayed for custom post types registered by themes or plugins depends on their use of standard WordPress UI elements", 'duplicate-post'); ?>
314
  </span>
315
  </td>
316
  </tr>
@@ -319,19 +352,24 @@ img#donate-button{
319
  <section>
320
  <table class="form-table">
321
  <tr valign="top">
322
- <th scope="row"><?php _e("Show links in", 'duplicate-post'); ?>
323
  </th>
324
  <td><label><input type="checkbox" name="duplicate_post_show_row"
325
  value="1" <?php if(get_option('duplicate_post_show_row') == 1) echo 'checked="checked"'; ?>"/>
326
- <?php _e("Post list", 'duplicate-post'); ?> </label> <label><input
327
- type="checkbox" name="duplicate_post_show_submitbox" value="1" <?php if(get_option('duplicate_post_show_submitbox') == 1) echo 'checked="checked"'; ?>"/>
328
- <?php _e("Edit screen", 'duplicate-post'); ?> </label> <label><input
329
- type="checkbox" name="duplicate_post_show_adminbar" value="1" <?php if(get_option('duplicate_post_show_adminbar') == 1) echo 'checked="checked"'; ?>"/>
330
- <?php _e("Admin bar", 'duplicate-post'); ?> </label>
 
 
 
 
 
331
  </td>
332
  </tr>
333
  <tr valign="top">
334
- <td colspan="2"><span class="description"><?php _e("Whether the links are displayed for custom post types registered by themes or plugins depends on their use of standard WordPress UI elements", 'duplicate-post'); ?>
335
  <br /> <?php printf(__('You can also use the template tag duplicate_post_clone_post_link( $link, $before, $after, $id ). More info <a href="%s">here</a>', 'duplicate-post'), 'https://wordpress.org/plugins/duplicate-post/other_notes/'); ?>
336
  </span>
337
  </td>
@@ -340,7 +378,7 @@ img#donate-button{
340
  </section>
341
  <p class="submit">
342
  <input type="submit" class="button-primary"
343
- value="<?php _e('Save Changes', 'duplicate-post') ?>" />
344
  </p>
345
 
346
  </form>
18
  register_setting( 'duplicate_post_group', 'duplicate_post_copyslug');
19
  register_setting( 'duplicate_post_group', 'duplicate_post_copyexcerpt');
20
  register_setting( 'duplicate_post_group', 'duplicate_post_copycontent');
21
+ register_setting( 'duplicate_post_group', 'duplicate_post_copythumbnail');
22
+ register_setting( 'duplicate_post_group', 'duplicate_post_copytemplate');
23
+ register_setting( 'duplicate_post_group', 'duplicate_post_copyformat');
24
+ register_setting( 'duplicate_post_group', 'duplicate_post_copyauthor');
25
  register_setting( 'duplicate_post_group', 'duplicate_post_copypassword');
26
  register_setting( 'duplicate_post_group', 'duplicate_post_copyattachments');
27
  register_setting( 'duplicate_post_group', 'duplicate_post_copychildren');
28
  register_setting( 'duplicate_post_group', 'duplicate_post_copycomments');
29
+ register_setting( 'duplicate_post_group', 'duplicate_post_copymenuorder');
30
  register_setting( 'duplicate_post_group', 'duplicate_post_blacklist');
31
  register_setting( 'duplicate_post_group', 'duplicate_post_taxonomies_blacklist');
32
  register_setting( 'duplicate_post_group', 'duplicate_post_title_prefix');
37
  register_setting( 'duplicate_post_group', 'duplicate_post_show_row');
38
  register_setting( 'duplicate_post_group', 'duplicate_post_show_adminbar');
39
  register_setting( 'duplicate_post_group', 'duplicate_post_show_submitbox');
40
+ register_setting( 'duplicate_post_group', 'duplicate_post_show_bulkactions');
41
  }
42
 
43
 
75
  <br>
76
  </div>
77
  <h1>
78
+ <?php esc_html_e("Duplicate Post Options", 'duplicate-post'); ?>
79
  </h1>
80
+
81
  <div
82
+ style="margin: 9px 15px 4px 0; padding: 5px 30px; text-align: center; float: left; clear:left; border: solid 3px #cccccc; width: 600px;">
83
+ <p>
84
+ <?php esc_html_e('Help me develop the plugin, add new features and improve support!', 'duplicate-post'); ?>
85
+ <br/>
86
+ <?php esc_html_e('Donate whatever sum you choose, even just 10¢.', 'duplicate-post'); ?>
87
+ <br/>
88
+ <a href="http://lopo.it/duplicate-post-plugin"><img id="donate-button" style="margin: 0px auto;" src="<?php echo plugins_url( 'donate.png', __FILE__ ); ?>" alt="Donate"/></a>
89
+ <br/>
90
+ <a href="http://lopo.it/duplicate-post-plugin"><?php esc_html_e('Visit plugin site'); ?></a>
91
+ - <a href="https://translate.wordpress.org/projects/wp-plugins/duplicate-post"><?php esc_html_e('Translate', 'duplicate-post'); ?></a>
92
+ - <a href="https://wordpress.org/plugins/duplicate-post/faq/"><?php esc_html_e('FAQ', 'duplicate-post'); ?></a>
93
+ - <a href="https://wordpress.org/support/plugin/duplicate-post"><?php esc_html_e('Support Forum', 'duplicate-post'); ?></a>
94
+ </p>
95
  </div>
96
+
97
 
98
  <script>
99
  jQuery(document).on( 'click', '.nav-tab-wrapper a', function() {
103
  jQuery('section').eq(jQuery(this).index()).show();
104
  return false;
105
  });
106
+
107
  function toggle_private_taxonomies(){
108
+ jQuery('.taxonomy_private').toggle(300);
109
  }
110
+
111
+
112
  jQuery(function(){
113
+ jQuery('.taxonomy_private').hide(300);
114
  });
115
 
116
  </script>
183
 
184
  <h2 class="nav-tab-wrapper">
185
  <a class="nav-tab nav-tab-active"
186
+ href="<?php echo admin_url() ?>/index.php?page=duplicate-post-what"><?php esc_html_e('What to copy', 'duplicate-post'); ?>
187
  </a> <a class="nav-tab"
188
+ href="<?php echo admin_url() ?>/index.php?page=duplicate-post-who"><?php esc_html_e('Permissions', 'duplicate-post'); ?>
189
  </a> <a class="nav-tab"
190
+ href="<?php echo admin_url() ?>/index.php?page=duplicate-post-where"><?php esc_html_e('Display', 'duplicate-post'); ?>
191
  </a>
192
  </h2>
193
 
195
 
196
  <table class="form-table">
197
  <tr valign="top">
198
+ <th scope="row"><?php esc_html_e('Post/page elements to copy', 'duplicate-post'); ?>
199
  </th>
200
  <td colspan="2"><label> <input type="checkbox"
201
  name="duplicate_post_copytitle" value="1" <?php if(get_option('duplicate_post_copytitle') == 1) echo 'checked="checked"'; ?>"/>
202
+ <?php esc_html_e("Title", 'default'); ?>
203
  </label> <label> <input type="checkbox"
204
  name="duplicate_post_copydate" value="1" <?php if(get_option('duplicate_post_copydate') == 1) echo 'checked="checked"'; ?>"/>
205
+ <?php esc_html_e("Date", 'default'); ?>
206
  </label> <label> <input type="checkbox"
207
  name="duplicate_post_copystatus" value="1" <?php if(get_option('duplicate_post_copystatus') == 1) echo 'checked="checked"'; ?>"/>
208
+ <?php esc_html_e("Status", 'default'); ?>
209
  </label> <label> <input type="checkbox"
210
  name="duplicate_post_copyslug" value="1" <?php if(get_option('duplicate_post_copyslug') == 1) echo 'checked="checked"'; ?>"/>
211
+ <?php esc_html_e("Slug", 'default'); ?>
212
  </label> <label> <input type="checkbox"
213
  name="duplicate_post_copyexcerpt" value="1" <?php if(get_option('duplicate_post_copyexcerpt') == 1) echo 'checked="checked"'; ?>"/>
214
+ <?php esc_html_e("Excerpt", 'default'); ?>
215
  </label> <label> <input type="checkbox"
216
  name="duplicate_post_copycontent" value="1" <?php if(get_option('duplicate_post_copycontent') == 1) echo 'checked="checked"'; ?>"/>
217
+ <?php esc_html_e("Content", 'default'); ?>
218
+ </label> <label> <input type="checkbox"
219
+ name="duplicate_post_copythumbnail" value="1" <?php if(get_option('duplicate_post_copythumbnail') == 1) echo 'checked="checked"'; ?>"/>
220
+ <?php esc_html_e("Featured Image", 'default'); ?>
221
+ </label> <label> <input type="checkbox"
222
+ name="duplicate_post_copytemplate" value="1" <?php if(get_option('duplicate_post_copytemplate') == 1) echo 'checked="checked"'; ?>"/>
223
+ <?php esc_html_e("Template", 'default'); ?>
224
+ </label> <label> <input type="checkbox"
225
+ name="duplicate_post_copyformat" value="1" <?php if(get_option('duplicate_post_copyformat') == 1) echo 'checked="checked"'; ?>"/>
226
+ <?php echo esc_html_x("Format", 'post format', 'default'); ?>
227
+ </label> <label> <input type="checkbox"
228
+ name="duplicate_post_copyauthor" value="1" <?php if(get_option('duplicate_post_copyauthor') == 1) echo 'checked="checked"'; ?>"/>
229
+ <?php esc_html_e("Author", 'default'); ?>
230
  </label> <label> <input type="checkbox"
231
  name="duplicate_post_copypassword" value="1" <?php if(get_option('duplicate_post_copypassword') == 1) echo 'checked="checked"'; ?>"/>
232
+ <?php esc_html_e("Password", 'default'); ?>
233
  </label> <label> <input type="checkbox"
234
  name="duplicate_post_copyattachments" value="1" <?php if(get_option('duplicate_post_copyattachments') == 1) echo 'checked="checked"'; ?>"/>
235
+ <?php esc_html_e("Attachments", 'duplicate-post'); ?>
236
  </label> <label> <input type="checkbox"
237
  name="duplicate_post_copychildren" value="1" <?php if(get_option('duplicate_post_copychildren') == 1) echo 'checked="checked"'; ?>"/>
238
+ <?php esc_html_e("Children", 'duplicate-post'); ?>
239
  </label> <label> <input type="checkbox"
240
  name="duplicate_post_copycomments" value="1" <?php if(get_option('duplicate_post_copycomments') == 1) echo 'checked="checked"'; ?>"/>
241
+ <?php esc_html_e("Comments", 'default'); ?> (<?php esc_html_e("except pingbacks and trackbacks", 'duplicate-post'); ?>)
242
+ </label> <label> <input type="checkbox"
243
+ name="duplicate_post_copymenuorder" value="1" <?php if(get_option('duplicate_post_copymenuorder') == 1) echo 'checked="checked"'; ?>"/>
244
+ <?php esc_html_e("Menu order", 'default'); ?>
245
  </label>
246
  </td>
247
  </tr>
248
  <tr valign="top">
249
+ <th scope="row"><?php esc_html_e("Title prefix", 'duplicate-post'); ?>
250
  </th>
251
  <td><input type="text" name="duplicate_post_title_prefix"
252
  value="<?php echo get_option('duplicate_post_title_prefix'); ?>" />
253
  </td>
254
+ <td><span class="description"><?php esc_html_e("Prefix to be added before the title, e.g. \"Copy of\" (blank for no prefix)", 'duplicate-post'); ?>
255
  </span>
256
  </td>
257
  </tr>
258
  <tr valign="top">
259
+ <th scope="row"><?php esc_html_e("Title suffix", 'duplicate-post'); ?>
260
  </th>
261
  <td><input type="text" name="duplicate_post_title_suffix"
262
  value="<?php echo get_option('duplicate_post_title_suffix'); ?>" />
263
  </td>
264
+ <td><span class="description"><?php esc_html_e("Suffix to be added after the title, e.g. \"(dup)\" (blank for no suffix)", 'duplicate-post'); ?>
265
  </span>
266
  </td>
267
  </tr>
268
  <tr valign="top">
269
+ <th scope="row"><?php esc_html_e("Increase menu order by", 'duplicate-post'); ?>
270
  </th>
271
  <td><input type="text" name="duplicate_post_increase_menu_order_by"
272
  value="<?php echo get_option('duplicate_post_increase_menu_order_by'); ?>" />
273
  </td>
274
+ <td><span class="description"><?php esc_html_e("Add this number to the original menu order (blank or zero to retain the value)", 'duplicate-post'); ?>
275
  </span>
276
  </td>
277
  </tr>
278
  <tr valign="top">
279
+ <th scope="row"><?php esc_html_e("Do not copy these fields", 'duplicate-post'); ?>
280
  </th>
281
  <td id="textfield"><input type="text"
282
  name="duplicate_post_blacklist"
283
  value="<?php echo get_option('duplicate_post_blacklist'); ?>" /></td>
284
+ <td><span class="description"><?php esc_html_e("Comma-separated list of meta fields that must not be copied", 'duplicate-post'); ?><br />
285
+ <small><?php esc_html_e("You can use * to match zero or more alphanumeric characters or underscores: e.g. field*", 'duplicate-post'); ?>
286
  </small> </span>
287
  </td>
288
  </tr>
289
  <tr valign="top">
290
+ <th scope="row"><?php esc_html_e("Do not copy these taxonomies", 'duplicate-post'); ?><br />
291
  <a class="toggle_link" href="#"
292
+ onclick="toggle_private_taxonomies();return false;"><?php esc_html_e('Show/hide private taxonomies', 'duplicate-post');?>
293
  </a>
294
  </th>
295
  <td colspan="2"><?php $taxonomies=get_taxonomies(array(),'objects'); usort($taxonomies, 'duplicate_post_tax_obj_cmp');
296
  $taxonomies_blacklist = get_option('duplicate_post_taxonomies_blacklist');
297
  if ($taxonomies_blacklist == "") $taxonomies_blacklist = array();
298
+ foreach ($taxonomies as $taxonomy ) :
299
+ if($taxonomy->name == 'post_format'){
300
+ continue;
301
+ }
302
+ ?> <label
303
  class="taxonomy_<?php echo ($taxonomy->public)?'public':'private';?>">
304
  <input type="checkbox"
305
  name="duplicate_post_taxonomies_blacklist[]"
306
  value="<?php echo $taxonomy->name?>"
307
  <?php if(in_array($taxonomy->name, $taxonomies_blacklist)) echo 'checked="checked"'?> />
308
  <?php echo $taxonomy->labels->name.' ['.$taxonomy->name.']'; ?>
309
+ </label> <?php endforeach; ?> <span class="description"><?php esc_html_e("Select the taxonomies you don't want to be copied", 'duplicate-post'); ?>
310
  </span>
311
  </td>
312
  </tr>
316
  <table class="form-table">
317
  <?php if ( current_user_can( 'promote_users' ) ){ ?>
318
  <tr valign="top">
319
+ <th scope="row"><?php esc_html_e("Roles allowed to copy", 'duplicate-post'); ?>
320
  </th>
321
  <td><?php global $wp_roles;
322
  $roles = $wp_roles->get_names();
326
  value="<?php echo $name ?>"
327
  <?php if($role->has_cap('copy_posts')) echo 'checked="checked"'?> />
328
  <?php echo translate_user_role($display_name); ?>
329
+ </label> <?php endforeach; ?> <span class="description"><?php esc_html_e("Warning: users will be able to copy all posts, even those of other users", 'duplicate-post'); ?><br />
330
+ <?php esc_html_e("Passwords and contents of password-protected posts may become visible to undesired users and visitors", 'duplicate-post'); ?>
331
  </span>
332
  </td>
333
  </tr>
334
  <?php } ?>
335
  <tr valign="top">
336
+ <th scope="row"><?php esc_html_e("Enable for these post types", 'duplicate-post'); ?>
337
  </th>
338
  <td><?php $post_types = get_post_types(array('show_ui' => true),'objects');
339
  foreach ($post_types as $post_type_object ) :
342
  value="<?php echo $post_type_object->name?>"
343
  <?php if(duplicate_post_is_post_type_enabled($post_type_object->name)) echo 'checked="checked"'?> />
344
  <?php echo $post_type_object->labels->name?>
345
+ </label> <?php endforeach; ?> <span class="description"><?php esc_html_e("Select the post types you want the plugin to be enabled", 'duplicate-post'); ?>
346
+ <br /> <?php esc_html_e("Whether the links are displayed for custom post types registered by themes or plugins depends on their use of standard WordPress UI elements", 'duplicate-post'); ?>
347
  </span>
348
  </td>
349
  </tr>
352
  <section>
353
  <table class="form-table">
354
  <tr valign="top">
355
+ <th scope="row"><?php esc_html_e("Show links in", 'duplicate-post'); ?>
356
  </th>
357
  <td><label><input type="checkbox" name="duplicate_post_show_row"
358
  value="1" <?php if(get_option('duplicate_post_show_row') == 1) echo 'checked="checked"'; ?>"/>
359
+ <?php esc_html_e("Post list", 'duplicate-post'); ?> </label>
360
+ <label><input type="checkbox" name="duplicate_post_show_submitbox" value="1" <?php if(get_option('duplicate_post_show_submitbox') == 1) echo 'checked="checked"'; ?>"/>
361
+ <?php esc_html_e("Edit screen", 'duplicate-post'); ?> </label>
362
+ <label><input type="checkbox" name="duplicate_post_show_adminbar" value="1" <?php if(get_option('duplicate_post_show_adminbar') == 1) echo 'checked="checked"'; ?>"/>
363
+ <?php esc_html_e("Admin bar", 'duplicate-post'); ?> </label>
364
+ <?php global $wp_version;
365
+ if( version_compare($wp_version, '4.7') >= 0 ){ ?>
366
+ <label><input type="checkbox" name="duplicate_post_show_bulkactions" value="1" <?php if(get_option('duplicate_post_show_bulkactions') == 1) echo 'checked="checked"'; ?>"/>
367
+ <?php esc_html_e("Bulk Actions", 'default'); ?> </label>
368
+ <?php } ?>
369
  </td>
370
  </tr>
371
  <tr valign="top">
372
+ <td colspan="2"><span class="description"><?php esc_html_e("Whether the links are displayed for custom post types registered by themes or plugins depends on their use of standard WordPress UI elements", 'duplicate-post'); ?>
373
  <br /> <?php printf(__('You can also use the template tag duplicate_post_clone_post_link( $link, $before, $after, $id ). More info <a href="%s">here</a>', 'duplicate-post'), 'https://wordpress.org/plugins/duplicate-post/other_notes/'); ?>
374
  </span>
375
  </td>
378
  </section>
379
  <p class="submit">
380
  <input type="submit" class="button-primary"
381
+ value="<?php esc_html_e('Save Changes', 'duplicate-post') ?>" />
382
  </p>
383
 
384
  </form>
duplicate-post.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Duplicate Post
4
  Plugin URI: http://lopo.it/duplicate-post-plugin/
5
  Description: Clone posts and pages.
6
- Version: 3.0.3
7
  Author: Enrico Battocchi
8
  Author URI: http://lopo.it
9
  Text Domain: duplicate-post
@@ -31,7 +31,7 @@ if ( ! defined( 'ABSPATH' ) ) {
31
  }
32
 
33
  // Version of the plugin
34
- define('DUPLICATE_POST_CURRENT_VERSION', '3.0.3' );
35
 
36
 
37
  /**
@@ -46,7 +46,7 @@ add_action( 'plugins_loaded', 'duplicate_post_load_plugin_textdomain' );
46
  add_filter("plugin_action_links_".plugin_basename(__FILE__), "duplicate_post_plugin_actions", 10, 4);
47
 
48
  function duplicate_post_plugin_actions( $actions, $plugin_file, $plugin_data, $context ) {
49
- array_unshift($actions, "<a href=\"".menu_page_url('duplicatepost', false)."\">".__("Settings")."</a>");
50
  return $actions;
51
  }
52
 
3
  Plugin Name: Duplicate Post
4
  Plugin URI: http://lopo.it/duplicate-post-plugin/
5
  Description: Clone posts and pages.
6
+ Version: 3.1
7
  Author: Enrico Battocchi
8
  Author URI: http://lopo.it
9
  Text Domain: duplicate-post
31
  }
32
 
33
  // Version of the plugin
34
+ define('DUPLICATE_POST_CURRENT_VERSION', '3.1' );
35
 
36
 
37
  /**
46
  add_filter("plugin_action_links_".plugin_basename(__FILE__), "duplicate_post_plugin_actions", 10, 4);
47
 
48
  function duplicate_post_plugin_actions( $actions, $plugin_file, $plugin_data, $context ) {
49
+ array_unshift($actions, "<a href=\"".menu_page_url('duplicatepost', false)."\">".esc_html__("Settings")."</a>");
50
  return $actions;
51
  }
52
 
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: lopo
3
  Donate link: http://lopo.it/duplicate-post-plugin/
4
  Tags: duplicate post, copy, clone
5
- Requires at least: 3.4
6
  Tested up to: 4.7
7
- Stable tag: 3.0.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -20,13 +20,15 @@ How it works:
20
 
21
  1. In 'Edit Posts'/'Edit Pages', you can click on 'Clone' link below the post/page title: this will immediately create a copy and return to the list.
22
 
23
- 2. In 'Edit Posts'/'Edit Pages', you can click on 'New Draft' link below the post/page title.
24
 
25
- 3. On the post edit screen, you can click on 'Copy to a new draft' above "Cancel"/"Move to trash".
26
 
27
- 4. While viewing a post as a logged in user, you can click on 'Copy to a new draft' as a dropdown link under "Edit Post" in the admin bar.
28
 
29
- 2, 3 and 4 will lead to the edit page for the new draft: change what you want, click on 'Publish' and you're done.
 
 
30
 
31
  There is also a **template tag**, so you can put it in your templates and clone your posts/pages from the front-end. Clicking on the link will lead you to the edit page for the new draft, just like the admin bar link.
32
 
@@ -74,12 +76,6 @@ From version 3.0 the plugin's translations are managed by the WordPress.org plat
74
  If Duplicate Post is still in English, or if there are some untraslated strings, you can help traslating to your language [here](https://translate.wordpress.org/projects/wp-plugins/duplicate-post): you only need a WordPress.org account.
75
  [Contact me](http://lopo.it/contatti/) if you wish to become an editor for your language.
76
 
77
- = Can you add it to the bulk actions in the post/page list? =
78
-
79
- I can't. There is no way to do it without hacking the core code of WordPress.
80
- There is an open ticket in WordPress Trac, as other plugin developers too are interested to this feature: we can only hope that eventually our wish will be fulfilled.
81
-
82
-
83
  == Screenshots ==
84
 
85
  1. Here you can copy the post you're editing to a new draft.
@@ -87,9 +83,13 @@ There is an open ticket in WordPress Trac, as other plugin developers too are in
87
  3. The options page.
88
  4. The template tag manually added to Twenty Ten theme. Click on the "Copy to a new draft" link and you're redirected to the edit screen for a new draft copy of your post.
89
  5. The admin bar link.
 
90
 
91
  == Upgrade Notice ==
92
 
 
 
 
93
  = 3.0.3 =
94
  Notices + small fixes and improvements
95
 
@@ -140,6 +140,16 @@ New features and customization, WP 3.0 compatibility: you should upgrade if you
140
 
141
  == Changelog ==
142
 
 
 
 
 
 
 
 
 
 
 
143
  = 3.0.3 =
144
  * Notices in admin after copying
145
  * Fixes warning in custom post type archives
2
  Contributors: lopo
3
  Donate link: http://lopo.it/duplicate-post-plugin/
4
  Tags: duplicate post, copy, clone
5
+ Requires at least: 3.6
6
  Tested up to: 4.7
7
+ Stable tag: 3.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
20
 
21
  1. In 'Edit Posts'/'Edit Pages', you can click on 'Clone' link below the post/page title: this will immediately create a copy and return to the list.
22
 
23
+ 2. NEW! In 'Edit Posts'/'Edit Pages', you can select one or more items, then choose 'Clone' in the 'Bulk Actions' dropdown to copy them all at once.
24
 
25
+ 3. In 'Edit Posts'/'Edit Pages', you can click on 'New Draft' link below the post/page title.
26
 
27
+ 4. On the post edit screen, you can click on 'Copy to a new draft' above "Cancel"/"Move to trash".
28
 
29
+ 5. While viewing a post as a logged in user, you can click on 'Copy to a new draft' as a dropdown link under "Edit Post" in the admin bar.
30
+
31
+ 3, 4 and 5 will lead to the edit page for the new draft: change what you want, click on 'Publish' and you're done.
32
 
33
  There is also a **template tag**, so you can put it in your templates and clone your posts/pages from the front-end. Clicking on the link will lead you to the edit page for the new draft, just like the admin bar link.
34
 
76
  If Duplicate Post is still in English, or if there are some untraslated strings, you can help traslating to your language [here](https://translate.wordpress.org/projects/wp-plugins/duplicate-post): you only need a WordPress.org account.
77
  [Contact me](http://lopo.it/contatti/) if you wish to become an editor for your language.
78
 
 
 
 
 
 
 
79
  == Screenshots ==
80
 
81
  1. Here you can copy the post you're editing to a new draft.
83
  3. The options page.
84
  4. The template tag manually added to Twenty Ten theme. Click on the "Copy to a new draft" link and you're redirected to the edit screen for a new draft copy of your post.
85
  5. The admin bar link.
86
+ 6. Bulk clone action.
87
 
88
  == Upgrade Notice ==
89
 
90
+ = 3.1 =
91
+ Bulk clone + custom field wildcards + other features + bugfixes
92
+
93
  = 3.0.3 =
94
  Notices + small fixes and improvements
95
 
140
 
141
  == Changelog ==
142
 
143
+ = 3.1 =
144
+ * Bulk clone action added (WP 4.7+)
145
+ * Wildcards enabled for custom fields to skip
146
+ * Options to copy post author, post format (moved from taxonomies), menu order, post template
147
+ * Check publish_posts/publish_pages capability to prevent Contributors from publishing by cloning
148
+ * Using wp_slash (WP 3.6+) or a better workaround (WP 4.4+) on the post and its meta, should also fix some compatibility issues
149
+ * Check if admin bar is showing before enqueueing CSS
150
+ * Probable fix for repeated clone bug
151
+ * Other minor bugs fixed
152
+
153
  = 3.0.3 =
154
  * Notices in admin after copying
155
  * Fixes warning in custom post type archives