PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 2.0.9
Adminify – White Label, Admin Menu Editor, Login Customizer v2.0.9
4.3.2 4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 All 165 releases
← All changes | Inc/Modules/MenuDuplicator/MenuDuplicator.php +194 -222 4.3.12.0.9 View file →
@@ -1,14 +1,10 @@
1 1 <?php
2 2
3 -namespace PXLBSAdminify\Inc\Modules\MenuDuplicator;
3 +namespace WPAdminify\Inc\Modules\MenuDuplicator;
4 4
5 -use PXLBSAdminify\Inc\Utils;
6 -
7 5 // no direct access allowed
8 -if (!defined('ABSPATH')) {
9 - exit;
10 -}
6 +if (!defined('ABSPATH')) exit;
11 7
12 8 /**
13 9 * @package WP Adminify
14 10 * Module: Menu Duplicator
@@ -17,265 +13,241 @@
17 13 */
18 14
19 15 class MenuDuplicator
20 16 {
17 + public function __construct()
18 + {
19 + add_action('admin_footer', [$this, 'jltwp_adminify_add_duplicate_button'], 11);
20 + add_action('admin_footer', [$this, 'jltwp_adminify_creating_menu_duplicate'], 6);
21 21
22 - public function __construct()
23 - {
24 - add_action('admin_footer', [$this, 'add_duplicate_button'], 11);
25 - add_action('admin_footer', [$this, 'creating_menu_duplicate'], 6);
22 + // Duplicate Nav Menu Item
23 + add_action('admin_footer', [$this, 'jltwp_adminify_duplicate_nav_menu_item'], 12);
24 + }
26 25
27 - // Duplicate Nav Menu Item
28 - add_action('admin_footer', [$this, 'duplicate_nav_menu_item'], 12);
29 - }
30 -
31 - /**
32 - * Duplicate Menu Button
33 - *
34 - * @return void
35 - */
36 - public function add_duplicate_button()
37 - {
38 - // Only users who can manage menus may see/use the duplicate action.
39 - if ( ! current_user_can( 'edit_theme_options' ) ) {
40 - return;
41 - }
42 -
43 - $current_screen = get_current_screen();
44 - $current_menu = (int) get_user_option('nav_menu_recently_edited');
45 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
46 - if ($current_screen->id == 'nav-menus' && isset($_GET['menu']) && sanitize_text_field(wp_unslash($_GET['menu'])) != '0') {
47 - // CSRF protection: sign the duplicate action with a nonce tied to the menu id.
48 - $duplicate_url = wp_nonce_url(
49 - add_query_arg( 'adminify-menu-duplicate', $current_menu, admin_url( 'nav-menus.php' ) ),
50 - 'adminify_duplicate_menu_' . $current_menu
51 - );
52 - $return = '';
53 - $return .= '<div class="AdminifyDuplicateMenuSpinenr spinner"></div><a class="AdminifyDuplicateMenuClick button button-primary button-large menu-save" href="' . esc_url( $duplicate_url ) . '">' . __('Duplicate Menu', 'adminify') . '</a>';
26 + /**
27 + * Duplicate Menu Button
28 + *
29 + * @return void
30 + */
31 + public function jltwp_adminify_add_duplicate_button()
32 + {
33 + $current_screen = get_current_screen();
34 + $current_menu = get_user_option('nav_menu_recently_edited');
35 + if ($current_screen->id == 'nav-menus' && $_GET['menu'] != '0') {
36 + $return = '';
37 + $return .= '<div style="display:none;" class="AdminifyDuplicateMenuSpinenr spinner is-active"></div><a class="AdminifyDuplicateMenuClick button button-primary button-large menu-save" href="?adminify-menu-duplicate=' . $current_menu . '">' . __('Duplicate Menu', 'adminify') . '</a>';
54 38 ?>
55 - <script type="text/javascript">
56 - var update_menu_form = jQuery('#update-nav-menu');
57 - update_menu_form.find('.publishing-action').append('<?php echo Utils::kses_custom($return); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped. ?>');
58 - jQuery('.AdminifyDuplicateMenuClick').click(function() {
59 - jQuery('.AdminifyDuplicateMenuSpinenr').addClass('is-active').show();
60 - });
61 - </script>
39 + <script type="text/javascript">
40 + var update_menu_form = jQuery('#update-nav-menu');
41 + update_menu_form.find('.publishing-action').append('<?php echo addslashes_gpc($return); ?>');
42 + jQuery('.AdminifyDuplicateMenuClick').click(function() {
43 + jQuery('.AdminifyDuplicateMenuSpinenr').show();
44 + });
45 + </script>
62 46
63 - <?php
64 - }
65 - }
47 + <?php
48 + }
49 + }
66 50
67 - /**
68 - * Creating Menu Duplication
69 - *
70 - * @return void
71 - */
72 - public function creating_menu_duplicate()
73 - {
74 - $current_screen = get_current_screen();
75 - if ($current_screen->id == 'nav-menus') {
76 - if (isset($_GET['adminify-menu-duplicate'])) {
51 + /**
52 + * Creating Menu Duplication
53 + *
54 + * @return void
55 + */
56 + public function jltwp_adminify_creating_menu_duplicate()
57 + {
58 + $current_screen = get_current_screen();
59 + if ($current_screen->id == 'nav-menus') {
60 + if (isset($_GET['adminify-menu-duplicate'])) {
61 + $id = intval($_GET['adminify-menu-duplicate']);
62 + $source = wp_get_nav_menu_object($id);
63 + $duplicate = $this->render_menu_duplicate($_GET['adminify-menu-duplicate'], $source->name . ' ' . __('(Copy)', 'adminify'));
64 + if ($duplicate) {
65 + ?>
66 + <script type="text/javascript">
67 + window.location.replace("<?php echo admin_url('nav-menus.php?action=edit&menu=' . $duplicate); ?>");
68 + </script>
69 + <?php
70 + } else {
71 + ?>
72 + <script type="text/javascript">
73 + window.location.replace("<?php echo admin_url('nav-menus.php'); ?>");
74 + </script>
75 + <?php
76 + }
77 + }
78 + }
79 + }
77 80
78 - $id = intval(wp_unslash($_GET['adminify-menu-duplicate']));
79 81
80 - // Authorization: only menu managers may duplicate.
81 - if ( ! current_user_can( 'edit_theme_options' ) ) {
82 - return;
83 - }
82 + /**
83 + * Render Menu Duplicate
84 + *
85 + * @return void
86 + */
87 + public function render_menu_duplicate($id = null, $name = null)
88 + {
84 89
85 - // CSRF: verify the nonce that was attached to the duplicate link.
86 - $nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';
87 - if ( ! wp_verify_nonce( $nonce, 'adminify_duplicate_menu_' . $id ) ) {
88 - wp_die( esc_html__( 'Security check failed.', 'adminify' ) );
89 - }
90 + // Sanity check
91 + if (empty($id) || empty($name)) {
92 + return false;
93 + }
90 94
91 - $source = wp_get_nav_menu_object($id);
92 - $duplicate = $this->render_menu_duplicate($id, $source->name . ' ' . __('(Copy)', 'adminify'));
93 - if ($duplicate) {
94 - ?>
95 - <script type="text/javascript">
96 - window.location.replace("<?php echo esc_url(admin_url('nav-menus.php?action=edit&menu=' . $duplicate)); ?>");
97 - </script>
98 - <?php
99 - } else {
100 - ?>
101 - <script type="text/javascript">
102 - window.location.replace("<?php echo esc_url(admin_url('nav-menus.php')); ?>");
103 - </script>
104 - <?php
105 - }
106 - }
107 - }
108 - }
95 + $id = intval($id);
96 + $name = sanitize_text_field($name);
97 + $source = wp_get_nav_menu_object($id);
98 + $source_items = wp_get_nav_menu_items($id);
109 99
100 + $menu_exists = wp_get_nav_menu_object($name);
110 101
111 - /**
112 - * Render Menu Duplicate
113 - *
114 - * @return void
115 - */
116 - public function render_menu_duplicate($id = null, $name = null)
117 - {
102 + if (!$menu_exists) {
103 + $new_id = wp_create_nav_menu($name);
104 + } else {
105 + return $new_id = $this->render_menu_duplicate($id, $name . ' ' . __('(Copy)', 'adminify'));
106 + }
118 107
119 - // Sanity check
120 - if (empty($id) || empty($name)) {
121 - return false;
122 - }
108 + if (!$new_id || is_array($new_id)) {
109 + return false;
110 + }
123 111
124 - $id = intval($id);
125 - $name = sanitize_text_field($name);
126 - $source = wp_get_nav_menu_object($id);
127 - $source_items = wp_get_nav_menu_items($id);
112 + // Key is the original db ID, val is the new
113 + $rel = array();
128 114
129 - $menu_exists = wp_get_nav_menu_object($name);
115 + $i = 1;
116 + foreach ($source_items as $menu_item) {
117 + $args = array(
118 + 'menu-item-db-id' => $menu_item->db_id,
119 + 'menu-item-object-id' => $menu_item->object_id,
120 + 'menu-item-object' => $menu_item->object,
121 + 'menu-item-position' => $i,
122 + 'menu-item-type' => $menu_item->type,
123 + 'menu-item-title' => $menu_item->title,
124 + 'menu-item-url' => $menu_item->url,
125 + 'menu-item-description' => $menu_item->description,
126 + 'menu-item-attr-title' => $menu_item->attr_title,
127 + 'menu-item-target' => $menu_item->target,
128 + 'menu-item-classes' => implode(' ', $menu_item->classes),
129 + 'menu-item-xfn' => $menu_item->xfn,
130 + 'menu-item-status' => $menu_item->post_status
131 + );
130 132
131 - if (!$menu_exists) {
132 - $new_id = wp_create_nav_menu($name);
133 - } else {
134 - return $new_id = $this->render_menu_duplicate($id, $name . ' ' . __('(Copy)', 'adminify'));
135 - }
133 + $parent_id = wp_update_nav_menu_item($new_id, 0, $args);
136 134
137 - if (!$new_id || is_array($new_id)) {
138 - return false;
139 - }
135 + $rel[$menu_item->db_id] = $parent_id;
140 136
141 - // Key is the original db ID, val is the new
142 - $rel = [];
137 + // did it have a parent? if so, we need to update with the NEW ID
138 + if ($menu_item->menu_item_parent) {
139 + $args['menu-item-parent-id'] = $rel[$menu_item->menu_item_parent];
140 + $parent_id = wp_update_nav_menu_item($new_id, $parent_id, $args);
141 + }
143 142
144 - $i = 1;
145 - foreach ($source_items as $menu_item) {
146 - $args = [
147 - 'menu-item-db-id' => $menu_item->db_id,
148 - 'menu-item-object-id' => $menu_item->object_id,
149 - 'menu-item-object' => $menu_item->object,
150 - 'menu-item-position' => $i,
151 - 'menu-item-type' => $menu_item->type,
152 - 'menu-item-title' => $menu_item->title,
153 - 'menu-item-url' => $menu_item->url,
154 - 'menu-item-description' => $menu_item->description,
155 - 'menu-item-attr-title' => $menu_item->attr_title,
156 - 'menu-item-target' => $menu_item->target,
157 - 'menu-item-classes' => implode(' ', $menu_item->classes),
158 - 'menu-item-xfn' => $menu_item->xfn,
159 - 'menu-item-status' => $menu_item->post_status,
160 - ];
143 + // allow developers to run any custom functionality they'd like
144 + do_action('duplicate_menu_item', $menu_item, $args);
161 145
162 - $parent_id = wp_update_nav_menu_item($new_id, 0, $args);
146 + $i++;
147 + }
163 148
164 - $rel[$menu_item->db_id] = $parent_id;
149 + return $new_id;
150 + }
165 151
166 - // did it have a parent? if so, we need to update with the NEW ID
167 - if ($menu_item->menu_item_parent) {
168 - $args['menu-item-parent-id'] = $rel[$menu_item->menu_item_parent];
169 - $parent_id = wp_update_nav_menu_item($new_id, $parent_id, $args);
170 - }
171 152
172 - // allow developers to run any custom functionality they'd like
173 - do_action('pxlbsadminify_duplicate_menu_item', $menu_item, $args);
153 + /**
154 + * Duplicate Nav Menu Item
155 + *
156 + * @return void
157 + */
158 + public function jltwp_adminify_duplicate_nav_menu_item()
159 + {
174 160
175 - $i++;
176 - }
161 + global $pagenow;
177 162
178 - return $new_id;
179 - }
163 + if ($pagenow != 'nav-menus.php' || !current_user_can('edit_theme_options')) {
164 + return;
165 + }
180 166
167 + ?>
168 + <script type="text/javascript">
169 + (function($) {
181 170
182 - /**
183 - * Duplicate Nav Menu Item
184 - *
185 - * @return void
186 - */
187 - public function duplicate_nav_menu_item()
188 - {
189 - global $pagenow;
171 + "use strict";
190 172
191 - if ($pagenow != 'nav-menus.php' || !current_user_can('edit_theme_options')) {
192 - return;
193 - }
173 + function adminifyGetMenuID(el) {
174 + return el.attr('id').replace('menu-item-', '') * 1;
175 + }
194 176
195 - ?>
196 - <script type="text/javascript">
197 - (function($) {
177 + function adminifyGetMenu(el) {
178 + return el.get(0).className.split('menu-item-depth-')[1].split(' ')[0];
179 + }
198 180
199 - "use strict";
181 + $(document).on('mouseover', 'li.menu-item:not(.adminify-duplicator-enabled)', function(e) {
200 182
201 - function adminifyGetMenuID(el) {
202 - return el.attr('id').replace('menu-item-', '') * 1;
203 - }
183 + var menu_item_enable = $(this).addClass('adminify-duplicator-enabled');
204 184
205 - function adminifyGetMenu(el) {
206 - return el.get(0).className.split('menu-item-depth-')[1].split(' ')[0];
207 - }
185 + menu_item_enable.find('.menu-item-actions').append('<span class="meta-sep hide-if-no-js"> | </span><a class="item-duplicate-this submitcancel hide-if-no-js" href="#">Duplicate</a>');
208 186
209 - $(document).on('mouseover', 'li.menu-item:not(.adminify-duplicator-enabled)', function(e) {
187 + });
210 188
211 - var menu_item_enable = $(this).addClass('adminify-duplicator-enabled');
189 + $(document).on('click', 'li.menu-item.adminify-duplicator-enabled .item-duplicate-this', function(e) {
212 190
213 - menu_item_enable.find('.menu-item-actions').append('<span class="meta-sep hide-if-no-js"> | </span><a class="item-duplicate-this submitcancel hide-if-no-js" href="#">Duplicate</a>');
191 + e.preventDefault();
192 + var li = $(this).closest('li.menu-item'),
193 + depth = 'menu-item-depth-' + adminifyGetMenu(li),
194 + availables = $('#menu-to-edit li[id^=menu-item-]'),
195 + ids = [],
196 + nowId = adminifyGetMenuID(li),
197 + newId, newEl, form_data;
214 198
215 - });
199 + form_data = {
200 + action: 'add-menu-item',
201 + menu: $('#menu').val(),
202 + 'menu-settings-column-nonce': $('#menu-settings-column-nonce').val(),
203 + 'menu-item': {
204 + '-1': {
205 + 'menu-item-db-id': 0,
206 + 'menu-item-object-id': li.find('input.menu-item-data-object-id').val(),
207 + 'menu-item-object': li.find('input.menu-item-data-object').val(),
208 + 'menu-item-parent-id': li.find('input.menu-item-data-parent-id').val(),
209 + 'menu-item-type': li.find('input.menu-item-data-type').val(),
210 + 'menu-item-title': li.find('input.edit-menu-item-title').val(),
211 + 'menu-item-url': li.find('input.edit-menu-item-url').val(),
212 + 'menu-item-description': li.find('textarea.edit-menu-item-description').val(),
213 + 'menu-item-attr-title': li.find('input.edit-menu-item-attr-title').val(),
214 + 'menu-item-target': li.find('.field-link-target input[type=checkbox]').is(':checked') ? '_blank' : '',
215 + 'menu-item-classes': li.find('input.edit-menu-item-classes').val(),
216 + 'menu-item-xfn': li.find('input.edit-menu-item-xfn').val()
217 + }
218 + }
219 + };
216 220
217 - $(document).on('click', 'li.menu-item.adminify-duplicator-enabled .item-duplicate-this', function(e) {
221 + $.post(ajaxurl, form_data, function(menuMarkup) {
222 + console.log($(menuMarkup));
218 223
219 - e.preventDefault();
220 - var li = $(this).closest('li.menu-item'),
221 - depth = 'menu-item-depth-' + adminifyGetMenu(li),
222 - availables = $('#menu-to-edit li[id^=menu-item-]'),
223 - ids = [],
224 - nowId = adminifyGetMenuID(li),
225 - newId, newEl, form_data;
224 + var newElement = $(menuMarkup);
226 225
227 - form_data = {
228 - action: 'add-menu-item',
229 - menu: $('#menu').val(),
230 - 'menu-settings-column-nonce': $('#menu-settings-column-nonce').val(),
231 - 'menu-item': {
232 - '-1': {
233 - 'menu-item-db-id': 0,
234 - 'menu-item-object-id': li.find('input.menu-item-data-object-id').val(),
235 - 'menu-item-object': li.find('input.menu-item-data-object').val(),
236 - 'menu-item-parent-id': li.find('input.menu-item-data-parent-id').val(),
237 - 'menu-item-type': li.find('input.menu-item-data-type').val(),
238 - 'menu-item-title': li.find('input.edit-menu-item-title').val(),
239 - 'menu-item-url': li.find('input.edit-menu-item-url').val(),
240 - 'menu-item-description': li.find('textarea.edit-menu-item-description').val(),
241 - 'menu-item-attr-title': li.find('input.edit-menu-item-attr-title').val(),
242 - 'menu-item-target': li.find('.field-link-target input[type=checkbox]').is(':checked') ? '_blank' : '',
243 - 'menu-item-classes': li.find('input.edit-menu-item-classes').val(),
244 - 'menu-item-xfn': li.find('input.edit-menu-item-xfn').val()
245 - }
246 - }
247 - };
226 + $('.hide-column-tog').not(':checked').each(function() {
227 + newElement.find('.field-' + $(this).val()).addClass('hidden-field');
228 + });
248 229
249 - $.post(ajaxurl, form_data, function(menuMarkup) {
250 - // console.log($(menuMarkup));
230 + newElement.removeClass('menu-item-depth-0');
231 + newElement.addClass(depth);
251 232
252 - var newElement = $(menuMarkup);
233 + newElement = newElement.wrap('<div>').parent().html();
253 234
254 - $('.hide-column-tog').not(':checked').each(function() {
255 - newElement.find('.field-' + $(this).val()).addClass('hidden-field');
256 - });
235 + if (li.next().hasClass(depth) || li.parent().children('li').last().get(0) === li.get(0)) {
236 + li.after(newElement);
237 + } else if (adminifyGetMenu(li.next()) < adminifyGetMenu(li)) {
238 + li.after(newElement);
239 + } else {
240 + if (adminifyGetMenu(li) != 0) {
241 + depth = 'menu-item-depth-' + (adminifyGetMenu(li) - 1);
242 + }
243 + li.nextUntil('.' + depth).last().after(newElement);
244 + }
245 + });
257 246
258 - newElement.removeClass('menu-item-depth-0');
259 - newElement.addClass(depth);
247 + });
260 248
261 - newElement = newElement.wrap('<div>').parent().html();
262 -
263 - if (li.next().hasClass(depth) || li.parent().children('li').last().get(0) === li.get(0)) {
264 - li.after(newElement);
265 - } else if (adminifyGetMenu(li.next()) < adminifyGetMenu(li)) {
266 - li.after(newElement);
267 - } else {
268 - if (adminifyGetMenu(li) != 0) {
269 - depth = 'menu-item-depth-' + (adminifyGetMenu(li) - 1);
270 - }
271 - li.nextUntil('.' + depth).last().after(newElement);
272 - }
273 - });
274 -
275 - });
276 -
277 - })(jQuery)
278 - </script>
249 + })(jQuery)
250 + </script>
279 251 <?php
280 - }
252 + }
281 253 }