PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.83
51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 All 39 releases
← All changes | includes/features/Duplicator/Duplicator.php +165 -0 51.1.251.1.83 View file →
@@ -1,0 +1,165 @@
1 +<?php /** @noinspection SpellCheckingInspection, DuplicatedCode, PhpUnused */
2 +
3 +namespace King_Addons;
4 +
5 +use Elementor\Core\Files\CSS\Post as Post_CSS;
6 +
7 +if (!defined('ABSPATH')) {
8 + exit; // Exit if accessed directly.
9 +}
10 +
11 +class Duplicator
12 +{
13 + const KNG_DUPLICATOR_ACTION = 'kng_duplicator_action';
14 + private static ?Duplicator $_instance = null;
15 +
16 + public static function instance(): Duplicator
17 + {
18 + if (is_null(self::$_instance)) {
19 + self::$_instance = new self();
20 + }
21 + return self::$_instance;
22 + }
23 +
24 + public function __construct()
25 + {
26 + add_action('admin_action_' . self::KNG_DUPLICATOR_ACTION, array($this, 'doDuplicateAction'));
27 + add_filter('page_row_actions', array($this, 'addDuplicatorActionLink'), 10, 2);
28 + add_filter('post_row_actions', array($this, 'addDuplicatorActionLink'), 10, 2);
29 + }
30 +
31 + public static function addDuplicatorActionLink($action, $post)
32 + {
33 + if (current_user_can('edit_post', $post->ID) && post_type_supports($post->post_type, 'elementor')) {
34 +
35 + /** @noinspection HtmlUnknownTarget */
36 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Already escaped
37 + $action[self::KNG_DUPLICATOR_ACTION] = sprintf(
38 + '<a href="%1$s" title="%2$s"><span class="screen-reader-text">%2$s</span>%3$s</a>',
39 + esc_url(self::getDuplicateActionURL($post->ID)),
40 + /* translators: 1: "King Addons" plus "Duplicator" word */
41 + sprintf(esc_attr__('Duplicate - %s', 'king-addons'), esc_attr($post->post_title)),
42 + esc_html__('King Addons Duplicator', 'king-addons')
43 + );
44 +
45 + }
46 +
47 + return $action;
48 + }
49 +
50 + public static function getDuplicateActionURL($post_id): string
51 + {
52 + return wp_nonce_url(
53 + add_query_arg(
54 + array(
55 + 'action' => self::KNG_DUPLICATOR_ACTION,
56 + 'post_id' => $post_id,
57 + 'paged' => (get_query_var('paged')) ? get_query_var('paged') : 1,
58 + ),
59 + admin_url('admin.php')
60 + ),
61 + self::KNG_DUPLICATOR_ACTION . '_' . absint($post_id)
62 + );
63 + }
64 +
65 + public static function doDuplicateAction(): void
66 + {
67 + /** @noinspection SpellCheckingInspection */
68 + $wp_nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
69 + $post_id = isset($_GET['post_id']) ? absint($_GET['post_id']) : 0;
70 +
71 + if (!$post_id || !wp_verify_nonce($wp_nonce, self::KNG_DUPLICATOR_ACTION . '_' . $post_id)) {
72 + return;
73 + }
74 +
75 + $post = get_post($post_id);
76 + if (is_null($post)) {
77 + return;
78 + }
79 +
80 + if (!current_user_can('edit_post', $post_id) || !post_type_supports($post->post_type, 'elementor')) {
81 + return;
82 + }
83 +
84 + $post = sanitize_post($post, 'db');
85 +
86 + $duplicated_post_id = self::insertPost($post);
87 +
88 + $wp_redirect = add_query_arg(
89 + array(
90 + 'post_type' => $post->post_type,
91 + 'paged' => isset($_GET['paged']) ? absint($_GET['paged']) : 1,
92 + ),
93 + admin_url('edit.php')
94 + );
95 +
96 + if (!is_wp_error($duplicated_post_id)) {
97 + self::duplicatePostTaxonomies($post, $duplicated_post_id);
98 + self::duplicatePostMeta($post_id, $duplicated_post_id);
99 +
100 + $css = Post_CSS::create($duplicated_post_id);
101 + $css->update();
102 + }
103 +
104 + wp_safe_redirect($wp_redirect);
105 + die();
106 + }
107 +
108 + protected static function insertPost($post): int
109 + {
110 + $post_meta = get_post_meta($post->ID);
111 +
112 + $duplicating_post_args = array(
113 + 'comment_status' => $post->comment_status,
114 + 'menu_order' => $post->menu_order,
115 + 'ping_status' => $post->ping_status,
116 + 'post_author' => wp_get_current_user()->ID,
117 + 'post_content' => $post->post_content,
118 + 'post_excerpt' => $post->post_excerpt,
119 + 'post_parent' => $post->post_parent,
120 + 'post_password' => $post->post_password,
121 + 'post_status' => 'draft',
122 + /* translators: 1: Duplicated post title */
123 + 'post_title' => sprintf(esc_attr__('%1$s - Duplicated', 'king-addons'), esc_attr($post->post_title)),
124 + 'post_type' => $post->post_type,
125 + 'to_ping' => $post->to_ping,
126 + );
127 +
128 + if (isset($post_meta['_elementor_edit_mode'][0])) {
129 + $data = array(
130 + 'meta_input' => array(
131 + '_elementor_edit_mode' => $post_meta['_elementor_edit_mode'][0],
132 + '_elementor_template_type' => $post_meta['_elementor_template_type'][0],
133 + ),
134 + );
135 + $duplicating_post_args = array_merge($duplicating_post_args, $data);
136 + }
137 +
138 + return wp_insert_post($duplicating_post_args);
139 + }
140 +
141 + public static function duplicatePostTaxonomies($post, $duplicated_post_id): void
142 + {
143 + $taxonomies = array_map('sanitize_text_field', get_object_taxonomies($post->post_type));
144 + if (!empty($taxonomies)) {
145 + foreach ($taxonomies as $taxonomy) {
146 + $wp_object_terms = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'slugs'));
147 + wp_set_object_terms($duplicated_post_id, $wp_object_terms, $taxonomy);
148 + }
149 + }
150 + }
151 +
152 + public static function duplicatePostMeta($previous_id, $new_id): void
153 + {
154 + $post_meta_keys = get_post_custom_keys($previous_id);
155 + if (!empty($post_meta_keys)) {
156 + foreach ($post_meta_keys as $meta_key) {
157 + $post_meta_values = get_post_custom_values($meta_key, $previous_id);
158 + foreach ($post_meta_values as $post_meta_value) {
159 + $post_meta_value = maybe_unserialize($post_meta_value);
160 + update_post_meta($new_id, $meta_key, wp_slash($post_meta_value));
161 + }
162 + }
163 + }
164 + }
165 +}