Duplicate Post - Version 1.1.1

Version Description

Some users have experienced a fatal error when upgrading to v1.1: this may fix it, if it's caused by a plugin conflict.

Download this release

Release Info

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

Code changes from version 1.1 to 1.1.1

duplicate-post-admin.php ADDED
@@ -0,0 +1,562 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Added by WarmStal
3
+ if(!is_admin())
4
+ return;
5
+
6
+ /*
7
+ * This function calls the creation of a new copy of the selected post (as a draft)
8
+ * then redirects to the edit post screen
9
+ */
10
+ function duplicate_post_save_as_new_post(){
11
+ if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_post' == $_REQUEST['action'] ) ) ) {
12
+ wp_die(__('No post to duplicate has been supplied!', DUPLICATE_POST_I18N_DOMAIN));
13
+ }
14
+
15
+ // Get the original post
16
+ $id = (isset($_GET['post']) ? $_GET['post'] : $_POST['post']);
17
+ $post = duplicate_post_get_post($id);
18
+
19
+ // Copy the post and insert it
20
+ if (isset($post) && $post!=null) {
21
+ $new_id = duplicate_post_create_duplicate_from_post($post);
22
+
23
+ // If you have written a plugin which uses non-WP database tables to save
24
+ // information about a post you can hook this action to dupe that data.
25
+ do_action( 'dp_duplicate_post', $new_id, $post );
26
+
27
+ // Redirect to the edit screen for the new draft post
28
+ wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
29
+ exit;
30
+ } else {
31
+ wp_die(__('Post creation failed, could not find original post:', DUPLICATE_POST_I18N_DOMAIN) . ' ' . $id);
32
+ }
33
+ }
34
+
35
+ /*
36
+ * Same as above, for pages
37
+ */
38
+ function duplicate_post_save_as_new_page(){
39
+ if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_page' == $_REQUEST['action'] ) ) ) {
40
+ wp_die(__('No page to duplicate has been supplied!', DUPLICATE_POST_I18N_DOMAIN));
41
+ }
42
+
43
+ // Get the original page
44
+ $id = (isset($_GET['post']) ? $_GET['post'] : $_POST['post']);
45
+ $post = duplicate_post_get_page($id);
46
+
47
+ // Copy the page and insert it
48
+ if (isset($post) && $post!=null) {
49
+ $new_id = duplicate_post_create_duplicate_from_page($post);
50
+
51
+ // If you have written a plugin which uses non-WP database tables to save
52
+ // information about a page you can hook this action to dupe that data.
53
+ do_action( 'dp_duplicate_page', $new_id, $post );
54
+
55
+ // Redirect to the edit screen for the new draft page
56
+ wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
57
+ exit;
58
+ } else {
59
+ wp_die(__('Post creation failed, could not find original post:', DUPLICATE_POST_I18N_DOMAIN) . ' ' . $id);
60
+ }
61
+ }
62
+
63
+ // Version of the plugin
64
+ define('DUPLICATE_POST_CURRENT_VERSION', '1.1' );
65
+ define('DUPLICATE_POST_COLUMN', 'control_duplicate_post');
66
+
67
+ // i18n plugin domain
68
+ define('DUPLICATE_POST_I18N_DOMAIN', 'duplicate-post');
69
+
70
+ /**
71
+ * Initialise the internationalisation domain
72
+ */
73
+ load_plugin_textdomain(DUPLICATE_POST_I18N_DOMAIN,
74
+ 'wp-content/plugins/duplicate-post/languages','duplicate-post/languages');
75
+
76
+ /**
77
+ * Plugin activation
78
+ */
79
+ add_action('activate_duplicate-post/duplicate-post.php','duplicate_post_plugin_activation');
80
+
81
+ function duplicate_post_plugin_activation() {
82
+ $installed_version = duplicate_post_get_installed_version();
83
+
84
+ if ( $installed_version==duplicate_post_get_current_version() ) {
85
+ // do nothing
86
+ } else {
87
+ // delete old, obsolete options
88
+ delete_option('duplicate_post_admin_user_level');
89
+ delete_option('duplicate_post_create_user_level');
90
+ delete_option('duplicate_post_view_user_level');
91
+ // Add all options, nothing already installed
92
+ add_option(
93
+ 'duplicate_post_copy_user_level',
94
+ '5',
95
+ 'Default user level to copy posts' );
96
+ }
97
+ // Update version number
98
+ update_option( 'duplicate_post_version', duplicate_post_get_current_version() );
99
+ }
100
+
101
+ /**
102
+ * Check if WP version < 2.8: if so, post_row_actions does not exist, so we must add a custom column (the old way)
103
+ */
104
+ global $wp_version;
105
+ if (strncmp($wp_version, "2.7",3) == 0 ){
106
+ add_filter('manage_posts_columns', 'duplicate_post_add_duplicate_post_column');
107
+ // Added by WarmStal
108
+ add_filter('manage_pages_columns', 'duplicate_post_add_duplicate_post_column');
109
+ add_action('manage_posts_custom_column', 'duplicate_post_make_duplicate_link', 10, 2);
110
+ // Added by WarmStal
111
+ add_action('manage_pages_custom_column', 'duplicate_page_make_duplicate_link', 10, 2);
112
+ } else {
113
+ /**
114
+ * Add to the links shown when the mouse gets over a post title in 'Edit Posts' or 'Edit Pages' screen
115
+ */
116
+ add_filter('post_row_actions', 'duplicate_post_make_duplicate_link_row',10,2);
117
+ add_filter('page_row_actions', 'duplicate_page_make_duplicate_link_row',10,2);
118
+ }
119
+
120
+ /**
121
+ * WP version < 2.8: add a custom column
122
+ */
123
+ function duplicate_post_add_duplicate_post_column($columns) {
124
+ if (duplicate_post_is_current_user_allowed_to_copy()) {
125
+ $columns[DUPLICATE_POST_COLUMN] = '';
126
+ }
127
+ return $columns;
128
+ }
129
+
130
+ /**
131
+ * WP version < 2.8: add link to custom column for posts
132
+ */
133
+ function duplicate_post_make_duplicate_link($column_name, $id) {
134
+ if (duplicate_post_is_current_user_allowed_to_copy()) {
135
+ if ($column_name == DUPLICATE_POST_COLUMN) {
136
+ echo "<a href='admin.php?action=duplicate_post_save_as_new_post&amp;post=" . $id
137
+ . "' title='" . __("Make a duplicate from this post", DUPLICATE_POST_I18N_DOMAIN)
138
+ . "' class='edit'>" . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . "</a>";
139
+ }
140
+ }
141
+ }
142
+
143
+ /**
144
+ * WP version < 2.8: add link to custom column for pages
145
+ */
146
+ // Added by WarmStal
147
+ function duplicate_page_make_duplicate_link($column_name, $id) {
148
+ if (duplicate_post_is_current_user_allowed_to_copy()) {
149
+ if ($column_name == DUPLICATE_POST_COLUMN) {
150
+ echo "<a href='admin.php?action=duplicate_post_save_as_new_page&amp;post=" . $id
151
+ . "' title='" . __("Make a duplicate from this page", DUPLICATE_POST_I18N_DOMAIN)
152
+ . "' class='edit'>" . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . "</a>";
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Connect actions to functions
159
+ */
160
+ add_action('admin_action_duplicate_post_save_as_new_post', 'duplicate_post_save_as_new_post');
161
+ add_action('admin_action_duplicate_post_save_as_new_page', 'duplicate_post_save_as_new_page');
162
+
163
+ /**
164
+ * Add the link to action list for post_row_actions
165
+ */
166
+ function duplicate_post_make_duplicate_link_row($actions, $post) {
167
+ if (duplicate_post_is_current_user_allowed_to_copy()) {
168
+ $actions['duplicate'] = '<a href="admin.php?action=duplicate_post_save_as_new_post&amp;post=' . $post->ID . '" title="' . __("Make a duplicate from this post", DUPLICATE_POST_I18N_DOMAIN)
169
+ . '" rel="permalink">' . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . '</a>';
170
+ }
171
+ return $actions;
172
+ }
173
+
174
+ /**
175
+ * Add the link to action list for page_row_actions
176
+ */
177
+ function duplicate_page_make_duplicate_link_row($actions, $page) {
178
+ if (duplicate_post_is_current_user_allowed_to_copy()) {
179
+ $actions['duplicate'] = '<a href="admin.php?action=duplicate_post_save_as_new_page&amp;post=' . $page->ID . '" title="' . __("Make a duplicate from this page", DUPLICATE_POST_I18N_DOMAIN)
180
+ . '" rel="permalink">' . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . '</a>';
181
+ }
182
+ return $actions;
183
+ }
184
+
185
+ /**
186
+ * Add a button in the post/page edit screen to create a clone
187
+ */
188
+ add_action( 'post_submitbox_start', 'duplicate_post_add_duplicate_post_button' );
189
+
190
+ function duplicate_post_add_duplicate_post_button() {
191
+ if ( isset( $_GET['post'] ) && duplicate_post_is_current_user_allowed_to_copy()) {
192
+ $act = "admin.php?action=duplicate_post_save_as_new_post";
193
+ global $post;
194
+ if ($post->post_type == "page") $act = "admin.php?action=duplicate_post_save_as_new_page";
195
+ $notifyUrl = $act."&post=" . $_GET['post'];
196
+ ?>
197
+ <div id="duplicate-action"><a class="submitduplicate duplication"
198
+ href="<?php echo $notifyUrl; ?>"><?php _e('Copy to a new draft', DUPLICATE_POST_I18N_DOMAIN); ?></a>
199
+ </div>
200
+ <?php
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Wrapper for the option 'duplicate_post_create_user_level'
206
+ */
207
+ function duplicate_post_get_copy_user_level() {
208
+ return get_option( 'duplicate_post_copy_user_level' );
209
+ }
210
+
211
+ /**
212
+ * Wrapper for the option 'duplicate_post_create_user_level'
213
+ */
214
+ function duplicate_post_set_copy_user_level($new_level) {
215
+ return update_option( 'duplicate_post_copy_user_level', $new_level );
216
+ }
217
+
218
+ /**
219
+ * Wrapper for the option 'duplicate_post_version'
220
+ */
221
+ function duplicate_post_get_installed_version() {
222
+ return get_option( 'duplicate_post_version' );
223
+ }
224
+
225
+ /**
226
+ * Wrapper for the defined constant DUPLICATE_POST_CURRENT_VERSION
227
+ */
228
+ function duplicate_post_get_current_version() {
229
+ return DUPLICATE_POST_CURRENT_VERSION;
230
+ }
231
+
232
+ /**
233
+ * Test if the user is allowed to create templates
234
+ */
235
+ function duplicate_post_is_current_user_allowed_to_copy() {
236
+ return current_user_can("level_" . duplicate_post_get_copy_user_level());
237
+ }
238
+
239
+ /**
240
+ * Get a level given a role
241
+ */
242
+ function duplicate_post_get_level_from_role($role) {
243
+ switch ($role) {
244
+ case 0: // subscribers 0
245
+ return 0;
246
+ case 1: // contributors 1
247
+ return 1;
248
+ case 2: // authors 2..4
249
+ return 2;
250
+ case 3: // editors 5..7
251
+ return 5;
252
+ case 4: // administrators 8..10
253
+ return 8;
254
+ default: // error
255
+ return 0;
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Get a role given a level
261
+ */
262
+ function duplicate_post_get_role_from_level($level) {
263
+ if ($level<=0) {
264
+ // subscribers 0
265
+ return 0;
266
+ } else if ($level==1) {
267
+ // contributors 1
268
+ return 1;
269
+ } else if ($level>=2 && $level<=4) {
270
+ // authors 2..4
271
+ return 2;
272
+ } else if ($level>=5 && $level<=7) {
273
+ // editors 5..7
274
+ return 3;
275
+ } else if ($level>=8) {
276
+ // admins 8..10
277
+ return 4;
278
+ }
279
+ return 0;
280
+ }
281
+
282
+ /**
283
+ * Get the currently registered user
284
+ */
285
+ function duplicate_post_get_current_user() {
286
+ if (function_exists('wp_get_current_user')) {
287
+ return wp_get_current_user();
288
+ } else if (function_exists('get_currentuserinfo')) {
289
+ global $userdata;
290
+ get_currentuserinfo();
291
+ return $userdata;
292
+ } else {
293
+ $user_login = $_COOKIE[USER_COOKIE];
294
+ $current_user = $wpdb->get_results("SELECT * FROM $wpdb->users WHERE user_login='$user_login'");
295
+ return $current_user;
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Escape single quotes, specialchar double quotes, and fix line endings.
301
+ */
302
+ function duplicate_post_js_escape($text) {
303
+ if (function_exists('js_escape')) {
304
+ return js_escape($text);
305
+ } else {
306
+ $safe_text = str_replace('&&', '&#038;&', $text);
307
+ $safe_text = str_replace('&&', '&#038;&', $safe_text);
308
+ $safe_text = preg_replace('/&(?:$|([^#])(?![a-z1-4]{1,8};))/', '&#038;$1', $safe_text);
309
+ $safe_text = str_replace('<', '&lt;', $safe_text);
310
+ $safe_text = str_replace('>', '&gt;', $safe_text);
311
+ $safe_text = str_replace('"', '&quot;', $safe_text);
312
+ $safe_text = str_replace('&#039;', "'", $safe_text);
313
+ $safe_text = preg_replace("/\r?\n/", "\\n", addslashes($safe_text));
314
+ return safe_text;
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Get a page from the database
320
+ */
321
+ function duplicate_post_get_page($id) {
322
+ global $wpdb;
323
+ $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
324
+ if ($post->post_type == "revision"){
325
+ $id = $post->post_parent;
326
+ $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
327
+ }
328
+ return $post[0];
329
+ }
330
+
331
+ /**
332
+ * Get a post from the database
333
+ */
334
+ function duplicate_post_get_post($id) {
335
+ global $wpdb;
336
+ $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
337
+ if ($post->post_type == "revision"){
338
+ $id = $post->post_parent;
339
+ $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
340
+ }
341
+ return $post[0];
342
+ }
343
+
344
+ /**
345
+ * Copy the taxonomies of a post to another post
346
+ */
347
+ function duplicate_post_copy_post_taxonomies($id, $new_id, $post_type) {
348
+ global $wpdb;
349
+ if (isset($wpdb->terms)) {
350
+ // WordPress 2.3
351
+ $taxonomies = get_object_taxonomies($post_type); //array("category", "post_tag");
352
+ foreach ($taxonomies as $taxonomy) {
353
+ $post_terms = wp_get_object_terms($id, $taxonomy);
354
+ for ($i=0; $i<count($post_terms); $i++) {
355
+ wp_set_object_terms($new_id, $post_terms[$i]->slug, $taxonomy, true);
356
+ }
357
+ }
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Copy the meta information of a post to another post
363
+ */
364
+ function duplicate_post_copy_post_meta_info($id, $new_id) {
365
+ global $wpdb;
366
+ $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$id");
367
+
368
+ if (count($post_meta_infos)!=0) {
369
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
370
+ $meta_no_copy = explode(",",get_option('duplicate_post_blacklist'));
371
+ foreach ($post_meta_infos as $meta_info) {
372
+ $meta_key = $meta_info->meta_key;
373
+ $meta_value = addslashes($meta_info->meta_value);
374
+ if (!in_array($meta_key,$meta_no_copy)) {
375
+ $sql_query_sel[]= "SELECT $new_id, '$meta_key', '$meta_value'";
376
+ }
377
+ }
378
+ $sql_query.= implode(" UNION ALL ", $sql_query_sel);
379
+ $wpdb->query($sql_query);
380
+ }
381
+ }
382
+
383
+ /**
384
+ * Create a duplicate from a post
385
+ */
386
+ function duplicate_post_create_duplicate_from_post($post) {
387
+ global $wpdb;
388
+ //$new_post_type = 'post';
389
+ $new_post_author = duplicate_post_get_current_user();
390
+ $new_post_date = (get_option('duplicate_post_copydate') == 1)? $post->post_date : current_time('mysql');
391
+ $new_post_date_gmt = get_gmt_from_date($new_post_date);
392
+ $prefix = get_option('duplicate_post_title_prefix');
393
+ if (!empty($prefix)) $prefix.= " ";
394
+
395
+ $new_post_type = $post->post_type;
396
+ $post_content = str_replace("'", "''", $post->post_content);
397
+ $post_content_filtered = str_replace("'", "''", $post->post_content_filtered);
398
+ $post_excerpt = str_replace("'", "''", $post->post_excerpt);
399
+ $post_title = $prefix.str_replace("'", "''", $post->post_title);
400
+ $post_status = str_replace("'", "''", $post->post_status);
401
+ $post_name = str_replace("'", "''", $post->post_name);
402
+ $comment_status = str_replace("'", "''", $post->comment_status);
403
+ $ping_status = str_replace("'", "''", $post->ping_status);
404
+
405
+ // Insert the new template in the post table
406
+ $wpdb->query(
407
+ "INSERT INTO $wpdb->posts
408
+ (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
409
+ VALUES
410
+ ('$new_post_author->ID', '$new_post_date', '$new_post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', 'draft', '$new_post_type', '$comment_status', '$ping_status', '$post->post_password', '$post->to_ping', '$post->pinged', '$new_post_date', '$new_post_date_gmt', '$post->post_parent', '$post->menu_order', '$post->post_mime_type')");
411
+
412
+ $new_post_id = $wpdb->insert_id;
413
+
414
+ // Copy the taxonomies
415
+ duplicate_post_copy_post_taxonomies($post->ID, $new_post_id, $post->post_type);
416
+
417
+ // Copy the meta information
418
+ duplicate_post_copy_post_meta_info($post->ID, $new_post_id);
419
+
420
+ return $new_post_id;
421
+ }
422
+
423
+ /**
424
+ * Create a duplicate from a page
425
+ */
426
+ function duplicate_post_create_duplicate_from_page($post) {
427
+ global $wpdb;
428
+ //$new_post_type = 'page';
429
+ $new_post_author = duplicate_post_get_current_user();
430
+ $new_post_date = (get_option('duplicate_post_copydate') == 1)? $post->post_date : current_time('mysql');
431
+ $new_post_date_gmt = get_gmt_from_date($new_post_date);
432
+ $prefix = get_option('duplicate_post_title_prefix');
433
+ if (!empty($prefix)) $prefix.= " ";
434
+
435
+ $new_post_type = $post->post_type;
436
+ $post_content = str_replace("'", "''", $post->post_content);
437
+ $post_content_filtered = str_replace("'", "''", $post->post_content_filtered);
438
+ $post_excerpt = str_replace("'", "''", $post->post_excerpt);
439
+ $post_title = $prefix.str_replace("'", "''", $post->post_title);
440
+ $post_status = str_replace("'", "''", $post->post_status);
441
+ $post_name = str_replace("'", "''", $post->post_name);
442
+ $comment_status = str_replace("'", "''", $post->comment_status);
443
+ $ping_status = str_replace("'", "''", $post->ping_status);
444
+
445
+ // Insert the new template in the post table
446
+ $wpdb->query(
447
+ "INSERT INTO $wpdb->posts
448
+ (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
449
+ VALUES
450
+ ('$new_post_author->ID', '$new_post_date', '$new_post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', 'draft', '$new_post_type', '$comment_status', '$ping_status', '$post->post_password', '$post_name', '$post->to_ping', '$post->pinged', '$new_post_date', '$new_post_date_gmt', '$post->post_parent', '$post->menu_order', '$post->post_mime_type')");
451
+
452
+ $new_page_id = $wpdb->insert_id;
453
+
454
+ // Copy the taxonomies
455
+ duplicate_post_copy_post_taxonomies($post->ID, $new_page_id, $post->post_type);
456
+
457
+ // Copy the meta information
458
+ duplicate_post_copy_post_meta_info($post->ID, $new_page_id);
459
+
460
+ return $new_page_id;
461
+ }
462
+
463
+
464
+ /**
465
+ * Add an option page where you can specify which meta fields you don't want to copy
466
+ */
467
+ if ( is_admin() ){ // admin actions
468
+ add_action('admin_menu', 'duplicate_post_menu');
469
+ add_action( 'admin_init', 'duplicate_post_register_settings');
470
+ }
471
+
472
+ function duplicate_post_register_settings() { // whitelist options
473
+ register_setting( 'duplicate_post_group', 'duplicate_post_copydate');
474
+ register_setting( 'duplicate_post_group', 'duplicate_post_blacklist');
475
+ register_setting( 'duplicate_post_group', 'duplicate_post_title_prefix');
476
+ register_setting( 'duplicate_post_group', 'duplicate_post_copy_user_level');
477
+ }
478
+
479
+
480
+ function duplicate_post_menu() {
481
+ add_options_page(__("Duplicate Post Options", DUPLICATE_POST_I18N_DOMAIN), __("Duplicate Post", DUPLICATE_POST_I18N_DOMAIN), 'administrator', 'duplicatepost', 'duplicate_post_options');
482
+ }
483
+
484
+ function duplicate_post_options() {
485
+ ?>
486
+ <div class="wrap">
487
+ <h2><?php _e("Duplicate Post", DUPLICATE_POST_I18N_DOMAIN); ?></h2>
488
+
489
+ <form method="post" action="options.php"><?php settings_fields('duplicate_post_group'); ?>
490
+
491
+ <table class="form-table">
492
+
493
+ <tr valign="top">
494
+ <th scope="row"><?php _e("Copy post/page date also", DUPLICATE_POST_I18N_DOMAIN); ?></th>
495
+ <td><input type="checkbox" name="duplicate_post_copydate" value="1" <?php if(get_option('duplicate_post_copydate') == 1) echo 'checked="checked"'; ?>"/>
496
+ <span class="description"><?php _e("Normally, the new draft has publication date set to current time: check the box to copy the original post/page date", DUPLICATE_POST_I18N_DOMAIN); ?></span>
497
+ </td>
498
+ </tr>
499
+ <tr valign="top">
500
+ <th scope="row"><?php _e("Do not copy these fields", DUPLICATE_POST_I18N_DOMAIN); ?></th>
501
+ <td><input type="text" name="duplicate_post_blacklist"
502
+ value="<?php echo get_option('duplicate_post_blacklist'); ?>" /> <span
503
+ class="description"><?php _e("Comma-separated list of meta fields that must not be copied when cloning a post/page", DUPLICATE_POST_I18N_DOMAIN); ?></span>
504
+ </td>
505
+ </tr>
506
+ <tr valign="top">
507
+ <th scope="row"><?php _e("Title prefix", DUPLICATE_POST_I18N_DOMAIN); ?></th>
508
+ <td><input type="text" name="duplicate_post_title_prefix"
509
+ value="<?php echo get_option('duplicate_post_title_prefix'); ?>" /> <span
510
+ class="description"><?php _e("Prefix to be added before the original title when cloning a post/page, e.g. \"Copy of\" (blank for no prefix)", DUPLICATE_POST_I18N_DOMAIN); ?></span>
511
+ </td>
512
+ </tr>
513
+ <tr valign="top">
514
+ <th scope="row"><?php _e("Minimum level to copy posts", DUPLICATE_POST_I18N_DOMAIN); ?></th>
515
+ <td><select name="duplicate_post_copy_user_level">
516
+ <?php global $wp_version;
517
+ if (strncmp($wp_version, "2.7",3) == 0 ){ ?>
518
+ <option value="1"
519
+ <?php if(get_option('duplicate_post_copy_user_level') == 1) echo 'selected="selected"'?>><?php echo _c("Contributor|User role", "default")?></option>
520
+ <option value="2"
521
+ <?php if(get_option('duplicate_post_copy_user_level') == 2) echo 'selected="selected"'?>><?php echo _c("Author|User role", "default")?></option>
522
+ <option value="5"
523
+ <?php if(get_option('duplicate_post_copy_user_level') == 5) echo 'selected="selected"'?>><?php echo _c("Editor|User role", "default")?></option>
524
+ <option value="8"
525
+ <?php if(get_option('duplicate_post_copy_user_level') == 8) echo 'selected="selected"'?>><?php echo _c("Administrator|User role", "default")?></option>
526
+
527
+ <?php } else { ?>
528
+ <option value="1"
529
+ <?php if(get_option('duplicate_post_copy_user_level') == 1) echo 'selected="selected"'?>><?php echo _x("Contributor", "User role", "default")?></option>
530
+ <option value="2"
531
+ <?php if(get_option('duplicate_post_copy_user_level') == 2) echo 'selected="selected"'?>><?php echo _x("Author", "User role", "default")?></option>
532
+ <option value="5"
533
+ <?php if(get_option('duplicate_post_copy_user_level') == 5) echo 'selected="selected"'?>><?php echo _x("Editor", "User role", "default")?></option>
534
+ <option value="8"
535
+ <?php if(get_option('duplicate_post_copy_user_level') == 8) echo 'selected="selected"'?>><?php echo _x("Administrator", "User role", "default")?></option>
536
+
537
+ <?php };?>
538
+ </select> <span class="description"><?php _e("Warning: users will be able to copy all posts, even those of higher level users", DUPLICATE_POST_I18N_DOMAIN); ?></span>
539
+ </td>
540
+ </tr>
541
+
542
+ </table>
543
+
544
+ <p class="submit"><input type="submit" class="button-primary"
545
+ value="<?php _e('Save Changes', DUPLICATE_POST_I18N_DOMAIN) ?>" /></p>
546
+
547
+ </form>
548
+ </div>
549
+ <?php
550
+ }
551
+
552
+ //Add some links on the plugin page
553
+ add_filter('plugin_row_meta', 'duplicate_post_add_plugin_links', 10, 2);
554
+
555
+ function duplicate_post_add_plugin_links($links, $file) {
556
+ if ( $file == plugin_basename(__FILE__) ) {
557
+ $links[] = '<a href="http://www.lopo.it/duplicate-post-plugin">' . __('Donate', DUPLICATE_POST_I18N_DOMAIN) . '</a>';
558
+ $links[] = '<a href="http://www.lopo.it/duplicate-post-plugin">' . __('Translate', DUPLICATE_POST_I18N_DOMAIN) . '</a>';
559
+ }
560
+ return $links;
561
+ }
562
+ ?>
duplicate-post.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Duplicate Post
4
  Plugin URI: http://www.lopo.it/duplicate-post-plugin/
5
  Description: Creates a copy of a post.
6
- Version: 1.1
7
  Author: Enrico Battocchi
8
  Author URI: http://www.lopo.it
9
  Text Domain: duplicate-post
@@ -26,564 +26,8 @@ along with this program; if not, write to the Free Software
26
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
- // Added by WarmStal
30
- if(!is_admin())
31
- return;
32
 
33
- /*
34
- * This function calls the creation of a new copy of the selected post (as a draft)
35
- * then redirects to the edit post screen
36
- */
37
- function duplicate_post_save_as_new_post(){
38
- if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_post' == $_REQUEST['action'] ) ) ) {
39
- wp_die(__('No post to duplicate has been supplied!', DUPLICATE_POST_I18N_DOMAIN));
40
- }
41
-
42
- // Get the original post
43
- $id = (isset($_GET['post']) ? $_GET['post'] : $_POST['post']);
44
- $post = duplicate_post_get_post($id);
45
-
46
- // Copy the post and insert it
47
- if (isset($post) && $post!=null) {
48
- $new_id = duplicate_post_create_duplicate_from_post($post);
49
-
50
- // If you have written a plugin which uses non-WP database tables to save
51
- // information about a post you can hook this action to dupe that data.
52
- do_action( 'dp_duplicate_post', $new_id, $post );
53
-
54
- // Redirect to the edit screen for the new draft post
55
- wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
56
- exit;
57
- } else {
58
- wp_die(__('Post creation failed, could not find original post:', DUPLICATE_POST_I18N_DOMAIN) . ' ' . $id);
59
- }
60
- }
61
-
62
- /*
63
- * Same as above, for pages
64
- */
65
- function duplicate_post_save_as_new_page(){
66
- if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_page' == $_REQUEST['action'] ) ) ) {
67
- wp_die(__('No page to duplicate has been supplied!', DUPLICATE_POST_I18N_DOMAIN));
68
- }
69
-
70
- // Get the original page
71
- $id = (isset($_GET['post']) ? $_GET['post'] : $_POST['post']);
72
- $post = duplicate_post_get_page($id);
73
-
74
- // Copy the page and insert it
75
- if (isset($post) && $post!=null) {
76
- $new_id = duplicate_post_create_duplicate_from_page($post);
77
-
78
- // If you have written a plugin which uses non-WP database tables to save
79
- // information about a page you can hook this action to dupe that data.
80
- do_action( 'dp_duplicate_page', $new_id, $post );
81
-
82
- // Redirect to the edit screen for the new draft page
83
- wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
84
- exit;
85
- } else {
86
- wp_die(__('Post creation failed, could not find original post:', DUPLICATE_POST_I18N_DOMAIN) . ' ' . $id);
87
- }
88
- }
89
-
90
- // Version of the plugin
91
- define('DUPLICATE_POST_CURRENT_VERSION', '1.1' );
92
- define('DUPLICATE_POST_COLUMN', 'control_duplicate_post');
93
-
94
- // i18n plugin domain
95
- define('DUPLICATE_POST_I18N_DOMAIN', 'duplicate-post');
96
-
97
- /**
98
- * Initialise the internationalisation domain
99
- */
100
- load_plugin_textdomain(DUPLICATE_POST_I18N_DOMAIN,
101
- 'wp-content/plugins/duplicate-post/languages','duplicate-post/languages');
102
-
103
- /**
104
- * Plugin activation
105
- */
106
- add_action('activate_duplicate-post/duplicate-post.php','duplicate_post_plugin_activation');
107
-
108
- function duplicate_post_plugin_activation() {
109
- $installed_version = duplicate_post_get_installed_version();
110
-
111
- if ( $installed_version==duplicate_post_get_current_version() ) {
112
- // do nothing
113
- } else {
114
- // delete old, obsolete options
115
- delete_option('duplicate_post_admin_user_level');
116
- delete_option('duplicate_post_create_user_level');
117
- delete_option('duplicate_post_view_user_level');
118
- // Add all options, nothing already installed
119
- add_option(
120
- 'duplicate_post_copy_user_level',
121
- '5',
122
- 'Default user level to copy posts' );
123
- }
124
- // Update version number
125
- update_option( 'duplicate_post_version', duplicate_post_get_current_version() );
126
- }
127
-
128
- /**
129
- * Check if WP version < 2.8: if so, post_row_actions does not exist, so we must add a custom column (the old way)
130
- */
131
- global $wp_version;
132
- if (strncmp($wp_version, "2.7",3) == 0 ){
133
- add_filter('manage_posts_columns', 'duplicate_post_add_duplicate_post_column');
134
- // Added by WarmStal
135
- add_filter('manage_pages_columns', 'duplicate_post_add_duplicate_post_column');
136
- add_action('manage_posts_custom_column', 'duplicate_post_make_duplicate_link', 10, 2);
137
- // Added by WarmStal
138
- add_action('manage_pages_custom_column', 'duplicate_page_make_duplicate_link', 10, 2);
139
- } else {
140
- /**
141
- * Add to the links shown when the mouse gets over a post title in 'Edit Posts' or 'Edit Pages' screen
142
- */
143
- add_filter('post_row_actions', 'duplicate_post_make_duplicate_link_row',10,2);
144
- add_filter('page_row_actions', 'duplicate_page_make_duplicate_link_row',10,2);
145
- }
146
-
147
- /**
148
- * WP version < 2.8: add a custom column
149
- */
150
- function duplicate_post_add_duplicate_post_column($columns) {
151
- if (duplicate_post_is_current_user_allowed_to_copy()) {
152
- $columns[DUPLICATE_POST_COLUMN] = '';
153
- }
154
- return $columns;
155
- }
156
-
157
- /**
158
- * WP version < 2.8: add link to custom column for posts
159
- */
160
- function duplicate_post_make_duplicate_link($column_name, $id) {
161
- if (duplicate_post_is_current_user_allowed_to_copy()) {
162
- if ($column_name == DUPLICATE_POST_COLUMN) {
163
- echo "<a href='admin.php?action=duplicate_post_save_as_new_post&amp;post=" . $id
164
- . "' title='" . __("Make a duplicate from this post", DUPLICATE_POST_I18N_DOMAIN)
165
- . "' class='edit'>" . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . "</a>";
166
- }
167
- }
168
- }
169
-
170
- /**
171
- * WP version < 2.8: add link to custom column for pages
172
- */
173
- // Added by WarmStal
174
- function duplicate_page_make_duplicate_link($column_name, $id) {
175
- if (duplicate_post_is_current_user_allowed_to_copy()) {
176
- if ($column_name == DUPLICATE_POST_COLUMN) {
177
- echo "<a href='admin.php?action=duplicate_post_save_as_new_page&amp;post=" . $id
178
- . "' title='" . __("Make a duplicate from this page", DUPLICATE_POST_I18N_DOMAIN)
179
- . "' class='edit'>" . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . "</a>";
180
- }
181
- }
182
- }
183
-
184
- /**
185
- * Connect actions to functions
186
- */
187
- add_action('admin_action_duplicate_post_save_as_new_post', 'duplicate_post_save_as_new_post');
188
- add_action('admin_action_duplicate_post_save_as_new_page', 'duplicate_post_save_as_new_page');
189
-
190
- /**
191
- * Add the link to action list for post_row_actions
192
- */
193
- function duplicate_post_make_duplicate_link_row($actions, $post) {
194
- if (duplicate_post_is_current_user_allowed_to_copy()) {
195
- $actions['duplicate'] = '<a href="admin.php?action=duplicate_post_save_as_new_post&amp;post=' . $post->ID . '" title="' . __("Make a duplicate from this post", DUPLICATE_POST_I18N_DOMAIN)
196
- . '" rel="permalink">' . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . '</a>';
197
- }
198
- return $actions;
199
- }
200
-
201
- /**
202
- * Add the link to action list for page_row_actions
203
- */
204
- function duplicate_page_make_duplicate_link_row($actions, $page) {
205
- if (duplicate_post_is_current_user_allowed_to_copy()) {
206
- $actions['duplicate'] = '<a href="admin.php?action=duplicate_post_save_as_new_page&amp;post=' . $page->ID . '" title="' . __("Make a duplicate from this page", DUPLICATE_POST_I18N_DOMAIN)
207
- . '" rel="permalink">' . __("Duplicate", DUPLICATE_POST_I18N_DOMAIN) . '</a>';
208
- }
209
- return $actions;
210
- }
211
-
212
- /**
213
- * Add a button in the post/page edit screen to create a clone
214
- */
215
- add_action( 'post_submitbox_start', 'duplicate_post_add_duplicate_post_button' );
216
-
217
- function duplicate_post_add_duplicate_post_button() {
218
- if ( isset( $_GET['post'] ) && duplicate_post_is_current_user_allowed_to_copy()) {
219
- $act = "admin.php?action=duplicate_post_save_as_new_post";
220
- global $post;
221
- if ($post->post_type == "page") $act = "admin.php?action=duplicate_post_save_as_new_page";
222
- $notifyUrl = $act."&post=" . $_GET['post'];
223
- ?>
224
- <div id="duplicate-action"><a class="submitduplicate duplication"
225
- href="<?php echo $notifyUrl; ?>"><?php _e('Copy to a new draft', DUPLICATE_POST_I18N_DOMAIN); ?></a>
226
- </div>
227
- <?php
228
- }
229
- }
230
-
231
- /**
232
- * Wrapper for the option 'duplicate_post_create_user_level'
233
- */
234
- function duplicate_post_get_copy_user_level() {
235
- return get_option( 'duplicate_post_copy_user_level' );
236
- }
237
-
238
- /**
239
- * Wrapper for the option 'duplicate_post_create_user_level'
240
- */
241
- function duplicate_post_set_copy_user_level($new_level) {
242
- return update_option( 'duplicate_post_copy_user_level', $new_level );
243
- }
244
-
245
- /**
246
- * Wrapper for the option 'duplicate_post_version'
247
- */
248
- function duplicate_post_get_installed_version() {
249
- return get_option( 'duplicate_post_version' );
250
- }
251
-
252
- /**
253
- * Wrapper for the defined constant DUPLICATE_POST_CURRENT_VERSION
254
- */
255
- function duplicate_post_get_current_version() {
256
- return DUPLICATE_POST_CURRENT_VERSION;
257
- }
258
-
259
- /**
260
- * Test if the user is allowed to create templates
261
- */
262
- function duplicate_post_is_current_user_allowed_to_copy() {
263
- return current_user_can("level_" . duplicate_post_get_copy_user_level());
264
- }
265
-
266
- /**
267
- * Get a level given a role
268
- */
269
- function duplicate_post_get_level_from_role($role) {
270
- switch ($role) {
271
- case 0: // subscribers 0
272
- return 0;
273
- case 1: // contributors 1
274
- return 1;
275
- case 2: // authors 2..4
276
- return 2;
277
- case 3: // editors 5..7
278
- return 5;
279
- case 4: // administrators 8..10
280
- return 8;
281
- default: // error
282
- return 0;
283
- }
284
- }
285
-
286
- /**
287
- * Get a role given a level
288
- */
289
- function duplicate_post_get_role_from_level($level) {
290
- if ($level<=0) {
291
- // subscribers 0
292
- return 0;
293
- } else if ($level==1) {
294
- // contributors 1
295
- return 1;
296
- } else if ($level>=2 && $level<=4) {
297
- // authors 2..4
298
- return 2;
299
- } else if ($level>=5 && $level<=7) {
300
- // editors 5..7
301
- return 3;
302
- } else if ($level>=8) {
303
- // admins 8..10
304
- return 4;
305
- }
306
- return 0;
307
- }
308
-
309
- /**
310
- * Get the currently registered user
311
- */
312
- function duplicate_post_get_current_user() {
313
- if (function_exists('wp_get_current_user')) {
314
- return wp_get_current_user();
315
- } else if (function_exists('get_currentuserinfo')) {
316
- global $userdata;
317
- get_currentuserinfo();
318
- return $userdata;
319
- } else {
320
- $user_login = $_COOKIE[USER_COOKIE];
321
- $current_user = $wpdb->get_results("SELECT * FROM $wpdb->users WHERE user_login='$user_login'");
322
- return $current_user;
323
- }
324
- }
325
-
326
- /**
327
- * Escape single quotes, specialchar double quotes, and fix line endings.
328
- */
329
- function duplicate_post_js_escape($text) {
330
- if (function_exists('js_escape')) {
331
- return js_escape($text);
332
- } else {
333
- $safe_text = str_replace('&&', '&#038;&', $text);
334
- $safe_text = str_replace('&&', '&#038;&', $safe_text);
335
- $safe_text = preg_replace('/&(?:$|([^#])(?![a-z1-4]{1,8};))/', '&#038;$1', $safe_text);
336
- $safe_text = str_replace('<', '&lt;', $safe_text);
337
- $safe_text = str_replace('>', '&gt;', $safe_text);
338
- $safe_text = str_replace('"', '&quot;', $safe_text);
339
- $safe_text = str_replace('&#039;', "'", $safe_text);
340
- $safe_text = preg_replace("/\r?\n/", "\\n", addslashes($safe_text));
341
- return safe_text;
342
- }
343
- }
344
-
345
- /**
346
- * Get a page from the database
347
- */
348
- function duplicate_post_get_page($id) {
349
- global $wpdb;
350
- $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
351
- if ($post->post_type == "revision"){
352
- $id = $post->post_parent;
353
- $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
354
- }
355
- return $post[0];
356
- }
357
-
358
- /**
359
- * Get a post from the database
360
- */
361
- function duplicate_post_get_post($id) {
362
- global $wpdb;
363
- $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
364
- if ($post->post_type == "revision"){
365
- $id = $post->post_parent;
366
- $post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
367
- }
368
- return $post[0];
369
- }
370
-
371
- /**
372
- * Copy the taxonomies of a post to another post
373
- */
374
- function duplicate_post_copy_post_taxonomies($id, $new_id, $post_type) {
375
- global $wpdb;
376
- if (isset($wpdb->terms)) {
377
- // WordPress 2.3
378
- $taxonomies = get_object_taxonomies($post_type); //array("category", "post_tag");
379
- foreach ($taxonomies as $taxonomy) {
380
- $post_terms = wp_get_object_terms($id, $taxonomy);
381
- for ($i=0; $i<count($post_terms); $i++) {
382
- wp_set_object_terms($new_id, $post_terms[$i]->slug, $taxonomy, true);
383
- }
384
- }
385
- }
386
- }
387
-
388
- /**
389
- * Copy the meta information of a post to another post
390
- */
391
- function duplicate_post_copy_post_meta_info($id, $new_id) {
392
- global $wpdb;
393
- $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$id");
394
-
395
- if (count($post_meta_infos)!=0) {
396
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
397
- $meta_no_copy = explode(",",get_option('duplicate_post_blacklist'));
398
- foreach ($post_meta_infos as $meta_info) {
399
- $meta_key = $meta_info->meta_key;
400
- $meta_value = addslashes($meta_info->meta_value);
401
- if (!in_array($meta_key,$meta_no_copy)) {
402
- $sql_query_sel[]= "SELECT $new_id, '$meta_key', '$meta_value'";
403
- }
404
- }
405
- $sql_query.= implode(" UNION ALL ", $sql_query_sel);
406
- $wpdb->query($sql_query);
407
- }
408
- }
409
-
410
- /**
411
- * Create a duplicate from a post
412
- */
413
- function duplicate_post_create_duplicate_from_post($post) {
414
- global $wpdb;
415
- //$new_post_type = 'post';
416
- $new_post_author = duplicate_post_get_current_user();
417
- $new_post_date = (get_option('duplicate_post_copydate') == 1)? $post->post_date : current_time('mysql');
418
- $new_post_date_gmt = get_gmt_from_date($new_post_date);
419
- $prefix = get_option('duplicate_post_title_prefix');
420
- if (!empty($prefix)) $prefix.= " ";
421
-
422
- $new_post_type = $post->post_type;
423
- $post_content = str_replace("'", "''", $post->post_content);
424
- $post_content_filtered = str_replace("'", "''", $post->post_content_filtered);
425
- $post_excerpt = str_replace("'", "''", $post->post_excerpt);
426
- $post_title = $prefix.str_replace("'", "''", $post->post_title);
427
- $post_status = str_replace("'", "''", $post->post_status);
428
- $post_name = str_replace("'", "''", $post->post_name);
429
- $comment_status = str_replace("'", "''", $post->comment_status);
430
- $ping_status = str_replace("'", "''", $post->ping_status);
431
-
432
- // Insert the new template in the post table
433
- $wpdb->query(
434
- "INSERT INTO $wpdb->posts
435
- (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
436
- VALUES
437
- ('$new_post_author->ID', '$new_post_date', '$new_post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', 'draft', '$new_post_type', '$comment_status', '$ping_status', '$post->post_password', '$post->to_ping', '$post->pinged', '$new_post_date', '$new_post_date_gmt', '$post->post_parent', '$post->menu_order', '$post->post_mime_type')");
438
-
439
- $new_post_id = $wpdb->insert_id;
440
-
441
- // Copy the taxonomies
442
- duplicate_post_copy_post_taxonomies($post->ID, $new_post_id, $post->post_type);
443
-
444
- // Copy the meta information
445
- duplicate_post_copy_post_meta_info($post->ID, $new_post_id);
446
-
447
- return $new_post_id;
448
- }
449
-
450
- /**
451
- * Create a duplicate from a page
452
- */
453
- function duplicate_post_create_duplicate_from_page($post) {
454
- global $wpdb;
455
- //$new_post_type = 'page';
456
- $new_post_author = duplicate_post_get_current_user();
457
- $new_post_date = (get_option('duplicate_post_copydate') == 1)? $post->post_date : current_time('mysql');
458
- $new_post_date_gmt = get_gmt_from_date($new_post_date);
459
- $prefix = get_option('duplicate_post_title_prefix');
460
- if (!empty($prefix)) $prefix.= " ";
461
-
462
- $new_post_type = $post->post_type;
463
- $post_content = str_replace("'", "''", $post->post_content);
464
- $post_content_filtered = str_replace("'", "''", $post->post_content_filtered);
465
- $post_excerpt = str_replace("'", "''", $post->post_excerpt);
466
- $post_title = $prefix.str_replace("'", "''", $post->post_title);
467
- $post_status = str_replace("'", "''", $post->post_status);
468
- $post_name = str_replace("'", "''", $post->post_name);
469
- $comment_status = str_replace("'", "''", $post->comment_status);
470
- $ping_status = str_replace("'", "''", $post->ping_status);
471
-
472
- // Insert the new template in the post table
473
- $wpdb->query(
474
- "INSERT INTO $wpdb->posts
475
- (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
476
- VALUES
477
- ('$new_post_author->ID', '$new_post_date', '$new_post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', 'draft', '$new_post_type', '$comment_status', '$ping_status', '$post->post_password', '$post_name', '$post->to_ping', '$post->pinged', '$new_post_date', '$new_post_date_gmt', '$post->post_parent', '$post->menu_order', '$post->post_mime_type')");
478
-
479
- $new_page_id = $wpdb->insert_id;
480
-
481
- // Copy the taxonomies
482
- duplicate_post_copy_post_taxonomies($post->ID, $new_page_id, $post->post_type);
483
-
484
- // Copy the meta information
485
- duplicate_post_copy_post_meta_info($post->ID, $new_page_id);
486
-
487
- return $new_page_id;
488
- }
489
-
490
-
491
- /**
492
- * Add an option page where you can specify which meta fields you don't want to copy
493
- */
494
- if ( is_admin() ){ // admin actions
495
- add_action('admin_menu', 'duplicate_post_menu');
496
- add_action( 'admin_init', 'register_mysettings');
497
- }
498
-
499
- function register_mysettings() { // whitelist options
500
- register_setting( 'duplicate_post_group', 'duplicate_post_copydate');
501
- register_setting( 'duplicate_post_group', 'duplicate_post_blacklist');
502
- register_setting( 'duplicate_post_group', 'duplicate_post_title_prefix');
503
- register_setting( 'duplicate_post_group', 'duplicate_post_copy_user_level');
504
- }
505
-
506
-
507
- function duplicate_post_menu() {
508
- add_options_page(__("Duplicate Post Options", DUPLICATE_POST_I18N_DOMAIN), __("Duplicate Post", DUPLICATE_POST_I18N_DOMAIN), 'administrator', 'duplicatepost', 'duplicate_post_options');
509
- }
510
-
511
- function duplicate_post_options() {
512
- ?>
513
- <div class="wrap">
514
- <h2><?php _e("Duplicate Post", DUPLICATE_POST_I18N_DOMAIN); ?></h2>
515
-
516
- <form method="post" action="options.php"><?php settings_fields('duplicate_post_group'); ?>
517
-
518
- <table class="form-table">
519
-
520
- <tr valign="top">
521
- <th scope="row"><?php _e("Copy post/page date also", DUPLICATE_POST_I18N_DOMAIN); ?></th>
522
- <td><input type="checkbox" name="duplicate_post_copydate" value="1" <?php if(get_option('duplicate_post_copydate') == 1) echo 'checked="checked"'; ?>"/>
523
- <span class="description"><?php _e("Normally, the new draft has publication date set to current time: check the box to copy the original post/page date", DUPLICATE_POST_I18N_DOMAIN); ?></span>
524
- </td>
525
- </tr>
526
- <tr valign="top">
527
- <th scope="row"><?php _e("Do not copy these fields", DUPLICATE_POST_I18N_DOMAIN); ?></th>
528
- <td><input type="text" name="duplicate_post_blacklist"
529
- value="<?php echo get_option('duplicate_post_blacklist'); ?>" /> <span
530
- class="description"><?php _e("Comma-separated list of meta fields that must not be copied when cloning a post/page", DUPLICATE_POST_I18N_DOMAIN); ?></span>
531
- </td>
532
- </tr>
533
- <tr valign="top">
534
- <th scope="row"><?php _e("Title prefix", DUPLICATE_POST_I18N_DOMAIN); ?></th>
535
- <td><input type="text" name="duplicate_post_title_prefix"
536
- value="<?php echo get_option('duplicate_post_title_prefix'); ?>" /> <span
537
- class="description"><?php _e("Prefix to be added before the original title when cloning a post/page, e.g. \"Copy of\" (blank for no prefix)", DUPLICATE_POST_I18N_DOMAIN); ?></span>
538
- </td>
539
- </tr>
540
- <tr valign="top">
541
- <th scope="row"><?php _e("Minimum level to copy posts", DUPLICATE_POST_I18N_DOMAIN); ?></th>
542
- <td><select name="duplicate_post_copy_user_level">
543
- <?php global $wp_version;
544
- if (strncmp($wp_version, "2.7",3) == 0 ){ ?>
545
- <option value="1"
546
- <?php if(get_option('duplicate_post_copy_user_level') == 1) echo 'selected="selected"'?>><?php echo _c("Contributor|User role", "default")?></option>
547
- <option value="2"
548
- <?php if(get_option('duplicate_post_copy_user_level') == 2) echo 'selected="selected"'?>><?php echo _c("Author|User role", "default")?></option>
549
- <option value="5"
550
- <?php if(get_option('duplicate_post_copy_user_level') == 5) echo 'selected="selected"'?>><?php echo _c("Editor|User role", "default")?></option>
551
- <option value="8"
552
- <?php if(get_option('duplicate_post_copy_user_level') == 8) echo 'selected="selected"'?>><?php echo _c("Administrator|User role", "default")?></option>
553
-
554
- <?php } else { ?>
555
- <option value="1"
556
- <?php if(get_option('duplicate_post_copy_user_level') == 1) echo 'selected="selected"'?>><?php echo _x("Contributor", "User role", "default")?></option>
557
- <option value="2"
558
- <?php if(get_option('duplicate_post_copy_user_level') == 2) echo 'selected="selected"'?>><?php echo _x("Author", "User role", "default")?></option>
559
- <option value="5"
560
- <?php if(get_option('duplicate_post_copy_user_level') == 5) echo 'selected="selected"'?>><?php echo _x("Editor", "User role", "default")?></option>
561
- <option value="8"
562
- <?php if(get_option('duplicate_post_copy_user_level') == 8) echo 'selected="selected"'?>><?php echo _x("Administrator", "User role", "default")?></option>
563
-
564
- <?php };?>
565
- </select> <span class="description"><?php _e("Warning: users will be able to copy all posts, even those of higher level users", DUPLICATE_POST_I18N_DOMAIN); ?></span>
566
- </td>
567
- </tr>
568
-
569
- </table>
570
-
571
- <p class="submit"><input type="submit" class="button-primary"
572
- value="<?php _e('Save Changes', DUPLICATE_POST_I18N_DOMAIN) ?>" /></p>
573
-
574
- </form>
575
- </div>
576
- <?php
577
- }
578
-
579
- //Add some links on the plugin page
580
- add_filter('plugin_row_meta', 'duplicate_post_add_plugin_links', 10, 2);
581
-
582
- function duplicate_post_add_plugin_links($links, $file) {
583
- if ( $file == plugin_basename(__FILE__) ) {
584
- $links[] = '<a href="http://www.lopo.it/duplicate-post-plugin">' . __('Donate', DUPLICATE_POST_I18N_DOMAIN) . '</a>';
585
- $links[] = '<a href="http://www.lopo.it/duplicate-post-plugin">' . __('Translate', DUPLICATE_POST_I18N_DOMAIN) . '</a>';
586
- }
587
- return $links;
588
  }
589
  ?>
3
  Plugin Name: Duplicate Post
4
  Plugin URI: http://www.lopo.it/duplicate-post-plugin/
5
  Description: Creates a copy of a post.
6
+ Version: 1.1.1
7
  Author: Enrico Battocchi
8
  Author URI: http://www.lopo.it
9
  Text Domain: duplicate-post
26
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
 
 
 
29
 
30
+ if (is_admin()){
31
+ require_once (dirname(__FILE__).'/duplicate-post-admin.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
  ?>
languages/duplicate-post-nl.mo ADDED
Binary file
languages/duplicate-post-nl.po ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Duplicate Post plugin for WordPress
2
+ # Copyright (C) 2009 Enrico Battocchi
3
+ # This file is distributed under the same license as the Duplicate Post package.
4
+ # Enrico Battocchi <enrico.battocchi@gmail.com>, 2009.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: Duplicate Post 1.0\n"
9
+ "Report-Msgid-Bugs-To: \n"
10
+ "POT-Creation-Date: 2010-05-21 10:01+0000\n"
11
+ "PO-Revision-Date: 2010-06-30 19:43+0000\n"
12
+ "Last-Translator: Enrico Battocchi <Unknown>\n"
13
+ "Language-Team: Enrico Battocchi / WarmStal D!sign <mail@warmstal.nl>\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=UTF-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+ "X-Launchpad-Export-Date: 2010-06-30 19:44+0000\n"
18
+ "X-Generator: Launchpad (build Unknown)\n"
19
+ "X-Poedit-Country: NETHERLANDS\n"
20
+ "X-Poedit-Language: Dutch\n"
21
+ "X-Poedit-SearchPath-0: .\n"
22
+ "X-Poedit-Basepath: ../\n"
23
+ "X-Poedit-KeywordsList: _e;__\n"
24
+
25
+ #: duplicate-post.php:39
26
+ msgid "No post to duplicate has been supplied!"
27
+ msgstr "Er is geen bericht orgineel opgegeven!"
28
+
29
+ #: duplicate-post.php:58 duplicate-post.php:86
30
+ msgid "Post creation failed, could not find original post:"
31
+ msgstr "Fout bij aanmaken bericht, orgineel bericht niet gevonden:"
32
+
33
+ #: duplicate-post.php:67
34
+ msgid "No page to duplicate has been supplied!"
35
+ msgstr "Er is geen pagina orgineel opgegeven!"
36
+
37
+ #: duplicate-post.php:164 duplicate-post.php:195
38
+ msgid "Make a duplicate from this post"
39
+ msgstr "Dupliceer dit bericht"
40
+
41
+ #: duplicate-post.php:165 duplicate-post.php:179 duplicate-post.php:196
42
+ #: duplicate-post.php:207
43
+ msgid "Duplicate"
44
+ msgstr "Dupliceren"
45
+
46
+ #: duplicate-post.php:178 duplicate-post.php:206
47
+ msgid "Make a duplicate from this page"
48
+ msgstr "Dupliceer deze pagina"
49
+
50
+ #: duplicate-post.php:225
51
+ msgid "Copy to a new draft"
52
+ msgstr "Kopiëren naar een nieuw concept"
53
+
54
+ #: duplicate-post.php:519
55
+ msgid "Duplicate Post Options"
56
+ msgstr "Opties dupliceren bericht/pagina"
57
+
58
+ #. #-#-#-#-# plugin.pot (Duplicate Post 1.1) #-#-#-#-#
59
+ #. Plugin Name of the plugin/theme
60
+ #: duplicate-post.php:519 duplicate-post.php:525
61
+ msgid "Duplicate Post"
62
+ msgstr "Dupliceren"
63
+
64
+ #: duplicate-post.php:532
65
+ msgid "Copy post/page date also"
66
+ msgstr "Kopieer ook de publicatiedatum"
67
+
68
+ #: duplicate-post.php:534
69
+ msgid ""
70
+ "Normally, the new draft has publication date set to current time: check the "
71
+ "box to copy the original post/page date"
72
+ msgstr ""
73
+ "Normaal wordt voor een nieuw bericht of pagina het huidige tijdstip genomen "
74
+ "voor de publicatiedatum. Selecteer om de oorspronkelijk datum mee te "
75
+ "kopieren."
76
+
77
+ #: duplicate-post.php:538
78
+ msgid "Do not copy these fields"
79
+ msgstr "Kopieer niet deze velden"
80
+
81
+ #: duplicate-post.php:541
82
+ msgid ""
83
+ "Comma-separated list of meta fields that must not be copied when cloning a "
84
+ "post/page"
85
+ msgstr ""
86
+ "Kommagescheiden lijst van meta-velden die niet worden meegedupliceerd."
87
+
88
+ #: duplicate-post.php:545
89
+ msgid "Title prefix"
90
+ msgstr "Titel prefix"
91
+
92
+ #: duplicate-post.php:548
93
+ msgid ""
94
+ "Prefix to be added before the original title when cloning a post/page, e.g. "
95
+ "\"Copy of\" (blank for no prefix)"
96
+ msgstr "Prefix die voor orginele titel wordt geplaatst. b.v. \"Kopie van\"."
97
+
98
+ #: duplicate-post.php:552
99
+ msgid "Minimum level to copy posts"
100
+ msgstr "Minimum rechtenniveau om te dupliceren"
101
+
102
+ #: duplicate-post.php:576
103
+ msgid ""
104
+ "Warning: users will be able to copy all posts, even those of higher level "
105
+ "users"
106
+ msgstr ""
107
+ "Waarschuwing: gebruikers kunnen alle berichten/pagina's copieren. Ook die "
108
+ "van gebruikers met meer rechten"
109
+
110
+ #: duplicate-post.php:583
111
+ msgid "Save Changes"
112
+ msgstr "Opslaan"
113
+
114
+ #: duplicate-post.php:595
115
+ msgid "Donate"
116
+ msgstr "Doneer"
117
+
118
+ #: duplicate-post.php:596
119
+ msgid "Translate"
120
+ msgstr "Vertaal"
121
+
122
+ #. Plugin URI of the plugin/theme
123
+ msgid "http://www.lopo.it/duplicate-post-plugin/"
124
+ msgstr "http://www.lopo.it/duplicate-post-plugin/"
125
+
126
+ #. Description of the plugin/theme
127
+ msgid "Creates a copy of a post."
128
+ msgstr "Dupliceert bericht"
129
+
130
+ #. Author of the plugin/theme
131
+ msgid "Enrico Battocchi"
132
+ msgstr "Enrico Battocchi"
133
+
134
+ #. Author URI of the plugin/theme
135
+ msgid "http://www.lopo.it"
136
+ msgstr "http://www.lopo.it"
137
+
138
+ #~ msgid "http://wordpress.org/extend/plugins/duplicate-post/"
139
+ #~ msgstr "http://wordpress.org/extend/plugins/duplicate-post/"
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.lopo.it/duplicate-post-plugin/
4
  Tags: duplicate, post, copy
5
  Requires at least: 2.7
6
  Tested up to: 3.0
7
- Stable tag: 1.1
8
 
9
  Creates a copy of a post.
10
 
@@ -22,13 +22,13 @@ In the Options page it is now possible to choose:
22
  * a prefix to place before the title of the cloned post/page
23
  * the minimum user level to clone posts or pages
24
 
25
- Duplicate post is natively in English, but it's shipped with translations in 10 other languages (though some are incomplete). Now there is a [Launchpad translation project](https://translations.launchpad.net/duplicate-post/) available to help translating this plugin: feel free to contribute (you can also send me an e-mail using the form on my website).
26
 
27
  If you're a plugin developer, I suggest to read the section made just for you under "Other Notes", to ensure compatibility between your plugin(s) and mine!
28
 
29
  The plugin has been tested against versions 2.7 -> 3.0. It should be compatible with the Custom Post Type and Custom Taxonomies features of WP 3.0. It's not yet been tested with the multiblog feature active (but it used to work with WPMU).
30
 
31
- Thanks for all the suggestions, bug reports, translations and donations: Franz, Ben ter Stal, [Naoko McCracken](http://blog.detlog.org), [Simon Wheatley](http://www.simonwheatley.co.uk/), [Magnus Anemo](http://www.anemo.se/en), Michelle Drumm, Richard Vencu, [el_libre](http://www.catmidia.cat/), Antoine Jouve, Sebastian, Yaron, Hiroshi Tagawa, Adam Skiba, Bartosz Kaszubowski, Braiam Peguero, Jonay, tam, my friends Livia, Alessandra, Ada and anybody else that I may have forgotten (sorry!)
32
 
33
  Credit must be given to the (great) [Post Template](http://post-templates.vincentprat.info) plugin by Vincent Prat: I made this by hacking his work to get something more focused to a sporadic use, without the need to create and manage templates just to make simple copies of some posts every now and then. If my plugin doesn't fits your needs (and even if it does) check Vincent's.
34
 
@@ -66,11 +66,19 @@ If you find this useful and you if you want to contribute, there are three ways:
66
 
67
  == Upgrade Notice ==
68
 
 
 
 
69
  = 1.1 =
70
  New features and customization, WP 3.0 compatibility: you should upgrade if you want to copy Custom Posts with Custom Taxonomies.
71
 
72
  == Changelog ==
73
 
 
 
 
 
 
74
  = 1.1 =
75
  * WP 3.0 compatibility (not tested against multiblog feature, so beware)
76
  * Option page: minimum user level, title prefix, fields not to be copied, copy post/page date also
4
  Tags: duplicate, post, copy
5
  Requires at least: 2.7
6
  Tested up to: 3.0
7
+ Stable tag: 1.1.1
8
 
9
  Creates a copy of a post.
10
 
22
  * a prefix to place before the title of the cloned post/page
23
  * the minimum user level to clone posts or pages
24
 
25
+ Duplicate post is natively in English, but it's shipped with translations in 11 other languages (though some are incomplete). Now there is a [Launchpad translation project](https://translations.launchpad.net/duplicate-post/) available to help translating this plugin: feel free to contribute (you can also send me an e-mail using the form on my website).
26
 
27
  If you're a plugin developer, I suggest to read the section made just for you under "Other Notes", to ensure compatibility between your plugin(s) and mine!
28
 
29
  The plugin has been tested against versions 2.7 -> 3.0. It should be compatible with the Custom Post Type and Custom Taxonomies features of WP 3.0. It's not yet been tested with the multiblog feature active (but it used to work with WPMU).
30
 
31
+ Thanks for all the suggestions, bug reports, translations and donations: Franz, Ben ter Stal, [Naoko McCracken](http://blog.detlog.org), [Simon Wheatley](http://www.simonwheatley.co.uk/), [Magnus Anemo](http://www.anemo.se/en), Michelle Drumm, [TVbytheNumbers.com](http://www.TVbytheNumbers.com), Richard Vencu, [el_libre](http://www.catmidia.cat/), Antoine Jouve, Sebastian, Yaron, Hiroshi Tagawa, Adam Skiba, Bartosz Kaszubowski, Braiam Peguero, Jonay, tam, my friends Livia, Alessandra, Ada and anybody else that I may have forgotten (sorry!)
32
 
33
  Credit must be given to the (great) [Post Template](http://post-templates.vincentprat.info) plugin by Vincent Prat: I made this by hacking his work to get something more focused to a sporadic use, without the need to create and manage templates just to make simple copies of some posts every now and then. If my plugin doesn't fits your needs (and even if it does) check Vincent's.
34
 
66
 
67
  == Upgrade Notice ==
68
 
69
+ = 1.1.1 =
70
+ Some users have experienced a fatal error when upgrading to v1.1: this may fix it, if it's caused by a plugin conflict.
71
+
72
  = 1.1 =
73
  New features and customization, WP 3.0 compatibility: you should upgrade if you want to copy Custom Posts with Custom Taxonomies.
74
 
75
  == Changelog ==
76
 
77
+ = 1.1.1 =
78
+ * Plugin split in two files for faster opening in Plugins list page
79
+ * fix conflicts with a few other plugins
80
+ * Added Dutch language files
81
+
82
  = 1.1 =
83
  * WP 3.0 compatibility (not tested against multiblog feature, so beware)
84
  * Option page: minimum user level, title prefix, fields not to be copied, copy post/page date also