Version Description
(2021-11-18) =
Bugfixes:
- Fixes a bug where some strings where not translated.
- Fixes a bug where meta data went missing for duplicate posts created by the Rewrite & Republish feature. Props to ocean90.
- Fixes a bug where the plugin would not initialize if installed via composer.
Other:
- Replaces Mailchimp with MailBlue newsletter integration.
- Improved compatibility for PHP 8.0.
- Improved sort order of the taxonomies list on the options page.
- Most plugin files have been renamed. If you extend this plugin of include any of the files from the plugin from within your own plugin, you may need to adjust the file name used in the
include
/require
statement.
Download this release
Release Info
Developer | lopo |
Plugin | Duplicate Post |
Version | 4.2 |
Comparing to | |
See all releases |
Code changes from version 4.1.2 to 4.2
- duplicate-post-admin.php → admin-functions.php +99 -143
- duplicate-post-common.php → common-functions.php +11 -9
- compat/duplicate-post-gutenberg.php +0 -39
- compat/{duplicate-post-jetpack.php → jetpack-functions.php} +2 -2
- compat/{duplicate-post-wpml.php → wpml-functions.php} +18 -10
- duplicate-post.php +26 -18
- js/dist/{duplicate-post-edit-412.js → duplicate-post-edit-420.js} +0 -0
- js/dist/{duplicate-post-elementor-412.js → duplicate-post-elementor-420.js} +0 -0
- js/dist/{duplicate-post-options-412.js → duplicate-post-options-420.js} +0 -0
- js/dist/{duplicate-post-quick-edit-412.js → duplicate-post-quick-edit-420.js} +0 -0
- js/dist/{duplicate-post-strings-412.js → duplicate-post-strings-420.js} +0 -0
- duplicate-post-options.php → options.php +1 -7
- readme.txt +16 -1
- src/admin/{class-options-form-generator.php → options-form-generator.php} +23 -19
- src/admin/{class-options-inputs.php → options-inputs.php} +14 -19
- src/admin/{class-options-page.php → options-page.php} +10 -11
- src/admin/{class-options.php → options.php} +27 -30
- src/admin/views/options.php +7 -9
- src/{class-duplicate-post.php → duplicate-post.php} +3 -7
- src/handlers/{class-bulk-handler.php → bulk-handler.php} +5 -9
- src/handlers/{class-check-changes-handler.php → check-changes-handler.php} +28 -28
- src/handlers/{class-handler.php → handler.php} +3 -7
- src/handlers/{class-link-handler.php → link-handler.php} +21 -23
- src/handlers/{class-save-post-handler.php → save-post-handler.php} +5 -9
- src/{class-permissions-helper.php → permissions-helper.php} +30 -36
- src/{class-post-duplicator.php → post-duplicator.php} +58 -51
- src/{class-post-republisher.php → post-republisher.php} +20 -23
- src/{class-revisions-migrator.php → revisions-migrator.php} +5 -9
- src/ui/{class-admin-bar.php → admin-bar.php} +5 -8
- src/ui/{class-asset-manager.php → asset-manager.php} +24 -29
- src/ui/{class-block-editor.php → block-editor.php} +3 -8
- src/ui/{class-bulk-actions.php → bulk-actions.php} +2 -8
- src/ui/class-metabox.php +0 -121
- src/ui/{class-classic-editor.php → classic-editor.php} +27 -32
- src/ui/{class-column.php → column.php} +13 -13
- src/ui/{class-link-builder.php → link-builder.php} +28 -32
- src/ui/metabox.php +116 -0
- src/ui/newsletter.php +127 -0
- src/ui/{class-post-states.php → post-states.php} +3 -8
- src/ui/{class-row-actions.php → row-actions.php} +23 -28
- src/ui/{class-user-interface.php → user-interface.php} +9 -6
- src/{class-utils.php → utils.php} +24 -22
- src/watchers/{class-bulk-actions-watcher.php → bulk-actions-watcher.php} +11 -16
- src/watchers/{class-copied-post-watcher.php → copied-post-watcher.php} +8 -12
- src/watchers/{class-link-actions-watcher.php → link-actions-watcher.php} +14 -19
- src/watchers/{class-original-post-watcher.php → original-post-watcher.php} +9 -12
- src/watchers/{class-republished-post-watcher.php → republished-post-watcher.php} +8 -12
- src/watchers/{class-watchers.php → watchers.php} +1 -6
- vendor/composer/ClassLoader.php +105 -12
- vendor/composer/InstalledVersions.php +339 -272
- vendor/composer/autoload_classmap.php +135 -32
- vendor/composer/autoload_psr4.php +1 -0
- vendor/composer/autoload_real.php +2 -0
- vendor/composer/autoload_static.php +151 -32
- vendor/composer/installed.php +41 -21
- vendor/composer/platform_check.php +26 -0
duplicate-post-admin.php → admin-functions.php
RENAMED
@@ -2,7 +2,7 @@
|
|
2 |
/**
|
3 |
* Backend functions.
|
4 |
*
|
5 |
-
* @package
|
6 |
* @since 2.0
|
7 |
*/
|
8 |
|
@@ -10,10 +10,12 @@ if ( ! is_admin() ) {
|
|
10 |
return;
|
11 |
}
|
12 |
|
13 |
-
|
14 |
|
15 |
-
require_once
|
16 |
-
|
|
|
|
|
17 |
|
18 |
/**
|
19 |
* Wrapper for the option 'duplicate_post_version'.
|
@@ -40,7 +42,8 @@ function duplicate_post_admin_init() {
|
|
40 |
if ( intval( get_site_option( 'duplicate_post_show_notice' ) ) === 1 ) {
|
41 |
if ( is_multisite() ) {
|
42 |
add_action( 'network_admin_notices', 'duplicate_post_show_update_notice' );
|
43 |
-
}
|
|
|
44 |
add_action( 'admin_notices', 'duplicate_post_show_update_notice' );
|
45 |
}
|
46 |
add_action( 'wp_ajax_duplicate_post_dismiss_notice', 'duplicate_post_dismiss_notice' );
|
@@ -82,12 +85,12 @@ function duplicate_post_plugin_upgrade() {
|
|
82 |
|
83 |
if ( empty( $installed_version ) ) {
|
84 |
// Get default roles.
|
85 |
-
$default_roles =
|
86 |
'editor',
|
87 |
'administrator',
|
88 |
'wpseo_manager',
|
89 |
'wpseo_editor',
|
90 |
-
|
91 |
|
92 |
foreach ( $default_roles as $name ) {
|
93 |
$role = get_role( $name );
|
@@ -119,9 +122,9 @@ function duplicate_post_plugin_upgrade() {
|
|
119 |
add_option( 'duplicate_post_copychildren', '0' );
|
120 |
add_option( 'duplicate_post_copycomments', '0' );
|
121 |
add_option( 'duplicate_post_copymenuorder', '1' );
|
122 |
-
add_option( 'duplicate_post_taxonomies_blacklist',
|
123 |
add_option( 'duplicate_post_blacklist', '' );
|
124 |
-
add_option( 'duplicate_post_types_enabled',
|
125 |
add_option( 'duplicate_post_show_original_column', '0' );
|
126 |
add_option( 'duplicate_post_show_original_in_post_states', '0' );
|
127 |
add_option( 'duplicate_post_show_original_meta_box', '0' );
|
@@ -136,32 +139,32 @@ function duplicate_post_plugin_upgrade() {
|
|
136 |
add_option( 'duplicate_post_show_link_in', $show_links_in_defaults );
|
137 |
|
138 |
$taxonomies_blacklist = get_option( 'duplicate_post_taxonomies_blacklist' );
|
139 |
-
if (
|
140 |
-
$taxonomies_blacklist =
|
141 |
}
|
142 |
if ( in_array( 'post_format', $taxonomies_blacklist, true ) ) {
|
143 |
update_option( 'duplicate_post_copyformat', 0 );
|
144 |
-
$taxonomies_blacklist = array_diff( $taxonomies_blacklist,
|
145 |
update_option( 'duplicate_post_taxonomies_blacklist', $taxonomies_blacklist );
|
146 |
}
|
147 |
|
148 |
$meta_blacklist = explode( ',', get_option( 'duplicate_post_blacklist' ) );
|
149 |
-
if (
|
150 |
-
$meta_blacklist =
|
151 |
}
|
152 |
$meta_blacklist = array_map( 'trim', $meta_blacklist );
|
153 |
if ( in_array( '_wp_page_template', $meta_blacklist, true ) ) {
|
154 |
update_option( 'duplicate_post_copytemplate', 0 );
|
155 |
-
$meta_blacklist = array_diff( $meta_blacklist,
|
156 |
}
|
157 |
if ( in_array( '_thumbnail_id', $meta_blacklist, true ) ) {
|
158 |
update_option( 'duplicate_post_copythumbnail', 0 );
|
159 |
-
$meta_blacklist = array_diff( $meta_blacklist,
|
160 |
}
|
161 |
update_option( 'duplicate_post_blacklist', implode( ',', $meta_blacklist ) );
|
162 |
|
163 |
delete_option( 'duplicate_post_show_notice' );
|
164 |
-
if ( version_compare( $installed_version, '4.
|
165 |
update_site_option( 'duplicate_post_show_notice', 1 );
|
166 |
}
|
167 |
|
@@ -191,12 +194,12 @@ function duplicate_post_migrate_show_links_in_options( $defaults ) {
|
|
191 |
|
192 |
$new_options = [];
|
193 |
foreach ( $options_to_migrate as $old => $new ) {
|
194 |
-
$new_options[ $new ] =
|
195 |
|
196 |
-
|
197 |
}
|
198 |
|
199 |
-
|
200 |
}
|
201 |
|
202 |
/**
|
@@ -210,10 +213,9 @@ function duplicate_post_show_update_notice() {
|
|
210 |
}
|
211 |
|
212 |
$current_screen = get_current_screen();
|
213 |
-
if (
|
214 |
-
empty( $current_screen )
|
215 |
-
|
216 |
-
( $current_screen->base !== 'dashboard' && $current_screen->base !== 'plugins' )
|
217 |
) {
|
218 |
return;
|
219 |
}
|
@@ -224,37 +226,37 @@ function duplicate_post_show_update_notice() {
|
|
224 |
__( "What's new in Yoast Duplicate Post version %s:", 'duplicate-post' ),
|
225 |
DUPLICATE_POST_CURRENT_VERSION
|
226 |
) . '</strong> ';
|
227 |
-
$message .= __( '
|
228 |
. ' ';
|
229 |
|
230 |
-
$message .= '<a href="https://
|
231 |
. sprintf(
|
232 |
/* translators: %s: Yoast Duplicate Post version. */
|
233 |
-
__( 'Read
|
234 |
DUPLICATE_POST_CURRENT_VERSION
|
235 |
)
|
236 |
. '</a></p>';
|
237 |
|
238 |
$message .= '<p>%%SIGNUP_FORM%%</p>';
|
239 |
|
240 |
-
$allowed_tags =
|
241 |
-
'a' =>
|
242 |
-
'href' =>
|
243 |
-
|
244 |
-
'br' =>
|
245 |
-
'p' =>
|
246 |
-
'strong' =>
|
247 |
-
|
248 |
|
249 |
$sanitized_message = wp_kses( $message, $allowed_tags );
|
250 |
-
$sanitized_message = str_replace( '%%SIGNUP_FORM%%',
|
251 |
|
252 |
$img_path = plugins_url( '/duplicate_post_yoast_icon-125x125.png', __FILE__ );
|
253 |
|
254 |
-
echo '<div id="duplicate-post-notice" class="' . esc_attr( $class ) . '" style="display: flex; align-items:
|
255 |
-
<img src="' . esc_url( $img_path ) . '" alt=""/>
|
256 |
-
<div style="margin: 0.5em">' . $sanitized_message
|
257 |
-
'</div></div>';
|
258 |
|
259 |
echo "<script>
|
260 |
function duplicate_post_dismiss_notice(){
|
@@ -281,8 +283,7 @@ function duplicate_post_show_update_notice() {
|
|
281 |
* @return bool
|
282 |
*/
|
283 |
function duplicate_post_dismiss_notice() {
|
284 |
-
|
285 |
-
return $result;
|
286 |
}
|
287 |
|
288 |
/**
|
@@ -306,8 +307,8 @@ function duplicate_post_copy_post_taxonomies( $new_id, $post ) {
|
|
306 |
}
|
307 |
|
308 |
$taxonomies_blacklist = get_option( 'duplicate_post_taxonomies_blacklist' );
|
309 |
-
if (
|
310 |
-
$taxonomies_blacklist =
|
311 |
}
|
312 |
if ( intval( get_option( 'duplicate_post_copyformat' ) ) === 0 ) {
|
313 |
$taxonomies_blacklist[] = 'post_format';
|
@@ -324,8 +325,8 @@ function duplicate_post_copy_post_taxonomies( $new_id, $post ) {
|
|
324 |
|
325 |
$taxonomies = array_diff( $post_taxonomies, $taxonomies_blacklist );
|
326 |
foreach ( $taxonomies as $taxonomy ) {
|
327 |
-
$post_terms = wp_get_object_terms( $post->ID, $taxonomy,
|
328 |
-
$terms =
|
329 |
$num_terms = count( $post_terms );
|
330 |
for ( $i = 0; $i < $num_terms; $i++ ) {
|
331 |
$terms[] = $post_terms[ $i ]->slug;
|
@@ -347,9 +348,10 @@ function duplicate_post_copy_post_meta_info( $new_id, $post ) {
|
|
347 |
return;
|
348 |
}
|
349 |
$meta_blacklist = get_option( 'duplicate_post_blacklist' );
|
350 |
-
if (
|
351 |
-
$meta_blacklist =
|
352 |
-
}
|
|
|
353 |
$meta_blacklist = explode( ',', $meta_blacklist );
|
354 |
$meta_blacklist = array_filter( $meta_blacklist );
|
355 |
$meta_blacklist = array_map( 'trim', $meta_blacklist );
|
@@ -365,7 +367,8 @@ function duplicate_post_copy_post_meta_info( $new_id, $post ) {
|
|
365 |
$meta_blacklist[] = '_thumbnail_id';
|
366 |
}
|
367 |
|
368 |
-
$meta_blacklist = apply_filters_deprecated( 'duplicate_post_blacklist_filter',
|
|
|
369 |
/**
|
370 |
* Filters the meta fields excludelist when copying a post.
|
371 |
*
|
@@ -377,15 +380,16 @@ function duplicate_post_copy_post_meta_info( $new_id, $post ) {
|
|
377 |
|
378 |
$meta_blacklist_string = '(' . implode( ')|(', $meta_blacklist ) . ')';
|
379 |
if ( strpos( $meta_blacklist_string, '*' ) !== false ) {
|
380 |
-
$meta_blacklist_string = str_replace(
|
381 |
|
382 |
-
$meta_keys =
|
383 |
foreach ( $post_meta_keys as $meta_key ) {
|
384 |
if ( ! preg_match( '#^' . $meta_blacklist_string . '$#', $meta_key ) ) {
|
385 |
$meta_keys[] = $meta_key;
|
386 |
}
|
387 |
}
|
388 |
-
}
|
|
|
389 |
$meta_keys = array_diff( $post_meta_keys, $meta_blacklist );
|
390 |
}
|
391 |
|
@@ -411,15 +415,14 @@ function duplicate_post_copy_post_meta_info( $new_id, $post ) {
|
|
411 |
* Workaround for inconsistent wp_slash.
|
412 |
* Works only with WP 4.4+ (map_deep)
|
413 |
*
|
414 |
-
* @ignore
|
415 |
-
*
|
416 |
* @param mixed $value Array or object to be recursively slashed.
|
417 |
* @return string|mixed
|
418 |
*/
|
419 |
function duplicate_post_addslashes_deep( $value ) {
|
420 |
if ( function_exists( 'map_deep' ) ) {
|
421 |
return map_deep( $value, 'duplicate_post_addslashes_to_strings_only' );
|
422 |
-
}
|
|
|
423 |
return wp_slash( $value );
|
424 |
}
|
425 |
}
|
@@ -427,20 +430,16 @@ function duplicate_post_addslashes_deep( $value ) {
|
|
427 |
/**
|
428 |
* Adds slashes only to strings.
|
429 |
*
|
430 |
-
* @ignore
|
431 |
-
*
|
432 |
* @param mixed $value Value to slash only if string.
|
433 |
* @return string|mixed
|
434 |
*/
|
435 |
function duplicate_post_addslashes_to_strings_only( $value ) {
|
436 |
-
return
|
437 |
}
|
438 |
|
439 |
/**
|
440 |
* Replacement function for faulty core wp_slash().
|
441 |
*
|
442 |
-
* @ignore
|
443 |
-
*
|
444 |
* @param mixed $value What to add slash to.
|
445 |
* @return mixed
|
446 |
*/
|
@@ -459,16 +458,16 @@ function duplicate_post_copy_attachments( $new_id, $post ) {
|
|
459 |
$old_thumbnail_id = get_post_thumbnail_id( $post->ID );
|
460 |
// Get children.
|
461 |
$children = get_posts(
|
462 |
-
|
463 |
'post_type' => 'any',
|
464 |
'numberposts' => -1,
|
465 |
'post_status' => 'any',
|
466 |
'post_parent' => $post->ID,
|
467 |
-
|
468 |
);
|
469 |
// Clone old attachments.
|
470 |
foreach ( $children as $child ) {
|
471 |
-
if (
|
472 |
continue;
|
473 |
}
|
474 |
$url = wp_get_attachment_url( $child->ID );
|
@@ -480,7 +479,7 @@ function duplicate_post_copy_attachments( $new_id, $post ) {
|
|
480 |
|
481 |
$desc = wp_slash( $child->post_content );
|
482 |
|
483 |
-
$file_array =
|
484 |
$file_array['name'] = basename( $url );
|
485 |
$file_array['tmp_name'] = $tmp;
|
486 |
// "Upload" to the media collection
|
@@ -491,12 +490,12 @@ function duplicate_post_copy_attachments( $new_id, $post ) {
|
|
491 |
continue;
|
492 |
}
|
493 |
$new_post_author = wp_get_current_user();
|
494 |
-
$cloned_child =
|
495 |
'ID' => $new_attachment_id,
|
496 |
'post_title' => $child->post_title,
|
497 |
'post_exceprt' => $child->post_title,
|
498 |
'post_author' => $new_post_author->ID,
|
499 |
-
|
500 |
wp_update_post( wp_slash( $cloned_child ) );
|
501 |
|
502 |
$alt_title = get_post_meta( $child->ID, '_wp_attachment_image_alt', true );
|
@@ -521,16 +520,16 @@ function duplicate_post_copy_attachments( $new_id, $post ) {
|
|
521 |
function duplicate_post_copy_children( $new_id, $post, $status = '' ) {
|
522 |
// Get children.
|
523 |
$children = get_posts(
|
524 |
-
|
525 |
'post_type' => 'any',
|
526 |
'numberposts' => -1,
|
527 |
'post_status' => 'any',
|
528 |
'post_parent' => $post->ID,
|
529 |
-
|
530 |
);
|
531 |
|
532 |
foreach ( $children as $child ) {
|
533 |
-
if (
|
534 |
continue;
|
535 |
}
|
536 |
duplicate_post_create_duplicate( $child, $status, $new_id );
|
@@ -545,21 +544,21 @@ function duplicate_post_copy_children( $new_id, $post, $status = '' ) {
|
|
545 |
*/
|
546 |
function duplicate_post_copy_comments( $new_id, $post ) {
|
547 |
$comments = get_comments(
|
548 |
-
|
549 |
'post_id' => $post->ID,
|
550 |
'order' => 'ASC',
|
551 |
'orderby' => 'comment_date_gmt',
|
552 |
-
|
553 |
);
|
554 |
|
555 |
-
$old_id_to_new =
|
556 |
foreach ( $comments as $comment ) {
|
557 |
// Do not copy pingbacks or trackbacks.
|
558 |
if ( $comment->comment_type === 'pingback' || $comment->comment_type === 'trackback' ) {
|
559 |
continue;
|
560 |
}
|
561 |
$parent = ( $comment->comment_parent && $old_id_to_new[ $comment->comment_parent ] ) ? $old_id_to_new[ $comment->comment_parent ] : 0;
|
562 |
-
$commentdata =
|
563 |
'comment_post_ID' => $new_id,
|
564 |
'comment_author' => $comment->comment_author,
|
565 |
'comment_author_email' => $comment->comment_author_email,
|
@@ -572,7 +571,7 @@ function duplicate_post_copy_comments( $new_id, $post ) {
|
|
572 |
'comment_agent' => $comment->comment_agent,
|
573 |
'comment_karma' => $comment->comment_karma,
|
574 |
'comment_approved' => $comment->comment_approved,
|
575 |
-
|
576 |
if ( intval( get_option( 'duplicate_post_copydate' ) ) === 1 ) {
|
577 |
$commentdata['comment_date'] = $comment->comment_date;
|
578 |
$commentdata['comment_date_gmt'] = get_gmt_from_date( $comment->comment_date );
|
@@ -621,11 +620,11 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
621 |
wp_die( esc_html( __( 'You aren\'t allowed to duplicate this post', 'duplicate-post' ) ) );
|
622 |
}
|
623 |
|
624 |
-
if ( ! duplicate_post_is_post_type_enabled( $post->post_type ) &&
|
625 |
wp_die(
|
626 |
esc_html(
|
627 |
-
__( 'Copy features for this post type are not enabled in options page', 'duplicate-post' ) . ': '
|
628 |
-
$post->post_type
|
629 |
)
|
630 |
);
|
631 |
}
|
@@ -633,7 +632,7 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
633 |
$new_post_status = ( empty( $status ) ) ? $post->post_status : $status;
|
634 |
$title = ' ';
|
635 |
|
636 |
-
if (
|
637 |
$prefix = sanitize_text_field( get_option( 'duplicate_post_title_prefix' ) );
|
638 |
$suffix = sanitize_text_field( get_option( 'duplicate_post_title_suffix' ) );
|
639 |
if ( intval( get_option( 'duplicate_post_copytitle' ) ) === 1 ) {
|
@@ -644,7 +643,8 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
644 |
if ( ! empty( $suffix ) ) {
|
645 |
$suffix = ' ' . $suffix;
|
646 |
}
|
647 |
-
}
|
|
|
648 |
$title = ' ';
|
649 |
}
|
650 |
$title = trim( $prefix . $title . $suffix );
|
@@ -659,19 +659,17 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
659 |
|
660 |
if ( intval( get_option( 'duplicate_post_copystatus' ) ) === 0 ) {
|
661 |
$new_post_status = 'draft';
|
662 |
-
}
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
}
|
669 |
-
} else {
|
670 |
-
if ( ! current_user_can( 'publish_posts' ) ) {
|
671 |
-
$new_post_status = 'pending';
|
672 |
-
}
|
673 |
}
|
674 |
}
|
|
|
|
|
|
|
675 |
}
|
676 |
}
|
677 |
|
@@ -683,10 +681,9 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
683 |
if ( current_user_can( 'edit_others_pages' ) ) {
|
684 |
$new_post_author_id = $post->post_author;
|
685 |
}
|
686 |
-
}
|
687 |
-
|
688 |
-
|
689 |
-
}
|
690 |
}
|
691 |
}
|
692 |
|
@@ -702,7 +699,7 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
702 |
}
|
703 |
$new_post_parent = empty( $parent_id ) ? $post->post_parent : $parent_id;
|
704 |
|
705 |
-
$new_post =
|
706 |
'menu_order' => $menu_order,
|
707 |
'comment_status' => $post->comment_status,
|
708 |
'ping_status' => $post->ping_status,
|
@@ -717,7 +714,7 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
717 |
'post_title' => $title,
|
718 |
'post_type' => $post->post_type,
|
719 |
'post_name' => $post_name,
|
720 |
-
|
721 |
|
722 |
if ( intval( get_option( 'duplicate_post_copydate' ) ) === 1 ) {
|
723 |
$new_post_date = $post->post_date;
|
@@ -738,11 +735,12 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
738 |
|
739 |
// If you have written a plugin which uses non-WP database tables to save
|
740 |
// information about a post you can hook this action to dupe that data.
|
741 |
-
if (
|
742 |
|
743 |
-
if (
|
744 |
do_action( 'dp_duplicate_page', $new_post_id, $post, $status );
|
745 |
-
}
|
|
|
746 |
do_action( 'dp_duplicate_post', $new_post_id, $post, $status );
|
747 |
}
|
748 |
|
@@ -771,50 +769,8 @@ function duplicate_post_create_duplicate( $post, $status = '', $parent_id = '' )
|
|
771 |
* @return array
|
772 |
*/
|
773 |
function duplicate_post_add_plugin_links( $links, $file ) {
|
774 |
-
if ( plugin_basename(
|
775 |
$links[] = '<a href="https://yoast.com/wordpress/plugins/duplicate-post">' . esc_html__( 'Documentation', 'duplicate-post' ) . '</a>';
|
776 |
}
|
777 |
return $links;
|
778 |
}
|
779 |
-
|
780 |
-
/**
|
781 |
-
* Renders the newsletter signup form.
|
782 |
-
*
|
783 |
-
* @return string The HTML of the newsletter signup form (escaped).
|
784 |
-
*/
|
785 |
-
function duplicate_post_newsletter_signup_form() {
|
786 |
-
$copy = sprintf(
|
787 |
-
/* translators: 1: Yoast */
|
788 |
-
__(
|
789 |
-
'If you want to stay up to date about all the exciting developments around Duplicate Post, subscribe to the %1$s newsletter!',
|
790 |
-
'duplicate-post'
|
791 |
-
),
|
792 |
-
'Yoast'
|
793 |
-
);
|
794 |
-
|
795 |
-
$email_label = __( 'Email Address', 'duplicate-post' );
|
796 |
-
|
797 |
-
$html = '
|
798 |
-
<!-- Begin Mailchimp Signup Form -->
|
799 |
-
<div id="mc_embed_signup">
|
800 |
-
<form action="https://yoast.us1.list-manage.com/subscribe/post?u=ffa93edfe21752c921f860358&id=972f1c9122" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
|
801 |
-
<div id="mc_embed_signup_scroll">
|
802 |
-
' . $copy . '
|
803 |
-
<div class="mc-field-group" style="margin-top: 8px;">
|
804 |
-
<label for="mce-EMAIL">' . $email_label . '</label>
|
805 |
-
<input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
|
806 |
-
<input type="submit" value="' . esc_attr__( 'Subscribe', 'duplicate-post' ) . '" name="subscribe" id="mc-embedded-subscribe" class="button">
|
807 |
-
</div>
|
808 |
-
<div id="mce-responses" class="clear">
|
809 |
-
<div class="response" id="mce-error-response" style="display:none"></div>
|
810 |
-
<div class="response" id="mce-success-response" style="display:none"></div>
|
811 |
-
</div> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
|
812 |
-
<div class="screen-reader-text" aria-hidden="true"><input type="text" name="b_ffa93edfe21752c921f860358_972f1c9122" tabindex="-1" value=""></div>
|
813 |
-
</div>
|
814 |
-
</form>
|
815 |
-
</div>
|
816 |
-
<!--End mc_embed_signup-->
|
817 |
-
';
|
818 |
-
|
819 |
-
return $html;
|
820 |
-
}
|
2 |
/**
|
3 |
* Backend functions.
|
4 |
*
|
5 |
+
* @package Yoast\WP\Duplicate_Post
|
6 |
* @since 2.0
|
7 |
*/
|
8 |
|
10 |
return;
|
11 |
}
|
12 |
|
13 |
+
use Yoast\WP\Duplicate_Post\UI\Newsletter;
|
14 |
|
15 |
+
require_once DUPLICATE_POST_PATH . 'options.php';
|
16 |
+
|
17 |
+
require_once DUPLICATE_POST_PATH . 'compat/wpml-functions.php';
|
18 |
+
require_once DUPLICATE_POST_PATH . 'compat/jetpack-functions.php';
|
19 |
|
20 |
/**
|
21 |
* Wrapper for the option 'duplicate_post_version'.
|
42 |
if ( intval( get_site_option( 'duplicate_post_show_notice' ) ) === 1 ) {
|
43 |
if ( is_multisite() ) {
|
44 |
add_action( 'network_admin_notices', 'duplicate_post_show_update_notice' );
|
45 |
+
}
|
46 |
+
else {
|
47 |
add_action( 'admin_notices', 'duplicate_post_show_update_notice' );
|
48 |
}
|
49 |
add_action( 'wp_ajax_duplicate_post_dismiss_notice', 'duplicate_post_dismiss_notice' );
|
85 |
|
86 |
if ( empty( $installed_version ) ) {
|
87 |
// Get default roles.
|
88 |
+
$default_roles = [
|
89 |
'editor',
|
90 |
'administrator',
|
91 |
'wpseo_manager',
|
92 |
'wpseo_editor',
|
93 |
+
];
|
94 |
|
95 |
foreach ( $default_roles as $name ) {
|
96 |
$role = get_role( $name );
|
122 |
add_option( 'duplicate_post_copychildren', '0' );
|
123 |
add_option( 'duplicate_post_copycomments', '0' );
|
124 |
add_option( 'duplicate_post_copymenuorder', '1' );
|
125 |
+
add_option( 'duplicate_post_taxonomies_blacklist', [] );
|
126 |
add_option( 'duplicate_post_blacklist', '' );
|
127 |
+
add_option( 'duplicate_post_types_enabled', [ 'post', 'page' ] );
|
128 |
add_option( 'duplicate_post_show_original_column', '0' );
|
129 |
add_option( 'duplicate_post_show_original_in_post_states', '0' );
|
130 |
add_option( 'duplicate_post_show_original_meta_box', '0' );
|
139 |
add_option( 'duplicate_post_show_link_in', $show_links_in_defaults );
|
140 |
|
141 |
$taxonomies_blacklist = get_option( 'duplicate_post_taxonomies_blacklist' );
|
142 |
+
if ( $taxonomies_blacklist === '' ) {
|
143 |
+
$taxonomies_blacklist = [];
|
144 |
}
|
145 |
if ( in_array( 'post_format', $taxonomies_blacklist, true ) ) {
|
146 |
update_option( 'duplicate_post_copyformat', 0 );
|
147 |
+
$taxonomies_blacklist = array_diff( $taxonomies_blacklist, [ 'post_format' ] );
|
148 |
update_option( 'duplicate_post_taxonomies_blacklist', $taxonomies_blacklist );
|
149 |
}
|
150 |
|
151 |
$meta_blacklist = explode( ',', get_option( 'duplicate_post_blacklist' ) );
|
152 |
+
if ( $meta_blacklist === '' ) {
|
153 |
+
$meta_blacklist = [];
|
154 |
}
|
155 |
$meta_blacklist = array_map( 'trim', $meta_blacklist );
|
156 |
if ( in_array( '_wp_page_template', $meta_blacklist, true ) ) {
|
157 |
update_option( 'duplicate_post_copytemplate', 0 );
|
158 |
+
$meta_blacklist = array_diff( $meta_blacklist, [ '_wp_page_template' ] );
|
159 |
}
|
160 |
if ( in_array( '_thumbnail_id', $meta_blacklist, true ) ) {
|
161 |
update_option( 'duplicate_post_copythumbnail', 0 );
|
162 |
+
$meta_blacklist = array_diff( $meta_blacklist, [ '_thumbnail_id' ] );
|
163 |
}
|
164 |
update_option( 'duplicate_post_blacklist', implode( ',', $meta_blacklist ) );
|
165 |
|
166 |
delete_option( 'duplicate_post_show_notice' );
|
167 |
+
if ( version_compare( $installed_version, '4.2.0' ) < 0 ) {
|
168 |
update_site_option( 'duplicate_post_show_notice', 1 );
|
169 |
}
|
170 |
|
194 |
|
195 |
$new_options = [];
|
196 |
foreach ( $options_to_migrate as $old => $new ) {
|
197 |
+
$new_options[ $new ] = get_option( $old, $defaults[ $new ] );
|
198 |
|
199 |
+
delete_option( $old );
|
200 |
}
|
201 |
|
202 |
+
update_option( 'duplicate_post_show_link_in', $new_options );
|
203 |
}
|
204 |
|
205 |
/**
|
213 |
}
|
214 |
|
215 |
$current_screen = get_current_screen();
|
216 |
+
if ( empty( $current_screen )
|
217 |
+
|| empty( $current_screen->base )
|
218 |
+
|| ( $current_screen->base !== 'dashboard' && $current_screen->base !== 'plugins' )
|
|
|
219 |
) {
|
220 |
return;
|
221 |
}
|
226 |
__( "What's new in Yoast Duplicate Post version %s:", 'duplicate-post' ),
|
227 |
DUPLICATE_POST_CURRENT_VERSION
|
228 |
) . '</strong> ';
|
229 |
+
$message .= __( 'improved compatibility with PHP 8.0 and fixes for some bugs regarding translations and the Rewrite & Republish feature.', 'duplicate-post' )
|
230 |
. ' ';
|
231 |
|
232 |
+
$message .= '<a href="https://wordpress.org/plugins/duplicate-post/#developers">'
|
233 |
. sprintf(
|
234 |
/* translators: %s: Yoast Duplicate Post version. */
|
235 |
+
__( 'Read the changelog', 'duplicate-post' ),
|
236 |
DUPLICATE_POST_CURRENT_VERSION
|
237 |
)
|
238 |
. '</a></p>';
|
239 |
|
240 |
$message .= '<p>%%SIGNUP_FORM%%</p>';
|
241 |
|
242 |
+
$allowed_tags = [
|
243 |
+
'a' => [
|
244 |
+
'href' => [],
|
245 |
+
],
|
246 |
+
'br' => [],
|
247 |
+
'p' => [],
|
248 |
+
'strong' => [],
|
249 |
+
];
|
250 |
|
251 |
$sanitized_message = wp_kses( $message, $allowed_tags );
|
252 |
+
$sanitized_message = str_replace( '%%SIGNUP_FORM%%', Newsletter::newsletter_signup_form(), $sanitized_message );
|
253 |
|
254 |
$img_path = plugins_url( '/duplicate_post_yoast_icon-125x125.png', __FILE__ );
|
255 |
|
256 |
+
echo '<div id="duplicate-post-notice" class="' . esc_attr( $class ) . '" style="display: flex; align-items: flex-start;">
|
257 |
+
<img src="' . esc_url( $img_path ) . '" alt="" style="margin: 1.5em 0.5em 1.5em 0;"/>
|
258 |
+
<div style="margin: 0.5em">' . $sanitized_message // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: escaped properly above.
|
259 |
+
. '</div></div>';
|
260 |
|
261 |
echo "<script>
|
262 |
function duplicate_post_dismiss_notice(){
|
283 |
* @return bool
|
284 |
*/
|
285 |
function duplicate_post_dismiss_notice() {
|
286 |
+
return update_site_option( 'duplicate_post_show_notice', 0 );
|
|
|
287 |
}
|
288 |
|
289 |
/**
|
307 |
}
|
308 |
|
309 |
$taxonomies_blacklist = get_option( 'duplicate_post_taxonomies_blacklist' );
|
310 |
+
if ( $taxonomies_blacklist === '' ) {
|
311 |
+
$taxonomies_blacklist = [];
|
312 |
}
|
313 |
if ( intval( get_option( 'duplicate_post_copyformat' ) ) === 0 ) {
|
314 |
$taxonomies_blacklist[] = 'post_format';
|
325 |
|
326 |
$taxonomies = array_diff( $post_taxonomies, $taxonomies_blacklist );
|
327 |
foreach ( $taxonomies as $taxonomy ) {
|
328 |
+
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, [ 'orderby' => 'term_order' ] );
|
329 |
+
$terms = [];
|
330 |
$num_terms = count( $post_terms );
|
331 |
for ( $i = 0; $i < $num_terms; $i++ ) {
|
332 |
$terms[] = $post_terms[ $i ]->slug;
|
348 |
return;
|
349 |
}
|
350 |
$meta_blacklist = get_option( 'duplicate_post_blacklist' );
|
351 |
+
if ( $meta_blacklist === '' ) {
|
352 |
+
$meta_blacklist = [];
|
353 |
+
}
|
354 |
+
else {
|
355 |
$meta_blacklist = explode( ',', $meta_blacklist );
|
356 |
$meta_blacklist = array_filter( $meta_blacklist );
|
357 |
$meta_blacklist = array_map( 'trim', $meta_blacklist );
|
367 |
$meta_blacklist[] = '_thumbnail_id';
|
368 |
}
|
369 |
|
370 |
+
$meta_blacklist = apply_filters_deprecated( 'duplicate_post_blacklist_filter', [ $meta_blacklist ], '3.2.5', 'duplicate_post_excludelist_filter' );
|
371 |
+
|
372 |
/**
|
373 |
* Filters the meta fields excludelist when copying a post.
|
374 |
*
|
380 |
|
381 |
$meta_blacklist_string = '(' . implode( ')|(', $meta_blacklist ) . ')';
|
382 |
if ( strpos( $meta_blacklist_string, '*' ) !== false ) {
|
383 |
+
$meta_blacklist_string = str_replace( [ '*' ], [ '[a-zA-Z0-9_]*' ], $meta_blacklist_string );
|
384 |
|
385 |
+
$meta_keys = [];
|
386 |
foreach ( $post_meta_keys as $meta_key ) {
|
387 |
if ( ! preg_match( '#^' . $meta_blacklist_string . '$#', $meta_key ) ) {
|
388 |
$meta_keys[] = $meta_key;
|
389 |
}
|
390 |
}
|
391 |
+
}
|
392 |
+
else {
|
393 |
$meta_keys = array_diff( $post_meta_keys, $meta_blacklist );
|
394 |
}
|
395 |
|
415 |
* Workaround for inconsistent wp_slash.
|
416 |
* Works only with WP 4.4+ (map_deep)
|
417 |
*
|
|
|
|
|
418 |
* @param mixed $value Array or object to be recursively slashed.
|
419 |
* @return string|mixed
|
420 |
*/
|
421 |
function duplicate_post_addslashes_deep( $value ) {
|
422 |
if ( function_exists( 'map_deep' ) ) {
|
423 |
return map_deep( $value, 'duplicate_post_addslashes_to_strings_only' );
|
424 |
+
}
|
425 |
+
else {
|
426 |
return wp_slash( $value );
|
427 |
}
|
428 |
}
|
430 |
/**
|
431 |
* Adds slashes only to strings.
|
432 |
*
|
|
|
|
|
433 |
* @param mixed $value Value to slash only if string.
|
434 |
* @return string|mixed
|
435 |
*/
|
436 |
function duplicate_post_addslashes_to_strings_only( $value ) {
|
437 |
+
return Yoast\WP\Duplicate_Post\Utils::addslashes_to_strings_only( $value );
|
438 |
}
|
439 |
|
440 |
/**
|
441 |
* Replacement function for faulty core wp_slash().
|
442 |
*
|
|
|
|
|
443 |
* @param mixed $value What to add slash to.
|
444 |
* @return mixed
|
445 |
*/
|
458 |
$old_thumbnail_id = get_post_thumbnail_id( $post->ID );
|
459 |
// Get children.
|
460 |
$children = get_posts(
|
461 |
+
[
|
462 |
'post_type' => 'any',
|
463 |
'numberposts' => -1,
|
464 |
'post_status' => 'any',
|
465 |
'post_parent' => $post->ID,
|
466 |
+
]
|
467 |
);
|
468 |
// Clone old attachments.
|
469 |
foreach ( $children as $child ) {
|
470 |
+
if ( $child->post_type !== 'attachment' ) {
|
471 |
continue;
|
472 |
}
|
473 |
$url = wp_get_attachment_url( $child->ID );
|
479 |
|
480 |
$desc = wp_slash( $child->post_content );
|
481 |
|
482 |
+
$file_array = [];
|
483 |
$file_array['name'] = basename( $url );
|
484 |
$file_array['tmp_name'] = $tmp;
|
485 |
// "Upload" to the media collection
|
490 |
continue;
|
491 |
}
|
492 |
$new_post_author = wp_get_current_user();
|
493 |
+
$cloned_child = [
|
494 |
'ID' => $new_attachment_id,
|
495 |
'post_title' => $child->post_title,
|
496 |
'post_exceprt' => $child->post_title,
|
497 |
'post_author' => $new_post_author->ID,
|
498 |
+
];
|
499 |
wp_update_post( wp_slash( $cloned_child ) );
|
500 |
|
501 |
$alt_title = get_post_meta( $child->ID, '_wp_attachment_image_alt', true );
|
520 |
function duplicate_post_copy_children( $new_id, $post, $status = '' ) {
|
521 |
// Get children.
|
522 |
$children = get_posts(
|
523 |
+
[
|
524 |
'post_type' => 'any',
|
525 |
'numberposts' => -1,
|
526 |
'post_status' => 'any',
|
527 |
'post_parent' => $post->ID,
|
528 |
+
]
|
529 |
);
|
530 |
|
531 |
foreach ( $children as $child ) {
|
532 |
+
if ( $child->post_type === 'attachment' ) {
|
533 |
continue;
|
534 |
}
|
535 |
duplicate_post_create_duplicate( $child, $status, $new_id );
|
544 |
*/
|
545 |
function duplicate_post_copy_comments( $new_id, $post ) {
|
546 |
$comments = get_comments(
|
547 |
+
[
|
548 |
'post_id' => $post->ID,
|
549 |
'order' => 'ASC',
|
550 |
'orderby' => 'comment_date_gmt',
|
551 |
+
]
|
552 |
);
|
553 |
|
554 |
+
$old_id_to_new = [];
|
555 |
foreach ( $comments as $comment ) {
|
556 |
// Do not copy pingbacks or trackbacks.
|
557 |
if ( $comment->comment_type === 'pingback' || $comment->comment_type === 'trackback' ) {
|
558 |
continue;
|
559 |
}
|
560 |
$parent = ( $comment->comment_parent && $old_id_to_new[ $comment->comment_parent ] ) ? $old_id_to_new[ $comment->comment_parent ] : 0;
|
561 |
+
$commentdata = [
|
562 |
'comment_post_ID' => $new_id,
|
563 |
'comment_author' => $comment->comment_author,
|
564 |
'comment_author_email' => $comment->comment_author_email,
|
571 |
'comment_agent' => $comment->comment_agent,
|
572 |
'comment_karma' => $comment->comment_karma,
|
573 |
'comment_approved' => $comment->comment_approved,
|
574 |
+
];
|
575 |
if ( intval( get_option( 'duplicate_post_copydate' ) ) === 1 ) {
|
576 |
$commentdata['comment_date'] = $comment->comment_date;
|
577 |
$commentdata['comment_date_gmt'] = get_gmt_from_date( $comment->comment_date );
|
620 |
wp_die( esc_html( __( 'You aren\'t allowed to duplicate this post', 'duplicate-post' ) ) );
|
621 |
}
|
622 |
|
623 |
+
if ( ! duplicate_post_is_post_type_enabled( $post->post_type ) && $post->post_type !== 'attachment' ) {
|
624 |
wp_die(
|
625 |
esc_html(
|
626 |
+
__( 'Copy features for this post type are not enabled in options page', 'duplicate-post' ) . ': '
|
627 |
+
. $post->post_type
|
628 |
)
|
629 |
);
|
630 |
}
|
632 |
$new_post_status = ( empty( $status ) ) ? $post->post_status : $status;
|
633 |
$title = ' ';
|
634 |
|
635 |
+
if ( $post->post_type !== 'attachment' ) {
|
636 |
$prefix = sanitize_text_field( get_option( 'duplicate_post_title_prefix' ) );
|
637 |
$suffix = sanitize_text_field( get_option( 'duplicate_post_title_suffix' ) );
|
638 |
if ( intval( get_option( 'duplicate_post_copytitle' ) ) === 1 ) {
|
643 |
if ( ! empty( $suffix ) ) {
|
644 |
$suffix = ' ' . $suffix;
|
645 |
}
|
646 |
+
}
|
647 |
+
else {
|
648 |
$title = ' ';
|
649 |
}
|
650 |
$title = trim( $prefix . $title . $suffix );
|
659 |
|
660 |
if ( intval( get_option( 'duplicate_post_copystatus' ) ) === 0 ) {
|
661 |
$new_post_status = 'draft';
|
662 |
+
}
|
663 |
+
elseif ( $new_post_status === 'publish' || $new_post_status === 'future' ) {
|
664 |
+
// Check if the user has the right capability.
|
665 |
+
if ( is_post_type_hierarchical( $post->post_type ) ) {
|
666 |
+
if ( ! current_user_can( 'publish_pages' ) ) {
|
667 |
+
$new_post_status = 'pending';
|
|
|
|
|
|
|
|
|
|
|
668 |
}
|
669 |
}
|
670 |
+
elseif ( ! current_user_can( 'publish_posts' ) ) {
|
671 |
+
$new_post_status = 'pending';
|
672 |
+
}
|
673 |
}
|
674 |
}
|
675 |
|
681 |
if ( current_user_can( 'edit_others_pages' ) ) {
|
682 |
$new_post_author_id = $post->post_author;
|
683 |
}
|
684 |
+
}
|
685 |
+
elseif ( current_user_can( 'edit_others_posts' ) ) {
|
686 |
+
$new_post_author_id = $post->post_author;
|
|
|
687 |
}
|
688 |
}
|
689 |
|
699 |
}
|
700 |
$new_post_parent = empty( $parent_id ) ? $post->post_parent : $parent_id;
|
701 |
|
702 |
+
$new_post = [
|
703 |
'menu_order' => $menu_order,
|
704 |
'comment_status' => $post->comment_status,
|
705 |
'ping_status' => $post->ping_status,
|
714 |
'post_title' => $title,
|
715 |
'post_type' => $post->post_type,
|
716 |
'post_name' => $post_name,
|
717 |
+
];
|
718 |
|
719 |
if ( intval( get_option( 'duplicate_post_copydate' ) ) === 1 ) {
|
720 |
$new_post_date = $post->post_date;
|
735 |
|
736 |
// If you have written a plugin which uses non-WP database tables to save
|
737 |
// information about a post you can hook this action to dupe that data.
|
738 |
+
if ( $new_post_id !== 0 && ! is_wp_error( $new_post_id ) ) {
|
739 |
|
740 |
+
if ( $post->post_type === 'page' || is_post_type_hierarchical( $post->post_type ) ) {
|
741 |
do_action( 'dp_duplicate_page', $new_post_id, $post, $status );
|
742 |
+
}
|
743 |
+
else {
|
744 |
do_action( 'dp_duplicate_post', $new_post_id, $post, $status );
|
745 |
}
|
746 |
|
769 |
* @return array
|
770 |
*/
|
771 |
function duplicate_post_add_plugin_links( $links, $file ) {
|
772 |
+
if ( plugin_basename( __DIR__ . '/duplicate-post.php' ) === $file ) {
|
773 |
$links[] = '<a href="https://yoast.com/wordpress/plugins/duplicate-post">' . esc_html__( 'Documentation', 'duplicate-post' ) . '</a>';
|
774 |
}
|
775 |
return $links;
|
776 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
duplicate-post-common.php → common-functions.php
RENAMED
@@ -2,8 +2,8 @@
|
|
2 |
/**
|
3 |
* Common functions.
|
4 |
*
|
5 |
-
* @package
|
6 |
-
* @since
|
7 |
*/
|
8 |
|
9 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
@@ -17,11 +17,12 @@ use Yoast\WP\Duplicate_Post\Utils;
|
|
17 |
* @return bool
|
18 |
*/
|
19 |
function duplicate_post_is_post_type_enabled( $post_type ) {
|
20 |
-
$duplicate_post_types_enabled = get_option( 'duplicate_post_types_enabled',
|
21 |
if ( ! is_array( $duplicate_post_types_enabled ) ) {
|
22 |
-
$duplicate_post_types_enabled =
|
23 |
}
|
24 |
-
|
|
|
25 |
$duplicate_post_types_enabled = apply_filters( 'duplicate_post_enabled_post_types', $duplicate_post_types_enabled );
|
26 |
return in_array( $post_type, $duplicate_post_types_enabled, true );
|
27 |
}
|
@@ -49,7 +50,8 @@ function duplicate_post_get_clone_post_link( $id = 0, $context = 'display', $dra
|
|
49 |
|
50 |
if ( $draft ) {
|
51 |
return $link_builder->build_new_draft_link( $post, $context );
|
52 |
-
}
|
|
|
53 |
return $link_builder->build_clone_link( $post, $context );
|
54 |
}
|
55 |
}
|
@@ -73,11 +75,11 @@ function duplicate_post_clone_post_link( $link = null, $before = '', $after = ''
|
|
73 |
return;
|
74 |
}
|
75 |
|
76 |
-
if (
|
77 |
-
$link =
|
78 |
}
|
79 |
|
80 |
-
$link = '<a class="post-clone-link" href="' . esc_url( $url ) . '">' . $link . '</a>';
|
81 |
|
82 |
/**
|
83 |
* Filter on the clone link HTML.
|
2 |
/**
|
3 |
* Common functions.
|
4 |
*
|
5 |
+
* @package Yoast\WP\Duplicate_Post
|
6 |
+
* @since 2.0
|
7 |
*/
|
8 |
|
9 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
17 |
* @return bool
|
18 |
*/
|
19 |
function duplicate_post_is_post_type_enabled( $post_type ) {
|
20 |
+
$duplicate_post_types_enabled = get_option( 'duplicate_post_types_enabled', [ 'post', 'page' ] );
|
21 |
if ( ! is_array( $duplicate_post_types_enabled ) ) {
|
22 |
+
$duplicate_post_types_enabled = [ $duplicate_post_types_enabled ];
|
23 |
}
|
24 |
+
|
25 |
+
/** This filter is documented in src/permissions-helper.php */
|
26 |
$duplicate_post_types_enabled = apply_filters( 'duplicate_post_enabled_post_types', $duplicate_post_types_enabled );
|
27 |
return in_array( $post_type, $duplicate_post_types_enabled, true );
|
28 |
}
|
50 |
|
51 |
if ( $draft ) {
|
52 |
return $link_builder->build_new_draft_link( $post, $context );
|
53 |
+
}
|
54 |
+
else {
|
55 |
return $link_builder->build_clone_link( $post, $context );
|
56 |
}
|
57 |
}
|
75 |
return;
|
76 |
}
|
77 |
|
78 |
+
if ( $link === null ) {
|
79 |
+
$link = __( 'Copy to a new draft', 'duplicate-post' );
|
80 |
}
|
81 |
|
82 |
+
$link = '<a class="post-clone-link" href="' . esc_url( $url ) . '">' . esc_html( $link ) . '</a>';
|
83 |
|
84 |
/**
|
85 |
* Filter on the clone link HTML.
|
compat/duplicate-post-gutenberg.php
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Gutenberg (Block editor)/Classic Editor compatibility functions
|
4 |
-
*
|
5 |
-
* @package Duplicate Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
-
|
9 |
-
add_filter( 'duplicate_post_get_clone_post_link', 'duplicate_post_classic_editor_clone_link', 10, 4 );
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Edits the clone link URL to enforce Classic Editor legacy support.
|
13 |
-
*
|
14 |
-
* @see duplicate_post_get_clone_post_link()
|
15 |
-
*
|
16 |
-
* @param string $url The duplicate post link URL.
|
17 |
-
* @param int $post_id The original post ID.
|
18 |
-
* @param string $context The context in which the URL is used.
|
19 |
-
* @param bool $draft Whether the link is "New Draft" or "Clone".
|
20 |
-
*
|
21 |
-
* @return string
|
22 |
-
*/
|
23 |
-
function duplicate_post_classic_editor_clone_link( $url, $post_id, $context, $draft ) {
|
24 |
-
$post = get_post( $post_id );
|
25 |
-
if ( ! $post ) {
|
26 |
-
return $url;
|
27 |
-
}
|
28 |
-
|
29 |
-
if ( isset( $_GET['classic-editor'] ) // phpcs:ignore WordPress.Security.NonceVerification
|
30 |
-
|| ( $draft && function_exists( 'gutenberg_post_has_blocks' ) && ! gutenberg_post_has_blocks( $post ) )
|
31 |
-
|| ( $draft && function_exists( 'has_blocks' ) && ! has_blocks( $post ) ) ) {
|
32 |
-
if ( 'display' === $context ) {
|
33 |
-
$url .= '&classic-editor';
|
34 |
-
} else {
|
35 |
-
$url .= '&classic-editor';
|
36 |
-
}
|
37 |
-
}
|
38 |
-
return $url;
|
39 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compat/{duplicate-post-jetpack.php → jetpack-functions.php}
RENAMED
@@ -2,8 +2,8 @@
|
|
2 |
/**
|
3 |
* JetPack compatibility functions.
|
4 |
*
|
5 |
-
* @package
|
6 |
-
* @since
|
7 |
*/
|
8 |
|
9 |
add_action( 'admin_init', 'duplicate_post_jetpack_init' );
|
2 |
/**
|
3 |
* JetPack compatibility functions.
|
4 |
*
|
5 |
+
* @package Yoast\WP\Duplicate_Post
|
6 |
+
* @since 3.2
|
7 |
*/
|
8 |
|
9 |
add_action( 'admin_init', 'duplicate_post_jetpack_init' );
|
compat/{duplicate-post-wpml.php → wpml-functions.php}
RENAMED
@@ -4,8 +4,8 @@
|
|
4 |
*
|
5 |
* @global array $duplicated_posts Array to store the posts being duplicated.
|
6 |
*
|
7 |
-
* @package
|
8 |
-
* @since
|
9 |
*/
|
10 |
|
11 |
add_action( 'admin_init', 'duplicate_post_wpml_init' );
|
@@ -21,8 +21,10 @@ function duplicate_post_wpml_init() {
|
|
21 |
}
|
22 |
}
|
23 |
|
24 |
-
global $duplicated_posts;
|
25 |
-
|
|
|
|
|
26 |
|
27 |
/**
|
28 |
* Copy post translations.
|
@@ -66,7 +68,9 @@ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' )
|
|
66 |
}
|
67 |
}
|
68 |
}
|
69 |
-
|
|
|
|
|
70 |
}
|
71 |
}
|
72 |
|
@@ -75,16 +79,19 @@ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' )
|
|
75 |
*
|
76 |
* @global array() $duplicated_posts Array of duplicated posts.
|
77 |
*/
|
78 |
-
function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
|
79 |
global $duplicated_posts;
|
80 |
|
81 |
foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) {
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
$original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
|
84 |
-
$new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
|
85 |
if ( is_array( $original_string_packages ) ) {
|
86 |
foreach ( $original_string_packages as $original_string_package ) {
|
87 |
-
$translated_original_strings = $original_string_package->get_translated_strings(
|
88 |
|
89 |
foreach ( $new_string_packages as $new_string_package ) {
|
90 |
$cache = new WPML_WP_Cache( 'WPML_Package' );
|
@@ -96,7 +103,8 @@ function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConv
|
|
96 |
foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) {
|
97 |
|
98 |
do_action(
|
99 |
-
|
|
|
100 |
$new_string->id,
|
101 |
$language,
|
102 |
$translated_string['value'],
|
4 |
*
|
5 |
* @global array $duplicated_posts Array to store the posts being duplicated.
|
6 |
*
|
7 |
+
* @package Yoast\WP\Duplicate_Post
|
8 |
+
* @since 3.2
|
9 |
*/
|
10 |
|
11 |
add_action( 'admin_init', 'duplicate_post_wpml_init' );
|
21 |
}
|
22 |
}
|
23 |
|
24 |
+
global $duplicated_posts;
|
25 |
+
|
26 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: Renaming a global variable is a BC break.
|
27 |
+
$duplicated_posts = [];
|
28 |
|
29 |
/**
|
30 |
* Copy post translations.
|
68 |
}
|
69 |
}
|
70 |
}
|
71 |
+
|
72 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: see above.
|
73 |
+
$duplicated_posts[ $post->ID ] = $post_id;
|
74 |
}
|
75 |
}
|
76 |
|
79 |
*
|
80 |
* @global array() $duplicated_posts Array of duplicated posts.
|
81 |
*/
|
82 |
+
function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: renaming the function would be a BC-break.
|
83 |
global $duplicated_posts;
|
84 |
|
85 |
foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) {
|
86 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter.
|
87 |
+
$original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id );
|
88 |
+
|
89 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter.
|
90 |
+
$new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id );
|
91 |
|
|
|
|
|
92 |
if ( is_array( $original_string_packages ) ) {
|
93 |
foreach ( $original_string_packages as $original_string_package ) {
|
94 |
+
$translated_original_strings = $original_string_package->get_translated_strings( [] );
|
95 |
|
96 |
foreach ( $new_string_packages as $new_string_package ) {
|
97 |
$cache = new WPML_WP_Cache( 'WPML_Package' );
|
103 |
foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) {
|
104 |
|
105 |
do_action(
|
106 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter.
|
107 |
+
'wpml_add_string_translation',
|
108 |
$new_string->id,
|
109 |
$language,
|
110 |
$translated_string['value'],
|
duplicate-post.php
CHANGED
@@ -1,16 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
* Plugin Name: Yoast Duplicate Post
|
4 |
-
* Plugin URI:
|
5 |
* Description: The go-to tool for cloning posts and pages, including the powerful Rewrite & Republish feature.
|
6 |
-
* Version:
|
7 |
-
* Author:
|
8 |
-
* Author URI:
|
9 |
* Text Domain: duplicate-post
|
10 |
*
|
11 |
-
* @package Duplicate Post
|
12 |
-
* @since 0.1
|
13 |
-
*
|
14 |
* Copyright 2020 Yoast BV (email : info@yoast.com)
|
15 |
*
|
16 |
* This program is free software; you can redistribute it and/or modify
|
@@ -42,13 +45,15 @@ if ( ! defined( 'DUPLICATE_POST_PATH' ) ) {
|
|
42 |
define( 'DUPLICATE_POST_PATH', plugin_dir_path( __FILE__ ) );
|
43 |
}
|
44 |
|
45 |
-
define( 'DUPLICATE_POST_CURRENT_VERSION', '4.
|
46 |
|
47 |
-
$duplicate_post_autoload_file =
|
48 |
|
49 |
if ( is_readable( $duplicate_post_autoload_file ) ) {
|
50 |
require $duplicate_post_autoload_file;
|
|
|
51 |
|
|
|
52 |
// Initialize the main autoloaded class.
|
53 |
add_action( 'plugins_loaded', '__duplicate_post_main' );
|
54 |
}
|
@@ -56,7 +61,11 @@ if ( is_readable( $duplicate_post_autoload_file ) ) {
|
|
56 |
/**
|
57 |
* Loads the Duplicate Post main class.
|
58 |
*
|
59 |
-
* @
|
|
|
|
|
|
|
|
|
60 |
*/
|
61 |
function __duplicate_post_main() {
|
62 |
new Duplicate_Post();
|
@@ -67,7 +76,7 @@ function __duplicate_post_main() {
|
|
67 |
* Initialises the internationalisation domain.
|
68 |
*/
|
69 |
function duplicate_post_load_plugin_textdomain() {
|
70 |
-
load_plugin_textdomain( 'duplicate-post', false, basename(
|
71 |
}
|
72 |
add_action( 'plugins_loaded', 'duplicate_post_load_plugin_textdomain' );
|
73 |
|
@@ -76,28 +85,27 @@ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'duplicate_pos
|
|
76 |
/**
|
77 |
* Adds 'Settings' link to plugin entry in the Plugins list.
|
78 |
*
|
79 |
-
* @ignore
|
80 |
* @see 'plugin_action_links_$plugin_file'
|
81 |
*
|
82 |
* @param array $actions An array of plugin action links.
|
83 |
* @return array
|
84 |
*/
|
85 |
function duplicate_post_plugin_actions( $actions ) {
|
86 |
-
$settings_action =
|
87 |
'settings' => sprintf(
|
88 |
'<a href="%1$s" %2$s>%3$s</a>',
|
89 |
menu_page_url( 'duplicatepost', false ),
|
90 |
'aria-label="' . __( 'Settings for Duplicate Post', 'duplicate-post' ) . '"',
|
91 |
-
esc_html__( 'Settings', '
|
92 |
),
|
93 |
-
|
94 |
|
95 |
-
$actions = $settings_action + $actions;
|
96 |
return $actions;
|
97 |
}
|
98 |
|
99 |
-
require_once
|
100 |
|
101 |
if ( is_admin() ) {
|
102 |
-
include_once
|
103 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Duplicate Post plugin.
|
4 |
+
*
|
5 |
+
* @package Yoast\WP\Duplicate_Post
|
6 |
+
* @since 0.1
|
7 |
+
*
|
8 |
+
* @wordpress-plugin
|
9 |
* Plugin Name: Yoast Duplicate Post
|
10 |
+
* Plugin URI: https://yoast.com/wordpress/plugins/duplicate-post/
|
11 |
* Description: The go-to tool for cloning posts and pages, including the powerful Rewrite & Republish feature.
|
12 |
+
* Version: 4.2
|
13 |
+
* Author: Enrico Battocchi & Team Yoast
|
14 |
+
* Author URI: https://yoast.com
|
15 |
* Text Domain: duplicate-post
|
16 |
*
|
|
|
|
|
|
|
17 |
* Copyright 2020 Yoast BV (email : info@yoast.com)
|
18 |
*
|
19 |
* This program is free software; you can redistribute it and/or modify
|
45 |
define( 'DUPLICATE_POST_PATH', plugin_dir_path( __FILE__ ) );
|
46 |
}
|
47 |
|
48 |
+
define( 'DUPLICATE_POST_CURRENT_VERSION', '4.2' );
|
49 |
|
50 |
+
$duplicate_post_autoload_file = DUPLICATE_POST_PATH . 'vendor/autoload.php';
|
51 |
|
52 |
if ( is_readable( $duplicate_post_autoload_file ) ) {
|
53 |
require $duplicate_post_autoload_file;
|
54 |
+
}
|
55 |
|
56 |
+
if ( class_exists( Duplicate_Post::class ) ) {
|
57 |
// Initialize the main autoloaded class.
|
58 |
add_action( 'plugins_loaded', '__duplicate_post_main' );
|
59 |
}
|
61 |
/**
|
62 |
* Loads the Duplicate Post main class.
|
63 |
*
|
64 |
+
* {@internal Function name change would be BC-break.}
|
65 |
+
*
|
66 |
+
* @phpcs:disable PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
|
67 |
+
* @phpcs:disable WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore
|
68 |
+
* @phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound
|
69 |
*/
|
70 |
function __duplicate_post_main() {
|
71 |
new Duplicate_Post();
|
76 |
* Initialises the internationalisation domain.
|
77 |
*/
|
78 |
function duplicate_post_load_plugin_textdomain() {
|
79 |
+
load_plugin_textdomain( 'duplicate-post', false, basename( __DIR__ ) . '/languages/' );
|
80 |
}
|
81 |
add_action( 'plugins_loaded', 'duplicate_post_load_plugin_textdomain' );
|
82 |
|
85 |
/**
|
86 |
* Adds 'Settings' link to plugin entry in the Plugins list.
|
87 |
*
|
|
|
88 |
* @see 'plugin_action_links_$plugin_file'
|
89 |
*
|
90 |
* @param array $actions An array of plugin action links.
|
91 |
* @return array
|
92 |
*/
|
93 |
function duplicate_post_plugin_actions( $actions ) {
|
94 |
+
$settings_action = [
|
95 |
'settings' => sprintf(
|
96 |
'<a href="%1$s" %2$s>%3$s</a>',
|
97 |
menu_page_url( 'duplicatepost', false ),
|
98 |
'aria-label="' . __( 'Settings for Duplicate Post', 'duplicate-post' ) . '"',
|
99 |
+
esc_html__( 'Settings', 'duplicate-post' )
|
100 |
),
|
101 |
+
];
|
102 |
|
103 |
+
$actions = ( $settings_action + $actions );
|
104 |
return $actions;
|
105 |
}
|
106 |
|
107 |
+
require_once DUPLICATE_POST_PATH . 'common-functions.php';
|
108 |
|
109 |
if ( is_admin() ) {
|
110 |
+
include_once DUPLICATE_POST_PATH . 'admin-functions.php';
|
111 |
}
|
js/dist/{duplicate-post-edit-412.js → duplicate-post-edit-420.js}
RENAMED
File without changes
|
js/dist/{duplicate-post-elementor-412.js → duplicate-post-elementor-420.js}
RENAMED
File without changes
|
js/dist/{duplicate-post-options-412.js → duplicate-post-options-420.js}
RENAMED
File without changes
|
js/dist/{duplicate-post-quick-edit-412.js → duplicate-post-quick-edit-420.js}
RENAMED
File without changes
|
js/dist/{duplicate-post-strings-412.js → duplicate-post-strings-420.js}
RENAMED
File without changes
|
duplicate-post-options.php → options.php
RENAMED
@@ -1,10 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Options page
|
4 |
-
*
|
5 |
-
* @package Duplicate Post
|
6 |
-
* @since 2.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
@@ -14,7 +8,7 @@ use Yoast\WP\Duplicate_Post\Admin\Options_Inputs;
|
|
14 |
use Yoast\WP\Duplicate_Post\Admin\Options_Page;
|
15 |
use Yoast\WP\Duplicate_Post\UI\Asset_Manager;
|
16 |
|
17 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
18 |
exit();
|
19 |
}
|
20 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
8 |
use Yoast\WP\Duplicate_Post\Admin\Options_Page;
|
9 |
use Yoast\WP\Duplicate_Post\UI\Asset_Manager;
|
10 |
|
11 |
+
if ( ! \defined( 'ABSPATH' ) ) {
|
12 |
exit();
|
13 |
}
|
14 |
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://yoast.com/wordpress/plugins/duplicate-post/
|
|
4 |
Tags: duplicate post, copy, clone
|
5 |
Requires at least: 5.6
|
6 |
Tested up to: 5.8
|
7 |
-
Stable tag: 4.
|
8 |
Requires PHP: 5.6.20
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
@@ -151,6 +151,21 @@ New features and customization, WP 3.0 compatibility: you should upgrade if you
|
|
151 |
|
152 |
== Changelog ==
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
= 4.1.2 (2021-03-23) =
|
155 |
|
156 |
Enhancements:
|
4 |
Tags: duplicate post, copy, clone
|
5 |
Requires at least: 5.6
|
6 |
Tested up to: 5.8
|
7 |
+
Stable tag: 4.2
|
8 |
Requires PHP: 5.6.20
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
151 |
|
152 |
== Changelog ==
|
153 |
|
154 |
+
= 4.2 (2021-11-18) =
|
155 |
+
|
156 |
+
Bugfixes:
|
157 |
+
|
158 |
+
* Fixes a bug where some strings where not translated.
|
159 |
+
* Fixes a bug where meta data went missing for duplicate posts created by the Rewrite & Republish feature. Props to [ocean90](https://github.com/ocean90).
|
160 |
+
* Fixes a bug where the plugin would not initialize if installed via composer.
|
161 |
+
|
162 |
+
Other:
|
163 |
+
|
164 |
+
* Replaces Mailchimp with MailBlue newsletter integration.
|
165 |
+
* Improved compatibility for PHP 8.0.
|
166 |
+
* Improved sort order of the taxonomies list on the options page.
|
167 |
+
* Most plugin files have been renamed. If you extend this plugin of include any of the files from the plugin from within your own plugin, you may need to adjust the file name used in the `include`/`require` statement.
|
168 |
+
|
169 |
= 4.1.2 (2021-03-23) =
|
170 |
|
171 |
Enhancements:
|
src/admin/{class-options-form-generator.php → options-form-generator.php}
RENAMED
@@ -1,18 +1,12 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post plugin file.
|
4 |
-
*
|
5 |
-
* @package Yoast\WP\Duplicate_Post\Admin
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
9 |
|
|
|
10 |
use Yoast\WP\Duplicate_Post\Utils;
|
11 |
|
12 |
/**
|
13 |
-
* Class Options_Form_Generator
|
14 |
-
*
|
15 |
-
* @package Yoast\WP\Duplicate_Post\Admin
|
16 |
*/
|
17 |
class Options_Form_Generator {
|
18 |
|
@@ -109,16 +103,25 @@ class Options_Form_Generator {
|
|
109 |
}
|
110 |
|
111 |
/**
|
112 |
-
* Sorts taxonomy objects based on being public, followed by being private
|
|
|
113 |
*
|
114 |
-
* @param
|
115 |
-
* @param
|
116 |
*
|
117 |
-
* @return
|
118 |
-
*
|
119 |
*/
|
120 |
public function sort_taxonomy_objects( $taxonomy1, $taxonomy2 ) {
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
}
|
123 |
|
124 |
/**
|
@@ -171,7 +174,7 @@ class Options_Form_Generator {
|
|
171 |
'id' => 'duplicate-post-' . $this->prepare_input_id( $name ),
|
172 |
'value' => $name,
|
173 |
'checked' => \in_array( $taxonomy->name, $taxonomies_blacklist, true ),
|
174 |
-
'label' =>
|
175 |
],
|
176 |
]
|
177 |
);
|
@@ -199,7 +202,7 @@ class Options_Form_Generator {
|
|
199 |
foreach ( Utils::get_roles() as $name => $display_name ) {
|
200 |
$role = \get_role( $name );
|
201 |
|
202 |
-
if ( count( \array_intersect_key( $role->capabilities, $edit_capabilities ) ) > 0 ) {
|
203 |
$output .= $this->generate_options_input(
|
204 |
[
|
205 |
'duplicate_post_roles[]' => [
|
@@ -207,7 +210,7 @@ class Options_Form_Generator {
|
|
207 |
'id' => 'duplicate-post-' . $this->prepare_input_id( $name ),
|
208 |
'value' => $name,
|
209 |
'checked' => $role->has_cap( 'copy_posts' ),
|
210 |
-
'label' => \
|
211 |
],
|
212 |
]
|
213 |
);
|
@@ -241,7 +244,7 @@ class Options_Form_Generator {
|
|
241 |
'id' => 'duplicate-post-' . $this->prepare_input_id( $name ),
|
242 |
'value' => $name,
|
243 |
'checked' => $this->is_post_type_enabled( $post_type_object->name ),
|
244 |
-
'label' =>
|
245 |
],
|
246 |
]
|
247 |
);
|
@@ -291,10 +294,11 @@ class Options_Form_Generator {
|
|
291 |
/**
|
292 |
* Checks whether or not a post type is enabled.
|
293 |
*
|
|
|
|
|
294 |
* @param string $post_type The post type.
|
295 |
*
|
296 |
* @return bool Whether or not the post type is enabled.
|
297 |
-
* @codeCoverageIgnore As this is a simple wrapper for a function that is also being used elsewhere, we can skip testing for now.
|
298 |
*/
|
299 |
public function is_post_type_enabled( $post_type ) {
|
300 |
$duplicate_post_types_enabled = \get_option( 'duplicate_post_types_enabled', [ 'post', 'page' ] );
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
4 |
|
5 |
+
use WP_Taxonomy;
|
6 |
use Yoast\WP\Duplicate_Post\Utils;
|
7 |
|
8 |
/**
|
9 |
+
* Class Options_Form_Generator.
|
|
|
|
|
10 |
*/
|
11 |
class Options_Form_Generator {
|
12 |
|
103 |
}
|
104 |
|
105 |
/**
|
106 |
+
* Sorts taxonomy objects based on being public, followed by being private
|
107 |
+
* and when the visibility is equal, on the taxonomy public name (case-sensitive).
|
108 |
*
|
109 |
+
* @param WP_Taxonomy $taxonomy1 First taxonomy object.
|
110 |
+
* @param WP_Taxonomy $taxonomy2 Second taxonomy object.
|
111 |
*
|
112 |
+
* @return int An integer less than, equal to, or greater than zero indicating respectively
|
113 |
+
* the first taxonomy should be sorted before, at the same level or after the second taxonomy.
|
114 |
*/
|
115 |
public function sort_taxonomy_objects( $taxonomy1, $taxonomy2 ) {
|
116 |
+
if ( $taxonomy1->public === true && $taxonomy2->public === false ) {
|
117 |
+
return -1;
|
118 |
+
}
|
119 |
+
elseif ( $taxonomy1->public === false && $taxonomy2->public === true ) {
|
120 |
+
return 1;
|
121 |
+
}
|
122 |
+
|
123 |
+
// Same visibility, sort by name.
|
124 |
+
return \strnatcmp( $taxonomy1->labels->name, $taxonomy2->labels->name );
|
125 |
}
|
126 |
|
127 |
/**
|
174 |
'id' => 'duplicate-post-' . $this->prepare_input_id( $name ),
|
175 |
'value' => $name,
|
176 |
'checked' => \in_array( $taxonomy->name, $taxonomies_blacklist, true ),
|
177 |
+
'label' => $taxonomy->labels->name . ' [' . $taxonomy->name . ']',
|
178 |
],
|
179 |
]
|
180 |
);
|
202 |
foreach ( Utils::get_roles() as $name => $display_name ) {
|
203 |
$role = \get_role( $name );
|
204 |
|
205 |
+
if ( \count( \array_intersect_key( $role->capabilities, $edit_capabilities ) ) > 0 ) {
|
206 |
$output .= $this->generate_options_input(
|
207 |
[
|
208 |
'duplicate_post_roles[]' => [
|
210 |
'id' => 'duplicate-post-' . $this->prepare_input_id( $name ),
|
211 |
'value' => $name,
|
212 |
'checked' => $role->has_cap( 'copy_posts' ),
|
213 |
+
'label' => \translate_user_role( $display_name ),
|
214 |
],
|
215 |
]
|
216 |
);
|
244 |
'id' => 'duplicate-post-' . $this->prepare_input_id( $name ),
|
245 |
'value' => $name,
|
246 |
'checked' => $this->is_post_type_enabled( $post_type_object->name ),
|
247 |
+
'label' => $post_type_object->labels->name,
|
248 |
],
|
249 |
]
|
250 |
);
|
294 |
/**
|
295 |
* Checks whether or not a post type is enabled.
|
296 |
*
|
297 |
+
* @codeCoverageIgnore As this is a simple wrapper for a function that is also being used elsewhere, we can skip testing for now.
|
298 |
+
*
|
299 |
* @param string $post_type The post type.
|
300 |
*
|
301 |
* @return bool Whether or not the post type is enabled.
|
|
|
302 |
*/
|
303 |
public function is_post_type_enabled( $post_type ) {
|
304 |
$duplicate_post_types_enabled = \get_option( 'duplicate_post_types_enabled', [ 'post', 'page' ] );
|
src/admin/{class-options-inputs.php → options-inputs.php}
RENAMED
@@ -1,25 +1,20 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post plugin file.
|
4 |
-
*
|
5 |
-
* @package Yoast\WP\Duplicate_Post\Admin
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
9 |
|
10 |
/**
|
11 |
-
* Class Options_Inputs
|
12 |
*/
|
13 |
class Options_Inputs {
|
14 |
|
15 |
/**
|
16 |
* Creates a basic input based on the passed parameters.
|
17 |
*
|
18 |
-
* @param string $type
|
19 |
-
* @param string $name
|
20 |
-
* @param string $value
|
21 |
-
* @param string $id
|
22 |
-
* @param string $attributes
|
23 |
*
|
24 |
* @return string The input's HTML output.
|
25 |
*/
|
@@ -37,15 +32,15 @@ class Options_Inputs {
|
|
37 |
/**
|
38 |
* Creates a checkbox input.
|
39 |
*
|
40 |
-
* @param string $name
|
41 |
-
* @param string $value
|
42 |
-
* @param string $id
|
43 |
* @param bool $checked Whether or not the checkbox should be checked.
|
44 |
*
|
45 |
* @return string The checkbox' HTML output.
|
46 |
*/
|
47 |
public function checkbox( $name, $value, $id, $checked = false ) {
|
48 |
-
$checked = $checked
|
49 |
|
50 |
return $this->input( 'checkbox', $name, $value, $id, $checked );
|
51 |
}
|
@@ -53,9 +48,9 @@ class Options_Inputs {
|
|
53 |
/**
|
54 |
* Creates a text field input.
|
55 |
*
|
56 |
-
* @param string $name
|
57 |
* @param string $value The value of the text field.
|
58 |
-
* @param string $id
|
59 |
*
|
60 |
* @return string The text field's HTML output.
|
61 |
*/
|
@@ -66,9 +61,9 @@ class Options_Inputs {
|
|
66 |
/**
|
67 |
* Creates a number input.
|
68 |
*
|
69 |
-
* @param string $name
|
70 |
* @param string $value The value of the number input.
|
71 |
-
* @param string $id
|
72 |
*
|
73 |
* @return string The number input's HTML output.
|
74 |
*/
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
4 |
|
5 |
/**
|
6 |
+
* Class Options_Inputs.
|
7 |
*/
|
8 |
class Options_Inputs {
|
9 |
|
10 |
/**
|
11 |
* Creates a basic input based on the passed parameters.
|
12 |
*
|
13 |
+
* @param string $type The type of input.
|
14 |
+
* @param string $name The name of the input.
|
15 |
+
* @param string $value The value of the input.
|
16 |
+
* @param string $id The ID of the input.
|
17 |
+
* @param string $attributes The additional attributes to use. Optional.
|
18 |
*
|
19 |
* @return string The input's HTML output.
|
20 |
*/
|
32 |
/**
|
33 |
* Creates a checkbox input.
|
34 |
*
|
35 |
+
* @param string $name The name of the checkbox.
|
36 |
+
* @param string $value The value of the checkbox.
|
37 |
+
* @param string $id The ID of the checkbox.
|
38 |
* @param bool $checked Whether or not the checkbox should be checked.
|
39 |
*
|
40 |
* @return string The checkbox' HTML output.
|
41 |
*/
|
42 |
public function checkbox( $name, $value, $id, $checked = false ) {
|
43 |
+
$checked = \checked( $checked, true, false );
|
44 |
|
45 |
return $this->input( 'checkbox', $name, $value, $id, $checked );
|
46 |
}
|
48 |
/**
|
49 |
* Creates a text field input.
|
50 |
*
|
51 |
+
* @param string $name The name of the text field.
|
52 |
* @param string $value The value of the text field.
|
53 |
+
* @param string $id The ID of the text field.
|
54 |
*
|
55 |
* @return string The text field's HTML output.
|
56 |
*/
|
61 |
/**
|
62 |
* Creates a number input.
|
63 |
*
|
64 |
+
* @param string $name The name of the number input.
|
65 |
* @param string $value The value of the number input.
|
66 |
+
* @param string $id The ID of the number input.
|
67 |
*
|
68 |
* @return string The number input's HTML output.
|
69 |
*/
|
src/admin/{class-options-page.php → options-page.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post plugin file.
|
4 |
-
*
|
5 |
-
* @package Yoast\WP\Duplicate_Post\Admin
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
9 |
|
@@ -11,9 +6,10 @@ use Yoast\WP\Duplicate_Post\UI\Asset_Manager;
|
|
11 |
use Yoast\WP\Duplicate_Post\Utils;
|
12 |
|
13 |
/**
|
14 |
-
* Class Options_Page
|
15 |
*/
|
16 |
class Options_Page {
|
|
|
17 |
/**
|
18 |
* The Options instance.
|
19 |
*
|
@@ -90,11 +86,12 @@ class Options_Page {
|
|
90 |
/**
|
91 |
* Generates the inputs for the specified tab / fieldset.
|
92 |
*
|
|
|
|
|
93 |
* @param string $tab The tab to get the configuration for.
|
94 |
* @param string $fieldset The fieldset to get the configuration for. Optional.
|
95 |
*
|
96 |
* @return string The HTML output for the controls present on the tab / fieldset.
|
97 |
-
* @codeCoverageIgnore As this is a simple wrapper for two functions that are already tested elsewhere, we can skip testing.
|
98 |
*/
|
99 |
public function generate_tab_inputs( $tab, $fieldset = '' ) {
|
100 |
$options = $this->options->get_options_for_tab( $tab, $fieldset );
|
@@ -105,10 +102,11 @@ class Options_Page {
|
|
105 |
/**
|
106 |
* Generates an input for a single option.
|
107 |
*
|
|
|
|
|
108 |
* @param string $option The option configuration to base the input on.
|
109 |
*
|
110 |
* @return string The input HTML.
|
111 |
-
* @codeCoverageIgnore As this is a simple wrapper for two functions that are already tested elsewhere, we can skip testing.
|
112 |
*/
|
113 |
public function generate_input( $option ) {
|
114 |
return $this->generator->generate_options_input( $this->options->get_option( $option ) );
|
@@ -144,13 +142,14 @@ class Options_Page {
|
|
144 |
/**
|
145 |
* Generates the options page.
|
146 |
*
|
147 |
-
* @return void
|
148 |
* @codeCoverageIgnore
|
|
|
|
|
149 |
*/
|
150 |
public function generate_page() {
|
151 |
$this->register_capabilities();
|
152 |
|
153 |
-
require_once DUPLICATE_POST_PATH . 'src/admin/views/options.php';
|
154 |
}
|
155 |
|
156 |
/**
|
@@ -159,7 +158,7 @@ class Options_Page {
|
|
159 |
* @return bool Whether or not the settings have been updated.
|
160 |
*/
|
161 |
protected function settings_updated() {
|
162 |
-
return isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] === 'true';
|
163 |
}
|
164 |
|
165 |
/**
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
4 |
|
6 |
use Yoast\WP\Duplicate_Post\Utils;
|
7 |
|
8 |
/**
|
9 |
+
* Class Options_Page.
|
10 |
*/
|
11 |
class Options_Page {
|
12 |
+
|
13 |
/**
|
14 |
* The Options instance.
|
15 |
*
|
86 |
/**
|
87 |
* Generates the inputs for the specified tab / fieldset.
|
88 |
*
|
89 |
+
* @codeCoverageIgnore As this is a simple wrapper for two functions that are already tested elsewhere, we can skip testing.
|
90 |
+
*
|
91 |
* @param string $tab The tab to get the configuration for.
|
92 |
* @param string $fieldset The fieldset to get the configuration for. Optional.
|
93 |
*
|
94 |
* @return string The HTML output for the controls present on the tab / fieldset.
|
|
|
95 |
*/
|
96 |
public function generate_tab_inputs( $tab, $fieldset = '' ) {
|
97 |
$options = $this->options->get_options_for_tab( $tab, $fieldset );
|
102 |
/**
|
103 |
* Generates an input for a single option.
|
104 |
*
|
105 |
+
* @codeCoverageIgnore As this is a simple wrapper for two functions that are already tested elsewhere, we can skip testing.
|
106 |
+
*
|
107 |
* @param string $option The option configuration to base the input on.
|
108 |
*
|
109 |
* @return string The input HTML.
|
|
|
110 |
*/
|
111 |
public function generate_input( $option ) {
|
112 |
return $this->generator->generate_options_input( $this->options->get_option( $option ) );
|
142 |
/**
|
143 |
* Generates the options page.
|
144 |
*
|
|
|
145 |
* @codeCoverageIgnore
|
146 |
+
*
|
147 |
+
* @return void
|
148 |
*/
|
149 |
public function generate_page() {
|
150 |
$this->register_capabilities();
|
151 |
|
152 |
+
require_once \DUPLICATE_POST_PATH . 'src/admin/views/options.php';
|
153 |
}
|
154 |
|
155 |
/**
|
158 |
* @return bool Whether or not the settings have been updated.
|
159 |
*/
|
160 |
protected function settings_updated() {
|
161 |
+
return isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] === 'true';
|
162 |
}
|
163 |
|
164 |
/**
|
src/admin/{class-options.php → options.php}
RENAMED
@@ -1,15 +1,11 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Options class
|
4 |
-
*
|
5 |
-
* @package Duplicate Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
10 |
|
11 |
/**
|
12 |
-
*
|
|
|
|
|
13 |
*/
|
14 |
class Options {
|
15 |
|
@@ -39,7 +35,7 @@ class Options {
|
|
39 |
|
40 |
$options = \array_filter(
|
41 |
$options,
|
42 |
-
function ( $option ) use ( $tab ) {
|
43 |
return \array_key_exists( 'tab', $option ) && $option['tab'] === $tab;
|
44 |
}
|
45 |
);
|
@@ -52,7 +48,7 @@ class Options {
|
|
52 |
if ( ! empty( $fieldset ) ) {
|
53 |
$options = \array_filter(
|
54 |
$options,
|
55 |
-
function ( $option ) use ( $fieldset ) {
|
56 |
return \array_key_exists( 'fieldset', $option ) && $option['fieldset'] === $fieldset;
|
57 |
}
|
58 |
);
|
@@ -77,8 +73,9 @@ class Options {
|
|
77 |
/**
|
78 |
* Gets the list of registered options.
|
79 |
*
|
80 |
-
* @return array The options.
|
81 |
* @codeCoverageIgnore
|
|
|
|
|
82 |
*/
|
83 |
public function get_options() {
|
84 |
return [
|
@@ -86,84 +83,84 @@ class Options {
|
|
86 |
'tab' => 'what-to-copy',
|
87 |
'fieldset' => 'elements-to-copy',
|
88 |
'type' => 'checkbox',
|
89 |
-
'label' => \__( 'Title', '
|
90 |
'value' => 1,
|
91 |
],
|
92 |
'duplicate_post_copydate' => [
|
93 |
'tab' => 'what-to-copy',
|
94 |
'fieldset' => 'elements-to-copy',
|
95 |
'type' => 'checkbox',
|
96 |
-
'label' => \__( 'Date', '
|
97 |
'value' => 1,
|
98 |
],
|
99 |
'duplicate_post_copystatus' => [
|
100 |
'tab' => 'what-to-copy',
|
101 |
'fieldset' => 'elements-to-copy',
|
102 |
'type' => 'checkbox',
|
103 |
-
'label' => \__( 'Status', '
|
104 |
'value' => 1,
|
105 |
],
|
106 |
'duplicate_post_copyslug' => [
|
107 |
'tab' => 'what-to-copy',
|
108 |
'fieldset' => 'elements-to-copy',
|
109 |
'type' => 'checkbox',
|
110 |
-
'label' => \__( 'Slug', '
|
111 |
'value' => 1,
|
112 |
],
|
113 |
'duplicate_post_copyexcerpt' => [
|
114 |
'tab' => 'what-to-copy',
|
115 |
'fieldset' => 'elements-to-copy',
|
116 |
'type' => 'checkbox',
|
117 |
-
'label' => \__( 'Excerpt', '
|
118 |
'value' => 1,
|
119 |
],
|
120 |
'duplicate_post_copycontent' => [
|
121 |
'tab' => 'what-to-copy',
|
122 |
'fieldset' => 'elements-to-copy',
|
123 |
'type' => 'checkbox',
|
124 |
-
'label' => \__( 'Content', '
|
125 |
'value' => 1,
|
126 |
],
|
127 |
'duplicate_post_copythumbnail' => [
|
128 |
'tab' => 'what-to-copy',
|
129 |
'fieldset' => 'elements-to-copy',
|
130 |
'type' => 'checkbox',
|
131 |
-
'label' => \__( 'Featured Image', '
|
132 |
'value' => 1,
|
133 |
],
|
134 |
'duplicate_post_copytemplate' => [
|
135 |
'tab' => 'what-to-copy',
|
136 |
'fieldset' => 'elements-to-copy',
|
137 |
'type' => 'checkbox',
|
138 |
-
'label' => \__( 'Template', '
|
139 |
'value' => 1,
|
140 |
],
|
141 |
'duplicate_post_copyformat' => [
|
142 |
'tab' => 'what-to-copy',
|
143 |
'fieldset' => 'elements-to-copy',
|
144 |
'type' => 'checkbox',
|
145 |
-
'label' => \__( 'Post format', '
|
146 |
'value' => 1,
|
147 |
],
|
148 |
'duplicate_post_copyauthor' => [
|
149 |
'tab' => 'what-to-copy',
|
150 |
'fieldset' => 'elements-to-copy',
|
151 |
'type' => 'checkbox',
|
152 |
-
'label' => \__( 'Author', '
|
153 |
'value' => 1,
|
154 |
],
|
155 |
'duplicate_post_copypassword' => [
|
156 |
'tab' => 'what-to-copy',
|
157 |
'fieldset' => 'elements-to-copy',
|
158 |
'type' => 'checkbox',
|
159 |
-
'label' => \__( 'Password', '
|
160 |
'value' => 1,
|
161 |
],
|
162 |
'duplicate_post_copyattachments' => [
|
163 |
'tab' => 'what-to-copy',
|
164 |
'fieldset' => 'elements-to-copy',
|
165 |
'type' => 'checkbox',
|
166 |
-
'label' => \__( 'Attachments', '
|
167 |
'value' => 1,
|
168 |
'description' => \__( 'you probably want this unchecked, unless you have very special requirements', 'duplicate-post' ),
|
169 |
],
|
@@ -171,14 +168,14 @@ class Options {
|
|
171 |
'tab' => 'what-to-copy',
|
172 |
'fieldset' => 'elements-to-copy',
|
173 |
'type' => 'checkbox',
|
174 |
-
'label' => \__( 'Children', '
|
175 |
'value' => 1,
|
176 |
],
|
177 |
'duplicate_post_copycomments' => [
|
178 |
'tab' => 'what-to-copy',
|
179 |
'fieldset' => 'elements-to-copy',
|
180 |
'type' => 'checkbox',
|
181 |
-
'label' => \__( 'Comments', '
|
182 |
'value' => 1,
|
183 |
'description' => \__( 'except pingbacks and trackbacks', 'duplicate-post' ),
|
184 |
],
|
@@ -186,7 +183,7 @@ class Options {
|
|
186 |
'tab' => 'what-to-copy',
|
187 |
'fieldset' => 'elements-to-copy',
|
188 |
'type' => 'checkbox',
|
189 |
-
'label' => \__( 'Menu order', '
|
190 |
'value' => 1,
|
191 |
],
|
192 |
'duplicate_post_title_prefix' => [
|
@@ -216,8 +213,8 @@ class Options {
|
|
216 |
'label' => \__( 'Do not copy these fields', 'duplicate-post' ),
|
217 |
'value' => \get_option( 'duplicate_post_blacklist' ),
|
218 |
'description' => [
|
219 |
-
__( 'Comma-separated list of meta fields that must not be copied.', 'duplicate-post' ),
|
220 |
-
__( 'You can use * to match zero or more alphanumeric characters or underscores: e.g. field*', 'duplicate-post' ),
|
221 |
],
|
222 |
],
|
223 |
'duplicate_post_taxonomies_blacklist' => [
|
@@ -239,7 +236,7 @@ class Options {
|
|
239 |
'label' => \__( 'In a metabox in the Edit screen', 'duplicate-post' ),
|
240 |
'value' => 1,
|
241 |
'description' => [
|
242 |
-
__( "You'll also be able to delete the reference to the original item with a checkbox", 'duplicate-post' ),
|
243 |
],
|
244 |
],
|
245 |
'duplicate_post_show_original_column' => [
|
@@ -249,7 +246,7 @@ class Options {
|
|
249 |
'label' => \__( 'In a column in the Post list', 'duplicate-post' ),
|
250 |
'value' => 1,
|
251 |
'description' => [
|
252 |
-
__( "You'll also be able to delete the reference to the original item with a checkbox in Quick Edit", 'duplicate-post' ),
|
253 |
],
|
254 |
],
|
255 |
'duplicate_post_show_original_in_post_states' => [
|
@@ -307,7 +304,7 @@ class Options {
|
|
307 |
],
|
308 |
'bulkactions' => [
|
309 |
'type' => 'checkbox',
|
310 |
-
'label' => \__( 'Bulk Actions', '
|
311 |
'value' => 1,
|
312 |
],
|
313 |
],
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Admin;
|
4 |
|
5 |
/**
|
6 |
+
* Options class.
|
7 |
+
*
|
8 |
+
* @since 4.0
|
9 |
*/
|
10 |
class Options {
|
11 |
|
35 |
|
36 |
$options = \array_filter(
|
37 |
$options,
|
38 |
+
static function ( $option ) use ( $tab ) {
|
39 |
return \array_key_exists( 'tab', $option ) && $option['tab'] === $tab;
|
40 |
}
|
41 |
);
|
48 |
if ( ! empty( $fieldset ) ) {
|
49 |
$options = \array_filter(
|
50 |
$options,
|
51 |
+
static function ( $option ) use ( $fieldset ) {
|
52 |
return \array_key_exists( 'fieldset', $option ) && $option['fieldset'] === $fieldset;
|
53 |
}
|
54 |
);
|
73 |
/**
|
74 |
* Gets the list of registered options.
|
75 |
*
|
|
|
76 |
* @codeCoverageIgnore
|
77 |
+
*
|
78 |
+
* @return array The options.
|
79 |
*/
|
80 |
public function get_options() {
|
81 |
return [
|
83 |
'tab' => 'what-to-copy',
|
84 |
'fieldset' => 'elements-to-copy',
|
85 |
'type' => 'checkbox',
|
86 |
+
'label' => \__( 'Title', 'duplicate-post' ),
|
87 |
'value' => 1,
|
88 |
],
|
89 |
'duplicate_post_copydate' => [
|
90 |
'tab' => 'what-to-copy',
|
91 |
'fieldset' => 'elements-to-copy',
|
92 |
'type' => 'checkbox',
|
93 |
+
'label' => \__( 'Date', 'duplicate-post' ),
|
94 |
'value' => 1,
|
95 |
],
|
96 |
'duplicate_post_copystatus' => [
|
97 |
'tab' => 'what-to-copy',
|
98 |
'fieldset' => 'elements-to-copy',
|
99 |
'type' => 'checkbox',
|
100 |
+
'label' => \__( 'Status', 'duplicate-post' ),
|
101 |
'value' => 1,
|
102 |
],
|
103 |
'duplicate_post_copyslug' => [
|
104 |
'tab' => 'what-to-copy',
|
105 |
'fieldset' => 'elements-to-copy',
|
106 |
'type' => 'checkbox',
|
107 |
+
'label' => \__( 'Slug', 'duplicate-post' ),
|
108 |
'value' => 1,
|
109 |
],
|
110 |
'duplicate_post_copyexcerpt' => [
|
111 |
'tab' => 'what-to-copy',
|
112 |
'fieldset' => 'elements-to-copy',
|
113 |
'type' => 'checkbox',
|
114 |
+
'label' => \__( 'Excerpt', 'duplicate-post' ),
|
115 |
'value' => 1,
|
116 |
],
|
117 |
'duplicate_post_copycontent' => [
|
118 |
'tab' => 'what-to-copy',
|
119 |
'fieldset' => 'elements-to-copy',
|
120 |
'type' => 'checkbox',
|
121 |
+
'label' => \__( 'Content', 'duplicate-post' ),
|
122 |
'value' => 1,
|
123 |
],
|
124 |
'duplicate_post_copythumbnail' => [
|
125 |
'tab' => 'what-to-copy',
|
126 |
'fieldset' => 'elements-to-copy',
|
127 |
'type' => 'checkbox',
|
128 |
+
'label' => \__( 'Featured Image', 'duplicate-post' ),
|
129 |
'value' => 1,
|
130 |
],
|
131 |
'duplicate_post_copytemplate' => [
|
132 |
'tab' => 'what-to-copy',
|
133 |
'fieldset' => 'elements-to-copy',
|
134 |
'type' => 'checkbox',
|
135 |
+
'label' => \__( 'Template', 'duplicate-post' ),
|
136 |
'value' => 1,
|
137 |
],
|
138 |
'duplicate_post_copyformat' => [
|
139 |
'tab' => 'what-to-copy',
|
140 |
'fieldset' => 'elements-to-copy',
|
141 |
'type' => 'checkbox',
|
142 |
+
'label' => \__( 'Post format', 'duplicate-post' ),
|
143 |
'value' => 1,
|
144 |
],
|
145 |
'duplicate_post_copyauthor' => [
|
146 |
'tab' => 'what-to-copy',
|
147 |
'fieldset' => 'elements-to-copy',
|
148 |
'type' => 'checkbox',
|
149 |
+
'label' => \__( 'Author', 'duplicate-post' ),
|
150 |
'value' => 1,
|
151 |
],
|
152 |
'duplicate_post_copypassword' => [
|
153 |
'tab' => 'what-to-copy',
|
154 |
'fieldset' => 'elements-to-copy',
|
155 |
'type' => 'checkbox',
|
156 |
+
'label' => \__( 'Password', 'duplicate-post' ),
|
157 |
'value' => 1,
|
158 |
],
|
159 |
'duplicate_post_copyattachments' => [
|
160 |
'tab' => 'what-to-copy',
|
161 |
'fieldset' => 'elements-to-copy',
|
162 |
'type' => 'checkbox',
|
163 |
+
'label' => \__( 'Attachments', 'duplicate-post' ),
|
164 |
'value' => 1,
|
165 |
'description' => \__( 'you probably want this unchecked, unless you have very special requirements', 'duplicate-post' ),
|
166 |
],
|
168 |
'tab' => 'what-to-copy',
|
169 |
'fieldset' => 'elements-to-copy',
|
170 |
'type' => 'checkbox',
|
171 |
+
'label' => \__( 'Children', 'duplicate-post' ),
|
172 |
'value' => 1,
|
173 |
],
|
174 |
'duplicate_post_copycomments' => [
|
175 |
'tab' => 'what-to-copy',
|
176 |
'fieldset' => 'elements-to-copy',
|
177 |
'type' => 'checkbox',
|
178 |
+
'label' => \__( 'Comments', 'duplicate-post' ),
|
179 |
'value' => 1,
|
180 |
'description' => \__( 'except pingbacks and trackbacks', 'duplicate-post' ),
|
181 |
],
|
183 |
'tab' => 'what-to-copy',
|
184 |
'fieldset' => 'elements-to-copy',
|
185 |
'type' => 'checkbox',
|
186 |
+
'label' => \__( 'Menu order', 'duplicate-post' ),
|
187 |
'value' => 1,
|
188 |
],
|
189 |
'duplicate_post_title_prefix' => [
|
213 |
'label' => \__( 'Do not copy these fields', 'duplicate-post' ),
|
214 |
'value' => \get_option( 'duplicate_post_blacklist' ),
|
215 |
'description' => [
|
216 |
+
\__( 'Comma-separated list of meta fields that must not be copied.', 'duplicate-post' ),
|
217 |
+
\__( 'You can use * to match zero or more alphanumeric characters or underscores: e.g. field*', 'duplicate-post' ),
|
218 |
],
|
219 |
],
|
220 |
'duplicate_post_taxonomies_blacklist' => [
|
236 |
'label' => \__( 'In a metabox in the Edit screen', 'duplicate-post' ),
|
237 |
'value' => 1,
|
238 |
'description' => [
|
239 |
+
\__( "You'll also be able to delete the reference to the original item with a checkbox", 'duplicate-post' ),
|
240 |
],
|
241 |
],
|
242 |
'duplicate_post_show_original_column' => [
|
246 |
'label' => \__( 'In a column in the Post list', 'duplicate-post' ),
|
247 |
'value' => 1,
|
248 |
'description' => [
|
249 |
+
\__( "You'll also be able to delete the reference to the original item with a checkbox in Quick Edit", 'duplicate-post' ),
|
250 |
],
|
251 |
],
|
252 |
'duplicate_post_show_original_in_post_states' => [
|
304 |
],
|
305 |
'bulkactions' => [
|
306 |
'type' => 'checkbox',
|
307 |
+
'label' => \__( 'Bulk Actions', 'duplicate-post' ),
|
308 |
'value' => 1,
|
309 |
],
|
310 |
],
|
src/admin/views/options.php
CHANGED
@@ -1,15 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post plugin file.
|
4 |
-
*
|
5 |
-
* @package Yoast\WP\Duplicate_Post\Admin\Views
|
6 |
-
*/
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
|
|
11 |
exit();
|
12 |
}
|
|
|
13 |
?>
|
14 |
<div class="wrap">
|
15 |
<h1>
|
@@ -214,7 +212,7 @@ if ( ! defined( 'DUPLICATE_POST_CURRENT_VERSION' ) ) {
|
|
214 |
<br/>
|
215 |
<?php
|
216 |
\printf(
|
217 |
-
|
218 |
\esc_html__( 'You can also use the template tag %1$sduplicate_post_clone_post_link( $link, $before, $after, $id )%2$s. %3$sMore info on the template tag%4$s.', 'duplicate-post' ),
|
219 |
'<code>',
|
220 |
'</code>',
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
namespace Yoast\WP\Duplicate_Post\Admin\Views;
|
4 |
+
|
5 |
+
if ( ! \defined( 'DUPLICATE_POST_CURRENT_VERSION' ) ) {
|
6 |
+
\header( 'Status: 403 Forbidden' );
|
7 |
+
\header( 'HTTP/1.1 403 Forbidden' );
|
8 |
exit();
|
9 |
}
|
10 |
+
|
11 |
?>
|
12 |
<div class="wrap">
|
13 |
<h1>
|
212 |
<br/>
|
213 |
<?php
|
214 |
\printf(
|
215 |
+
/* translators: 1: Code start tag, 2: Code closing tag, 3: Link start tag to the template tag documentation, 4: Link closing tag. */
|
216 |
\esc_html__( 'You can also use the template tag %1$sduplicate_post_clone_post_link( $link, $before, $after, $id )%2$s. %3$sMore info on the template tag%4$s.', 'duplicate-post' ),
|
217 |
'<code>',
|
218 |
'</code>',
|
src/{class-duplicate-post.php → duplicate-post.php}
RENAMED
@@ -1,10 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post main class.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
@@ -13,7 +7,9 @@ use Yoast\WP\Duplicate_Post\UI\User_Interface;
|
|
13 |
use Yoast\WP\Duplicate_Post\Watchers\Watchers;
|
14 |
|
15 |
/**
|
16 |
-
*
|
|
|
|
|
17 |
*/
|
18 |
class Duplicate_Post {
|
19 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Watchers\Watchers;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post main class.
|
11 |
+
*
|
12 |
+
* @since 4.0
|
13 |
*/
|
14 |
class Duplicate_Post {
|
15 |
|
src/handlers/{class-bulk-handler.php → bulk-handler.php}
RENAMED
@@ -1,10 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post handler class for duplication bulk actions.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
10 |
|
@@ -13,7 +7,9 @@ use Yoast\WP\Duplicate_Post\Post_Duplicator;
|
|
13 |
use Yoast\WP\Duplicate_Post\Utils;
|
14 |
|
15 |
/**
|
16 |
-
*
|
|
|
|
|
17 |
*/
|
18 |
class Bulk_Handler {
|
19 |
|
@@ -99,7 +95,7 @@ class Bulk_Handler {
|
|
99 |
if ( ! empty( $post ) && $this->permissions_helper->should_rewrite_and_republish_be_allowed( $post ) ) {
|
100 |
$new_post_id = $this->post_duplicator->create_duplicate_for_rewrite_and_republish( $post );
|
101 |
if ( ! \is_wp_error( $new_post_id ) ) {
|
102 |
-
|
103 |
}
|
104 |
}
|
105 |
}
|
@@ -131,7 +127,7 @@ class Bulk_Handler {
|
|
131 |
|| ( \is_post_type_hierarchical( $post->post_type ) && ! Utils::has_ancestors_marked( $post, $post_ids ) )
|
132 |
) {
|
133 |
if ( ! \is_wp_error( \duplicate_post_create_duplicate( $post ) ) ) {
|
134 |
-
|
135 |
}
|
136 |
}
|
137 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post handler class for duplication bulk actions.
|
11 |
+
*
|
12 |
+
* @since 4.0
|
13 |
*/
|
14 |
class Bulk_Handler {
|
15 |
|
95 |
if ( ! empty( $post ) && $this->permissions_helper->should_rewrite_and_republish_be_allowed( $post ) ) {
|
96 |
$new_post_id = $this->post_duplicator->create_duplicate_for_rewrite_and_republish( $post );
|
97 |
if ( ! \is_wp_error( $new_post_id ) ) {
|
98 |
+
++$counter;
|
99 |
}
|
100 |
}
|
101 |
}
|
127 |
|| ( \is_post_type_hierarchical( $post->post_type ) && ! Utils::has_ancestors_marked( $post, $post_ids ) )
|
128 |
) {
|
129 |
if ( ! \is_wp_error( \duplicate_post_create_duplicate( $post ) ) ) {
|
130 |
+
++$counter;
|
131 |
}
|
132 |
}
|
133 |
}
|
src/handlers/{class-check-changes-handler.php → check-changes-handler.php}
RENAMED
@@ -1,18 +1,17 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post handler class for changes overview.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
10 |
|
|
|
11 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
12 |
use Yoast\WP\Duplicate_Post\Utils;
|
13 |
|
14 |
/**
|
|
|
|
|
15 |
* Represents the handler for checking the changes between a copy and the original post.
|
|
|
|
|
16 |
*/
|
17 |
class Check_Changes_Handler {
|
18 |
|
@@ -26,14 +25,14 @@ class Check_Changes_Handler {
|
|
26 |
/**
|
27 |
* Holds the current post object.
|
28 |
*
|
29 |
-
* @var
|
30 |
*/
|
31 |
private $post;
|
32 |
|
33 |
/**
|
34 |
* Holds the original post object.
|
35 |
*
|
36 |
-
* @var
|
37 |
*/
|
38 |
private $original;
|
39 |
|
@@ -63,17 +62,17 @@ class Check_Changes_Handler {
|
|
63 |
public function check_changes_action_handler() {
|
64 |
global $wp_version;
|
65 |
|
66 |
-
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
67 |
-
( isset( $_REQUEST['action'] ) &&
|
68 |
\wp_die(
|
69 |
\esc_html__( 'No post has been supplied!', 'duplicate-post' )
|
70 |
);
|
71 |
return;
|
72 |
}
|
73 |
|
74 |
-
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
75 |
|
76 |
-
\check_admin_referer( 'duplicate_post_check_changes_' . $id );
|
77 |
|
78 |
$this->post = \get_post( $id );
|
79 |
|
@@ -108,13 +107,13 @@ class Check_Changes_Handler {
|
|
108 |
<h1 class="long-header">
|
109 |
<?php
|
110 |
echo \sprintf(
|
111 |
-
|
112 |
\esc_html__( 'Compare changes of duplicated post with the original (“%s”)', 'duplicate-post' ),
|
113 |
Utils::get_edit_or_view_link( $this->original ) // phpcs:ignore WordPress.Security.EscapeOutput
|
114 |
);
|
115 |
?>
|
116 |
</h1>
|
117 |
-
<a href="<?php echo \esc_url( $post_edit_link ); ?>"><?php \esc_html_e( '← Return to editor', '
|
118 |
<div class="revisions">
|
119 |
<div class="revisions-control-frame">
|
120 |
<div class="revisions-controls"></div>
|
@@ -124,16 +123,16 @@ class Check_Changes_Handler {
|
|
124 |
<div class="diff">
|
125 |
<?php
|
126 |
$fields = [
|
127 |
-
'post_title' => \__( 'Title', '
|
128 |
-
'post_content' => \__( 'Content', '
|
129 |
-
'post_excerpt' => \__( 'Excerpt', '
|
130 |
];
|
131 |
|
132 |
-
$args =
|
133 |
'show_split_view' => true,
|
134 |
-
'title_left' => __( 'Removed', '
|
135 |
-
'title_right' => __( 'Added', '
|
136 |
-
|
137 |
|
138 |
if ( \version_compare( $wp_version, '5.7' ) < 0 ) {
|
139 |
unset( $args['title_left'] );
|
@@ -141,22 +140,23 @@ class Check_Changes_Handler {
|
|
141 |
}
|
142 |
|
143 |
$post_array = \get_post( $this->post, \ARRAY_A );
|
|
|
144 |
/** This filter is documented in wp-admin/includes/revision.php */
|
145 |
-
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reason:
|
146 |
$fields = \apply_filters( '_wp_post_revision_fields', $fields, $post_array );
|
147 |
|
148 |
foreach ( $fields as $field => $name ) {
|
149 |
/** This filter is documented in wp-admin/includes/revision.php */
|
150 |
-
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reason:
|
151 |
-
$content_from = apply_filters( "_wp_post_revision_field_{$field}", $this->original->$field, $field, $this->original, 'from' );
|
152 |
|
153 |
/** This filter is documented in wp-admin/includes/revision.php */
|
154 |
-
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reason:
|
155 |
$content_to = \apply_filters( "_wp_post_revision_field_{$field}", $this->post->$field, $field, $this->post, 'to' );
|
156 |
|
157 |
$diff = \wp_text_diff( $content_from, $content_to, $args );
|
158 |
|
159 |
-
if ( ! $diff && 'post_title'
|
160 |
// It's a better user experience to still show the Title, even if it didn't change.
|
161 |
$diff = '<table class="diff"><colgroup><col class="content diffsplit left"><col class="content diffsplit middle"><col class="content diffsplit right"></colgroup><tbody><tr>';
|
162 |
$diff .= '<td>' . \esc_html( $this->original->post_title ) . '</td><td></td><td>' . \esc_html( $this->post->post_title ) . '</td>';
|
@@ -194,7 +194,7 @@ class Check_Changes_Handler {
|
|
194 |
\set_current_screen( 'revision' );
|
195 |
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- The revision screen expects $post to be set.
|
196 |
$post = $this->post;
|
197 |
-
require_once ABSPATH . 'wp-admin/admin-header.php';
|
198 |
}
|
199 |
|
200 |
/**
|
@@ -205,6 +205,6 @@ class Check_Changes_Handler {
|
|
205 |
* @return void
|
206 |
*/
|
207 |
public function require_wordpress_footer() {
|
208 |
-
require_once ABSPATH . 'wp-admin/admin-footer.php';
|
209 |
}
|
210 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post handler class for changes overview.
|
11 |
+
*
|
12 |
* Represents the handler for checking the changes between a copy and the original post.
|
13 |
+
*
|
14 |
+
* @since 4.0
|
15 |
*/
|
16 |
class Check_Changes_Handler {
|
17 |
|
25 |
/**
|
26 |
* Holds the current post object.
|
27 |
*
|
28 |
+
* @var WP_Post
|
29 |
*/
|
30 |
private $post;
|
31 |
|
32 |
/**
|
33 |
* Holds the original post object.
|
34 |
*
|
35 |
+
* @var WP_Post
|
36 |
*/
|
37 |
private $original;
|
38 |
|
62 |
public function check_changes_action_handler() {
|
63 |
global $wp_version;
|
64 |
|
65 |
+
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
66 |
+
|| ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'duplicate_post_check_changes' ) ) ) {
|
67 |
\wp_die(
|
68 |
\esc_html__( 'No post has been supplied!', 'duplicate-post' )
|
69 |
);
|
70 |
return;
|
71 |
}
|
72 |
|
73 |
+
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
74 |
|
75 |
+
\check_admin_referer( 'duplicate_post_check_changes_' . $id );
|
76 |
|
77 |
$this->post = \get_post( $id );
|
78 |
|
107 |
<h1 class="long-header">
|
108 |
<?php
|
109 |
echo \sprintf(
|
110 |
+
/* translators: %s: original item link (to view or edit) or title. */
|
111 |
\esc_html__( 'Compare changes of duplicated post with the original (“%s”)', 'duplicate-post' ),
|
112 |
Utils::get_edit_or_view_link( $this->original ) // phpcs:ignore WordPress.Security.EscapeOutput
|
113 |
);
|
114 |
?>
|
115 |
</h1>
|
116 |
+
<a href="<?php echo \esc_url( $post_edit_link ); ?>"><?php \esc_html_e( '← Return to editor', 'duplicate-post' ); ?></a>
|
117 |
<div class="revisions">
|
118 |
<div class="revisions-control-frame">
|
119 |
<div class="revisions-controls"></div>
|
123 |
<div class="diff">
|
124 |
<?php
|
125 |
$fields = [
|
126 |
+
'post_title' => \__( 'Title', 'duplicate-post' ),
|
127 |
+
'post_content' => \__( 'Content', 'duplicate-post' ),
|
128 |
+
'post_excerpt' => \__( 'Excerpt', 'duplicate-post' ),
|
129 |
];
|
130 |
|
131 |
+
$args = [
|
132 |
'show_split_view' => true,
|
133 |
+
'title_left' => \__( 'Removed', 'duplicate-post' ),
|
134 |
+
'title_right' => \__( 'Added', 'duplicate-post' ),
|
135 |
+
];
|
136 |
|
137 |
if ( \version_compare( $wp_version, '5.7' ) < 0 ) {
|
138 |
unset( $args['title_left'] );
|
140 |
}
|
141 |
|
142 |
$post_array = \get_post( $this->post, \ARRAY_A );
|
143 |
+
|
144 |
/** This filter is documented in wp-admin/includes/revision.php */
|
145 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reason: using WP core hook.
|
146 |
$fields = \apply_filters( '_wp_post_revision_fields', $fields, $post_array );
|
147 |
|
148 |
foreach ( $fields as $field => $name ) {
|
149 |
/** This filter is documented in wp-admin/includes/revision.php */
|
150 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reason: using WP core hook.
|
151 |
+
$content_from = \apply_filters( "_wp_post_revision_field_{$field}", $this->original->$field, $field, $this->original, 'from' );
|
152 |
|
153 |
/** This filter is documented in wp-admin/includes/revision.php */
|
154 |
+
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reason: using WP core hook.
|
155 |
$content_to = \apply_filters( "_wp_post_revision_field_{$field}", $this->post->$field, $field, $this->post, 'to' );
|
156 |
|
157 |
$diff = \wp_text_diff( $content_from, $content_to, $args );
|
158 |
|
159 |
+
if ( ! $diff && $field === 'post_title' ) {
|
160 |
// It's a better user experience to still show the Title, even if it didn't change.
|
161 |
$diff = '<table class="diff"><colgroup><col class="content diffsplit left"><col class="content diffsplit middle"><col class="content diffsplit right"></colgroup><tbody><tr>';
|
162 |
$diff .= '<td>' . \esc_html( $this->original->post_title ) . '</td><td></td><td>' . \esc_html( $this->post->post_title ) . '</td>';
|
194 |
\set_current_screen( 'revision' );
|
195 |
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- The revision screen expects $post to be set.
|
196 |
$post = $this->post;
|
197 |
+
require_once \ABSPATH . 'wp-admin/admin-header.php';
|
198 |
}
|
199 |
|
200 |
/**
|
205 |
* @return void
|
206 |
*/
|
207 |
public function require_wordpress_footer() {
|
208 |
+
require_once \ABSPATH . 'wp-admin/admin-footer.php';
|
209 |
}
|
210 |
}
|
src/handlers/{class-handler.php → handler.php}
RENAMED
@@ -1,10 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post handler class for duplication actions.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
10 |
|
@@ -12,7 +6,9 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Post_Duplicator;
|
13 |
|
14 |
/**
|
15 |
-
*
|
|
|
|
|
16 |
*/
|
17 |
class Handler {
|
18 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
4 |
|
6 |
use Yoast\WP\Duplicate_Post\Post_Duplicator;
|
7 |
|
8 |
/**
|
9 |
+
* Duplicate Post handler class for duplication actions.
|
10 |
+
*
|
11 |
+
* @since 4.0
|
12 |
*/
|
13 |
class Handler {
|
14 |
|
src/handlers/{class-link-handler.php → link-handler.php}
RENAMED
@@ -1,10 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post handler class for duplication actions from links.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
10 |
|
@@ -12,7 +6,9 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Post_Duplicator;
|
13 |
|
14 |
/**
|
15 |
-
*
|
|
|
|
|
16 |
*/
|
17 |
class Link_Handler {
|
18 |
|
@@ -62,14 +58,14 @@ class Link_Handler {
|
|
62 |
\wp_die( \esc_html__( 'Current user is not allowed to copy posts.', 'duplicate-post' ) );
|
63 |
}
|
64 |
|
65 |
-
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
66 |
-
( isset( $_REQUEST['action'] ) &&
|
67 |
\wp_die( \esc_html__( 'No post to duplicate has been supplied!', 'duplicate-post' ) );
|
68 |
}
|
69 |
|
70 |
-
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
71 |
|
72 |
-
\check_admin_referer( 'duplicate_post_new_draft_' . $id );
|
73 |
|
74 |
$post = \get_post( $id );
|
75 |
|
@@ -118,14 +114,14 @@ class Link_Handler {
|
|
118 |
\wp_die( \esc_html__( 'Current user is not allowed to copy posts.', 'duplicate-post' ) );
|
119 |
}
|
120 |
|
121 |
-
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
122 |
-
( isset( $_REQUEST['action'] ) &&
|
123 |
\wp_die( \esc_html__( 'No post to duplicate has been supplied!', 'duplicate-post' ) );
|
124 |
}
|
125 |
|
126 |
-
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
127 |
|
128 |
-
\check_admin_referer( 'duplicate_post_clone_' . $id );
|
129 |
|
130 |
$post = \get_post( $id );
|
131 |
|
@@ -154,16 +150,18 @@ class Link_Handler {
|
|
154 |
|
155 |
$post_type = $post->post_type;
|
156 |
$sendback = \wp_get_referer();
|
157 |
-
if ( ! $sendback || strpos( $sendback, 'post.php' ) !== false || strpos( $sendback, 'post-new.php' ) !== false ) {
|
158 |
-
if ( 'attachment'
|
159 |
$sendback = \admin_url( 'upload.php' );
|
160 |
-
}
|
|
|
161 |
$sendback = \admin_url( 'edit.php' );
|
162 |
if ( ! empty( $post_type ) ) {
|
163 |
$sendback = \add_query_arg( 'post_type', $post_type, $sendback );
|
164 |
}
|
165 |
}
|
166 |
-
}
|
|
|
167 |
$sendback = \remove_query_arg( [ 'trashed', 'untrashed', 'deleted', 'cloned', 'ids' ], $sendback );
|
168 |
}
|
169 |
|
@@ -190,14 +188,14 @@ class Link_Handler {
|
|
190 |
\wp_die( \esc_html__( 'Current user is not allowed to copy posts.', 'duplicate-post' ) );
|
191 |
}
|
192 |
|
193 |
-
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
194 |
-
( isset( $_REQUEST['action'] ) &&
|
195 |
\wp_die( \esc_html__( 'No post to duplicate has been supplied!', 'duplicate-post' ) );
|
196 |
}
|
197 |
|
198 |
-
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
199 |
|
200 |
-
\check_admin_referer( 'duplicate_post_rewrite_' . $id );
|
201 |
|
202 |
$post = \get_post( $id );
|
203 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
4 |
|
6 |
use Yoast\WP\Duplicate_Post\Post_Duplicator;
|
7 |
|
8 |
/**
|
9 |
+
* Duplicate Post handler class for duplication actions from links.
|
10 |
+
*
|
11 |
+
* @since 4.0
|
12 |
*/
|
13 |
class Link_Handler {
|
14 |
|
58 |
\wp_die( \esc_html__( 'Current user is not allowed to copy posts.', 'duplicate-post' ) );
|
59 |
}
|
60 |
|
61 |
+
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
62 |
+
|| ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'duplicate_post_new_draft' ) ) ) {
|
63 |
\wp_die( \esc_html__( 'No post to duplicate has been supplied!', 'duplicate-post' ) );
|
64 |
}
|
65 |
|
66 |
+
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
67 |
|
68 |
+
\check_admin_referer( 'duplicate_post_new_draft_' . $id );
|
69 |
|
70 |
$post = \get_post( $id );
|
71 |
|
114 |
\wp_die( \esc_html__( 'Current user is not allowed to copy posts.', 'duplicate-post' ) );
|
115 |
}
|
116 |
|
117 |
+
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
118 |
+
|| ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'duplicate_post_clone' ) ) ) {
|
119 |
\wp_die( \esc_html__( 'No post to duplicate has been supplied!', 'duplicate-post' ) );
|
120 |
}
|
121 |
|
122 |
+
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
123 |
|
124 |
+
\check_admin_referer( 'duplicate_post_clone_' . $id );
|
125 |
|
126 |
$post = \get_post( $id );
|
127 |
|
150 |
|
151 |
$post_type = $post->post_type;
|
152 |
$sendback = \wp_get_referer();
|
153 |
+
if ( ! $sendback || \strpos( $sendback, 'post.php' ) !== false || \strpos( $sendback, 'post-new.php' ) !== false ) {
|
154 |
+
if ( $post_type === 'attachment' ) {
|
155 |
$sendback = \admin_url( 'upload.php' );
|
156 |
+
}
|
157 |
+
else {
|
158 |
$sendback = \admin_url( 'edit.php' );
|
159 |
if ( ! empty( $post_type ) ) {
|
160 |
$sendback = \add_query_arg( 'post_type', $post_type, $sendback );
|
161 |
}
|
162 |
}
|
163 |
+
}
|
164 |
+
else {
|
165 |
$sendback = \remove_query_arg( [ 'trashed', 'untrashed', 'deleted', 'cloned', 'ids' ], $sendback );
|
166 |
}
|
167 |
|
188 |
\wp_die( \esc_html__( 'Current user is not allowed to copy posts.', 'duplicate-post' ) );
|
189 |
}
|
190 |
|
191 |
+
if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] )
|
192 |
+
|| ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'duplicate_post_rewrite' ) ) ) {
|
193 |
\wp_die( \esc_html__( 'No post to duplicate has been supplied!', 'duplicate-post' ) );
|
194 |
}
|
195 |
|
196 |
+
$id = ( isset( $_GET['post'] ) ? \intval( \wp_unslash( $_GET['post'] ) ) : \intval( \wp_unslash( $_POST['post'] ) ) );
|
197 |
|
198 |
+
\check_admin_referer( 'duplicate_post_rewrite_' . $id );
|
199 |
|
200 |
$post = \get_post( $id );
|
201 |
|
src/handlers/{class-save-post-handler.php → save-post-handler.php}
RENAMED
@@ -1,17 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post handler class for save_post action.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
10 |
|
11 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
12 |
|
13 |
/**
|
14 |
-
*
|
|
|
|
|
15 |
*/
|
16 |
class Save_Post_Handler {
|
17 |
|
@@ -51,8 +47,8 @@ class Save_Post_Handler {
|
|
51 |
* @return void
|
52 |
*/
|
53 |
public function delete_on_save_post( $post_id ) {
|
54 |
-
if ( ( \defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
|
55 |
-
|| empty( $_POST['duplicate_post_remove_original'] )
|
56 |
|| ! \current_user_can( 'edit_post', $post_id ) ) {
|
57 |
return;
|
58 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Handlers;
|
4 |
|
5 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post handler class for save_post action.
|
9 |
+
*
|
10 |
+
* @since 4.0
|
11 |
*/
|
12 |
class Save_Post_Handler {
|
13 |
|
47 |
* @return void
|
48 |
*/
|
49 |
public function delete_on_save_post( $post_id ) {
|
50 |
+
if ( ( \defined( 'DOING_AUTOSAVE' ) && \DOING_AUTOSAVE )
|
51 |
+
|| empty( $_POST['duplicate_post_remove_original'] )
|
52 |
|| ! \current_user_can( 'edit_post', $post_id ) ) {
|
53 |
return;
|
54 |
}
|
src/{class-permissions-helper.php → permissions-helper.php}
RENAMED
@@ -1,15 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Permissions helper for Duplicate Post.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
|
|
|
|
11 |
/**
|
12 |
-
*
|
|
|
|
|
13 |
*/
|
14 |
class Permissions_Helper {
|
15 |
|
@@ -61,33 +59,33 @@ class Permissions_Helper {
|
|
61 |
/**
|
62 |
* Determines if the post is a copy intended for Rewrite & Republish.
|
63 |
*
|
64 |
-
* @param
|
65 |
*
|
66 |
* @return bool Whether the post is a copy intended for Rewrite & Republish.
|
67 |
*/
|
68 |
-
public function is_rewrite_and_republish_copy(
|
69 |
return ( \intval( \get_post_meta( $post->ID, '_dp_is_rewrite_republish_copy', true ) ) === 1 );
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
* Gets the Rewrite & Republish copy ID for the passed post.
|
74 |
*
|
75 |
-
* @param
|
76 |
*
|
77 |
* @return int The Rewrite & Republish copy ID.
|
78 |
*/
|
79 |
-
public function get_rewrite_and_republish_copy_id(
|
80 |
return \get_post_meta( $post->ID, '_dp_has_rewrite_republish_copy', true );
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
* Gets the copy post object for the passed post.
|
85 |
*
|
86 |
-
* @param
|
87 |
*
|
88 |
-
* @return
|
89 |
*/
|
90 |
-
public function get_rewrite_and_republish_copy(
|
91 |
$copy_id = $this->get_rewrite_and_republish_copy_id( $post );
|
92 |
|
93 |
if ( empty( $copy_id ) ) {
|
@@ -100,22 +98,22 @@ class Permissions_Helper {
|
|
100 |
/**
|
101 |
* Determines if the post has a copy intended for Rewrite & Republish.
|
102 |
*
|
103 |
-
* @param
|
104 |
*
|
105 |
* @return bool Whether the post has a copy intended for Rewrite & Republish.
|
106 |
*/
|
107 |
-
public function has_rewrite_and_republish_copy(
|
108 |
return ( ! empty( $this->get_rewrite_and_republish_copy_id( $post ) ) );
|
109 |
}
|
110 |
|
111 |
/**
|
112 |
* Determines if the post has a copy intended for Rewrite & Republish which is scheduled to be published.
|
113 |
*
|
114 |
-
* @param
|
115 |
*
|
116 |
-
* @return bool
|
117 |
*/
|
118 |
-
public function has_scheduled_rewrite_and_republish_copy(
|
119 |
$copy = $this->get_rewrite_and_republish_copy( $post );
|
120 |
|
121 |
if ( ! empty( $copy ) && $copy->post_status === 'future' ) {
|
@@ -176,11 +174,11 @@ class Permissions_Helper {
|
|
176 |
/**
|
177 |
* Determines if the original post has changed since the creation of the copy.
|
178 |
*
|
179 |
-
* @param
|
180 |
*
|
181 |
* @return bool Whether the original post has changed since the creation of the copy.
|
182 |
*/
|
183 |
-
public function has_original_changed(
|
184 |
if ( ! $this->is_rewrite_and_republish_copy( $post ) ) {
|
185 |
return false;
|
186 |
}
|
@@ -200,16 +198,16 @@ class Permissions_Helper {
|
|
200 |
/**
|
201 |
* Determines if duplicate links for the post can be displayed.
|
202 |
*
|
203 |
-
* @param
|
204 |
*
|
205 |
* @return bool Whether the links can be displayed.
|
206 |
*/
|
207 |
-
public function should_links_be_displayed(
|
208 |
/**
|
209 |
* Filter allowing displaying duplicate post links for current post.
|
210 |
*
|
211 |
-
* @param bool
|
212 |
-
* @param
|
213 |
*
|
214 |
* @return bool Whether or not to display the duplicate post links.
|
215 |
*/
|
@@ -221,11 +219,11 @@ class Permissions_Helper {
|
|
221 |
/**
|
222 |
* Determines if the Rewrite & Republish link for the post should be displayed.
|
223 |
*
|
224 |
-
* @param
|
225 |
*
|
226 |
* @return bool Whether the links should be displayed.
|
227 |
*/
|
228 |
-
public function should_rewrite_and_republish_be_allowed(
|
229 |
return $post->post_status === 'publish'
|
230 |
&& ! $this->is_rewrite_and_republish_copy( $post )
|
231 |
&& ! $this->has_rewrite_and_republish_copy( $post );
|
@@ -251,22 +249,22 @@ class Permissions_Helper {
|
|
251 |
/**
|
252 |
* Determines whether a Rewrite & Republish copy can be republished.
|
253 |
*
|
254 |
-
* @param
|
255 |
*
|
256 |
* @return bool Whether the Rewrite & Republish copy can be republished.
|
257 |
*/
|
258 |
-
public function is_copy_allowed_to_be_republished(
|
259 |
return \in_array( $post->post_status, [ 'dp-rewrite-republish', 'private' ], true );
|
260 |
}
|
261 |
|
262 |
/**
|
263 |
* Determines if the post has a trashed copy intended for Rewrite & Republish.
|
264 |
*
|
265 |
-
* @param
|
266 |
*
|
267 |
* @return bool Whether the post has a trashed copy intended for Rewrite & Republish.
|
268 |
*/
|
269 |
-
public function has_trashed_rewrite_and_republish_copy(
|
270 |
$copy_id = \get_post_meta( $post->ID, '_dp_has_rewrite_republish_copy', true );
|
271 |
|
272 |
if ( ! $copy_id ) {
|
@@ -275,10 +273,6 @@ class Permissions_Helper {
|
|
275 |
|
276 |
$copy = \get_post( $copy_id );
|
277 |
|
278 |
-
|
279 |
-
return true;
|
280 |
-
}
|
281 |
-
|
282 |
-
return false;
|
283 |
}
|
284 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
+
|
7 |
/**
|
8 |
+
* Permissions helper for Duplicate Post.
|
9 |
+
*
|
10 |
+
* @since 4.0
|
11 |
*/
|
12 |
class Permissions_Helper {
|
13 |
|
59 |
/**
|
60 |
* Determines if the post is a copy intended for Rewrite & Republish.
|
61 |
*
|
62 |
+
* @param WP_Post $post The post object.
|
63 |
*
|
64 |
* @return bool Whether the post is a copy intended for Rewrite & Republish.
|
65 |
*/
|
66 |
+
public function is_rewrite_and_republish_copy( WP_Post $post ) {
|
67 |
return ( \intval( \get_post_meta( $post->ID, '_dp_is_rewrite_republish_copy', true ) ) === 1 );
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
* Gets the Rewrite & Republish copy ID for the passed post.
|
72 |
*
|
73 |
+
* @param WP_Post $post The post object.
|
74 |
*
|
75 |
* @return int The Rewrite & Republish copy ID.
|
76 |
*/
|
77 |
+
public function get_rewrite_and_republish_copy_id( WP_Post $post ) {
|
78 |
return \get_post_meta( $post->ID, '_dp_has_rewrite_republish_copy', true );
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
* Gets the copy post object for the passed post.
|
83 |
*
|
84 |
+
* @param WP_Post $post The post to get the copy for.
|
85 |
*
|
86 |
+
* @return WP_Post|null The copy's post object or null if it doesn't exist.
|
87 |
*/
|
88 |
+
public function get_rewrite_and_republish_copy( WP_Post $post ) {
|
89 |
$copy_id = $this->get_rewrite_and_republish_copy_id( $post );
|
90 |
|
91 |
if ( empty( $copy_id ) ) {
|
98 |
/**
|
99 |
* Determines if the post has a copy intended for Rewrite & Republish.
|
100 |
*
|
101 |
+
* @param WP_Post $post The post object.
|
102 |
*
|
103 |
* @return bool Whether the post has a copy intended for Rewrite & Republish.
|
104 |
*/
|
105 |
+
public function has_rewrite_and_republish_copy( WP_Post $post ) {
|
106 |
return ( ! empty( $this->get_rewrite_and_republish_copy_id( $post ) ) );
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
* Determines if the post has a copy intended for Rewrite & Republish which is scheduled to be published.
|
111 |
*
|
112 |
+
* @param WP_Post $post The post object.
|
113 |
*
|
114 |
+
* @return bool|WP_Post The scheduled copy if present, false if the post has no scheduled copy.
|
115 |
*/
|
116 |
+
public function has_scheduled_rewrite_and_republish_copy( WP_Post $post ) {
|
117 |
$copy = $this->get_rewrite_and_republish_copy( $post );
|
118 |
|
119 |
if ( ! empty( $copy ) && $copy->post_status === 'future' ) {
|
174 |
/**
|
175 |
* Determines if the original post has changed since the creation of the copy.
|
176 |
*
|
177 |
+
* @param WP_Post $post The post object.
|
178 |
*
|
179 |
* @return bool Whether the original post has changed since the creation of the copy.
|
180 |
*/
|
181 |
+
public function has_original_changed( WP_Post $post ) {
|
182 |
if ( ! $this->is_rewrite_and_republish_copy( $post ) ) {
|
183 |
return false;
|
184 |
}
|
198 |
/**
|
199 |
* Determines if duplicate links for the post can be displayed.
|
200 |
*
|
201 |
+
* @param WP_Post $post The post object.
|
202 |
*
|
203 |
* @return bool Whether the links can be displayed.
|
204 |
*/
|
205 |
+
public function should_links_be_displayed( WP_Post $post ) {
|
206 |
/**
|
207 |
* Filter allowing displaying duplicate post links for current post.
|
208 |
*
|
209 |
+
* @param bool $display_links Whether the duplicate links will be displayed.
|
210 |
+
* @param WP_Post $post The post object.
|
211 |
*
|
212 |
* @return bool Whether or not to display the duplicate post links.
|
213 |
*/
|
219 |
/**
|
220 |
* Determines if the Rewrite & Republish link for the post should be displayed.
|
221 |
*
|
222 |
+
* @param WP_Post $post The post object.
|
223 |
*
|
224 |
* @return bool Whether the links should be displayed.
|
225 |
*/
|
226 |
+
public function should_rewrite_and_republish_be_allowed( WP_Post $post ) {
|
227 |
return $post->post_status === 'publish'
|
228 |
&& ! $this->is_rewrite_and_republish_copy( $post )
|
229 |
&& ! $this->has_rewrite_and_republish_copy( $post );
|
249 |
/**
|
250 |
* Determines whether a Rewrite & Republish copy can be republished.
|
251 |
*
|
252 |
+
* @param WP_Post $post The post object.
|
253 |
*
|
254 |
* @return bool Whether the Rewrite & Republish copy can be republished.
|
255 |
*/
|
256 |
+
public function is_copy_allowed_to_be_republished( WP_Post $post ) {
|
257 |
return \in_array( $post->post_status, [ 'dp-rewrite-republish', 'private' ], true );
|
258 |
}
|
259 |
|
260 |
/**
|
261 |
* Determines if the post has a trashed copy intended for Rewrite & Republish.
|
262 |
*
|
263 |
+
* @param WP_Post $post The post object.
|
264 |
*
|
265 |
* @return bool Whether the post has a trashed copy intended for Rewrite & Republish.
|
266 |
*/
|
267 |
+
public function has_trashed_rewrite_and_republish_copy( WP_Post $post ) {
|
268 |
$copy_id = \get_post_meta( $post->ID, '_dp_has_rewrite_republish_copy', true );
|
269 |
|
270 |
if ( ! $copy_id ) {
|
273 |
|
274 |
$copy = \get_post( $copy_id );
|
275 |
|
276 |
+
return ( $copy && $copy->post_status === 'trash' );
|
|
|
|
|
|
|
|
|
277 |
}
|
278 |
}
|
src/{class-post-duplicator.php → post-duplicator.php}
RENAMED
@@ -1,15 +1,14 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to create copies.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
|
|
|
|
|
|
11 |
/**
|
12 |
-
*
|
|
|
|
|
13 |
*/
|
14 |
class Post_Duplicator {
|
15 |
|
@@ -48,41 +47,45 @@ class Post_Duplicator {
|
|
48 |
/**
|
49 |
* Creates a copy of a post object, accordingly to an options array.
|
50 |
*
|
51 |
-
* @param
|
52 |
-
* @param array
|
53 |
*
|
54 |
-
* @return int
|
55 |
*/
|
56 |
-
public function create_duplicate(
|
57 |
$defaults = $this->get_default_options();
|
58 |
$options = \wp_parse_args( $options, $defaults );
|
59 |
|
60 |
$title = '';
|
61 |
$new_post_status = $post->post_status;
|
62 |
-
if (
|
63 |
$title = $this->generate_copy_title( $post, $options );
|
64 |
$new_post_status = $this->generate_copy_status( $post, $options );
|
65 |
}
|
66 |
|
67 |
$new_post_author_id = $this->generate_copy_author( $post, $options );
|
68 |
|
69 |
-
$menu_order =
|
|
|
|
|
|
|
|
|
70 |
if ( ! empty( $options['increase_menu_order_by'] ) && \is_numeric( $options['increase_menu_order_by'] ) ) {
|
71 |
$menu_order += \intval( $options['increase_menu_order_by'] );
|
72 |
}
|
73 |
|
74 |
$new_post = [
|
75 |
'post_author' => $new_post_author_id,
|
76 |
-
'post_content' => $options['copy_content'] ? $post->post_content : '',
|
77 |
-
'post_content_filtered' => $options['copy_content'] ? $post->post_content_filtered : '',
|
78 |
'post_title' => $title,
|
79 |
-
'post_excerpt' => $options['copy_excerpt'] ? $post->post_excerpt : '',
|
80 |
'post_status' => $new_post_status,
|
81 |
'post_type' => $post->post_type,
|
82 |
'comment_status' => $post->comment_status,
|
83 |
'ping_status' => $post->ping_status,
|
84 |
-
'post_password' => $options['copy_password'] ? $post->post_password : '',
|
85 |
-
'post_name' => $options['copy_name'] ? $post->post_name : '',
|
86 |
'post_parent' => empty( $options['parent_id'] ) ? $post->post_parent : $options['parent_id'],
|
87 |
'menu_order' => $menu_order,
|
88 |
'post_mime_type' => $post->post_mime_type,
|
@@ -99,8 +102,8 @@ class Post_Duplicator {
|
|
99 |
/**
|
100 |
* Filter new post values.
|
101 |
*
|
102 |
-
* @param array
|
103 |
-
* @param
|
104 |
*
|
105 |
* @return array
|
106 |
*/
|
@@ -141,11 +144,11 @@ class Post_Duplicator {
|
|
141 |
/**
|
142 |
* Wraps the function to create a copy for the Rewrite & Republish feature.
|
143 |
*
|
144 |
-
* @param
|
145 |
*
|
146 |
-
* @return int
|
147 |
*/
|
148 |
-
public function create_duplicate_for_rewrite_and_republish(
|
149 |
$options = [
|
150 |
'copy_title' => true,
|
151 |
'copy_date' => true,
|
@@ -176,9 +179,9 @@ class Post_Duplicator {
|
|
176 |
/**
|
177 |
* Copies the taxonomies of a post to another post.
|
178 |
*
|
179 |
-
* @param int
|
180 |
-
* @param
|
181 |
-
* @param array
|
182 |
*
|
183 |
* @return void
|
184 |
*/
|
@@ -228,9 +231,9 @@ class Post_Duplicator {
|
|
228 |
/**
|
229 |
* Copies the meta information of a post to another post.
|
230 |
*
|
231 |
-
* @param int
|
232 |
-
* @param
|
233 |
-
* @param array
|
234 |
*
|
235 |
* @return void
|
236 |
*/
|
@@ -272,7 +275,8 @@ class Post_Duplicator {
|
|
272 |
$meta_keys[] = $meta_key;
|
273 |
}
|
274 |
}
|
275 |
-
}
|
|
|
276 |
$meta_keys = \array_diff( $post_meta_keys, $meta_excludelist );
|
277 |
}
|
278 |
|
@@ -289,9 +293,13 @@ class Post_Duplicator {
|
|
289 |
|
290 |
foreach ( $meta_keys as $meta_key ) {
|
291 |
$meta_values = \get_post_custom_values( $meta_key, $post->ID );
|
|
|
|
|
|
|
|
|
292 |
foreach ( $meta_values as $meta_value ) {
|
293 |
$meta_value = \maybe_unserialize( $meta_value );
|
294 |
-
\
|
295 |
}
|
296 |
}
|
297 |
}
|
@@ -299,12 +307,12 @@ class Post_Duplicator {
|
|
299 |
/**
|
300 |
* Generates and returns the title for the copy.
|
301 |
*
|
302 |
-
* @param
|
303 |
-
* @param array
|
304 |
*
|
305 |
* @return string The calculated title for the copy.
|
306 |
*/
|
307 |
-
public function generate_copy_title(
|
308 |
$prefix = \sanitize_text_field( $options['title_prefix'] );
|
309 |
$suffix = \sanitize_text_field( $options['title_suffix'] );
|
310 |
if ( $options['copy_title'] ) {
|
@@ -315,7 +323,8 @@ class Post_Duplicator {
|
|
315 |
if ( ! empty( $suffix ) ) {
|
316 |
$suffix = ' ' . $suffix;
|
317 |
}
|
318 |
-
}
|
|
|
319 |
$title = '';
|
320 |
}
|
321 |
return \trim( $prefix . $title . $suffix );
|
@@ -324,26 +333,25 @@ class Post_Duplicator {
|
|
324 |
/**
|
325 |
* Generates and returns the status for the copy.
|
326 |
*
|
327 |
-
* @param
|
328 |
-
* @param array
|
329 |
*
|
330 |
* @return string The calculated status for the copy.
|
331 |
*/
|
332 |
-
public function generate_copy_status(
|
333 |
$new_post_status = 'draft';
|
334 |
|
335 |
if ( $options['copy_status'] ) {
|
336 |
$new_post_status = $post->post_status;
|
337 |
if ( $new_post_status === 'publish' || $new_post_status === 'future' ) {
|
338 |
-
//
|
339 |
if ( \is_post_type_hierarchical( $post->post_type ) ) {
|
340 |
if ( ! \current_user_can( 'publish_pages' ) ) {
|
341 |
$new_post_status = 'pending';
|
342 |
}
|
343 |
-
}
|
344 |
-
|
345 |
-
|
346 |
-
}
|
347 |
}
|
348 |
}
|
349 |
}
|
@@ -354,24 +362,23 @@ class Post_Duplicator {
|
|
354 |
/**
|
355 |
* Generates and returns the author ID for the copy.
|
356 |
*
|
357 |
-
* @param
|
358 |
-
* @param array
|
359 |
*
|
360 |
* @return int|string The calculated author ID for the copy.
|
361 |
*/
|
362 |
-
public function generate_copy_author(
|
363 |
$new_post_author = \wp_get_current_user();
|
364 |
$new_post_author_id = $new_post_author->ID;
|
365 |
if ( $options['copy_author'] ) {
|
366 |
-
//
|
367 |
if ( \is_post_type_hierarchical( $post->post_type ) ) {
|
368 |
if ( \current_user_can( 'edit_others_pages' ) ) {
|
369 |
$new_post_author_id = $post->post_author;
|
370 |
}
|
371 |
-
}
|
372 |
-
|
373 |
-
|
374 |
-
}
|
375 |
}
|
376 |
}
|
377 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
5 |
+
use WP_Error;
|
6 |
+
use WP_Post;
|
7 |
+
|
8 |
/**
|
9 |
+
* Duplicate Post class to create copies.
|
10 |
+
*
|
11 |
+
* @since 4.0
|
12 |
*/
|
13 |
class Post_Duplicator {
|
14 |
|
47 |
/**
|
48 |
* Creates a copy of a post object, accordingly to an options array.
|
49 |
*
|
50 |
+
* @param WP_Post $post The original post object.
|
51 |
+
* @param array $options The options overriding the default ones.
|
52 |
*
|
53 |
+
* @return int|WP_Error The copy ID, or a WP_Error object on failure.
|
54 |
*/
|
55 |
+
public function create_duplicate( WP_Post $post, array $options = [] ) {
|
56 |
$defaults = $this->get_default_options();
|
57 |
$options = \wp_parse_args( $options, $defaults );
|
58 |
|
59 |
$title = '';
|
60 |
$new_post_status = $post->post_status;
|
61 |
+
if ( $post->post_type !== 'attachment' ) {
|
62 |
$title = $this->generate_copy_title( $post, $options );
|
63 |
$new_post_status = $this->generate_copy_status( $post, $options );
|
64 |
}
|
65 |
|
66 |
$new_post_author_id = $this->generate_copy_author( $post, $options );
|
67 |
|
68 |
+
$menu_order = 0;
|
69 |
+
if ( $options['copy_menu_order'] ) {
|
70 |
+
$menu_order = $post->menu_order;
|
71 |
+
}
|
72 |
+
|
73 |
if ( ! empty( $options['increase_menu_order_by'] ) && \is_numeric( $options['increase_menu_order_by'] ) ) {
|
74 |
$menu_order += \intval( $options['increase_menu_order_by'] );
|
75 |
}
|
76 |
|
77 |
$new_post = [
|
78 |
'post_author' => $new_post_author_id,
|
79 |
+
'post_content' => ( $options['copy_content'] ) ? $post->post_content : '',
|
80 |
+
'post_content_filtered' => ( $options['copy_content'] ) ? $post->post_content_filtered : '',
|
81 |
'post_title' => $title,
|
82 |
+
'post_excerpt' => ( $options['copy_excerpt'] ) ? $post->post_excerpt : '',
|
83 |
'post_status' => $new_post_status,
|
84 |
'post_type' => $post->post_type,
|
85 |
'comment_status' => $post->comment_status,
|
86 |
'ping_status' => $post->ping_status,
|
87 |
+
'post_password' => ( $options['copy_password'] ) ? $post->post_password : '',
|
88 |
+
'post_name' => ( $options['copy_name'] ) ? $post->post_name : '',
|
89 |
'post_parent' => empty( $options['parent_id'] ) ? $post->post_parent : $options['parent_id'],
|
90 |
'menu_order' => $menu_order,
|
91 |
'post_mime_type' => $post->post_mime_type,
|
102 |
/**
|
103 |
* Filter new post values.
|
104 |
*
|
105 |
+
* @param array $new_post New post values.
|
106 |
+
* @param WP_Post $post Original post object.
|
107 |
*
|
108 |
* @return array
|
109 |
*/
|
144 |
/**
|
145 |
* Wraps the function to create a copy for the Rewrite & Republish feature.
|
146 |
*
|
147 |
+
* @param WP_Post $post The original post object.
|
148 |
*
|
149 |
+
* @return int|WP_Error The copy ID, or a WP_Error object on failure.
|
150 |
*/
|
151 |
+
public function create_duplicate_for_rewrite_and_republish( WP_Post $post ) {
|
152 |
$options = [
|
153 |
'copy_title' => true,
|
154 |
'copy_date' => true,
|
179 |
/**
|
180 |
* Copies the taxonomies of a post to another post.
|
181 |
*
|
182 |
+
* @param int $new_id New post ID.
|
183 |
+
* @param WP_Post $post The original post object.
|
184 |
+
* @param array $options The options array.
|
185 |
*
|
186 |
* @return void
|
187 |
*/
|
231 |
/**
|
232 |
* Copies the meta information of a post to another post.
|
233 |
*
|
234 |
+
* @param int $new_id The new post ID.
|
235 |
+
* @param WP_Post $post The original post object.
|
236 |
+
* @param array $options The options array.
|
237 |
*
|
238 |
* @return void
|
239 |
*/
|
275 |
$meta_keys[] = $meta_key;
|
276 |
}
|
277 |
}
|
278 |
+
}
|
279 |
+
else {
|
280 |
$meta_keys = \array_diff( $post_meta_keys, $meta_excludelist );
|
281 |
}
|
282 |
|
293 |
|
294 |
foreach ( $meta_keys as $meta_key ) {
|
295 |
$meta_values = \get_post_custom_values( $meta_key, $post->ID );
|
296 |
+
|
297 |
+
// Clear existing meta data so that add_post_meta() works properly with non-unique keys.
|
298 |
+
\delete_post_meta( $new_id, $meta_key );
|
299 |
+
|
300 |
foreach ( $meta_values as $meta_value ) {
|
301 |
$meta_value = \maybe_unserialize( $meta_value );
|
302 |
+
\add_post_meta( $new_id, $meta_key, Utils::recursively_slash_strings( $meta_value ) );
|
303 |
}
|
304 |
}
|
305 |
}
|
307 |
/**
|
308 |
* Generates and returns the title for the copy.
|
309 |
*
|
310 |
+
* @param WP_Post $post The original post object.
|
311 |
+
* @param array $options The options array.
|
312 |
*
|
313 |
* @return string The calculated title for the copy.
|
314 |
*/
|
315 |
+
public function generate_copy_title( WP_Post $post, array $options ) {
|
316 |
$prefix = \sanitize_text_field( $options['title_prefix'] );
|
317 |
$suffix = \sanitize_text_field( $options['title_suffix'] );
|
318 |
if ( $options['copy_title'] ) {
|
323 |
if ( ! empty( $suffix ) ) {
|
324 |
$suffix = ' ' . $suffix;
|
325 |
}
|
326 |
+
}
|
327 |
+
else {
|
328 |
$title = '';
|
329 |
}
|
330 |
return \trim( $prefix . $title . $suffix );
|
333 |
/**
|
334 |
* Generates and returns the status for the copy.
|
335 |
*
|
336 |
+
* @param WP_Post $post The original post object.
|
337 |
+
* @param array $options The options array.
|
338 |
*
|
339 |
* @return string The calculated status for the copy.
|
340 |
*/
|
341 |
+
public function generate_copy_status( WP_Post $post, array $options ) {
|
342 |
$new_post_status = 'draft';
|
343 |
|
344 |
if ( $options['copy_status'] ) {
|
345 |
$new_post_status = $post->post_status;
|
346 |
if ( $new_post_status === 'publish' || $new_post_status === 'future' ) {
|
347 |
+
// Check if the user has the right capability.
|
348 |
if ( \is_post_type_hierarchical( $post->post_type ) ) {
|
349 |
if ( ! \current_user_can( 'publish_pages' ) ) {
|
350 |
$new_post_status = 'pending';
|
351 |
}
|
352 |
+
}
|
353 |
+
elseif ( ! \current_user_can( 'publish_posts' ) ) {
|
354 |
+
$new_post_status = 'pending';
|
|
|
355 |
}
|
356 |
}
|
357 |
}
|
362 |
/**
|
363 |
* Generates and returns the author ID for the copy.
|
364 |
*
|
365 |
+
* @param WP_Post $post The original post object.
|
366 |
+
* @param array $options The options array.
|
367 |
*
|
368 |
* @return int|string The calculated author ID for the copy.
|
369 |
*/
|
370 |
+
public function generate_copy_author( WP_Post $post, array $options ) {
|
371 |
$new_post_author = \wp_get_current_user();
|
372 |
$new_post_author_id = $new_post_author->ID;
|
373 |
if ( $options['copy_author'] ) {
|
374 |
+
// Check if the user has the right capability.
|
375 |
if ( \is_post_type_hierarchical( $post->post_type ) ) {
|
376 |
if ( \current_user_can( 'edit_others_pages' ) ) {
|
377 |
$new_post_author_id = $post->post_author;
|
378 |
}
|
379 |
+
}
|
380 |
+
elseif ( \current_user_can( 'edit_others_posts' ) ) {
|
381 |
+
$new_post_author_id = $post->post_author;
|
|
|
382 |
}
|
383 |
}
|
384 |
|
src/{class-post-republisher.php → post-republisher.php}
RENAMED
@@ -1,17 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to republish a rewritten post.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
11 |
use WP_Post;
|
12 |
|
13 |
/**
|
14 |
-
*
|
|
|
|
|
15 |
*/
|
16 |
class Post_Republisher {
|
17 |
|
@@ -126,7 +122,7 @@ class Post_Republisher {
|
|
126 |
/**
|
127 |
* Executes the republish request.
|
128 |
*
|
129 |
-
* @param
|
130 |
*
|
131 |
* @return void
|
132 |
*/
|
@@ -156,7 +152,7 @@ class Post_Republisher {
|
|
156 |
/**
|
157 |
* Republishes the original post with the passed post, when using the Block Editor.
|
158 |
*
|
159 |
-
* @param
|
160 |
*
|
161 |
* @return void
|
162 |
*/
|
@@ -170,8 +166,8 @@ class Post_Republisher {
|
|
170 |
* Runs also in the Block Editor to save the custom meta data only when there
|
171 |
* are custom meta boxes.
|
172 |
*
|
173 |
-
* @param int
|
174 |
-
* @param
|
175 |
*
|
176 |
* @return void
|
177 |
*/
|
@@ -186,7 +182,7 @@ class Post_Republisher {
|
|
186 |
/**
|
187 |
* Republishes the scheduled Rewrited and Republish post.
|
188 |
*
|
189 |
-
* @param
|
190 |
*
|
191 |
* @return void
|
192 |
*/
|
@@ -222,7 +218,8 @@ class Post_Republisher {
|
|
222 |
|
223 |
if ( \intval( \get_post_meta( $copy_id, '_dp_has_been_republished', true ) ) === 1 ) {
|
224 |
$this->delete_copy( $copy_id, $post_id );
|
225 |
-
}
|
|
|
226 |
\wp_die( \esc_html__( 'An error occurred while deleting the Rewrite & Republish copy.', 'duplicate-post' ) );
|
227 |
}
|
228 |
}
|
@@ -238,7 +235,7 @@ class Post_Republisher {
|
|
238 |
return false;
|
239 |
}
|
240 |
|
241 |
-
return isset( $_GET['meta-box-loader'] ) === false;
|
242 |
}
|
243 |
|
244 |
/**
|
@@ -247,7 +244,7 @@ class Post_Republisher {
|
|
247 |
* @return bool Whether or not the request is a REST request.
|
248 |
*/
|
249 |
public function is_rest_request() {
|
250 |
-
return defined( 'REST_REQUEST' ) && REST_REQUEST;
|
251 |
}
|
252 |
|
253 |
/**
|
@@ -279,8 +276,8 @@ class Post_Republisher {
|
|
279 |
/**
|
280 |
* Deletes the copy and associated post meta, if applicable.
|
281 |
*
|
282 |
-
* @param int $copy_id
|
283 |
-
* @param int|null $post_id
|
284 |
* @param bool $permanently_delete Whether to permanently delete the copy. Defaults to true.
|
285 |
*
|
286 |
* @return void
|
@@ -306,8 +303,8 @@ class Post_Republisher {
|
|
306 |
/**
|
307 |
* Republishes the post elements overwriting the original post.
|
308 |
*
|
309 |
-
* @param
|
310 |
-
* @param
|
311 |
*
|
312 |
* @return void
|
313 |
*/
|
@@ -338,7 +335,7 @@ class Post_Republisher {
|
|
338 |
/**
|
339 |
* Republishes the post taxonomies overwriting the ones of the original post.
|
340 |
*
|
341 |
-
* @param
|
342 |
*
|
343 |
* @return void
|
344 |
*/
|
@@ -356,7 +353,7 @@ class Post_Republisher {
|
|
356 |
/**
|
357 |
* Republishes the post meta overwriting the ones of the original post.
|
358 |
*
|
359 |
-
* @param
|
360 |
*
|
361 |
* @return void
|
362 |
*/
|
@@ -397,8 +394,8 @@ class Post_Republisher {
|
|
397 |
/**
|
398 |
* Determines the post status to use when publishing the Rewrite & Republish copy.
|
399 |
*
|
400 |
-
* @param
|
401 |
-
* @param
|
402 |
*
|
403 |
* @return string The post status to use.
|
404 |
*/
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
5 |
use WP_Post;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post class to republish a rewritten post.
|
9 |
+
*
|
10 |
+
* @since 4.0
|
11 |
*/
|
12 |
class Post_Republisher {
|
13 |
|
122 |
/**
|
123 |
* Executes the republish request.
|
124 |
*
|
125 |
+
* @param WP_Post $post The copy's post object.
|
126 |
*
|
127 |
* @return void
|
128 |
*/
|
152 |
/**
|
153 |
* Republishes the original post with the passed post, when using the Block Editor.
|
154 |
*
|
155 |
+
* @param WP_Post $post The copy's post object.
|
156 |
*
|
157 |
* @return void
|
158 |
*/
|
166 |
* Runs also in the Block Editor to save the custom meta data only when there
|
167 |
* are custom meta boxes.
|
168 |
*
|
169 |
+
* @param int $post_id The copy's post ID.
|
170 |
+
* @param WP_Post $post The copy's post object.
|
171 |
*
|
172 |
* @return void
|
173 |
*/
|
182 |
/**
|
183 |
* Republishes the scheduled Rewrited and Republish post.
|
184 |
*
|
185 |
+
* @param WP_Post $copy The scheduled copy.
|
186 |
*
|
187 |
* @return void
|
188 |
*/
|
218 |
|
219 |
if ( \intval( \get_post_meta( $copy_id, '_dp_has_been_republished', true ) ) === 1 ) {
|
220 |
$this->delete_copy( $copy_id, $post_id );
|
221 |
+
}
|
222 |
+
else {
|
223 |
\wp_die( \esc_html__( 'An error occurred while deleting the Rewrite & Republish copy.', 'duplicate-post' ) );
|
224 |
}
|
225 |
}
|
235 |
return false;
|
236 |
}
|
237 |
|
238 |
+
return isset( $_GET['meta-box-loader'] ) === false;
|
239 |
}
|
240 |
|
241 |
/**
|
244 |
* @return bool Whether or not the request is a REST request.
|
245 |
*/
|
246 |
public function is_rest_request() {
|
247 |
+
return \defined( 'REST_REQUEST' ) && \REST_REQUEST;
|
248 |
}
|
249 |
|
250 |
/**
|
276 |
/**
|
277 |
* Deletes the copy and associated post meta, if applicable.
|
278 |
*
|
279 |
+
* @param int $copy_id The copy's ID.
|
280 |
+
* @param int|null $post_id The original post's ID. Optional.
|
281 |
* @param bool $permanently_delete Whether to permanently delete the copy. Defaults to true.
|
282 |
*
|
283 |
* @return void
|
303 |
/**
|
304 |
* Republishes the post elements overwriting the original post.
|
305 |
*
|
306 |
+
* @param WP_Post $post The post object.
|
307 |
+
* @param WP_Post $original_post The original post.
|
308 |
*
|
309 |
* @return void
|
310 |
*/
|
335 |
/**
|
336 |
* Republishes the post taxonomies overwriting the ones of the original post.
|
337 |
*
|
338 |
+
* @param WP_Post $post The copy's post object.
|
339 |
*
|
340 |
* @return void
|
341 |
*/
|
353 |
/**
|
354 |
* Republishes the post meta overwriting the ones of the original post.
|
355 |
*
|
356 |
+
* @param WP_Post $post The copy's post object.
|
357 |
*
|
358 |
* @return void
|
359 |
*/
|
394 |
/**
|
395 |
* Determines the post status to use when publishing the Rewrite & Republish copy.
|
396 |
*
|
397 |
+
* @param WP_Post $post The post object.
|
398 |
+
* @param WP_Post $original_post The original post object.
|
399 |
*
|
400 |
* @return string The post status to use.
|
401 |
*/
|
src/{class-revisions-migrator.php → revisions-migrator.php}
RENAMED
@@ -1,15 +1,11 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to migrate revisions from the Rewrite & Republish copy to the original post.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
11 |
/**
|
12 |
-
*
|
|
|
|
|
13 |
*/
|
14 |
class Revisions_Migrator {
|
15 |
|
@@ -54,14 +50,14 @@ class Revisions_Migrator {
|
|
54 |
}
|
55 |
|
56 |
$revisions = \wp_get_post_revisions( $original_post, [ 'order' => 'ASC' ] );
|
57 |
-
$delete = \count( $revisions ) - $revisions_to_keep;
|
58 |
if ( $delete < 1 ) {
|
59 |
return;
|
60 |
}
|
61 |
|
62 |
$revisions = \array_slice( $revisions, 0, $delete );
|
63 |
|
64 |
-
for ( $i = 0; isset( $revisions[ $i ] ); $i
|
65 |
if ( \strpos( $revisions[ $i ]->post_name, 'autosave' ) !== false ) {
|
66 |
continue;
|
67 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
5 |
/**
|
6 |
+
* Duplicate Post class to migrate revisions from the Rewrite & Republish copy to the original post.
|
7 |
+
*
|
8 |
+
* @since 4.0
|
9 |
*/
|
10 |
class Revisions_Migrator {
|
11 |
|
50 |
}
|
51 |
|
52 |
$revisions = \wp_get_post_revisions( $original_post, [ 'order' => 'ASC' ] );
|
53 |
+
$delete = ( \count( $revisions ) - $revisions_to_keep );
|
54 |
if ( $delete < 1 ) {
|
55 |
return;
|
56 |
}
|
57 |
|
58 |
$revisions = \array_slice( $revisions, 0, $delete );
|
59 |
|
60 |
+
for ( $i = 0; isset( $revisions[ $i ] ); $i++ ) {
|
61 |
if ( \strpos( $revisions[ $i ]->post_name, 'autosave' ) !== false ) {
|
62 |
continue;
|
63 |
}
|
src/ui/{class-admin-bar.php → admin-bar.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the admin bar.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
@@ -12,7 +7,7 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Utils;
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
*/
|
17 |
class Admin_Bar {
|
18 |
|
@@ -111,7 +106,8 @@ class Admin_Bar {
|
|
111 |
'href' => $this->link_builder->build_rewrite_and_republish_link( $post ),
|
112 |
]
|
113 |
);
|
114 |
-
}
|
|
|
115 |
if ( $show_new_draft ) {
|
116 |
$wp_admin_bar->add_menu(
|
117 |
[
|
@@ -167,7 +163,8 @@ class Admin_Bar {
|
|
167 |
|
168 |
if ( \is_admin() ) {
|
169 |
$post = \get_post();
|
170 |
-
}
|
|
|
171 |
$post = $wp_the_query->get_queried_object();
|
172 |
}
|
173 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post class to manage the admin bar.
|
11 |
*/
|
12 |
class Admin_Bar {
|
13 |
|
106 |
'href' => $this->link_builder->build_rewrite_and_republish_link( $post ),
|
107 |
]
|
108 |
);
|
109 |
+
}
|
110 |
+
else {
|
111 |
if ( $show_new_draft ) {
|
112 |
$wp_admin_bar->add_menu(
|
113 |
[
|
163 |
|
164 |
if ( \is_admin() ) {
|
165 |
$post = \get_post();
|
166 |
+
}
|
167 |
+
else {
|
168 |
$post = $wp_the_query->get_queried_object();
|
169 |
}
|
170 |
|
src/ui/{class-asset-manager.php → asset-manager.php}
RENAMED
@@ -1,16 +1,11 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage assets.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
10 |
use Yoast\WP\Duplicate_Post\Utils;
|
11 |
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
class Asset_Manager {
|
16 |
|
@@ -30,8 +25,8 @@ class Asset_Manager {
|
|
30 |
* @return void
|
31 |
*/
|
32 |
public function register_styles() {
|
33 |
-
\wp_register_style( 'duplicate-post', \plugins_url( '/css/duplicate-post.css', DUPLICATE_POST_FILE ), [], DUPLICATE_POST_CURRENT_VERSION );
|
34 |
-
\wp_register_style( 'duplicate-post-options', \plugins_url( '/css/duplicate-post-options.css', DUPLICATE_POST_FILE ), [], DUPLICATE_POST_CURRENT_VERSION );
|
35 |
}
|
36 |
|
37 |
/**
|
@@ -40,45 +35,45 @@ class Asset_Manager {
|
|
40 |
* @return void
|
41 |
*/
|
42 |
public function register_scripts() {
|
43 |
-
$flattened_version = Utils::flatten_version( DUPLICATE_POST_CURRENT_VERSION );
|
44 |
|
45 |
\wp_register_script(
|
46 |
'duplicate_post_edit_script',
|
47 |
-
\plugins_url( \sprintf( 'js/dist/duplicate-post-edit-%s.js', $flattened_version ), DUPLICATE_POST_FILE ),
|
48 |
[
|
49 |
'wp-components',
|
50 |
'wp-element',
|
51 |
'wp-i18n',
|
52 |
],
|
53 |
-
DUPLICATE_POST_CURRENT_VERSION,
|
54 |
true
|
55 |
);
|
56 |
|
57 |
\wp_register_script(
|
58 |
'duplicate_post_strings',
|
59 |
-
\plugins_url( \sprintf( 'js/dist/duplicate-post-strings-%s.js', $flattened_version ), DUPLICATE_POST_FILE ),
|
60 |
[
|
61 |
'wp-components',
|
62 |
'wp-element',
|
63 |
'wp-i18n',
|
64 |
],
|
65 |
-
DUPLICATE_POST_CURRENT_VERSION,
|
66 |
true
|
67 |
);
|
68 |
|
69 |
\wp_register_script(
|
70 |
'duplicate_post_quick_edit_script',
|
71 |
-
\plugins_url( \sprintf( 'js/dist/duplicate-post-quick-edit-%s.js', $flattened_version ), DUPLICATE_POST_FILE ),
|
72 |
[ 'jquery' ],
|
73 |
-
DUPLICATE_POST_CURRENT_VERSION,
|
74 |
true
|
75 |
);
|
76 |
|
77 |
\wp_register_script(
|
78 |
'duplicate_post_options_script',
|
79 |
-
\plugins_url( \sprintf( 'js/dist/duplicate-post-options-%s.js', $flattened_version ), DUPLICATE_POST_FILE ),
|
80 |
[ 'jquery' ],
|
81 |
-
DUPLICATE_POST_CURRENT_VERSION,
|
82 |
true
|
83 |
);
|
84 |
}
|
@@ -104,11 +99,11 @@ class Asset_Manager {
|
|
104 |
/**
|
105 |
* Enqueues the script for the Block editor and passes object via localization.
|
106 |
*
|
107 |
-
* @param array $
|
108 |
*
|
109 |
* @return void
|
110 |
*/
|
111 |
-
public function enqueue_edit_script( $
|
112 |
$handle = 'duplicate_post_edit_script';
|
113 |
\wp_enqueue_script( $handle );
|
114 |
\wp_add_inline_script(
|
@@ -119,24 +114,24 @@ class Asset_Manager {
|
|
119 |
\wp_localize_script(
|
120 |
$handle,
|
121 |
'duplicatePost',
|
122 |
-
$
|
123 |
);
|
124 |
}
|
125 |
|
126 |
/**
|
127 |
* Enqueues the script for the Javascript strings and passes object via localization.
|
128 |
*
|
129 |
-
* @param array $
|
130 |
*
|
131 |
* @return void
|
132 |
*/
|
133 |
-
public function enqueue_strings_script( $
|
134 |
$handle = 'duplicate_post_strings';
|
135 |
\wp_enqueue_script( $handle );
|
136 |
\wp_localize_script(
|
137 |
$handle,
|
138 |
'duplicatePostStrings',
|
139 |
-
$
|
140 |
);
|
141 |
}
|
142 |
|
@@ -161,26 +156,26 @@ class Asset_Manager {
|
|
161 |
/**
|
162 |
* Enqueues the script for the Elementor plugin.
|
163 |
*
|
164 |
-
* @param array $
|
165 |
*
|
166 |
* @return void
|
167 |
*/
|
168 |
-
public function enqueue_elementor_script( $
|
169 |
-
$flattened_version = Utils::flatten_version( DUPLICATE_POST_CURRENT_VERSION );
|
170 |
$handle = 'duplicate_post_elementor_script';
|
171 |
|
172 |
\wp_register_script(
|
173 |
$handle,
|
174 |
-
\plugins_url( \sprintf( 'js/dist/duplicate-post-elementor-%s.js', $flattened_version ), DUPLICATE_POST_FILE ),
|
175 |
[ 'jquery' ],
|
176 |
-
DUPLICATE_POST_CURRENT_VERSION,
|
177 |
true
|
178 |
);
|
179 |
\wp_enqueue_script( $handle );
|
180 |
\wp_localize_script(
|
181 |
$handle,
|
182 |
'duplicatePost',
|
183 |
-
$
|
184 |
);
|
185 |
}
|
186 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
5 |
use Yoast\WP\Duplicate_Post\Utils;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post class to manage assets.
|
9 |
*/
|
10 |
class Asset_Manager {
|
11 |
|
25 |
* @return void
|
26 |
*/
|
27 |
public function register_styles() {
|
28 |
+
\wp_register_style( 'duplicate-post', \plugins_url( '/css/duplicate-post.css', \DUPLICATE_POST_FILE ), [], \DUPLICATE_POST_CURRENT_VERSION );
|
29 |
+
\wp_register_style( 'duplicate-post-options', \plugins_url( '/css/duplicate-post-options.css', \DUPLICATE_POST_FILE ), [], \DUPLICATE_POST_CURRENT_VERSION );
|
30 |
}
|
31 |
|
32 |
/**
|
35 |
* @return void
|
36 |
*/
|
37 |
public function register_scripts() {
|
38 |
+
$flattened_version = Utils::flatten_version( \DUPLICATE_POST_CURRENT_VERSION );
|
39 |
|
40 |
\wp_register_script(
|
41 |
'duplicate_post_edit_script',
|
42 |
+
\plugins_url( \sprintf( 'js/dist/duplicate-post-edit-%s.js', $flattened_version ), \DUPLICATE_POST_FILE ),
|
43 |
[
|
44 |
'wp-components',
|
45 |
'wp-element',
|
46 |
'wp-i18n',
|
47 |
],
|
48 |
+
\DUPLICATE_POST_CURRENT_VERSION,
|
49 |
true
|
50 |
);
|
51 |
|
52 |
\wp_register_script(
|
53 |
'duplicate_post_strings',
|
54 |
+
\plugins_url( \sprintf( 'js/dist/duplicate-post-strings-%s.js', $flattened_version ), \DUPLICATE_POST_FILE ),
|
55 |
[
|
56 |
'wp-components',
|
57 |
'wp-element',
|
58 |
'wp-i18n',
|
59 |
],
|
60 |
+
\DUPLICATE_POST_CURRENT_VERSION,
|
61 |
true
|
62 |
);
|
63 |
|
64 |
\wp_register_script(
|
65 |
'duplicate_post_quick_edit_script',
|
66 |
+
\plugins_url( \sprintf( 'js/dist/duplicate-post-quick-edit-%s.js', $flattened_version ), \DUPLICATE_POST_FILE ),
|
67 |
[ 'jquery' ],
|
68 |
+
\DUPLICATE_POST_CURRENT_VERSION,
|
69 |
true
|
70 |
);
|
71 |
|
72 |
\wp_register_script(
|
73 |
'duplicate_post_options_script',
|
74 |
+
\plugins_url( \sprintf( 'js/dist/duplicate-post-options-%s.js', $flattened_version ), \DUPLICATE_POST_FILE ),
|
75 |
[ 'jquery' ],
|
76 |
+
\DUPLICATE_POST_CURRENT_VERSION,
|
77 |
true
|
78 |
);
|
79 |
}
|
99 |
/**
|
100 |
* Enqueues the script for the Block editor and passes object via localization.
|
101 |
*
|
102 |
+
* @param array $data_object The object to pass to the script.
|
103 |
*
|
104 |
* @return void
|
105 |
*/
|
106 |
+
public function enqueue_edit_script( $data_object = [] ) {
|
107 |
$handle = 'duplicate_post_edit_script';
|
108 |
\wp_enqueue_script( $handle );
|
109 |
\wp_add_inline_script(
|
114 |
\wp_localize_script(
|
115 |
$handle,
|
116 |
'duplicatePost',
|
117 |
+
$data_object
|
118 |
);
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
* Enqueues the script for the Javascript strings and passes object via localization.
|
123 |
*
|
124 |
+
* @param array $data_object The object to pass to the script.
|
125 |
*
|
126 |
* @return void
|
127 |
*/
|
128 |
+
public function enqueue_strings_script( $data_object = [] ) {
|
129 |
$handle = 'duplicate_post_strings';
|
130 |
\wp_enqueue_script( $handle );
|
131 |
\wp_localize_script(
|
132 |
$handle,
|
133 |
'duplicatePostStrings',
|
134 |
+
$data_object
|
135 |
);
|
136 |
}
|
137 |
|
156 |
/**
|
157 |
* Enqueues the script for the Elementor plugin.
|
158 |
*
|
159 |
+
* @param array $data_object The object to pass to the script.
|
160 |
*
|
161 |
* @return void
|
162 |
*/
|
163 |
+
public function enqueue_elementor_script( $data_object = [] ) {
|
164 |
+
$flattened_version = Utils::flatten_version( \DUPLICATE_POST_CURRENT_VERSION );
|
165 |
$handle = 'duplicate_post_elementor_script';
|
166 |
|
167 |
\wp_register_script(
|
168 |
$handle,
|
169 |
+
\plugins_url( \sprintf( 'js/dist/duplicate-post-elementor-%s.js', $flattened_version ), \DUPLICATE_POST_FILE ),
|
170 |
[ 'jquery' ],
|
171 |
+
\DUPLICATE_POST_CURRENT_VERSION,
|
172 |
true
|
173 |
);
|
174 |
\wp_enqueue_script( $handle );
|
175 |
\wp_localize_script(
|
176 |
$handle,
|
177 |
'duplicatePost',
|
178 |
+
$data_object
|
179 |
);
|
180 |
}
|
181 |
}
|
src/ui/{class-block-editor.php → block-editor.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the block editor UI.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
@@ -12,7 +7,7 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Utils;
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
*/
|
17 |
class Block_Editor {
|
18 |
|
@@ -234,7 +229,7 @@ class Block_Editor {
|
|
234 |
'rewriteAndRepublishLink' => $this->get_rewrite_republish_permalink(),
|
235 |
'showLinks' => Utils::get_option( 'duplicate_post_show_link' ),
|
236 |
'showLinksIn' => Utils::get_option( 'duplicate_post_show_link_in' ),
|
237 |
-
'rewriting' => $is_rewrite_and_republish_copy ? 1 : 0,
|
238 |
'originalEditURL' => $this->get_original_post_edit_url(),
|
239 |
];
|
240 |
}
|
@@ -267,7 +262,7 @@ class Block_Editor {
|
|
267 |
|
268 |
return \array_filter(
|
269 |
$suggestions,
|
270 |
-
function( $suggestion ) use ( $original_post_id ) {
|
271 |
return $suggestion->object_id !== $original_post_id;
|
272 |
}
|
273 |
);
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post class to manage the block editor UI.
|
11 |
*/
|
12 |
class Block_Editor {
|
13 |
|
229 |
'rewriteAndRepublishLink' => $this->get_rewrite_republish_permalink(),
|
230 |
'showLinks' => Utils::get_option( 'duplicate_post_show_link' ),
|
231 |
'showLinksIn' => Utils::get_option( 'duplicate_post_show_link_in' ),
|
232 |
+
'rewriting' => ( $is_rewrite_and_republish_copy ) ? 1 : 0,
|
233 |
'originalEditURL' => $this->get_original_post_edit_url(),
|
234 |
];
|
235 |
}
|
262 |
|
263 |
return \array_filter(
|
264 |
$suggestions,
|
265 |
+
static function ( $suggestion ) use ( $original_post_id ) {
|
266 |
return $suggestion->object_id !== $original_post_id;
|
267 |
}
|
268 |
);
|
src/ui/{class-bulk-actions.php → bulk-actions.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the bulk actions menu.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
@@ -11,7 +6,7 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
11 |
use Yoast\WP\Duplicate_Post\Utils;
|
12 |
|
13 |
/**
|
14 |
-
*
|
15 |
*/
|
16 |
class Bulk_Actions {
|
17 |
|
@@ -68,8 +63,7 @@ class Bulk_Actions {
|
|
68 |
* @return array The bulk actions array.
|
69 |
*/
|
70 |
public function register_bulk_action( $bulk_actions ) {
|
71 |
-
|
72 |
-
$is_draft_or_trash = isset( $_REQUEST['post_status'] ) && in_array( $_REQUEST['post_status'], array( 'draft', 'trash' ), true );
|
73 |
|
74 |
if ( \intval( Utils::get_option( 'duplicate_post_show_link', 'clone' ) ) === 1 ) {
|
75 |
$bulk_actions['duplicate_post_bulk_clone'] = \esc_html__( 'Clone', 'duplicate-post' );
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
6 |
use Yoast\WP\Duplicate_Post\Utils;
|
7 |
|
8 |
/**
|
9 |
+
* Duplicate Post class to manage the bulk actions menu.
|
10 |
*/
|
11 |
class Bulk_Actions {
|
12 |
|
63 |
* @return array The bulk actions array.
|
64 |
*/
|
65 |
public function register_bulk_action( $bulk_actions ) {
|
66 |
+
$is_draft_or_trash = isset( $_REQUEST['post_status'] ) && \in_array( $_REQUEST['post_status'], [ 'draft', 'trash' ], true );
|
|
|
67 |
|
68 |
if ( \intval( Utils::get_option( 'duplicate_post_show_link', 'clone' ) ) === 1 ) {
|
69 |
$bulk_actions['duplicate_post_bulk_clone'] = \esc_html__( 'Clone', 'duplicate-post' );
|
src/ui/class-metabox.php
DELETED
@@ -1,121 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the metabox.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
-
|
8 |
-
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
-
|
10 |
-
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
11 |
-
use Yoast\WP\Duplicate_Post\Utils;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Represents the Metabox class.
|
15 |
-
*/
|
16 |
-
class Metabox {
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Holds the permissions helper.
|
20 |
-
*
|
21 |
-
* @var Permissions_Helper
|
22 |
-
*/
|
23 |
-
protected $permissions_helper;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Initializes the class.
|
27 |
-
*
|
28 |
-
* @param Permissions_Helper $permissions_helper The permissions helper.
|
29 |
-
*/
|
30 |
-
public function __construct( Permissions_Helper $permissions_helper ) {
|
31 |
-
$this->permissions_helper = $permissions_helper;
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Adds hooks to integrate with WordPress.
|
36 |
-
*
|
37 |
-
* @return void
|
38 |
-
*/
|
39 |
-
public function register_hooks() {
|
40 |
-
if ( \intval( \get_option( 'duplicate_post_show_original_meta_box' ) ) === 1 ) {
|
41 |
-
\add_action( 'add_meta_boxes', [ $this, 'add_custom_metabox' ] );
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Adds a metabox to Edit screen.
|
47 |
-
*
|
48 |
-
* @return void
|
49 |
-
*/
|
50 |
-
public function add_custom_metabox() {
|
51 |
-
$screens = $this->permissions_helper->get_enabled_post_types();
|
52 |
-
if ( ! \is_array( $screens ) ) {
|
53 |
-
$screens = [ $screens ];
|
54 |
-
}
|
55 |
-
foreach ( $screens as $screen ) {
|
56 |
-
\add_meta_box(
|
57 |
-
'duplicate_post_show_original',
|
58 |
-
\__( 'Duplicate Post', 'duplicate-post' ),
|
59 |
-
[ $this, 'custom_metabox_html' ],
|
60 |
-
$screen,
|
61 |
-
'side'
|
62 |
-
);
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Outputs the HTML for the metabox.
|
68 |
-
*
|
69 |
-
* @param \WP_Post $post The current post.
|
70 |
-
*
|
71 |
-
* @return void
|
72 |
-
*/
|
73 |
-
public function custom_metabox_html( $post ) {
|
74 |
-
$original_item = Utils::get_original( $post );
|
75 |
-
if ( $post instanceof \WP_Post && $original_item instanceof \WP_Post ) {
|
76 |
-
if ( ! $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
77 |
-
?>
|
78 |
-
<p>
|
79 |
-
<input type="checkbox"
|
80 |
-
name="duplicate_post_remove_original"
|
81 |
-
id="duplicate-post-remove-original"
|
82 |
-
value="duplicate_post_remove_original"
|
83 |
-
aria-describedby="duplicate-post-remove-original-description">
|
84 |
-
<label for="duplicate-post-remove-original">
|
85 |
-
<?php \esc_html_e( 'Delete reference to original item.', 'duplicate-post' ); ?>
|
86 |
-
</label>
|
87 |
-
</p>
|
88 |
-
<?php
|
89 |
-
}
|
90 |
-
?>
|
91 |
-
<p id="duplicate-post-remove-original-description">
|
92 |
-
<?php
|
93 |
-
\printf(
|
94 |
-
\wp_kses(
|
95 |
-
/* translators: %s: post title */
|
96 |
-
\__(
|
97 |
-
'The original item this was copied from is: <span class="duplicate_post_original_item_title_span">%s</span>',
|
98 |
-
'duplicate-post'
|
99 |
-
),
|
100 |
-
[
|
101 |
-
'span' => [
|
102 |
-
'class' => [],
|
103 |
-
],
|
104 |
-
]
|
105 |
-
),
|
106 |
-
Utils::get_edit_or_view_link( $original_item ) // phpcs:ignore WordPress.Security.EscapeOutput
|
107 |
-
);
|
108 |
-
?>
|
109 |
-
</p>
|
110 |
-
<?php
|
111 |
-
} else {
|
112 |
-
?>
|
113 |
-
<script>
|
114 |
-
(function(jQuery){
|
115 |
-
jQuery('#duplicate_post_show_original').hide();
|
116 |
-
})(jQuery);
|
117 |
-
</script>
|
118 |
-
<?php
|
119 |
-
}
|
120 |
-
}
|
121 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/ui/{class-classic-editor.php → classic-editor.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the classic editor UI.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
@@ -12,7 +7,7 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Utils;
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
*/
|
17 |
class Classic_Editor {
|
18 |
|
@@ -86,8 +81,8 @@ class Classic_Editor {
|
|
86 |
* @return void
|
87 |
*/
|
88 |
public function enqueue_classic_editor_scripts() {
|
89 |
-
if ( $this->permissions_helper->is_classic_editor() && isset( $_GET['post'] ) ) {
|
90 |
-
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
91 |
$post = \get_post( $id );
|
92 |
|
93 |
if ( ! \is_null( $post ) && $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
@@ -103,8 +98,8 @@ class Classic_Editor {
|
|
103 |
*/
|
104 |
public function enqueue_classic_editor_styles() {
|
105 |
if ( $this->permissions_helper->is_classic_editor()
|
106 |
-
&& isset( $_GET['post'] ) ) {
|
107 |
-
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
108 |
$post = \get_post( $id );
|
109 |
|
110 |
if ( ! \is_null( $post ) && $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
@@ -116,14 +111,14 @@ class Classic_Editor {
|
|
116 |
/**
|
117 |
* Adds a button in the post/page edit screen to create a clone
|
118 |
*
|
119 |
-
* @param
|
120 |
*
|
121 |
* @return void
|
122 |
*/
|
123 |
public function add_new_draft_post_button( $post = null ) {
|
124 |
if ( \is_null( $post ) ) {
|
125 |
-
if ( isset( $_GET['post'] ) ) {
|
126 |
-
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
127 |
$post = \get_post( $id );
|
128 |
}
|
129 |
}
|
@@ -142,14 +137,14 @@ class Classic_Editor {
|
|
142 |
/**
|
143 |
* Adds a button in the post/page edit screen to create a clone for Rewrite & Republish.
|
144 |
*
|
145 |
-
* @param
|
146 |
*
|
147 |
* @return void
|
148 |
*/
|
149 |
public function add_rewrite_and_republish_post_button( $post = null ) {
|
150 |
if ( \is_null( $post ) ) {
|
151 |
-
if ( isset( $_GET['post'] ) ) {
|
152 |
-
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
153 |
$post = \get_post( $id );
|
154 |
}
|
155 |
}
|
@@ -171,14 +166,14 @@ class Classic_Editor {
|
|
171 |
/**
|
172 |
* Adds a message in the post/page edit screen to create a clone for Rewrite & Republish.
|
173 |
*
|
174 |
-
* @param
|
175 |
*
|
176 |
* @return void
|
177 |
*/
|
178 |
public function add_check_changes_link( $post = null ) {
|
179 |
if ( \is_null( $post ) ) {
|
180 |
-
if ( isset( $_GET['post'] ) ) {
|
181 |
-
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
182 |
$post = \get_post( $id );
|
183 |
}
|
184 |
}
|
@@ -254,7 +249,7 @@ class Classic_Editor {
|
|
254 |
|
255 |
if ( $post->post_type === 'post' ) {
|
256 |
$messages['post'][9] = \sprintf(
|
257 |
-
|
258 |
\esc_html__(
|
259 |
'This rewritten post %1$s is now scheduled to replace the original post. It will be published on %2$s.',
|
260 |
'duplicate-post'
|
@@ -267,7 +262,7 @@ class Classic_Editor {
|
|
267 |
|
268 |
if ( $post->post_type === 'page' ) {
|
269 |
$messages['page'][9] = \sprintf(
|
270 |
-
|
271 |
\esc_html__(
|
272 |
'This rewritten page %1$s is now scheduled to replace the original page. It will be published on %2$s.',
|
273 |
'duplicate-post'
|
@@ -283,7 +278,7 @@ class Classic_Editor {
|
|
283 |
/**
|
284 |
* Determines if the Rewrite & Republish copies for the post should be used.
|
285 |
*
|
286 |
-
* @param
|
287 |
*
|
288 |
* @return bool True if the Rewrite & Republish copies should be used.
|
289 |
*/
|
@@ -303,8 +298,8 @@ class Classic_Editor {
|
|
303 |
/**
|
304 |
* Removes the slug meta box in the Classic Editor when the post is a Rewrite & Republish copy.
|
305 |
*
|
306 |
-
* @param string
|
307 |
-
* @param
|
308 |
*
|
309 |
* @return void
|
310 |
*/
|
@@ -317,23 +312,23 @@ class Classic_Editor {
|
|
317 |
/**
|
318 |
* Removes the sample permalink slug editor in the Classic Editor when the post is a Rewrite & Republish copy.
|
319 |
*
|
320 |
-
* @param string
|
321 |
-
* @param int
|
322 |
-
* @param string
|
323 |
-
* @param string
|
324 |
-
* @param
|
325 |
*
|
326 |
* @return string The filtered HTML of the sample permalink slug editor.
|
327 |
*/
|
328 |
-
public function remove_sample_permalink_slug_editor( $
|
329 |
if ( ! $post instanceof WP_Post ) {
|
330 |
-
return $
|
331 |
}
|
332 |
|
333 |
if ( $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
334 |
return '';
|
335 |
}
|
336 |
|
337 |
-
return $
|
338 |
}
|
339 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post class to manage the classic editor UI.
|
11 |
*/
|
12 |
class Classic_Editor {
|
13 |
|
81 |
* @return void
|
82 |
*/
|
83 |
public function enqueue_classic_editor_scripts() {
|
84 |
+
if ( $this->permissions_helper->is_classic_editor() && isset( $_GET['post'] ) ) {
|
85 |
+
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
86 |
$post = \get_post( $id );
|
87 |
|
88 |
if ( ! \is_null( $post ) && $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
98 |
*/
|
99 |
public function enqueue_classic_editor_styles() {
|
100 |
if ( $this->permissions_helper->is_classic_editor()
|
101 |
+
&& isset( $_GET['post'] ) ) {
|
102 |
+
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
103 |
$post = \get_post( $id );
|
104 |
|
105 |
if ( ! \is_null( $post ) && $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
111 |
/**
|
112 |
* Adds a button in the post/page edit screen to create a clone
|
113 |
*
|
114 |
+
* @param WP_Post|null $post The post object that's being edited.
|
115 |
*
|
116 |
* @return void
|
117 |
*/
|
118 |
public function add_new_draft_post_button( $post = null ) {
|
119 |
if ( \is_null( $post ) ) {
|
120 |
+
if ( isset( $_GET['post'] ) ) {
|
121 |
+
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
122 |
$post = \get_post( $id );
|
123 |
}
|
124 |
}
|
137 |
/**
|
138 |
* Adds a button in the post/page edit screen to create a clone for Rewrite & Republish.
|
139 |
*
|
140 |
+
* @param WP_Post|null $post The post object that's being edited.
|
141 |
*
|
142 |
* @return void
|
143 |
*/
|
144 |
public function add_rewrite_and_republish_post_button( $post = null ) {
|
145 |
if ( \is_null( $post ) ) {
|
146 |
+
if ( isset( $_GET['post'] ) ) {
|
147 |
+
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
148 |
$post = \get_post( $id );
|
149 |
}
|
150 |
}
|
166 |
/**
|
167 |
* Adds a message in the post/page edit screen to create a clone for Rewrite & Republish.
|
168 |
*
|
169 |
+
* @param WP_Post|null $post The post object that's being edited.
|
170 |
*
|
171 |
* @return void
|
172 |
*/
|
173 |
public function add_check_changes_link( $post = null ) {
|
174 |
if ( \is_null( $post ) ) {
|
175 |
+
if ( isset( $_GET['post'] ) ) {
|
176 |
+
$id = \intval( \wp_unslash( $_GET['post'] ) );
|
177 |
$post = \get_post( $id );
|
178 |
}
|
179 |
}
|
249 |
|
250 |
if ( $post->post_type === 'post' ) {
|
251 |
$messages['post'][9] = \sprintf(
|
252 |
+
/* translators: 1: The post title with a link to the frontend page, 2: The scheduled date and time. */
|
253 |
\esc_html__(
|
254 |
'This rewritten post %1$s is now scheduled to replace the original post. It will be published on %2$s.',
|
255 |
'duplicate-post'
|
262 |
|
263 |
if ( $post->post_type === 'page' ) {
|
264 |
$messages['page'][9] = \sprintf(
|
265 |
+
/* translators: 1: The page title with a link to the frontend page, 2: The scheduled date and time. */
|
266 |
\esc_html__(
|
267 |
'This rewritten page %1$s is now scheduled to replace the original page. It will be published on %2$s.',
|
268 |
'duplicate-post'
|
278 |
/**
|
279 |
* Determines if the Rewrite & Republish copies for the post should be used.
|
280 |
*
|
281 |
+
* @param WP_Post $post The current post object.
|
282 |
*
|
283 |
* @return bool True if the Rewrite & Republish copies should be used.
|
284 |
*/
|
298 |
/**
|
299 |
* Removes the slug meta box in the Classic Editor when the post is a Rewrite & Republish copy.
|
300 |
*
|
301 |
+
* @param string $post_type Post type.
|
302 |
+
* @param WP_Post $post Post object.
|
303 |
*
|
304 |
* @return void
|
305 |
*/
|
312 |
/**
|
313 |
* Removes the sample permalink slug editor in the Classic Editor when the post is a Rewrite & Republish copy.
|
314 |
*
|
315 |
+
* @param string $html Sample permalink HTML markup.
|
316 |
+
* @param int $post_id Post ID.
|
317 |
+
* @param string $new_title New sample permalink title.
|
318 |
+
* @param string $new_slug New sample permalink slug.
|
319 |
+
* @param WP_Post $post Post object.
|
320 |
*
|
321 |
* @return string The filtered HTML of the sample permalink slug editor.
|
322 |
*/
|
323 |
+
public function remove_sample_permalink_slug_editor( $html, $post_id, $new_title, $new_slug, $post ) {
|
324 |
if ( ! $post instanceof WP_Post ) {
|
325 |
+
return $html;
|
326 |
}
|
327 |
|
328 |
if ( $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
329 |
return '';
|
330 |
}
|
331 |
|
332 |
+
return $html;
|
333 |
}
|
334 |
}
|
src/ui/{class-column.php → column.php}
RENAMED
@@ -1,17 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the custom column + quick edit.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
|
|
10 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
11 |
use Yoast\WP\Duplicate_Post\Utils;
|
12 |
|
13 |
/**
|
14 |
-
*
|
15 |
*/
|
16 |
class Column {
|
17 |
|
@@ -83,15 +79,19 @@ class Column {
|
|
83 |
* @return void
|
84 |
*/
|
85 |
public function show_original_item( $column_name, $post_id ) {
|
86 |
-
if ( 'duplicate_post_original_item'
|
87 |
$column_content = '-';
|
88 |
$data_attr = ' data-no-original="1"';
|
89 |
$original_item = Utils::get_original( $post_id );
|
90 |
if ( $original_item ) {
|
91 |
-
$post
|
92 |
-
$
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
-
$data_attr = $is_rewrite_and_republish_copy ? ' data-copy-is-for-rewrite-and-republish="1"' : '';
|
95 |
$column_content = Utils::get_edit_or_view_link( $original_item );
|
96 |
}
|
97 |
echo \sprintf(
|
@@ -110,7 +110,7 @@ class Column {
|
|
110 |
* @return void
|
111 |
*/
|
112 |
public function quick_edit_remove_original( $column_name ) {
|
113 |
-
if ( 'duplicate_post_original_item'
|
114 |
return;
|
115 |
}
|
116 |
\printf(
|
@@ -153,7 +153,7 @@ class Column {
|
|
153 |
* @return void
|
154 |
*/
|
155 |
public function admin_enqueue_scripts( $hook ) {
|
156 |
-
if ( 'edit.php'
|
157 |
$this->asset_manager->enqueue_quick_edit_script();
|
158 |
}
|
159 |
}
|
@@ -166,7 +166,7 @@ class Column {
|
|
166 |
* @return void
|
167 |
*/
|
168 |
public function admin_enqueue_styles( $hook ) {
|
169 |
-
if ( 'edit.php'
|
170 |
$this->asset_manager->enqueue_styles();
|
171 |
}
|
172 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post class to manage the custom column + quick edit.
|
11 |
*/
|
12 |
class Column {
|
13 |
|
79 |
* @return void
|
80 |
*/
|
81 |
public function show_original_item( $column_name, $post_id ) {
|
82 |
+
if ( $column_name === 'duplicate_post_original_item' ) {
|
83 |
$column_content = '-';
|
84 |
$data_attr = ' data-no-original="1"';
|
85 |
$original_item = Utils::get_original( $post_id );
|
86 |
if ( $original_item ) {
|
87 |
+
$post = \get_post( $post_id );
|
88 |
+
$data_attr = '';
|
89 |
+
|
90 |
+
if ( $post instanceof WP_Post
|
91 |
+
&& $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
92 |
+
$data_attr = ' data-copy-is-for-rewrite-and-republish="1"';
|
93 |
+
}
|
94 |
|
|
|
95 |
$column_content = Utils::get_edit_or_view_link( $original_item );
|
96 |
}
|
97 |
echo \sprintf(
|
110 |
* @return void
|
111 |
*/
|
112 |
public function quick_edit_remove_original( $column_name ) {
|
113 |
+
if ( $column_name !== 'duplicate_post_original_item' ) {
|
114 |
return;
|
115 |
}
|
116 |
\printf(
|
153 |
* @return void
|
154 |
*/
|
155 |
public function admin_enqueue_scripts( $hook ) {
|
156 |
+
if ( $hook === 'edit.php' ) {
|
157 |
$this->asset_manager->enqueue_quick_edit_script();
|
158 |
}
|
159 |
}
|
166 |
* @return void
|
167 |
*/
|
168 |
public function admin_enqueue_styles( $hook ) {
|
169 |
+
if ( $hook === 'edit.php' ) {
|
170 |
$this->asset_manager->enqueue_styles();
|
171 |
}
|
172 |
}
|
src/ui/{class-link-builder.php → link-builder.php}
RENAMED
@@ -1,24 +1,19 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post link builder.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
|
|
|
|
10 |
/**
|
11 |
-
*
|
12 |
-
*
|
13 |
-
* @package Yoast\WP\Duplicate_Post
|
14 |
*/
|
15 |
class Link_Builder {
|
16 |
|
17 |
/**
|
18 |
* Builds URL for duplication action for the Rewrite & Republish feature.
|
19 |
*
|
20 |
-
* @param int
|
21 |
-
* @param string
|
22 |
*
|
23 |
* @return string The URL for the link.
|
24 |
*/
|
@@ -29,8 +24,8 @@ class Link_Builder {
|
|
29 |
/**
|
30 |
* Builds URL for the "Clone" action.
|
31 |
*
|
32 |
-
* @param int
|
33 |
-
* @param string
|
34 |
*
|
35 |
* @return string The URL for the link.
|
36 |
*/
|
@@ -41,8 +36,8 @@ class Link_Builder {
|
|
41 |
/**
|
42 |
* Builds URL for the "Copy to a new draft" action.
|
43 |
*
|
44 |
-
* @param int
|
45 |
-
* @param string
|
46 |
*
|
47 |
* @return string The URL for the link.
|
48 |
*/
|
@@ -53,8 +48,8 @@ class Link_Builder {
|
|
53 |
/**
|
54 |
* Builds URL for the "Check Changes" action.
|
55 |
*
|
56 |
-
* @param int
|
57 |
-
* @param string
|
58 |
*
|
59 |
* @return string The URL for the link.
|
60 |
*/
|
@@ -65,35 +60,36 @@ class Link_Builder {
|
|
65 |
/**
|
66 |
* Builds URL for duplication action.
|
67 |
*
|
68 |
-
* @param int
|
69 |
-
* @param string
|
70 |
-
* @param string
|
71 |
*
|
72 |
* @return string The URL for the link.
|
73 |
*/
|
74 |
public function build_link( $post, $context, $action_name ) {
|
75 |
$post = \get_post( $post );
|
76 |
-
if ( ! $post instanceof
|
77 |
return '';
|
78 |
}
|
79 |
|
80 |
-
if ( 'display'
|
81 |
$action = '?action=' . $action_name . '&post=' . $post->ID;
|
82 |
-
}
|
|
|
83 |
$action = '?action=' . $action_name . '&post=' . $post->ID;
|
84 |
}
|
85 |
|
86 |
return \wp_nonce_url(
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
\apply_filters( 'duplicate_post_get_clone_post_link', \admin_url( 'admin.php' . $action ), $post->ID, $context, $action_name ),
|
98 |
$action_name . '_' . $post->ID
|
99 |
);
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
+
|
7 |
/**
|
8 |
+
* Duplicate Post link builder.
|
|
|
|
|
9 |
*/
|
10 |
class Link_Builder {
|
11 |
|
12 |
/**
|
13 |
* Builds URL for duplication action for the Rewrite & Republish feature.
|
14 |
*
|
15 |
+
* @param int|WP_Post $post The post object or ID.
|
16 |
+
* @param string $context The context in which the URL will be used.
|
17 |
*
|
18 |
* @return string The URL for the link.
|
19 |
*/
|
24 |
/**
|
25 |
* Builds URL for the "Clone" action.
|
26 |
*
|
27 |
+
* @param int|WP_Post $post The post object or ID.
|
28 |
+
* @param string $context The context in which the URL will be used.
|
29 |
*
|
30 |
* @return string The URL for the link.
|
31 |
*/
|
36 |
/**
|
37 |
* Builds URL for the "Copy to a new draft" action.
|
38 |
*
|
39 |
+
* @param int|WP_Post $post The post object or ID.
|
40 |
+
* @param string $context The context in which the URL will be used.
|
41 |
*
|
42 |
* @return string The URL for the link.
|
43 |
*/
|
48 |
/**
|
49 |
* Builds URL for the "Check Changes" action.
|
50 |
*
|
51 |
+
* @param int|WP_Post $post The post object or ID.
|
52 |
+
* @param string $context The context in which the URL will be used.
|
53 |
*
|
54 |
* @return string The URL for the link.
|
55 |
*/
|
60 |
/**
|
61 |
* Builds URL for duplication action.
|
62 |
*
|
63 |
+
* @param int|WP_Post $post The post object or ID.
|
64 |
+
* @param string $context The context in which the URL will be used.
|
65 |
+
* @param string $action_name The action for the URL.
|
66 |
*
|
67 |
* @return string The URL for the link.
|
68 |
*/
|
69 |
public function build_link( $post, $context, $action_name ) {
|
70 |
$post = \get_post( $post );
|
71 |
+
if ( ! $post instanceof WP_Post ) {
|
72 |
return '';
|
73 |
}
|
74 |
|
75 |
+
if ( $context === 'display' ) {
|
76 |
$action = '?action=' . $action_name . '&post=' . $post->ID;
|
77 |
+
}
|
78 |
+
else {
|
79 |
$action = '?action=' . $action_name . '&post=' . $post->ID;
|
80 |
}
|
81 |
|
82 |
return \wp_nonce_url(
|
83 |
+
/**
|
84 |
+
* Filter on the URL of the clone link
|
85 |
+
*
|
86 |
+
* @param string $url The URL of the clone link.
|
87 |
+
* @param int $ID The ID of the post
|
88 |
+
* @param string $context The context in which the URL is used.
|
89 |
+
* @param string $action_name The action name.
|
90 |
+
*
|
91 |
+
* @return string
|
92 |
+
*/
|
93 |
\apply_filters( 'duplicate_post_get_clone_post_link', \admin_url( 'admin.php' . $action ), $post->ID, $context, $action_name ),
|
94 |
$action_name . '_' . $post->ID
|
95 |
);
|
src/ui/metabox.php
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
+
|
5 |
+
use WP_Post;
|
6 |
+
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
7 |
+
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Duplicate Post class to manage the metabox.
|
11 |
+
*/
|
12 |
+
class Metabox {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Holds the permissions helper.
|
16 |
+
*
|
17 |
+
* @var Permissions_Helper
|
18 |
+
*/
|
19 |
+
protected $permissions_helper;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Initializes the class.
|
23 |
+
*
|
24 |
+
* @param Permissions_Helper $permissions_helper The permissions helper.
|
25 |
+
*/
|
26 |
+
public function __construct( Permissions_Helper $permissions_helper ) {
|
27 |
+
$this->permissions_helper = $permissions_helper;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Adds hooks to integrate with WordPress.
|
32 |
+
*
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
public function register_hooks() {
|
36 |
+
if ( \intval( \get_option( 'duplicate_post_show_original_meta_box' ) ) === 1 ) {
|
37 |
+
\add_action( 'add_meta_boxes', [ $this, 'add_custom_metabox' ], 10, 2 );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Adds a metabox to Edit screen.
|
43 |
+
*
|
44 |
+
* @param string $post_type The post type.
|
45 |
+
* @param WP_Post $post The current post object.
|
46 |
+
*
|
47 |
+
* @return void
|
48 |
+
*/
|
49 |
+
public function add_custom_metabox( $post_type, $post ) {
|
50 |
+
$enabled_post_types = $this->permissions_helper->get_enabled_post_types();
|
51 |
+
|
52 |
+
if ( \in_array( $post_type, $enabled_post_types, true )
|
53 |
+
&& $post instanceof WP_Post ) {
|
54 |
+
$original_item = Utils::get_original( $post );
|
55 |
+
|
56 |
+
if ( $original_item instanceof WP_Post ) {
|
57 |
+
\add_meta_box(
|
58 |
+
'duplicate_post_show_original',
|
59 |
+
\__( 'Duplicate Post', 'duplicate-post' ),
|
60 |
+
[ $this, 'custom_metabox_html' ],
|
61 |
+
$post_type,
|
62 |
+
'side',
|
63 |
+
'default',
|
64 |
+
[ 'original' => $original_item ]
|
65 |
+
);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Outputs the HTML for the metabox.
|
72 |
+
*
|
73 |
+
* @param WP_Post $post The current post.
|
74 |
+
* @param array $metabox The array containing the metabox data.
|
75 |
+
*
|
76 |
+
* @return void
|
77 |
+
*/
|
78 |
+
public function custom_metabox_html( $post, $metabox ) {
|
79 |
+
$original_item = $metabox['args']['original'];
|
80 |
+
if ( ! $this->permissions_helper->is_rewrite_and_republish_copy( $post ) ) {
|
81 |
+
?>
|
82 |
+
<p>
|
83 |
+
<input type="checkbox"
|
84 |
+
name="duplicate_post_remove_original"
|
85 |
+
id="duplicate-post-remove-original"
|
86 |
+
value="duplicate_post_remove_original"
|
87 |
+
aria-describedby="duplicate-post-remove-original-description">
|
88 |
+
<label for="duplicate-post-remove-original">
|
89 |
+
<?php \esc_html_e( 'Delete reference to original item.', 'duplicate-post' ); ?>
|
90 |
+
</label>
|
91 |
+
</p>
|
92 |
+
<?php
|
93 |
+
}
|
94 |
+
?>
|
95 |
+
<p id="duplicate-post-remove-original-description">
|
96 |
+
<?php
|
97 |
+
\printf(
|
98 |
+
\wp_kses(
|
99 |
+
/* translators: %s: post title */
|
100 |
+
\__(
|
101 |
+
'The original item this was copied from is: <span class="duplicate_post_original_item_title_span">%s</span>',
|
102 |
+
'duplicate-post'
|
103 |
+
),
|
104 |
+
[
|
105 |
+
'span' => [
|
106 |
+
'class' => [],
|
107 |
+
],
|
108 |
+
]
|
109 |
+
),
|
110 |
+
Utils::get_edit_or_view_link( $original_item ) // phpcs:ignore WordPress.Security.EscapeOutput
|
111 |
+
);
|
112 |
+
?>
|
113 |
+
</p>
|
114 |
+
<?php
|
115 |
+
}
|
116 |
+
}
|
src/ui/newsletter.php
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Newsletter class.
|
7 |
+
*/
|
8 |
+
class Newsletter {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Renders the newsletter signup form.
|
12 |
+
*
|
13 |
+
* @return string The HTML of the newsletter signup form (escaped).
|
14 |
+
*/
|
15 |
+
public static function newsletter_signup_form() {
|
16 |
+
|
17 |
+
$newsletter_form_response = self::newsletter_handle_form();
|
18 |
+
|
19 |
+
|
20 |
+
$copy = sprintf(
|
21 |
+
/* translators: 1: Yoast */
|
22 |
+
esc_html__(
|
23 |
+
'If you want to stay up to date about all the exciting developments around Duplicate Post, subscribe to the %1$s newsletter!',
|
24 |
+
'duplicate-post'
|
25 |
+
),
|
26 |
+
'Yoast'
|
27 |
+
);
|
28 |
+
|
29 |
+
$email_label = esc_html__( 'Email Address', 'duplicate-post' );
|
30 |
+
|
31 |
+
$response_html = '';
|
32 |
+
if ( is_array( $newsletter_form_response ) ) {
|
33 |
+
$response_status = $newsletter_form_response['status'];
|
34 |
+
$response_message = $newsletter_form_response['message'];
|
35 |
+
|
36 |
+
$response_html = '<div class="newsletter-response-' . $response_status . ' clear" id="newsletter-response" style="margin-top: 6px;">' . $response_message . '</div>';
|
37 |
+
}
|
38 |
+
|
39 |
+
$html = '
|
40 |
+
<!-- Begin Newsletter Signup Form -->
|
41 |
+
<form method="post" id="newsletter-subscribe-form" name="newsletter-subscribe-form" novalidate>
|
42 |
+
' . wp_nonce_field( 'newsletter', 'newsletter_nonce' ) . '
|
43 |
+
<p>' . $copy . '</p>
|
44 |
+
<div class="newsletter-field-group" style="display: flex; align-items: center;">
|
45 |
+
<label for="newsletter-email" style="margin-right: 4px;"><strong>' . $email_label . '</strong></label>
|
46 |
+
<input type="email" value="" name="EMAIL" class="required email" id="newsletter-email" style="margin-right: 4px;">
|
47 |
+
<input type="submit" value="' . esc_attr__( 'Subscribe', 'duplicate-post' ) . '" name="subscribe" id="newsletter-subscribe" class="button">
|
48 |
+
</div>
|
49 |
+
' . $response_html . '
|
50 |
+
</form>
|
51 |
+
<!--End Newsletter Signup Form-->
|
52 |
+
';
|
53 |
+
|
54 |
+
return $html;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Handles and validates Newsletter form.
|
59 |
+
*
|
60 |
+
* @return null|array.
|
61 |
+
*/
|
62 |
+
private static function newsletter_handle_form() {
|
63 |
+
|
64 |
+
//phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Already sanitized.
|
65 |
+
if ( isset( $_POST['newsletter_nonce'] ) && ! wp_verify_nonce( wp_unslash( $_POST['newsletter_nonce'] ), 'newsletter' ) ) {
|
66 |
+
return [
|
67 |
+
'status' => 'error',
|
68 |
+
'message' => esc_html__( 'Something went wrong. Please try again later.', 'duplicate-post' ),
|
69 |
+
];
|
70 |
+
}
|
71 |
+
|
72 |
+
$email = null;
|
73 |
+
if ( isset( $_POST['EMAIL'] ) ) {
|
74 |
+
$email = sanitize_email( wp_unslash( $_POST['EMAIL'] ) );
|
75 |
+
}
|
76 |
+
|
77 |
+
if ( $email === null ) {
|
78 |
+
return null;
|
79 |
+
}
|
80 |
+
|
81 |
+
if ( ! is_email( $email ) ) {
|
82 |
+
return [
|
83 |
+
'status' => 'error',
|
84 |
+
'message' => esc_html__( 'Please enter valid e-mail address.', 'duplicate-post' ),
|
85 |
+
];
|
86 |
+
}
|
87 |
+
|
88 |
+
return self::newsletter_subscribe_to_mailblue( $email );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Handles subscription request and provides feedback response.
|
93 |
+
*
|
94 |
+
* @param string $email Subscriber email.
|
95 |
+
*
|
96 |
+
* @return array Feedback response.
|
97 |
+
*/
|
98 |
+
private static function newsletter_subscribe_to_mailblue( $email ) {
|
99 |
+
$response = wp_remote_post(
|
100 |
+
'https://my.yoast.com/api/Mailing-list/subscribe',
|
101 |
+
[
|
102 |
+
'method' => 'POST',
|
103 |
+
'body' => [
|
104 |
+
'customerDetails' => [
|
105 |
+
'email' => $email,
|
106 |
+
'firstName' => '',
|
107 |
+
],
|
108 |
+
'list' => 'Yoast newsletter',
|
109 |
+
],
|
110 |
+
]
|
111 |
+
);
|
112 |
+
|
113 |
+
$wp_remote_retrieve_response_code = wp_remote_retrieve_response_code( $response );
|
114 |
+
|
115 |
+
if ( $wp_remote_retrieve_response_code <= 200 || $wp_remote_retrieve_response_code >= 300 ) {
|
116 |
+
return [
|
117 |
+
'status' => 'error',
|
118 |
+
'message' => esc_html__( 'Something went wrong. Please try again later.', 'duplicate-post' ),
|
119 |
+
];
|
120 |
+
}
|
121 |
+
|
122 |
+
return [
|
123 |
+
'status' => 'success',
|
124 |
+
'message' => esc_html__( 'You have successfully subscribed to the newsletter. Please check your inbox.', 'duplicate-post' ),
|
125 |
+
];
|
126 |
+
}
|
127 |
+
}
|
src/ui/{class-post-states.php → post-states.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the post states display.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
@@ -12,7 +7,7 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Utils;
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
*/
|
17 |
class Post_States {
|
18 |
|
@@ -44,8 +39,8 @@ class Post_States {
|
|
44 |
/**
|
45 |
* Shows link to original post in the post states.
|
46 |
*
|
47 |
-
* @param array
|
48 |
-
* @param
|
49 |
*
|
50 |
* @return array The updated post states array.
|
51 |
*/
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post class to manage the post states display.
|
11 |
*/
|
12 |
class Post_States {
|
13 |
|
39 |
/**
|
40 |
* Shows link to original post in the post states.
|
41 |
*
|
42 |
+
* @param array $post_states The array of post states.
|
43 |
+
* @param WP_Post $post The current post.
|
44 |
*
|
45 |
* @return array The updated post states array.
|
46 |
*/
|
src/ui/{class-row-actions.php → row-actions.php}
RENAMED
@@ -1,9 +1,4 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to manage the row actions.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
@@ -12,7 +7,7 @@ use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
|
12 |
use Yoast\WP\Duplicate_Post\Utils;
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
*/
|
17 |
class Row_Actions {
|
18 |
|
@@ -70,8 +65,8 @@ class Row_Actions {
|
|
70 |
/**
|
71 |
* Hooks in the `post_row_actions` and `page_row_actions` filters to add a 'Clone' link.
|
72 |
*
|
73 |
-
* @param array
|
74 |
-
* @param
|
75 |
*
|
76 |
* @return array The updated array of actions.
|
77 |
*/
|
@@ -84,12 +79,12 @@ class Row_Actions {
|
|
84 |
|
85 |
$title = \_draft_or_post_title( $post );
|
86 |
|
87 |
-
$actions['clone'] = '<a href="' . $this->link_builder->build_clone_link( $post->ID )
|
88 |
-
'" aria-label="' . \esc_attr(
|
89 |
-
|
90 |
\sprintf( \__( 'Clone “%s”', 'duplicate-post' ), $title )
|
91 |
-
) . '">'
|
92 |
-
\esc_html_x( 'Clone', 'verb', 'duplicate-post' ) . '</a>';
|
93 |
|
94 |
return $actions;
|
95 |
}
|
@@ -97,8 +92,8 @@ class Row_Actions {
|
|
97 |
/**
|
98 |
* Hooks in the `post_row_actions` and `page_row_actions` filters to add a 'New Draft' link.
|
99 |
*
|
100 |
-
* @param array
|
101 |
-
* @param
|
102 |
*
|
103 |
* @return array The updated array of actions.
|
104 |
*/
|
@@ -111,13 +106,13 @@ class Row_Actions {
|
|
111 |
|
112 |
$title = \_draft_or_post_title( $post );
|
113 |
|
114 |
-
$actions['edit_as_new_draft'] = '<a href="' . $this->link_builder->build_new_draft_link( $post->ID )
|
115 |
-
'" aria-label="' . \esc_attr(
|
116 |
-
|
117 |
\sprintf( \__( 'New draft of “%s”', 'duplicate-post' ), $title )
|
118 |
-
) . '">'
|
119 |
-
\esc_html__( 'New Draft', 'duplicate-post' )
|
120 |
-
'</a>';
|
121 |
|
122 |
return $actions;
|
123 |
}
|
@@ -125,8 +120,8 @@ class Row_Actions {
|
|
125 |
/**
|
126 |
* Hooks in the `post_row_actions` and `page_row_actions` filters to add a 'Rewrite & Republish' link.
|
127 |
*
|
128 |
-
* @param array
|
129 |
-
* @param
|
130 |
*
|
131 |
* @return array The updated array of actions.
|
132 |
*/
|
@@ -142,12 +137,12 @@ class Row_Actions {
|
|
142 |
|
143 |
$title = \_draft_or_post_title( $post );
|
144 |
|
145 |
-
$actions['rewrite'] = '<a href="' . $this->link_builder->build_rewrite_and_republish_link( $post->ID )
|
146 |
-
'" aria-label="' . \esc_attr(
|
147 |
-
|
148 |
\sprintf( \__( 'Rewrite & Republish “%s”', 'duplicate-post' ), $title )
|
149 |
-
) . '">'
|
150 |
-
\esc_html_x( 'Rewrite & Republish', 'verb', 'duplicate-post' ) . '</a>';
|
151 |
|
152 |
return $actions;
|
153 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
7 |
use Yoast\WP\Duplicate_Post\Utils;
|
8 |
|
9 |
/**
|
10 |
+
* Duplicate Post class to manage the row actions.
|
11 |
*/
|
12 |
class Row_Actions {
|
13 |
|
65 |
/**
|
66 |
* Hooks in the `post_row_actions` and `page_row_actions` filters to add a 'Clone' link.
|
67 |
*
|
68 |
+
* @param array $actions The array of actions from the filter.
|
69 |
+
* @param WP_Post $post The post object.
|
70 |
*
|
71 |
* @return array The updated array of actions.
|
72 |
*/
|
79 |
|
80 |
$title = \_draft_or_post_title( $post );
|
81 |
|
82 |
+
$actions['clone'] = '<a href="' . $this->link_builder->build_clone_link( $post->ID )
|
83 |
+
. '" aria-label="' . \esc_attr(
|
84 |
+
/* translators: %s: Post title. */
|
85 |
\sprintf( \__( 'Clone “%s”', 'duplicate-post' ), $title )
|
86 |
+
) . '">'
|
87 |
+
. \esc_html_x( 'Clone', 'verb', 'duplicate-post' ) . '</a>';
|
88 |
|
89 |
return $actions;
|
90 |
}
|
92 |
/**
|
93 |
* Hooks in the `post_row_actions` and `page_row_actions` filters to add a 'New Draft' link.
|
94 |
*
|
95 |
+
* @param array $actions The array of actions from the filter.
|
96 |
+
* @param WP_Post $post The post object.
|
97 |
*
|
98 |
* @return array The updated array of actions.
|
99 |
*/
|
106 |
|
107 |
$title = \_draft_or_post_title( $post );
|
108 |
|
109 |
+
$actions['edit_as_new_draft'] = '<a href="' . $this->link_builder->build_new_draft_link( $post->ID )
|
110 |
+
. '" aria-label="' . \esc_attr(
|
111 |
+
/* translators: %s: Post title. */
|
112 |
\sprintf( \__( 'New draft of “%s”', 'duplicate-post' ), $title )
|
113 |
+
) . '">'
|
114 |
+
. \esc_html__( 'New Draft', 'duplicate-post' )
|
115 |
+
. '</a>';
|
116 |
|
117 |
return $actions;
|
118 |
}
|
120 |
/**
|
121 |
* Hooks in the `post_row_actions` and `page_row_actions` filters to add a 'Rewrite & Republish' link.
|
122 |
*
|
123 |
+
* @param array $actions The array of actions from the filter.
|
124 |
+
* @param WP_Post $post The post object.
|
125 |
*
|
126 |
* @return array The updated array of actions.
|
127 |
*/
|
137 |
|
138 |
$title = \_draft_or_post_title( $post );
|
139 |
|
140 |
+
$actions['rewrite'] = '<a href="' . $this->link_builder->build_rewrite_and_republish_link( $post->ID )
|
141 |
+
. '" aria-label="' . \esc_attr(
|
142 |
+
/* translators: %s: Post title. */
|
143 |
\sprintf( \__( 'Rewrite & Republish “%s”', 'duplicate-post' ), $title )
|
144 |
+
) . '">'
|
145 |
+
. \esc_html_x( 'Rewrite & Republish', 'verb', 'duplicate-post' ) . '</a>';
|
146 |
|
147 |
return $actions;
|
148 |
}
|
src/ui/{class-user-interface.php → user-interface.php}
RENAMED
@@ -1,16 +1,11 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post user interface.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\UI;
|
9 |
|
10 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
11 |
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
class User_Interface {
|
16 |
|
@@ -70,6 +65,13 @@ class User_Interface {
|
|
70 |
*/
|
71 |
protected $metabox;
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
/**
|
74 |
* Column object.
|
75 |
*
|
@@ -107,6 +109,7 @@ class User_Interface {
|
|
107 |
$this->bulk_actions = new Bulk_Actions( $this->permissions_helper );
|
108 |
$this->column = new Column( $this->permissions_helper, $this->asset_manager );
|
109 |
$this->metabox = new Metabox( $this->permissions_helper );
|
|
|
110 |
$this->post_states = new Post_States( $this->permissions_helper );
|
111 |
$this->classic_editor = new Classic_Editor( $this->link_builder, $this->permissions_helper, $this->asset_manager );
|
112 |
$this->row_actions = new Row_Actions( $this->link_builder, $this->permissions_helper );
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\UI;
|
4 |
|
5 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post user interface.
|
9 |
*/
|
10 |
class User_Interface {
|
11 |
|
65 |
*/
|
66 |
protected $metabox;
|
67 |
|
68 |
+
/**
|
69 |
+
* Newsletter object.
|
70 |
+
*
|
71 |
+
* @var Newsletter
|
72 |
+
*/
|
73 |
+
protected $newsletter;
|
74 |
+
|
75 |
/**
|
76 |
* Column object.
|
77 |
*
|
109 |
$this->bulk_actions = new Bulk_Actions( $this->permissions_helper );
|
110 |
$this->column = new Column( $this->permissions_helper, $this->asset_manager );
|
111 |
$this->metabox = new Metabox( $this->permissions_helper );
|
112 |
+
$this->newsletter = new Newsletter();
|
113 |
$this->post_states = new Post_States( $this->permissions_helper );
|
114 |
$this->classic_editor = new Classic_Editor( $this->link_builder, $this->permissions_helper, $this->asset_manager );
|
115 |
$this->row_actions = new Row_Actions( $this->link_builder, $this->permissions_helper );
|
src/{class-utils.php → utils.php}
RENAMED
@@ -1,15 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Utility methods for Duplicate Post.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post;
|
10 |
|
|
|
|
|
11 |
/**
|
12 |
-
*
|
|
|
|
|
13 |
*/
|
14 |
class Utils {
|
15 |
|
@@ -57,10 +55,10 @@ class Utils {
|
|
57 |
/**
|
58 |
* Gets the original post.
|
59 |
*
|
60 |
-
* @param int
|
61 |
-
* @param string
|
62 |
*
|
63 |
-
* @return
|
64 |
*/
|
65 |
public static function get_original( $post = null, $output = \OBJECT ) {
|
66 |
$post = \get_post( $post );
|
@@ -82,8 +80,8 @@ class Utils {
|
|
82 |
*
|
83 |
* If we are copying children, and the post has already an ancestor marked for copy, we have to filter it out.
|
84 |
*
|
85 |
-
* @param
|
86 |
-
* @param array
|
87 |
*
|
88 |
* @return bool Whether the post has ancestors marked for copy.
|
89 |
*/
|
@@ -92,7 +90,7 @@ class Utils {
|
|
92 |
$parent = \wp_get_post_parent_id( $post->ID );
|
93 |
while ( $parent ) {
|
94 |
if ( \in_array( $parent, $post_ids, true ) ) {
|
95 |
-
|
96 |
}
|
97 |
$parent = \wp_get_post_parent_id( $parent );
|
98 |
}
|
@@ -102,7 +100,7 @@ class Utils {
|
|
102 |
/**
|
103 |
* Returns a link to edit, preview or view a post, in accordance to user capabilities.
|
104 |
*
|
105 |
-
* @param
|
106 |
*
|
107 |
* @return string|null The link to edit, preview or view a post.
|
108 |
*/
|
@@ -119,12 +117,13 @@ class Utils {
|
|
119 |
if ( $can_edit_post && $post->post_status !== 'trash' ) {
|
120 |
return \sprintf(
|
121 |
'<a href="%s" aria-label="%s">%s</a>',
|
122 |
-
\get_edit_post_link( $post->ID ),
|
123 |
/* translators: %s: post title */
|
124 |
-
\esc_attr( \sprintf( \__( 'Edit “%s”', '
|
125 |
$title
|
126 |
);
|
127 |
-
}
|
|
|
128 |
if ( \in_array( $post->post_status, [ 'pending', 'draft', 'future' ], true ) ) {
|
129 |
if ( $can_edit_post ) {
|
130 |
$preview_link = \get_preview_post_link( $post );
|
@@ -132,20 +131,22 @@ class Utils {
|
|
132 |
'<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
|
133 |
\esc_url( $preview_link ),
|
134 |
/* translators: %s: post title */
|
135 |
-
\esc_attr( \sprintf( \__( 'Preview “%s”', '
|
136 |
$title
|
137 |
);
|
138 |
}
|
139 |
-
}
|
|
|
140 |
return \sprintf(
|
141 |
'<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
|
142 |
-
\get_permalink( $post->ID ),
|
143 |
/* translators: %s: post title */
|
144 |
-
\esc_attr( \sprintf( \__( 'View “%s”', '
|
145 |
$title
|
146 |
);
|
147 |
}
|
148 |
}
|
|
|
149 |
return $title;
|
150 |
}
|
151 |
|
@@ -163,8 +164,9 @@ class Utils {
|
|
163 |
/**
|
164 |
* Gets the registered WordPress roles.
|
165 |
*
|
166 |
-
* @return array The roles.
|
167 |
* @codeCoverageIgnore As this is a simple wrapper method for a built-in WordPress method, we don't have to test it.
|
|
|
|
|
168 |
*/
|
169 |
public static function get_roles() {
|
170 |
global $wp_roles;
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
+
|
7 |
/**
|
8 |
+
* Utility methods for Duplicate Post.
|
9 |
+
*
|
10 |
+
* @since 4.0
|
11 |
*/
|
12 |
class Utils {
|
13 |
|
55 |
/**
|
56 |
* Gets the original post.
|
57 |
*
|
58 |
+
* @param int|WP_Post|null $post Optional. Post ID or Post object.
|
59 |
+
* @param string $output Optional, default is Object. Either OBJECT, ARRAY_A, or ARRAY_N.
|
60 |
*
|
61 |
+
* @return WP_Post|null Post data if successful, null otherwise.
|
62 |
*/
|
63 |
public static function get_original( $post = null, $output = \OBJECT ) {
|
64 |
$post = \get_post( $post );
|
80 |
*
|
81 |
* If we are copying children, and the post has already an ancestor marked for copy, we have to filter it out.
|
82 |
*
|
83 |
+
* @param WP_Post $post The post object.
|
84 |
+
* @param array $post_ids The array of marked post IDs.
|
85 |
*
|
86 |
* @return bool Whether the post has ancestors marked for copy.
|
87 |
*/
|
90 |
$parent = \wp_get_post_parent_id( $post->ID );
|
91 |
while ( $parent ) {
|
92 |
if ( \in_array( $parent, $post_ids, true ) ) {
|
93 |
+
++$ancestors_in_array;
|
94 |
}
|
95 |
$parent = \wp_get_post_parent_id( $parent );
|
96 |
}
|
100 |
/**
|
101 |
* Returns a link to edit, preview or view a post, in accordance to user capabilities.
|
102 |
*
|
103 |
+
* @param WP_Post $post Post ID or Post object.
|
104 |
*
|
105 |
* @return string|null The link to edit, preview or view a post.
|
106 |
*/
|
117 |
if ( $can_edit_post && $post->post_status !== 'trash' ) {
|
118 |
return \sprintf(
|
119 |
'<a href="%s" aria-label="%s">%s</a>',
|
120 |
+
\esc_url( \get_edit_post_link( $post->ID ) ),
|
121 |
/* translators: %s: post title */
|
122 |
+
\esc_attr( \sprintf( \__( 'Edit “%s”', 'duplicate-post' ), $title ) ),
|
123 |
$title
|
124 |
);
|
125 |
+
}
|
126 |
+
elseif ( \is_post_type_viewable( $post_type_object ) ) {
|
127 |
if ( \in_array( $post->post_status, [ 'pending', 'draft', 'future' ], true ) ) {
|
128 |
if ( $can_edit_post ) {
|
129 |
$preview_link = \get_preview_post_link( $post );
|
131 |
'<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
|
132 |
\esc_url( $preview_link ),
|
133 |
/* translators: %s: post title */
|
134 |
+
\esc_attr( \sprintf( \__( 'Preview “%s”', 'duplicate-post' ), $title ) ),
|
135 |
$title
|
136 |
);
|
137 |
}
|
138 |
+
}
|
139 |
+
elseif ( $post->post_status !== 'trash' ) {
|
140 |
return \sprintf(
|
141 |
'<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
|
142 |
+
\esc_url( \get_permalink( $post->ID ) ),
|
143 |
/* translators: %s: post title */
|
144 |
+
\esc_attr( \sprintf( \__( 'View “%s”', 'duplicate-post' ), $title ) ),
|
145 |
$title
|
146 |
);
|
147 |
}
|
148 |
}
|
149 |
+
|
150 |
return $title;
|
151 |
}
|
152 |
|
164 |
/**
|
165 |
* Gets the registered WordPress roles.
|
166 |
*
|
|
|
167 |
* @codeCoverageIgnore As this is a simple wrapper method for a built-in WordPress method, we don't have to test it.
|
168 |
+
*
|
169 |
+
* @return array The roles.
|
170 |
*/
|
171 |
public static function get_roles() {
|
172 |
global $wp_roles;
|
src/watchers/{class-bulk-actions-watcher.php → bulk-actions-watcher.php}
RENAMED
@@ -1,14 +1,9 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to watch for the bulk actions and show notices.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
9 |
|
10 |
/**
|
11 |
-
*
|
12 |
*/
|
13 |
class Bulk_Actions_Watcher {
|
14 |
|
@@ -51,12 +46,12 @@ class Bulk_Actions_Watcher {
|
|
51 |
* @return void
|
52 |
*/
|
53 |
public function add_bulk_clone_admin_notice() {
|
54 |
-
if ( ! empty( $_REQUEST['bulk_cloned'] ) ) {
|
55 |
-
$copied_posts = \intval( $_REQUEST['bulk_cloned'] );
|
56 |
\printf(
|
57 |
-
'<div id="message" class="notice notice-success fade"><p>'
|
58 |
-
\esc_html(
|
59 |
-
|
60 |
\_n(
|
61 |
'%s item copied.',
|
62 |
'%s items copied.',
|
@@ -75,12 +70,12 @@ class Bulk_Actions_Watcher {
|
|
75 |
* @return void
|
76 |
*/
|
77 |
public function add_bulk_rewrite_and_republish_admin_notice() {
|
78 |
-
if ( ! empty( $_REQUEST['bulk_rewriting'] ) ) {
|
79 |
-
$copied_posts = \intval( $_REQUEST['bulk_rewriting'] );
|
80 |
\printf(
|
81 |
-
'<div id="message" class="notice notice-success fade"><p>'
|
82 |
-
\esc_html(
|
83 |
-
|
84 |
\_n(
|
85 |
'%s post duplicated. You can now start rewriting your post in the duplicate of the original post. Once you choose to republish it your changes will be merged back into the original post.',
|
86 |
'%s posts duplicated. You can now start rewriting your posts in the duplicates of the original posts. Once you choose to republish them your changes will be merged back into the original post.',
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
4 |
|
5 |
/**
|
6 |
+
* Duplicate Post class to watch for the bulk actions and show notices.
|
7 |
*/
|
8 |
class Bulk_Actions_Watcher {
|
9 |
|
46 |
* @return void
|
47 |
*/
|
48 |
public function add_bulk_clone_admin_notice() {
|
49 |
+
if ( ! empty( $_REQUEST['bulk_cloned'] ) ) {
|
50 |
+
$copied_posts = \intval( $_REQUEST['bulk_cloned'] );
|
51 |
\printf(
|
52 |
+
'<div id="message" class="notice notice-success fade"><p>'
|
53 |
+
. \esc_html(
|
54 |
+
/* translators: %s: Number of posts copied. */
|
55 |
\_n(
|
56 |
'%s item copied.',
|
57 |
'%s items copied.',
|
70 |
* @return void
|
71 |
*/
|
72 |
public function add_bulk_rewrite_and_republish_admin_notice() {
|
73 |
+
if ( ! empty( $_REQUEST['bulk_rewriting'] ) ) {
|
74 |
+
$copied_posts = \intval( $_REQUEST['bulk_rewriting'] );
|
75 |
\printf(
|
76 |
+
'<div id="message" class="notice notice-success fade"><p>'
|
77 |
+
. \esc_html(
|
78 |
+
/* translators: %s: Number of posts copied. */
|
79 |
\_n(
|
80 |
'%s post duplicated. You can now start rewriting your post in the duplicate of the original post. Once you choose to republish it your changes will be merged back into the original post.',
|
81 |
'%s posts duplicated. You can now start rewriting your posts in the duplicates of the original posts. Once you choose to republish them your changes will be merged back into the original post.',
|
src/watchers/{class-copied-post-watcher.php → copied-post-watcher.php}
RENAMED
@@ -1,16 +1,12 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to watch if the current post has a Rewrite & Republish copy.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
9 |
|
|
|
10 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
11 |
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
class Copied_Post_Watcher {
|
16 |
|
@@ -45,7 +41,7 @@ class Copied_Post_Watcher {
|
|
45 |
/**
|
46 |
* Generates the translated text for the notice.
|
47 |
*
|
48 |
-
* @param
|
49 |
*
|
50 |
* @return string The translated text for the notice.
|
51 |
*/
|
@@ -88,14 +84,14 @@ class Copied_Post_Watcher {
|
|
88 |
|
89 |
$post = \get_post();
|
90 |
|
91 |
-
if ( ! $post instanceof
|
92 |
return;
|
93 |
}
|
94 |
|
95 |
if ( $this->permissions_helper->has_rewrite_and_republish_copy( $post ) ) {
|
96 |
-
print '<div id="message" class="notice notice-warning is-dismissible fade"><p>'
|
97 |
-
\esc_html( $this->get_notice_text( $post ) )
|
98 |
-
'</p></div>';
|
99 |
}
|
100 |
}
|
101 |
|
@@ -107,7 +103,7 @@ class Copied_Post_Watcher {
|
|
107 |
public function add_block_editor_notice() {
|
108 |
$post = \get_post();
|
109 |
|
110 |
-
if ( ! $post instanceof
|
111 |
return;
|
112 |
}
|
113 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
7 |
|
8 |
/**
|
9 |
+
* Duplicate Post class to watch if the current post has a Rewrite & Republish copy.
|
10 |
*/
|
11 |
class Copied_Post_Watcher {
|
12 |
|
41 |
/**
|
42 |
* Generates the translated text for the notice.
|
43 |
*
|
44 |
+
* @param WP_Post $post The current post object.
|
45 |
*
|
46 |
* @return string The translated text for the notice.
|
47 |
*/
|
84 |
|
85 |
$post = \get_post();
|
86 |
|
87 |
+
if ( ! $post instanceof WP_Post ) {
|
88 |
return;
|
89 |
}
|
90 |
|
91 |
if ( $this->permissions_helper->has_rewrite_and_republish_copy( $post ) ) {
|
92 |
+
print '<div id="message" class="notice notice-warning is-dismissible fade"><p>'
|
93 |
+
. \esc_html( $this->get_notice_text( $post ) )
|
94 |
+
. '</p></div>';
|
95 |
}
|
96 |
}
|
97 |
|
103 |
public function add_block_editor_notice() {
|
104 |
$post = \get_post();
|
105 |
|
106 |
+
if ( ! $post instanceof WP_Post ) {
|
107 |
return;
|
108 |
}
|
109 |
|
src/watchers/{class-link-actions-watcher.php → link-actions-watcher.php}
RENAMED
@@ -1,16 +1,11 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to watch for the link actions and show notices.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
9 |
|
10 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
11 |
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
class Link_Actions_Watcher {
|
16 |
|
@@ -65,16 +60,16 @@ class Link_Actions_Watcher {
|
|
65 |
* @return void
|
66 |
*/
|
67 |
public function add_clone_admin_notice() {
|
68 |
-
if ( ! empty( $_REQUEST['cloned'] ) ) {
|
69 |
if ( ! $this->permissions_helper->is_classic_editor() ) {
|
70 |
return;
|
71 |
}
|
72 |
|
73 |
-
$copied_posts = \intval( $_REQUEST['cloned'] );
|
74 |
\printf(
|
75 |
-
'<div id="message" class="notice notice-success fade"><p>'
|
76 |
-
\esc_html(
|
77 |
-
|
78 |
\_n(
|
79 |
'%s item copied.',
|
80 |
'%s items copied.',
|
@@ -93,16 +88,16 @@ class Link_Actions_Watcher {
|
|
93 |
* @return void
|
94 |
*/
|
95 |
public function add_rewrite_and_republish_admin_notice() {
|
96 |
-
if ( ! empty( $_REQUEST['rewriting'] ) ) {
|
97 |
if ( ! $this->permissions_helper->is_classic_editor() ) {
|
98 |
return;
|
99 |
}
|
100 |
|
101 |
-
print '<div id="message" class="notice notice-warning is-dismissible fade"><p>'
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
}
|
107 |
}
|
108 |
|
@@ -112,10 +107,10 @@ class Link_Actions_Watcher {
|
|
112 |
* @return void
|
113 |
*/
|
114 |
public function add_rewrite_and_republish_block_editor_notice() {
|
115 |
-
if ( ! empty( $_REQUEST['rewriting'] ) ) {
|
116 |
$notice = [
|
117 |
'text' => \wp_slash(
|
118 |
-
__(
|
119 |
'You can now start rewriting your post in this duplicate of the original post. If you click "Republish", this rewritten post will replace the original post.',
|
120 |
'duplicate-post'
|
121 |
)
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
4 |
|
5 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post class to watch for the link actions and show notices.
|
9 |
*/
|
10 |
class Link_Actions_Watcher {
|
11 |
|
60 |
* @return void
|
61 |
*/
|
62 |
public function add_clone_admin_notice() {
|
63 |
+
if ( ! empty( $_REQUEST['cloned'] ) ) {
|
64 |
if ( ! $this->permissions_helper->is_classic_editor() ) {
|
65 |
return;
|
66 |
}
|
67 |
|
68 |
+
$copied_posts = \intval( $_REQUEST['cloned'] );
|
69 |
\printf(
|
70 |
+
'<div id="message" class="notice notice-success fade"><p>'
|
71 |
+
. \esc_html(
|
72 |
+
/* translators: %s: Number of posts copied. */
|
73 |
\_n(
|
74 |
'%s item copied.',
|
75 |
'%s items copied.',
|
88 |
* @return void
|
89 |
*/
|
90 |
public function add_rewrite_and_republish_admin_notice() {
|
91 |
+
if ( ! empty( $_REQUEST['rewriting'] ) ) {
|
92 |
if ( ! $this->permissions_helper->is_classic_editor() ) {
|
93 |
return;
|
94 |
}
|
95 |
|
96 |
+
print '<div id="message" class="notice notice-warning is-dismissible fade"><p>'
|
97 |
+
. \esc_html__(
|
98 |
+
'You can now start rewriting your post in this duplicate of the original post. If you click "Republish", your changes will be merged into the original post and you’ll be redirected there.',
|
99 |
+
'duplicate-post'
|
100 |
+
) . '</p></div>';
|
101 |
}
|
102 |
}
|
103 |
|
107 |
* @return void
|
108 |
*/
|
109 |
public function add_rewrite_and_republish_block_editor_notice() {
|
110 |
+
if ( ! empty( $_REQUEST['rewriting'] ) ) {
|
111 |
$notice = [
|
112 |
'text' => \wp_slash(
|
113 |
+
\__(
|
114 |
'You can now start rewriting your post in this duplicate of the original post. If you click "Republish", this rewritten post will replace the original post.',
|
115 |
'duplicate-post'
|
116 |
)
|
src/watchers/{class-original-post-watcher.php → original-post-watcher.php}
RENAMED
@@ -1,19 +1,16 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post Original post watcher class.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
10 |
|
|
|
11 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
12 |
|
13 |
/**
|
14 |
-
* Original post watcher.
|
15 |
*
|
16 |
* Watches the original post for changes.
|
|
|
|
|
17 |
*/
|
18 |
class Original_Post_Watcher {
|
19 |
|
@@ -69,14 +66,14 @@ class Original_Post_Watcher {
|
|
69 |
|
70 |
$post = \get_post();
|
71 |
|
72 |
-
if ( ! $post instanceof
|
73 |
return;
|
74 |
}
|
75 |
|
76 |
if ( $this->permissions_helper->has_original_changed( $post ) ) {
|
77 |
-
print '<div id="message" class="notice notice-warning is-dismissible fade"><p>'
|
78 |
-
\esc_html( $this->get_notice_text() )
|
79 |
-
'</p></div>';
|
80 |
}
|
81 |
}
|
82 |
|
@@ -88,7 +85,7 @@ class Original_Post_Watcher {
|
|
88 |
public function add_block_editor_notice() {
|
89 |
$post = \get_post();
|
90 |
|
91 |
-
if ( ! $post instanceof
|
92 |
return;
|
93 |
}
|
94 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
4 |
|
5 |
+
use WP_Post;
|
6 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
7 |
|
8 |
/**
|
9 |
+
* Duplicate Post Original post watcher class.
|
10 |
*
|
11 |
* Watches the original post for changes.
|
12 |
+
*
|
13 |
+
* @since 4.0
|
14 |
*/
|
15 |
class Original_Post_Watcher {
|
16 |
|
66 |
|
67 |
$post = \get_post();
|
68 |
|
69 |
+
if ( ! $post instanceof WP_Post ) {
|
70 |
return;
|
71 |
}
|
72 |
|
73 |
if ( $this->permissions_helper->has_original_changed( $post ) ) {
|
74 |
+
print '<div id="message" class="notice notice-warning is-dismissible fade"><p>'
|
75 |
+
. \esc_html( $this->get_notice_text() )
|
76 |
+
. '</p></div>';
|
77 |
}
|
78 |
}
|
79 |
|
85 |
public function add_block_editor_notice() {
|
86 |
$post = \get_post();
|
87 |
|
88 |
+
if ( ! $post instanceof WP_Post ) {
|
89 |
return;
|
90 |
}
|
91 |
|
src/watchers/{class-republished-post-watcher.php → republished-post-watcher.php}
RENAMED
@@ -1,17 +1,13 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post class to watch if the post has been republished for Rewrite & Republish.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
* @since 4.0
|
7 |
-
*/
|
8 |
|
9 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
10 |
|
11 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
12 |
|
13 |
/**
|
14 |
-
*
|
|
|
|
|
15 |
*/
|
16 |
class Republished_Post_Watcher {
|
17 |
|
@@ -82,10 +78,10 @@ class Republished_Post_Watcher {
|
|
82 |
return;
|
83 |
}
|
84 |
|
85 |
-
if ( ! empty( $_REQUEST['dprepublished'] ) ) {
|
86 |
-
echo '<div id="message" class="notice notice-success is-dismissible"><p>'
|
87 |
-
\esc_html( $this->get_notice_text() )
|
88 |
-
'</p></div>';
|
89 |
}
|
90 |
}
|
91 |
|
@@ -95,7 +91,7 @@ class Republished_Post_Watcher {
|
|
95 |
* @return void
|
96 |
*/
|
97 |
public function add_block_editor_notice() {
|
98 |
-
if ( ! empty( $_REQUEST['dprepublished'] ) ) {
|
99 |
$notice = [
|
100 |
'text' => \wp_slash( $this->get_notice_text() ),
|
101 |
'status' => 'success',
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
4 |
|
5 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post class to watch if the post has been republished for Rewrite & Republish.
|
9 |
+
*
|
10 |
+
* @since 4.0
|
11 |
*/
|
12 |
class Republished_Post_Watcher {
|
13 |
|
78 |
return;
|
79 |
}
|
80 |
|
81 |
+
if ( ! empty( $_REQUEST['dprepublished'] ) ) {
|
82 |
+
echo '<div id="message" class="notice notice-success is-dismissible"><p>'
|
83 |
+
. \esc_html( $this->get_notice_text() )
|
84 |
+
. '</p></div>';
|
85 |
}
|
86 |
}
|
87 |
|
91 |
* @return void
|
92 |
*/
|
93 |
public function add_block_editor_notice() {
|
94 |
+
if ( ! empty( $_REQUEST['dprepublished'] ) ) {
|
95 |
$notice = [
|
96 |
'text' => \wp_slash( $this->get_notice_text() ),
|
97 |
'status' => 'success',
|
src/watchers/{class-watchers.php → watchers.php}
RENAMED
@@ -1,16 +1,11 @@
|
|
1 |
<?php
|
2 |
-
/**
|
3 |
-
* Duplicate Post user interface.
|
4 |
-
*
|
5 |
-
* @package Duplicate_Post
|
6 |
-
*/
|
7 |
|
8 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
9 |
|
10 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
11 |
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
class Watchers {
|
16 |
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace Yoast\WP\Duplicate_Post\Watchers;
|
4 |
|
5 |
use Yoast\WP\Duplicate_Post\Permissions_Helper;
|
6 |
|
7 |
/**
|
8 |
+
* Duplicate Post user interface.
|
9 |
*/
|
10 |
class Watchers {
|
11 |
|
vendor/composer/ClassLoader.php
CHANGED
@@ -42,30 +42,75 @@ namespace Composer\Autoload;
|
|
42 |
*/
|
43 |
class ClassLoader
|
44 |
{
|
|
|
45 |
private $vendorDir;
|
46 |
|
47 |
// PSR-4
|
|
|
|
|
|
|
|
|
48 |
private $prefixLengthsPsr4 = array();
|
|
|
|
|
|
|
|
|
49 |
private $prefixDirsPsr4 = array();
|
|
|
|
|
|
|
|
|
50 |
private $fallbackDirsPsr4 = array();
|
51 |
|
52 |
// PSR-0
|
|
|
|
|
|
|
|
|
53 |
private $prefixesPsr0 = array();
|
|
|
|
|
|
|
|
|
54 |
private $fallbackDirsPsr0 = array();
|
55 |
|
|
|
56 |
private $useIncludePath = false;
|
|
|
|
|
|
|
|
|
|
|
57 |
private $classMap = array();
|
|
|
|
|
58 |
private $classMapAuthoritative = false;
|
|
|
|
|
|
|
|
|
|
|
59 |
private $missingClasses = array();
|
|
|
|
|
60 |
private $apcuPrefix;
|
61 |
|
|
|
|
|
|
|
62 |
private static $registeredLoaders = array();
|
63 |
|
|
|
|
|
|
|
64 |
public function __construct($vendorDir = null)
|
65 |
{
|
66 |
$this->vendorDir = $vendorDir;
|
67 |
}
|
68 |
|
|
|
|
|
|
|
69 |
public function getPrefixes()
|
70 |
{
|
71 |
if (!empty($this->prefixesPsr0)) {
|
@@ -75,28 +120,47 @@ class ClassLoader
|
|
75 |
return array();
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
78 |
public function getPrefixesPsr4()
|
79 |
{
|
80 |
return $this->prefixDirsPsr4;
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
83 |
public function getFallbackDirs()
|
84 |
{
|
85 |
return $this->fallbackDirsPsr0;
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
88 |
public function getFallbackDirsPsr4()
|
89 |
{
|
90 |
return $this->fallbackDirsPsr4;
|
91 |
}
|
92 |
|
|
|
|
|
|
|
|
|
93 |
public function getClassMap()
|
94 |
{
|
95 |
return $this->classMap;
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
-
* @param
|
|
|
|
|
|
|
100 |
*/
|
101 |
public function addClassMap(array $classMap)
|
102 |
{
|
@@ -111,9 +175,11 @@ class ClassLoader
|
|
111 |
* Registers a set of PSR-0 directories for a given prefix, either
|
112 |
* appending or prepending to the ones previously set for this prefix.
|
113 |
*
|
114 |
-
* @param string
|
115 |
-
* @param
|
116 |
-
* @param bool
|
|
|
|
|
117 |
*/
|
118 |
public function add($prefix, $paths, $prepend = false)
|
119 |
{
|
@@ -156,11 +222,13 @@ class ClassLoader
|
|
156 |
* Registers a set of PSR-4 directories for a given namespace, either
|
157 |
* appending or prepending to the ones previously set for this namespace.
|
158 |
*
|
159 |
-
* @param string
|
160 |
-
* @param
|
161 |
-
* @param bool
|
162 |
*
|
163 |
* @throws \InvalidArgumentException
|
|
|
|
|
164 |
*/
|
165 |
public function addPsr4($prefix, $paths, $prepend = false)
|
166 |
{
|
@@ -204,8 +272,10 @@ class ClassLoader
|
|
204 |
* Registers a set of PSR-0 directories for a given prefix,
|
205 |
* replacing any others previously set for this prefix.
|
206 |
*
|
207 |
-
* @param string
|
208 |
-
* @param
|
|
|
|
|
209 |
*/
|
210 |
public function set($prefix, $paths)
|
211 |
{
|
@@ -220,10 +290,12 @@ class ClassLoader
|
|
220 |
* Registers a set of PSR-4 directories for a given namespace,
|
221 |
* replacing any others previously set for this namespace.
|
222 |
*
|
223 |
-
* @param string
|
224 |
-
* @param
|
225 |
*
|
226 |
* @throws \InvalidArgumentException
|
|
|
|
|
227 |
*/
|
228 |
public function setPsr4($prefix, $paths)
|
229 |
{
|
@@ -243,6 +315,8 @@ class ClassLoader
|
|
243 |
* Turns on searching the include path for class files.
|
244 |
*
|
245 |
* @param bool $useIncludePath
|
|
|
|
|
246 |
*/
|
247 |
public function setUseIncludePath($useIncludePath)
|
248 |
{
|
@@ -265,6 +339,8 @@ class ClassLoader
|
|
265 |
* that have not been registered with the class map.
|
266 |
*
|
267 |
* @param bool $classMapAuthoritative
|
|
|
|
|
268 |
*/
|
269 |
public function setClassMapAuthoritative($classMapAuthoritative)
|
270 |
{
|
@@ -285,6 +361,8 @@ class ClassLoader
|
|
285 |
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
286 |
*
|
287 |
* @param string|null $apcuPrefix
|
|
|
|
|
288 |
*/
|
289 |
public function setApcuPrefix($apcuPrefix)
|
290 |
{
|
@@ -305,6 +383,8 @@ class ClassLoader
|
|
305 |
* Registers this instance as an autoloader.
|
306 |
*
|
307 |
* @param bool $prepend Whether to prepend the autoloader or not
|
|
|
|
|
308 |
*/
|
309 |
public function register($prepend = false)
|
310 |
{
|
@@ -324,6 +404,8 @@ class ClassLoader
|
|
324 |
|
325 |
/**
|
326 |
* Unregisters this instance as an autoloader.
|
|
|
|
|
327 |
*/
|
328 |
public function unregister()
|
329 |
{
|
@@ -338,7 +420,7 @@ class ClassLoader
|
|
338 |
* Loads the given class or interface.
|
339 |
*
|
340 |
* @param string $class The name of the class
|
341 |
-
* @return
|
342 |
*/
|
343 |
public function loadClass($class)
|
344 |
{
|
@@ -347,6 +429,8 @@ class ClassLoader
|
|
347 |
|
348 |
return true;
|
349 |
}
|
|
|
|
|
350 |
}
|
351 |
|
352 |
/**
|
@@ -401,6 +485,11 @@ class ClassLoader
|
|
401 |
return self::$registeredLoaders;
|
402 |
}
|
403 |
|
|
|
|
|
|
|
|
|
|
|
404 |
private function findFileWithExtension($class, $ext)
|
405 |
{
|
406 |
// PSR-4 lookup
|
@@ -472,6 +561,10 @@ class ClassLoader
|
|
472 |
* Scope isolated include.
|
473 |
*
|
474 |
* Prevents access to $this/self from included files.
|
|
|
|
|
|
|
|
|
475 |
*/
|
476 |
function includeFile($file)
|
477 |
{
|
42 |
*/
|
43 |
class ClassLoader
|
44 |
{
|
45 |
+
/** @var ?string */
|
46 |
private $vendorDir;
|
47 |
|
48 |
// PSR-4
|
49 |
+
/**
|
50 |
+
* @var array[]
|
51 |
+
* @psalm-var array<string, array<string, int>>
|
52 |
+
*/
|
53 |
private $prefixLengthsPsr4 = array();
|
54 |
+
/**
|
55 |
+
* @var array[]
|
56 |
+
* @psalm-var array<string, array<int, string>>
|
57 |
+
*/
|
58 |
private $prefixDirsPsr4 = array();
|
59 |
+
/**
|
60 |
+
* @var array[]
|
61 |
+
* @psalm-var array<string, string>
|
62 |
+
*/
|
63 |
private $fallbackDirsPsr4 = array();
|
64 |
|
65 |
// PSR-0
|
66 |
+
/**
|
67 |
+
* @var array[]
|
68 |
+
* @psalm-var array<string, array<string, string[]>>
|
69 |
+
*/
|
70 |
private $prefixesPsr0 = array();
|
71 |
+
/**
|
72 |
+
* @var array[]
|
73 |
+
* @psalm-var array<string, string>
|
74 |
+
*/
|
75 |
private $fallbackDirsPsr0 = array();
|
76 |
|
77 |
+
/** @var bool */
|
78 |
private $useIncludePath = false;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @var string[]
|
82 |
+
* @psalm-var array<string, string>
|
83 |
+
*/
|
84 |
private $classMap = array();
|
85 |
+
|
86 |
+
/** @var bool */
|
87 |
private $classMapAuthoritative = false;
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @var bool[]
|
91 |
+
* @psalm-var array<string, bool>
|
92 |
+
*/
|
93 |
private $missingClasses = array();
|
94 |
+
|
95 |
+
/** @var ?string */
|
96 |
private $apcuPrefix;
|
97 |
|
98 |
+
/**
|
99 |
+
* @var self[]
|
100 |
+
*/
|
101 |
private static $registeredLoaders = array();
|
102 |
|
103 |
+
/**
|
104 |
+
* @param ?string $vendorDir
|
105 |
+
*/
|
106 |
public function __construct($vendorDir = null)
|
107 |
{
|
108 |
$this->vendorDir = $vendorDir;
|
109 |
}
|
110 |
|
111 |
+
/**
|
112 |
+
* @return string[]
|
113 |
+
*/
|
114 |
public function getPrefixes()
|
115 |
{
|
116 |
if (!empty($this->prefixesPsr0)) {
|
120 |
return array();
|
121 |
}
|
122 |
|
123 |
+
/**
|
124 |
+
* @return array[]
|
125 |
+
* @psalm-return array<string, array<int, string>>
|
126 |
+
*/
|
127 |
public function getPrefixesPsr4()
|
128 |
{
|
129 |
return $this->prefixDirsPsr4;
|
130 |
}
|
131 |
|
132 |
+
/**
|
133 |
+
* @return array[]
|
134 |
+
* @psalm-return array<string, string>
|
135 |
+
*/
|
136 |
public function getFallbackDirs()
|
137 |
{
|
138 |
return $this->fallbackDirsPsr0;
|
139 |
}
|
140 |
|
141 |
+
/**
|
142 |
+
* @return array[]
|
143 |
+
* @psalm-return array<string, string>
|
144 |
+
*/
|
145 |
public function getFallbackDirsPsr4()
|
146 |
{
|
147 |
return $this->fallbackDirsPsr4;
|
148 |
}
|
149 |
|
150 |
+
/**
|
151 |
+
* @return string[] Array of classname => path
|
152 |
+
* @psalm-var array<string, string>
|
153 |
+
*/
|
154 |
public function getClassMap()
|
155 |
{
|
156 |
return $this->classMap;
|
157 |
}
|
158 |
|
159 |
/**
|
160 |
+
* @param string[] $classMap Class to filename map
|
161 |
+
* @psalm-param array<string, string> $classMap
|
162 |
+
*
|
163 |
+
* @return void
|
164 |
*/
|
165 |
public function addClassMap(array $classMap)
|
166 |
{
|
175 |
* Registers a set of PSR-0 directories for a given prefix, either
|
176 |
* appending or prepending to the ones previously set for this prefix.
|
177 |
*
|
178 |
+
* @param string $prefix The prefix
|
179 |
+
* @param string[]|string $paths The PSR-0 root directories
|
180 |
+
* @param bool $prepend Whether to prepend the directories
|
181 |
+
*
|
182 |
+
* @return void
|
183 |
*/
|
184 |
public function add($prefix, $paths, $prepend = false)
|
185 |
{
|
222 |
* Registers a set of PSR-4 directories for a given namespace, either
|
223 |
* appending or prepending to the ones previously set for this namespace.
|
224 |
*
|
225 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
226 |
+
* @param string[]|string $paths The PSR-4 base directories
|
227 |
+
* @param bool $prepend Whether to prepend the directories
|
228 |
*
|
229 |
* @throws \InvalidArgumentException
|
230 |
+
*
|
231 |
+
* @return void
|
232 |
*/
|
233 |
public function addPsr4($prefix, $paths, $prepend = false)
|
234 |
{
|
272 |
* Registers a set of PSR-0 directories for a given prefix,
|
273 |
* replacing any others previously set for this prefix.
|
274 |
*
|
275 |
+
* @param string $prefix The prefix
|
276 |
+
* @param string[]|string $paths The PSR-0 base directories
|
277 |
+
*
|
278 |
+
* @return void
|
279 |
*/
|
280 |
public function set($prefix, $paths)
|
281 |
{
|
290 |
* Registers a set of PSR-4 directories for a given namespace,
|
291 |
* replacing any others previously set for this namespace.
|
292 |
*
|
293 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
294 |
+
* @param string[]|string $paths The PSR-4 base directories
|
295 |
*
|
296 |
* @throws \InvalidArgumentException
|
297 |
+
*
|
298 |
+
* @return void
|
299 |
*/
|
300 |
public function setPsr4($prefix, $paths)
|
301 |
{
|
315 |
* Turns on searching the include path for class files.
|
316 |
*
|
317 |
* @param bool $useIncludePath
|
318 |
+
*
|
319 |
+
* @return void
|
320 |
*/
|
321 |
public function setUseIncludePath($useIncludePath)
|
322 |
{
|
339 |
* that have not been registered with the class map.
|
340 |
*
|
341 |
* @param bool $classMapAuthoritative
|
342 |
+
*
|
343 |
+
* @return void
|
344 |
*/
|
345 |
public function setClassMapAuthoritative($classMapAuthoritative)
|
346 |
{
|
361 |
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
362 |
*
|
363 |
* @param string|null $apcuPrefix
|
364 |
+
*
|
365 |
+
* @return void
|
366 |
*/
|
367 |
public function setApcuPrefix($apcuPrefix)
|
368 |
{
|
383 |
* Registers this instance as an autoloader.
|
384 |
*
|
385 |
* @param bool $prepend Whether to prepend the autoloader or not
|
386 |
+
*
|
387 |
+
* @return void
|
388 |
*/
|
389 |
public function register($prepend = false)
|
390 |
{
|
404 |
|
405 |
/**
|
406 |
* Unregisters this instance as an autoloader.
|
407 |
+
*
|
408 |
+
* @return void
|
409 |
*/
|
410 |
public function unregister()
|
411 |
{
|
420 |
* Loads the given class or interface.
|
421 |
*
|
422 |
* @param string $class The name of the class
|
423 |
+
* @return true|null True if loaded, null otherwise
|
424 |
*/
|
425 |
public function loadClass($class)
|
426 |
{
|
429 |
|
430 |
return true;
|
431 |
}
|
432 |
+
|
433 |
+
return null;
|
434 |
}
|
435 |
|
436 |
/**
|
485 |
return self::$registeredLoaders;
|
486 |
}
|
487 |
|
488 |
+
/**
|
489 |
+
* @param string $class
|
490 |
+
* @param string $ext
|
491 |
+
* @return string|false
|
492 |
+
*/
|
493 |
private function findFileWithExtension($class, $ext)
|
494 |
{
|
495 |
// PSR-4 lookup
|
561 |
* Scope isolated include.
|
562 |
*
|
563 |
* Prevents access to $this/self from included files.
|
564 |
+
*
|
565 |
+
* @param string $file
|
566 |
+
* @return void
|
567 |
+
* @private
|
568 |
*/
|
569 |
function includeFile($file)
|
570 |
{
|
vendor/composer/InstalledVersions.php
CHANGED
@@ -1,283 +1,350 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
13 |
namespace Composer;
|
14 |
|
15 |
use Composer\Autoload\ClassLoader;
|
16 |
use Composer\Semver\VersionParser;
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
23 |
class InstalledVersions
|
24 |
{
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
)
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
return
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
if (
|
137 |
-
|
138 |
-
}
|
139 |
-
|
140 |
-
$ranges =
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
}
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
}
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
}
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
}
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
{
|
231 |
-
|
232 |
-
}
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
}
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
{
|
263 |
-
if
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
}
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
|
13 |
namespace Composer;
|
14 |
|
15 |
use Composer\Autoload\ClassLoader;
|
16 |
use Composer\Semver\VersionParser;
|
17 |
|
18 |
+
/**
|
19 |
+
* This class is copied in every Composer installed project and available to all
|
20 |
+
*
|
21 |
+
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
22 |
+
*
|
23 |
+
* To require its presence, you can require `composer-runtime-api ^2.0`
|
24 |
+
*/
|
25 |
class InstalledVersions
|
26 |
{
|
27 |
+
/**
|
28 |
+
* @var mixed[]|null
|
29 |
+
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
|
30 |
+
*/
|
31 |
+
private static $installed;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var bool|null
|
35 |
+
*/
|
36 |
+
private static $canGetVendors;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var array[]
|
40 |
+
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
41 |
+
*/
|
42 |
+
private static $installedByVendor = array();
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
46 |
+
*
|
47 |
+
* @return string[]
|
48 |
+
* @psalm-return list<string>
|
49 |
+
*/
|
50 |
+
public static function getInstalledPackages()
|
51 |
+
{
|
52 |
+
$packages = array();
|
53 |
+
foreach (self::getInstalled() as $installed) {
|
54 |
+
$packages[] = array_keys($installed['versions']);
|
55 |
+
}
|
56 |
+
|
57 |
+
if (1 === \count($packages)) {
|
58 |
+
return $packages[0];
|
59 |
+
}
|
60 |
+
|
61 |
+
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Returns a list of all package names with a specific type e.g. 'library'
|
66 |
+
*
|
67 |
+
* @param string $type
|
68 |
+
* @return string[]
|
69 |
+
* @psalm-return list<string>
|
70 |
+
*/
|
71 |
+
public static function getInstalledPackagesByType($type)
|
72 |
+
{
|
73 |
+
$packagesByType = array();
|
74 |
+
|
75 |
+
foreach (self::getInstalled() as $installed) {
|
76 |
+
foreach ($installed['versions'] as $name => $package) {
|
77 |
+
if (isset($package['type']) && $package['type'] === $type) {
|
78 |
+
$packagesByType[] = $name;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
return $packagesByType;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Checks whether the given package is installed
|
88 |
+
*
|
89 |
+
* This also returns true if the package name is provided or replaced by another package
|
90 |
+
*
|
91 |
+
* @param string $packageName
|
92 |
+
* @param bool $includeDevRequirements
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
public static function isInstalled($packageName, $includeDevRequirements = true)
|
96 |
+
{
|
97 |
+
foreach (self::getInstalled() as $installed) {
|
98 |
+
if (isset($installed['versions'][$packageName])) {
|
99 |
+
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
return false;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Checks whether the given package satisfies a version constraint
|
108 |
+
*
|
109 |
+
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
110 |
+
*
|
111 |
+
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
112 |
+
*
|
113 |
+
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
114 |
+
* @param string $packageName
|
115 |
+
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
116 |
+
* @return bool
|
117 |
+
*/
|
118 |
+
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
119 |
+
{
|
120 |
+
$constraint = $parser->parseConstraints($constraint);
|
121 |
+
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
122 |
+
|
123 |
+
return $provided->matches($constraint);
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Returns a version constraint representing all the range(s) which are installed for a given package
|
128 |
+
*
|
129 |
+
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
130 |
+
* whether a given version of a package is installed, and not just whether it exists
|
131 |
+
*
|
132 |
+
* @param string $packageName
|
133 |
+
* @return string Version constraint usable with composer/semver
|
134 |
+
*/
|
135 |
+
public static function getVersionRanges($packageName)
|
136 |
+
{
|
137 |
+
foreach (self::getInstalled() as $installed) {
|
138 |
+
if (!isset($installed['versions'][$packageName])) {
|
139 |
+
continue;
|
140 |
+
}
|
141 |
+
|
142 |
+
$ranges = array();
|
143 |
+
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
144 |
+
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
145 |
+
}
|
146 |
+
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
147 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
148 |
+
}
|
149 |
+
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
150 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
151 |
+
}
|
152 |
+
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
153 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
154 |
+
}
|
155 |
+
|
156 |
+
return implode(' || ', $ranges);
|
157 |
+
}
|
158 |
+
|
159 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* @param string $packageName
|
164 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
165 |
+
*/
|
166 |
+
public static function getVersion($packageName)
|
167 |
+
{
|
168 |
+
foreach (self::getInstalled() as $installed) {
|
169 |
+
if (!isset($installed['versions'][$packageName])) {
|
170 |
+
continue;
|
171 |
+
}
|
172 |
+
|
173 |
+
if (!isset($installed['versions'][$packageName]['version'])) {
|
174 |
+
return null;
|
175 |
+
}
|
176 |
+
|
177 |
+
return $installed['versions'][$packageName]['version'];
|
178 |
+
}
|
179 |
+
|
180 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* @param string $packageName
|
185 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
186 |
+
*/
|
187 |
+
public static function getPrettyVersion($packageName)
|
188 |
+
{
|
189 |
+
foreach (self::getInstalled() as $installed) {
|
190 |
+
if (!isset($installed['versions'][$packageName])) {
|
191 |
+
continue;
|
192 |
+
}
|
193 |
+
|
194 |
+
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
195 |
+
return null;
|
196 |
+
}
|
197 |
+
|
198 |
+
return $installed['versions'][$packageName]['pretty_version'];
|
199 |
+
}
|
200 |
+
|
201 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* @param string $packageName
|
206 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
207 |
+
*/
|
208 |
+
public static function getReference($packageName)
|
209 |
+
{
|
210 |
+
foreach (self::getInstalled() as $installed) {
|
211 |
+
if (!isset($installed['versions'][$packageName])) {
|
212 |
+
continue;
|
213 |
+
}
|
214 |
+
|
215 |
+
if (!isset($installed['versions'][$packageName]['reference'])) {
|
216 |
+
return null;
|
217 |
+
}
|
218 |
+
|
219 |
+
return $installed['versions'][$packageName]['reference'];
|
220 |
+
}
|
221 |
+
|
222 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* @param string $packageName
|
227 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
228 |
+
*/
|
229 |
+
public static function getInstallPath($packageName)
|
230 |
+
{
|
231 |
+
foreach (self::getInstalled() as $installed) {
|
232 |
+
if (!isset($installed['versions'][$packageName])) {
|
233 |
+
continue;
|
234 |
+
}
|
235 |
+
|
236 |
+
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
237 |
+
}
|
238 |
+
|
239 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* @return array
|
244 |
+
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
|
245 |
+
*/
|
246 |
+
public static function getRootPackage()
|
247 |
+
{
|
248 |
+
$installed = self::getInstalled();
|
249 |
+
|
250 |
+
return $installed[0]['root'];
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Returns the raw installed.php data for custom implementations
|
255 |
+
*
|
256 |
+
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
257 |
+
* @return array[]
|
258 |
+
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
|
259 |
+
*/
|
260 |
+
public static function getRawData()
|
261 |
+
{
|
262 |
+
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
263 |
+
|
264 |
+
if (null === self::$installed) {
|
265 |
+
// only require the installed.php file if this file is loaded from its dumped location,
|
266 |
+
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
267 |
+
if (substr(__DIR__, -8, 1) !== 'C') {
|
268 |
+
self::$installed = include __DIR__ . '/installed.php';
|
269 |
+
} else {
|
270 |
+
self::$installed = array();
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
return self::$installed;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
279 |
+
*
|
280 |
+
* @return array[]
|
281 |
+
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
282 |
+
*/
|
283 |
+
public static function getAllRawData()
|
284 |
+
{
|
285 |
+
return self::getInstalled();
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Lets you reload the static array from another file
|
290 |
+
*
|
291 |
+
* This is only useful for complex integrations in which a project needs to use
|
292 |
+
* this class but then also needs to execute another project's autoloader in process,
|
293 |
+
* and wants to ensure both projects have access to their version of installed.php.
|
294 |
+
*
|
295 |
+
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
296 |
+
* the data it needs from this class, then call reload() with
|
297 |
+
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
298 |
+
* the project in which it runs can then also use this class safely, without
|
299 |
+
* interference between PHPUnit's dependencies and the project's dependencies.
|
300 |
+
*
|
301 |
+
* @param array[] $data A vendor/composer/installed.php data set
|
302 |
+
* @return void
|
303 |
+
*
|
304 |
+
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
|
305 |
+
*/
|
306 |
+
public static function reload($data)
|
307 |
+
{
|
308 |
+
self::$installed = $data;
|
309 |
+
self::$installedByVendor = array();
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* @return array[]
|
314 |
+
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
315 |
+
*/
|
316 |
+
private static function getInstalled()
|
317 |
+
{
|
318 |
+
if (null === self::$canGetVendors) {
|
319 |
+
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
320 |
+
}
|
321 |
+
|
322 |
+
$installed = array();
|
323 |
+
|
324 |
+
if (self::$canGetVendors) {
|
325 |
+
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
326 |
+
if (isset(self::$installedByVendor[$vendorDir])) {
|
327 |
+
$installed[] = self::$installedByVendor[$vendorDir];
|
328 |
+
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
329 |
+
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
330 |
+
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
331 |
+
self::$installed = $installed[count($installed) - 1];
|
332 |
+
}
|
333 |
+
}
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
if (null === self::$installed) {
|
338 |
+
// only require the installed.php file if this file is loaded from its dumped location,
|
339 |
+
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
340 |
+
if (substr(__DIR__, -8, 1) !== 'C') {
|
341 |
+
self::$installed = require __DIR__ . '/installed.php';
|
342 |
+
} else {
|
343 |
+
self::$installed = array();
|
344 |
+
}
|
345 |
+
}
|
346 |
+
$installed[] = self::$installed;
|
347 |
+
|
348 |
+
return $installed;
|
349 |
+
}
|
350 |
}
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -7,36 +7,139 @@ $baseDir = dirname($vendorDir);
|
|
7 |
|
8 |
return array(
|
9 |
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
10 |
-
'
|
11 |
-
'
|
12 |
-
'
|
13 |
-
'
|
14 |
-
'
|
15 |
-
'
|
16 |
-
'
|
17 |
-
'
|
18 |
-
'
|
19 |
-
'
|
20 |
-
'
|
21 |
-
'
|
22 |
-
'
|
23 |
-
'
|
24 |
-
'
|
25 |
-
'
|
26 |
-
'
|
27 |
-
'
|
28 |
-
'
|
29 |
-
'
|
30 |
-
'
|
31 |
-
'
|
32 |
-
'
|
33 |
-
'
|
34 |
-
'
|
35 |
-
'
|
36 |
-
'
|
37 |
-
'
|
38 |
-
'
|
39 |
-
'
|
40 |
-
'
|
41 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
);
|
7 |
|
8 |
return array(
|
9 |
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
10 |
+
'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php',
|
11 |
+
'Composer\\Installers\\AimeosInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
|
12 |
+
'Composer\\Installers\\AnnotateCmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
|
13 |
+
'Composer\\Installers\\AsgardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
|
14 |
+
'Composer\\Installers\\AttogramInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
|
15 |
+
'Composer\\Installers\\BaseInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
|
16 |
+
'Composer\\Installers\\BitrixInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
|
17 |
+
'Composer\\Installers\\BonefishInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
|
18 |
+
'Composer\\Installers\\CakePHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
|
19 |
+
'Composer\\Installers\\ChefInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
|
20 |
+
'Composer\\Installers\\CiviCrmInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CiviCrmInstaller.php',
|
21 |
+
'Composer\\Installers\\ClanCatsFrameworkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
|
22 |
+
'Composer\\Installers\\CockpitInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
|
23 |
+
'Composer\\Installers\\CodeIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
|
24 |
+
'Composer\\Installers\\Concrete5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
|
25 |
+
'Composer\\Installers\\CraftInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
|
26 |
+
'Composer\\Installers\\CroogoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
|
27 |
+
'Composer\\Installers\\DecibelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
|
28 |
+
'Composer\\Installers\\DframeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
|
29 |
+
'Composer\\Installers\\DokuWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
|
30 |
+
'Composer\\Installers\\DolibarrInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
|
31 |
+
'Composer\\Installers\\DrupalInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
|
32 |
+
'Composer\\Installers\\ElggInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
|
33 |
+
'Composer\\Installers\\EliasisInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
|
34 |
+
'Composer\\Installers\\ExpressionEngineInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
|
35 |
+
'Composer\\Installers\\EzPlatformInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php',
|
36 |
+
'Composer\\Installers\\FuelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
|
37 |
+
'Composer\\Installers\\FuelphpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
|
38 |
+
'Composer\\Installers\\GravInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/GravInstaller.php',
|
39 |
+
'Composer\\Installers\\HuradInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
|
40 |
+
'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
|
41 |
+
'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
|
42 |
+
'Composer\\Installers\\ItopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
|
43 |
+
'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
|
44 |
+
'Composer\\Installers\\KanboardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
|
45 |
+
'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
|
46 |
+
'Composer\\Installers\\KnownInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
|
47 |
+
'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
|
48 |
+
'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
|
49 |
+
'Composer\\Installers\\LanManagementSystemInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php',
|
50 |
+
'Composer\\Installers\\LaravelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
|
51 |
+
'Composer\\Installers\\LavaLiteInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
|
52 |
+
'Composer\\Installers\\LithiumInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
|
53 |
+
'Composer\\Installers\\MODULEWorkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
|
54 |
+
'Composer\\Installers\\MODXEvoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
|
55 |
+
'Composer\\Installers\\MagentoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
|
56 |
+
'Composer\\Installers\\MajimaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
|
57 |
+
'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
|
58 |
+
'Composer\\Installers\\MantisBTInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
|
59 |
+
'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
|
60 |
+
'Composer\\Installers\\MayaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
|
61 |
+
'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
|
62 |
+
'Composer\\Installers\\MiaoxingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MiaoxingInstaller.php',
|
63 |
+
'Composer\\Installers\\MicroweberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
|
64 |
+
'Composer\\Installers\\ModxInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ModxInstaller.php',
|
65 |
+
'Composer\\Installers\\MoodleInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
|
66 |
+
'Composer\\Installers\\OctoberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
|
67 |
+
'Composer\\Installers\\OntoWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
|
68 |
+
'Composer\\Installers\\OsclassInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OsclassInstaller.php',
|
69 |
+
'Composer\\Installers\\OxidInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
|
70 |
+
'Composer\\Installers\\PPIInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
|
71 |
+
'Composer\\Installers\\PantheonInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
|
72 |
+
'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
|
73 |
+
'Composer\\Installers\\PhpBBInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
|
74 |
+
'Composer\\Installers\\PimcoreInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
|
75 |
+
'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
|
76 |
+
'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
|
77 |
+
'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
|
78 |
+
'Composer\\Installers\\PortoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
|
79 |
+
'Composer\\Installers\\PrestashopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
|
80 |
+
'Composer\\Installers\\ProcessWireInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ProcessWireInstaller.php',
|
81 |
+
'Composer\\Installers\\PuppetInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
|
82 |
+
'Composer\\Installers\\PxcmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php',
|
83 |
+
'Composer\\Installers\\RadPHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
|
84 |
+
'Composer\\Installers\\ReIndexInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php',
|
85 |
+
'Composer\\Installers\\Redaxo5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Redaxo5Installer.php',
|
86 |
+
'Composer\\Installers\\RedaxoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
|
87 |
+
'Composer\\Installers\\RoundcubeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
|
88 |
+
'Composer\\Installers\\SMFInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
|
89 |
+
'Composer\\Installers\\ShopwareInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
|
90 |
+
'Composer\\Installers\\SilverStripeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
|
91 |
+
'Composer\\Installers\\SiteDirectInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php',
|
92 |
+
'Composer\\Installers\\StarbugInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
|
93 |
+
'Composer\\Installers\\SyDESInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
|
94 |
+
'Composer\\Installers\\SyliusInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
|
95 |
+
'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
|
96 |
+
'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
|
97 |
+
'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
|
98 |
+
'Composer\\Installers\\TaoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
|
99 |
+
'Composer\\Installers\\TastyIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
|
100 |
+
'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
|
101 |
+
'Composer\\Installers\\TuskInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
|
102 |
+
'Composer\\Installers\\UserFrostingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php',
|
103 |
+
'Composer\\Installers\\VanillaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
|
104 |
+
'Composer\\Installers\\VgmcpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
|
105 |
+
'Composer\\Installers\\WHMCSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
|
106 |
+
'Composer\\Installers\\WinterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WinterInstaller.php',
|
107 |
+
'Composer\\Installers\\WolfCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
|
108 |
+
'Composer\\Installers\\WordPressInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
|
109 |
+
'Composer\\Installers\\YawikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
|
110 |
+
'Composer\\Installers\\ZendInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
|
111 |
+
'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
|
112 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options' => $baseDir . '/src/admin/options.php',
|
113 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options_Form_Generator' => $baseDir . '/src/admin/options-form-generator.php',
|
114 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options_Inputs' => $baseDir . '/src/admin/options-inputs.php',
|
115 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options_Page' => $baseDir . '/src/admin/options-page.php',
|
116 |
+
'Yoast\\WP\\Duplicate_Post\\Duplicate_Post' => $baseDir . '/src/duplicate-post.php',
|
117 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Bulk_Handler' => $baseDir . '/src/handlers/bulk-handler.php',
|
118 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Check_Changes_Handler' => $baseDir . '/src/handlers/check-changes-handler.php',
|
119 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Handler' => $baseDir . '/src/handlers/handler.php',
|
120 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Link_Handler' => $baseDir . '/src/handlers/link-handler.php',
|
121 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Save_Post_Handler' => $baseDir . '/src/handlers/save-post-handler.php',
|
122 |
+
'Yoast\\WP\\Duplicate_Post\\Permissions_Helper' => $baseDir . '/src/permissions-helper.php',
|
123 |
+
'Yoast\\WP\\Duplicate_Post\\Post_Duplicator' => $baseDir . '/src/post-duplicator.php',
|
124 |
+
'Yoast\\WP\\Duplicate_Post\\Post_Republisher' => $baseDir . '/src/post-republisher.php',
|
125 |
+
'Yoast\\WP\\Duplicate_Post\\Revisions_Migrator' => $baseDir . '/src/revisions-migrator.php',
|
126 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Admin_Bar' => $baseDir . '/src/ui/admin-bar.php',
|
127 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Asset_Manager' => $baseDir . '/src/ui/asset-manager.php',
|
128 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Block_Editor' => $baseDir . '/src/ui/block-editor.php',
|
129 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Bulk_Actions' => $baseDir . '/src/ui/bulk-actions.php',
|
130 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Classic_Editor' => $baseDir . '/src/ui/classic-editor.php',
|
131 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Column' => $baseDir . '/src/ui/column.php',
|
132 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Link_Builder' => $baseDir . '/src/ui/link-builder.php',
|
133 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Metabox' => $baseDir . '/src/ui/metabox.php',
|
134 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Newsletter' => $baseDir . '/src/ui/newsletter.php',
|
135 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Post_States' => $baseDir . '/src/ui/post-states.php',
|
136 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Row_Actions' => $baseDir . '/src/ui/row-actions.php',
|
137 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\User_Interface' => $baseDir . '/src/ui/user-interface.php',
|
138 |
+
'Yoast\\WP\\Duplicate_Post\\Utils' => $baseDir . '/src/utils.php',
|
139 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Bulk_Actions_Watcher' => $baseDir . '/src/watchers/bulk-actions-watcher.php',
|
140 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Copied_Post_Watcher' => $baseDir . '/src/watchers/copied-post-watcher.php',
|
141 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Link_Actions_Watcher' => $baseDir . '/src/watchers/link-actions-watcher.php',
|
142 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Original_Post_Watcher' => $baseDir . '/src/watchers/original-post-watcher.php',
|
143 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Republished_Post_Watcher' => $baseDir . '/src/watchers/republished-post-watcher.php',
|
144 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Watchers' => $baseDir . '/src/watchers/watchers.php',
|
145 |
);
|
vendor/composer/autoload_psr4.php
CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
|
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
|
|
9 |
);
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
9 |
+
'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
|
10 |
);
|
vendor/composer/autoload_real.php
CHANGED
@@ -22,6 +22,8 @@ class ComposerAutoloaderInitb771dd36b1819b8209dfac03b31cc9ed
|
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
|
|
|
|
25 |
spl_autoload_register(array('ComposerAutoloaderInitb771dd36b1819b8209dfac03b31cc9ed', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
27 |
spl_autoload_unregister(array('ComposerAutoloaderInitb771dd36b1819b8209dfac03b31cc9ed', 'loadClassLoader'));
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
require __DIR__ . '/platform_check.php';
|
26 |
+
|
27 |
spl_autoload_register(array('ComposerAutoloaderInitb771dd36b1819b8209dfac03b31cc9ed', 'loadClassLoader'), true, true);
|
28 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
29 |
spl_autoload_unregister(array('ComposerAutoloaderInitb771dd36b1819b8209dfac03b31cc9ed', 'loadClassLoader'));
|
vendor/composer/autoload_static.php
CHANGED
@@ -6,45 +6,164 @@ namespace Composer\Autoload;
|
|
6 |
|
7 |
class ComposerStaticInitb771dd36b1819b8209dfac03b31cc9ed
|
8 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
public static $classMap = array (
|
10 |
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
11 |
-
'
|
12 |
-
'
|
13 |
-
'
|
14 |
-
'
|
15 |
-
'
|
16 |
-
'
|
17 |
-
'
|
18 |
-
'
|
19 |
-
'
|
20 |
-
'
|
21 |
-
'
|
22 |
-
'
|
23 |
-
'
|
24 |
-
'
|
25 |
-
'
|
26 |
-
'
|
27 |
-
'
|
28 |
-
'
|
29 |
-
'
|
30 |
-
'
|
31 |
-
'
|
32 |
-
'
|
33 |
-
'
|
34 |
-
'
|
35 |
-
'
|
36 |
-
'
|
37 |
-
'
|
38 |
-
'
|
39 |
-
'
|
40 |
-
'
|
41 |
-
'
|
42 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
);
|
44 |
|
45 |
public static function getInitializer(ClassLoader $loader)
|
46 |
{
|
47 |
return \Closure::bind(function () use ($loader) {
|
|
|
|
|
48 |
$loader->classMap = ComposerStaticInitb771dd36b1819b8209dfac03b31cc9ed::$classMap;
|
49 |
|
50 |
}, null, ClassLoader::class);
|
6 |
|
7 |
class ComposerStaticInitb771dd36b1819b8209dfac03b31cc9ed
|
8 |
{
|
9 |
+
public static $prefixLengthsPsr4 = array (
|
10 |
+
'C' =>
|
11 |
+
array (
|
12 |
+
'Composer\\Installers\\' => 20,
|
13 |
+
),
|
14 |
+
);
|
15 |
+
|
16 |
+
public static $prefixDirsPsr4 = array (
|
17 |
+
'Composer\\Installers\\' =>
|
18 |
+
array (
|
19 |
+
0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
|
20 |
+
),
|
21 |
+
);
|
22 |
+
|
23 |
public static $classMap = array (
|
24 |
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
25 |
+
'Composer\\Installers\\AglInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AglInstaller.php',
|
26 |
+
'Composer\\Installers\\AimeosInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
|
27 |
+
'Composer\\Installers\\AnnotateCmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
|
28 |
+
'Composer\\Installers\\AsgardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
|
29 |
+
'Composer\\Installers\\AttogramInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
|
30 |
+
'Composer\\Installers\\BaseInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
|
31 |
+
'Composer\\Installers\\BitrixInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
|
32 |
+
'Composer\\Installers\\BonefishInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
|
33 |
+
'Composer\\Installers\\CakePHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
|
34 |
+
'Composer\\Installers\\ChefInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
|
35 |
+
'Composer\\Installers\\CiviCrmInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CiviCrmInstaller.php',
|
36 |
+
'Composer\\Installers\\ClanCatsFrameworkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
|
37 |
+
'Composer\\Installers\\CockpitInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
|
38 |
+
'Composer\\Installers\\CodeIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
|
39 |
+
'Composer\\Installers\\Concrete5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
|
40 |
+
'Composer\\Installers\\CraftInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
|
41 |
+
'Composer\\Installers\\CroogoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
|
42 |
+
'Composer\\Installers\\DecibelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
|
43 |
+
'Composer\\Installers\\DframeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
|
44 |
+
'Composer\\Installers\\DokuWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
|
45 |
+
'Composer\\Installers\\DolibarrInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
|
46 |
+
'Composer\\Installers\\DrupalInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
|
47 |
+
'Composer\\Installers\\ElggInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
|
48 |
+
'Composer\\Installers\\EliasisInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
|
49 |
+
'Composer\\Installers\\ExpressionEngineInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
|
50 |
+
'Composer\\Installers\\EzPlatformInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php',
|
51 |
+
'Composer\\Installers\\FuelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
|
52 |
+
'Composer\\Installers\\FuelphpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
|
53 |
+
'Composer\\Installers\\GravInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/GravInstaller.php',
|
54 |
+
'Composer\\Installers\\HuradInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
|
55 |
+
'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
|
56 |
+
'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
|
57 |
+
'Composer\\Installers\\ItopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
|
58 |
+
'Composer\\Installers\\JoomlaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
|
59 |
+
'Composer\\Installers\\KanboardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
|
60 |
+
'Composer\\Installers\\KirbyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
|
61 |
+
'Composer\\Installers\\KnownInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
|
62 |
+
'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
|
63 |
+
'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
|
64 |
+
'Composer\\Installers\\LanManagementSystemInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php',
|
65 |
+
'Composer\\Installers\\LaravelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
|
66 |
+
'Composer\\Installers\\LavaLiteInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
|
67 |
+
'Composer\\Installers\\LithiumInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
|
68 |
+
'Composer\\Installers\\MODULEWorkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
|
69 |
+
'Composer\\Installers\\MODXEvoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
|
70 |
+
'Composer\\Installers\\MagentoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
|
71 |
+
'Composer\\Installers\\MajimaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
|
72 |
+
'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
|
73 |
+
'Composer\\Installers\\MantisBTInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
|
74 |
+
'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
|
75 |
+
'Composer\\Installers\\MayaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
|
76 |
+
'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
|
77 |
+
'Composer\\Installers\\MiaoxingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MiaoxingInstaller.php',
|
78 |
+
'Composer\\Installers\\MicroweberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
|
79 |
+
'Composer\\Installers\\ModxInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ModxInstaller.php',
|
80 |
+
'Composer\\Installers\\MoodleInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
|
81 |
+
'Composer\\Installers\\OctoberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
|
82 |
+
'Composer\\Installers\\OntoWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
|
83 |
+
'Composer\\Installers\\OsclassInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OsclassInstaller.php',
|
84 |
+
'Composer\\Installers\\OxidInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
|
85 |
+
'Composer\\Installers\\PPIInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
|
86 |
+
'Composer\\Installers\\PantheonInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
|
87 |
+
'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
|
88 |
+
'Composer\\Installers\\PhpBBInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
|
89 |
+
'Composer\\Installers\\PimcoreInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
|
90 |
+
'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
|
91 |
+
'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
|
92 |
+
'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
|
93 |
+
'Composer\\Installers\\PortoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
|
94 |
+
'Composer\\Installers\\PrestashopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
|
95 |
+
'Composer\\Installers\\ProcessWireInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ProcessWireInstaller.php',
|
96 |
+
'Composer\\Installers\\PuppetInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
|
97 |
+
'Composer\\Installers\\PxcmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php',
|
98 |
+
'Composer\\Installers\\RadPHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
|
99 |
+
'Composer\\Installers\\ReIndexInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php',
|
100 |
+
'Composer\\Installers\\Redaxo5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Redaxo5Installer.php',
|
101 |
+
'Composer\\Installers\\RedaxoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
|
102 |
+
'Composer\\Installers\\RoundcubeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
|
103 |
+
'Composer\\Installers\\SMFInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
|
104 |
+
'Composer\\Installers\\ShopwareInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
|
105 |
+
'Composer\\Installers\\SilverStripeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
|
106 |
+
'Composer\\Installers\\SiteDirectInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php',
|
107 |
+
'Composer\\Installers\\StarbugInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
|
108 |
+
'Composer\\Installers\\SyDESInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
|
109 |
+
'Composer\\Installers\\SyliusInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
|
110 |
+
'Composer\\Installers\\Symfony1Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
|
111 |
+
'Composer\\Installers\\TYPO3CmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
|
112 |
+
'Composer\\Installers\\TYPO3FlowInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
|
113 |
+
'Composer\\Installers\\TaoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
|
114 |
+
'Composer\\Installers\\TastyIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
|
115 |
+
'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
|
116 |
+
'Composer\\Installers\\TuskInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
|
117 |
+
'Composer\\Installers\\UserFrostingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php',
|
118 |
+
'Composer\\Installers\\VanillaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
|
119 |
+
'Composer\\Installers\\VgmcpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
|
120 |
+
'Composer\\Installers\\WHMCSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
|
121 |
+
'Composer\\Installers\\WinterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WinterInstaller.php',
|
122 |
+
'Composer\\Installers\\WolfCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
|
123 |
+
'Composer\\Installers\\WordPressInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
|
124 |
+
'Composer\\Installers\\YawikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
|
125 |
+
'Composer\\Installers\\ZendInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
|
126 |
+
'Composer\\Installers\\ZikulaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
|
127 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options' => __DIR__ . '/../..' . '/src/admin/options.php',
|
128 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options_Form_Generator' => __DIR__ . '/../..' . '/src/admin/options-form-generator.php',
|
129 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options_Inputs' => __DIR__ . '/../..' . '/src/admin/options-inputs.php',
|
130 |
+
'Yoast\\WP\\Duplicate_Post\\Admin\\Options_Page' => __DIR__ . '/../..' . '/src/admin/options-page.php',
|
131 |
+
'Yoast\\WP\\Duplicate_Post\\Duplicate_Post' => __DIR__ . '/../..' . '/src/duplicate-post.php',
|
132 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Bulk_Handler' => __DIR__ . '/../..' . '/src/handlers/bulk-handler.php',
|
133 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Check_Changes_Handler' => __DIR__ . '/../..' . '/src/handlers/check-changes-handler.php',
|
134 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Handler' => __DIR__ . '/../..' . '/src/handlers/handler.php',
|
135 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Link_Handler' => __DIR__ . '/../..' . '/src/handlers/link-handler.php',
|
136 |
+
'Yoast\\WP\\Duplicate_Post\\Handlers\\Save_Post_Handler' => __DIR__ . '/../..' . '/src/handlers/save-post-handler.php',
|
137 |
+
'Yoast\\WP\\Duplicate_Post\\Permissions_Helper' => __DIR__ . '/../..' . '/src/permissions-helper.php',
|
138 |
+
'Yoast\\WP\\Duplicate_Post\\Post_Duplicator' => __DIR__ . '/../..' . '/src/post-duplicator.php',
|
139 |
+
'Yoast\\WP\\Duplicate_Post\\Post_Republisher' => __DIR__ . '/../..' . '/src/post-republisher.php',
|
140 |
+
'Yoast\\WP\\Duplicate_Post\\Revisions_Migrator' => __DIR__ . '/../..' . '/src/revisions-migrator.php',
|
141 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Admin_Bar' => __DIR__ . '/../..' . '/src/ui/admin-bar.php',
|
142 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Asset_Manager' => __DIR__ . '/../..' . '/src/ui/asset-manager.php',
|
143 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Block_Editor' => __DIR__ . '/../..' . '/src/ui/block-editor.php',
|
144 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Bulk_Actions' => __DIR__ . '/../..' . '/src/ui/bulk-actions.php',
|
145 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Classic_Editor' => __DIR__ . '/../..' . '/src/ui/classic-editor.php',
|
146 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Column' => __DIR__ . '/../..' . '/src/ui/column.php',
|
147 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Link_Builder' => __DIR__ . '/../..' . '/src/ui/link-builder.php',
|
148 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Metabox' => __DIR__ . '/../..' . '/src/ui/metabox.php',
|
149 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Newsletter' => __DIR__ . '/../..' . '/src/ui/newsletter.php',
|
150 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Post_States' => __DIR__ . '/../..' . '/src/ui/post-states.php',
|
151 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\Row_Actions' => __DIR__ . '/../..' . '/src/ui/row-actions.php',
|
152 |
+
'Yoast\\WP\\Duplicate_Post\\UI\\User_Interface' => __DIR__ . '/../..' . '/src/ui/user-interface.php',
|
153 |
+
'Yoast\\WP\\Duplicate_Post\\Utils' => __DIR__ . '/../..' . '/src/utils.php',
|
154 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Bulk_Actions_Watcher' => __DIR__ . '/../..' . '/src/watchers/bulk-actions-watcher.php',
|
155 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Copied_Post_Watcher' => __DIR__ . '/../..' . '/src/watchers/copied-post-watcher.php',
|
156 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Link_Actions_Watcher' => __DIR__ . '/../..' . '/src/watchers/link-actions-watcher.php',
|
157 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Original_Post_Watcher' => __DIR__ . '/../..' . '/src/watchers/original-post-watcher.php',
|
158 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Republished_Post_Watcher' => __DIR__ . '/../..' . '/src/watchers/republished-post-watcher.php',
|
159 |
+
'Yoast\\WP\\Duplicate_Post\\Watchers\\Watchers' => __DIR__ . '/../..' . '/src/watchers/watchers.php',
|
160 |
);
|
161 |
|
162 |
public static function getInitializer(ClassLoader $loader)
|
163 |
{
|
164 |
return \Closure::bind(function () use ($loader) {
|
165 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInitb771dd36b1819b8209dfac03b31cc9ed::$prefixLengthsPsr4;
|
166 |
+
$loader->prefixDirsPsr4 = ComposerStaticInitb771dd36b1819b8209dfac03b31cc9ed::$prefixDirsPsr4;
|
167 |
$loader->classMap = ComposerStaticInitb771dd36b1819b8209dfac03b31cc9ed::$classMap;
|
168 |
|
169 |
}, null, ClassLoader::class);
|
vendor/composer/installed.php
CHANGED
@@ -1,24 +1,44 @@
|
|
1 |
-
<?php return array
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
|
|
|
|
|
|
8 |
),
|
9 |
-
'
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
),
|
23 |
-
),
|
24 |
);
|
1 |
+
<?php return array(
|
2 |
+
'root' => array(
|
3 |
+
'pretty_version' => 'dev-master',
|
4 |
+
'version' => 'dev-master',
|
5 |
+
'type' => 'wordpress-plugin',
|
6 |
+
'install_path' => __DIR__ . '/../../',
|
7 |
+
'aliases' => array(),
|
8 |
+
'reference' => '95ce770dd62b0a430e53adcd2cbdd36d33b89fa4',
|
9 |
+
'name' => 'yoast/duplicate-post',
|
10 |
+
'dev' => false,
|
11 |
),
|
12 |
+
'versions' => array(
|
13 |
+
'composer/installers' => array(
|
14 |
+
'pretty_version' => 'v1.12.0',
|
15 |
+
'version' => '1.12.0.0',
|
16 |
+
'type' => 'composer-plugin',
|
17 |
+
'install_path' => __DIR__ . '/./installers',
|
18 |
+
'aliases' => array(),
|
19 |
+
'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19',
|
20 |
+
'dev_requirement' => false,
|
21 |
+
),
|
22 |
+
'roundcube/plugin-installer' => array(
|
23 |
+
'dev_requirement' => false,
|
24 |
+
'replaced' => array(
|
25 |
+
0 => '*',
|
26 |
+
),
|
27 |
+
),
|
28 |
+
'shama/baton' => array(
|
29 |
+
'dev_requirement' => false,
|
30 |
+
'replaced' => array(
|
31 |
+
0 => '*',
|
32 |
+
),
|
33 |
+
),
|
34 |
+
'yoast/duplicate-post' => array(
|
35 |
+
'pretty_version' => 'dev-master',
|
36 |
+
'version' => 'dev-master',
|
37 |
+
'type' => 'wordpress-plugin',
|
38 |
+
'install_path' => __DIR__ . '/../../',
|
39 |
+
'aliases' => array(),
|
40 |
+
'reference' => '95ce770dd62b0a430e53adcd2cbdd36d33b89fa4',
|
41 |
+
'dev_requirement' => false,
|
42 |
+
),
|
43 |
),
|
|
|
44 |
);
|
vendor/composer/platform_check.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// platform_check.php @generated by Composer
|
4 |
+
|
5 |
+
$issues = array();
|
6 |
+
|
7 |
+
if (!(PHP_VERSION_ID >= 50600)) {
|
8 |
+
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
|
9 |
+
}
|
10 |
+
|
11 |
+
if ($issues) {
|
12 |
+
if (!headers_sent()) {
|
13 |
+
header('HTTP/1.1 500 Internal Server Error');
|
14 |
+
}
|
15 |
+
if (!ini_get('display_errors')) {
|
16 |
+
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
17 |
+
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
18 |
+
} elseif (!headers_sent()) {
|
19 |
+
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
trigger_error(
|
23 |
+
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
24 |
+
E_USER_ERROR
|
25 |
+
);
|
26 |
+
}
|