PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.5.6
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.5.6
4.5.6 4.5.5 4.5.4 4.2.1 4.2.2 4.2.3 4.5.0 4.5.2 4.5.3 4.2.0 4.1.18 4.1.17 4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.0.9 4.1.0 4.1.1 4.1.2 All 148 releases
← All changes | includes/class-duplicator.php +51 -21 4.2.0 → 4.5.6 View file →
@@ -12,13 +12,13 @@
12 12 /**
13 13 * Duplicator Class
14 14 */
15 15
16 -if (!class_exists('BdThemes_Duplicator')) :
16 +if (!class_exists(__NAMESPACE__ . '\\BdThemes_Duplicator')) :
17 17 class BdThemes_Duplicator {
18 18
19 19 public function __construct() {
20 - add_action('admin_action_bdt_duplicate_as_draft', [$this, 'bdt_duplicate_as_draft']);
20 + add_action('admin_action_ultimate_post_kit_duplicate_as_draft', [$this, 'bdt_duplicate_as_draft']);
21 21 add_filter('post_row_actions', [$this, 'bdt_duplicate_post_link'], 10, 2);
22 22 add_filter('page_row_actions', [$this, 'bdt_duplicate_post_link'], 10, 2);
23 23 }
24 24
@@ -27,40 +27,61 @@
27 27 if (!current_user_can('edit_posts')) {
28 28 wp_die('You don\'t have permission to duplicate it; please go back!');
29 29 }
30 30
31 - if (!(isset($_GET['post']) || isset($_POST['post']) || (isset($_REQUEST['action']) && 'bdt_duplicate_as_draft' == $_REQUEST['action']))) {
31 + if (!(isset($_GET['post']) || isset($_POST['post']) || (isset($_REQUEST['action']) && 'ultimate_post_kit_duplicate_as_draft' == $_REQUEST['action']))) {
32 32 wp_die('No post to duplicate has been supplied!');
33 33 }
34 34
35 35 /**
36 - * Nonce verification
36 + * get the original post id
37 + *
38 + * This has to be read before the nonce check because the nonce action is bound
39 + * to the post being duplicated (see bdt_duplicate_post_link()). The value is
40 + * cast to an integer and used only to build that action string; nothing is read
41 + * or written with it until the nonce and capability checks below have passed.
37 42 */
38 - if (!isset($_GET['duplicate_nonce']) || !wp_verify_nonce($_GET['duplicate_nonce'], basename(__FILE__))) {
43 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- only used to construct the nonce action, which is verified on the next statement.
44 + $post_id = isset($_GET['post']) ? absint($_GET['post']) : absint($_POST['post'] ?? 0);
45 +
46 + /**
47 + * Nonce verification.
48 + *
49 + * The nonce is bound to the post being duplicated, so one nonce cannot be
50 + * replayed against every other post (and post type) on the site.
51 + */
52 + if (!isset($_GET['duplicate_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['duplicate_nonce'])), 'upk_duplicate_post_' . $post_id)) {
39 53 return;
40 54 }
41 55
42 56 /**
43 - * get the original post id
44 - */
45 - $post_id = (isset($_GET['post']) ? absint($_GET['post']) : absint($_POST['post']));
46 - /**
47 57 * and all the original post data then
48 58 */
49 59 $post = get_post($post_id);
50 60
61 + if (!$post) {
62 + wp_die(esc_html('Failed. Not Found Post: ' . $post_id));
63 + }
64 +
51 65 /**
52 - * if you don't want current user to be the new post author,
66 + * Authorise against THIS post, not against a generic role capability.
67 + *
68 + * edit_others_posts is only the capability for the built-in 'post' type; it
69 + * grants nothing over a post type registered with its own capability set. Use
70 + * the meta capability so WordPress maps it through the target post type, and
71 + * check create_posts separately because duplicating creates a new object.
53 72 */
54 - $current_user_id = get_current_user_id();
73 + if (!current_user_can('edit_post', $post_id)) {
74 + wp_die('You don\'t have permission to duplicate it; please go back!');
75 + }
55 76
56 - if (current_user_can('manage_options') || current_user_can('edit_others_posts')) {
57 - $this->duplicate_edit_post($post_id);
58 - } else if (current_user_can('edit_posts') && $post->post_author == $current_user_id) {
59 - $this->duplicate_edit_post($post_id);
60 - } else {
77 + $post_type_object = get_post_type_object($post->post_type);
78 +
79 + if (!$post_type_object || !current_user_can($post_type_object->cap->create_posts)) {
61 80 wp_die('You don\'t have permission to duplicate it; please go back!');
62 81 }
82 +
83 + $this->duplicate_edit_post($post_id);
63 84 }
64 85
65 86 /**
66 87 * duplicate edit post
@@ -180,15 +201,15 @@
180 201
181 202
182 203 public function bdt_duplicate_post_link($actions, $post) {
183 204
184 - if (current_user_can('manage_options') || current_user_can('edit_others_posts')) {
205 + if (current_user_can('edit_post', $post->ID)) {
185 206 if ($post->post_type == 'post') {
186 - $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=bdt_duplicate_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce') . '" title="Duplicate this post" rel="permalink">' . esc_html_x("Duplicate Post", "Admin String", "ultimate-post-kit") . '</a>';
207 + $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=ultimate_post_kit_duplicate_as_draft&post=' . $post->ID, 'upk_duplicate_post_' . $post->ID, 'duplicate_nonce') . '" title="Duplicate this post" rel="permalink">' . esc_html_x("Duplicate Post", "Admin String", "ultimate-post-kit") . '</a>';
187 208 } elseif ($post->post_type == 'page') {
188 - $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=bdt_duplicate_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce') . '" title="Duplicate this page" rel="permalink">' . esc_html_x("Duplicate Page", "Admin String", "ultimate-post-kit") . '</a>';
209 + $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=ultimate_post_kit_duplicate_as_draft&post=' . $post->ID, 'upk_duplicate_post_' . $post->ID, 'duplicate_nonce') . '" title="Duplicate this page" rel="permalink">' . esc_html_x("Duplicate Page", "Admin String", "ultimate-post-kit") . '</a>';
189 210 } elseif ($post->post_type == 'elementor_library') {
190 - $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=bdt_duplicate_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce') . '" title="Duplicate this template" rel="permalink">' . esc_html_x("Duplicate Template", "Admin String", "ultimate-post-kit") . '</a>';
211 + $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=ultimate_post_kit_duplicate_as_draft&post=' . $post->ID, 'upk_duplicate_post_' . $post->ID, 'duplicate_nonce') . '" title="Duplicate this template" rel="permalink">' . esc_html_x("Duplicate Template", "Admin String", "ultimate-post-kit") . '</a>';
191 212 }
192 213 }
193 214 return $actions;
194 215 }
@@ -194,6 +215,15 @@
194 215 }
195 216 }
196 217 endif;
197 218
198 -
219 +/**
220 + * Instantiate the namespaced class.
221 + *
222 + * The guard above and this statement must resolve to the same class. An
223 + * unqualified class_exists() string is always resolved against the global
224 + * namespace, so a sibling plugin declaring a global \BdThemes_Duplicator
225 + * (Live Copy Paste does) used to satisfy the old guard and skip the
226 + * declaration, while this line still asked for
227 + * UltimatePostKit\Includes\BdThemes_Duplicator -- a fatal error.
228 + */
199 229 new BdThemes_Duplicator();