PluginProbe ʕ •ᴥ•ʔ
Nested Pages / 3.2.15
Nested Pages v3.2.15
3.2.15 3.2.14 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 trunk 1.0 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.3.0 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.2 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.3.1 1.6.3.2 1.6.4 1.6.5 1.6.5.1 1.6.5.2 1.6.6 1.6.7 1.6.8 1.7.0 1.7.1 2.0.1 2.0.2 2.0.3 2.0.4 3.0.1 3.0.10 3.0.11 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.20 3.1.21 3.1.22 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7
wp-nested-pages / app / Entities / AdminCustomization / AdminMenuItems.php
wp-nested-pages / app / Entities / AdminCustomization Last commit date
AdminCustomizationBase.php 2 years ago AdminCustomizationFactory.php 2 years ago AdminMenuItems.php 4 years ago AdminMenuSanitization.php 2 years ago
AdminMenuItems.php
356 lines
1 <?php
2 namespace NestedPages\Entities\AdminCustomization;
3
4 /**
5 * Custom Admin Menu Items
6 */
7 class AdminMenuItems extends AdminCustomizationBase
8 {
9 public function __construct()
10 {
11 parent::__construct();
12 add_action('admin_menu', [$this, 'setOriginalMenus']);
13 add_action('admin_menu', [$this, 'createCustomMenu']);
14 add_action('admin_menu', [$this, 'relabelItems']);
15 add_action('admin_menu', [$this, 'createSubmenus']);
16 }
17
18 /**
19 * Save the original menu before it is modified (administrators)
20 */
21 public function setOriginalMenus()
22 {
23 global $menu;
24 global $submenu;
25 global $np_menu_original;
26 global $np_submenu_original;
27 $np_menu_original = $menu;
28 $np_submenu_original = $submenu;
29 $this->buildNestedMenu();
30 }
31
32 /**
33 * Relabel Items
34 */
35 public function relabelItems()
36 {
37 if ( !$this->settings->adminCustomEnabled('enabled_menu') ) return;
38 $menu_options = $this->settings->adminCustomEnabled('nav_menu_options');
39 if ( empty($menu_options) ) return;
40
41 global $menu;
42
43 // Label
44 foreach ( $menu as $key => $item ){
45 if ( isset($menu_options[$this->current_user_role][$item[2]]) && isset($menu_options[$this->current_user_role][$item[2]]['label']) ){
46 if ( $menu_options[$this->current_user_role][$item[2]]['label'] == '' ) continue;
47
48 $custom_label = sanitize_text_field($menu_options[$this->current_user_role][$item[2]]['label']);
49 // Add notification counts if needed
50 $dom = new \DOMDocument;
51 $dom->loadHtml($item[0]);
52 $span_tags = $dom->getElementsByTagName('span');
53 if ( $span_tags->length > 0 ) $custom_label .= "<span class='update-plugins count-{$span_tags[0]->nodeValue}'><span class='plugin-count'>{$span_tags[0]->nodeValue}</span></span>";
54 $menu[$key][0] = $custom_label;
55 }
56 }
57
58 // Icon
59 foreach ( $menu as $key => $item ){
60 if ( !isset($item[6]) ) continue;
61 if ( isset($menu_options[$this->current_user_role][$item[2]]) && isset($menu_options[$this->current_user_role][$item[2]]['icon']) ){
62 if ( $menu_options[$this->current_user_role][$item[2]]['icon'] == '' ) continue;
63 $menu[$key][6] = sanitize_text_field($menu_options[$this->current_user_role][$item[2]]['icon']);
64 }
65 }
66
67 // Link
68 foreach ( $menu as $key => $item ){
69 if ( !isset($item[2]) ) continue;
70 if ( isset($menu_options[$this->current_user_role][$item[2]]) && isset($menu_options[$this->current_user_role][$item[2]]['link']) ){
71 if ( $menu_options[$this->current_user_role][$item[2]]['link'] == '' ) continue;
72 $menu[$key][2] = sanitize_text_field($menu_options[$this->current_user_role][$item[2]]['link']);
73 }
74 }
75 }
76
77 /**
78 * Reorder Menu Items
79 * (Can't hook into the menu_order filter because it receives links. Links may change in plugin settings)
80 */
81 public function createCustomMenu()
82 {
83 $this->setCurrentUserRoles();
84 global $menu;
85 global $np_menu_original;
86
87 if ( !$this->settings->adminCustomEnabled('enabled_menu') ) return;
88 $menu_options = $this->settings->adminCustomEnabled('nav_menu_options');
89 if ( !$menu_options ) return;
90 if ( !isset($menu_options[$this->current_user_role]) ) return;
91
92 $new_menu = array();
93 $order = 1;
94 $separator_index = 1;
95
96 foreach ( $menu_options[$this->current_user_role] as $key => $item ){
97
98 // Settings can't be hidden (unable to return to reset customizations)
99 if ( isset($item['hidden']) && $item['link'] !== 'options-general.php' ) continue;
100
101 $slug = ( isset($item['original_link']) ) ? $item['original_link'] : $key;
102
103 // Loop through the original menu and get the item if it exists (associated through original link)
104 foreach ( $menu as $original_item ){
105 if ( isset($original_item[2]) && $original_item[2] == $slug ){
106 $new_menu[$order] = $original_item;
107 }
108 }
109
110 // Add Separators
111 if ( strpos($key, 'custom_sep') !== false || strpos($key, 'separator') !== false ) {
112 $new_menu[$order] = array('', 'read', 'separator' . $separator_index, '', 'wp-menu-separator');
113 $separator_index++;
114 }
115
116 $order++;
117 }
118
119
120 // Append top level menu items added by plugins since customization
121 foreach ( $np_menu_original[$this->current_user_role] as $key => $item) :
122 $exists = false;
123 foreach ( $new_menu as $new_menu_item ) :
124 if ( $item[2] == $new_menu_item[2] ) $exists = true;;
125 endforeach;
126 $is_hidden = false;
127 foreach ( $menu_options[$this->current_user_role] as $menu_option ) :
128 if ( !isset($menu_option['link']) ) continue;
129 if ( $item[2] == $menu_option['link'] && isset($menu_option['hidden']) ) $is_hidden = true;
130 endforeach;
131 if ( !$exists && $item[1] !== 'read' && !$is_hidden ) $new_menu[] = $item;
132 endforeach;
133
134 $menu = $new_menu;
135 }
136
137 /**
138 * Build the Submenus
139 */
140 public function createSubmenus()
141 {
142 global $submenu;
143 global $np_submenu_original;
144 $original_submenu = $np_submenu_original;
145
146 if ( !$this->settings->adminCustomEnabled('enabled_menu') ) return;
147 $menu_options = $this->settings->adminCustomEnabled('nav_menu_options');
148 if ( !$menu_options ) return;
149 if ( !isset($menu_options[$this->current_user_role]) ) return;
150
151 // First remove all submenus
152 foreach ( $submenu as $menu_slug => $submenu_items ){
153 foreach ( $submenu_items as $sub_pages ){
154 if ( !isset($sub_pages[2]) ) continue;
155 remove_submenu_page($menu_slug, $sub_pages[2]);
156 }
157 }
158
159 // Add the Submenu pages back in, ordered and labeled how we want
160 foreach ( $menu_options[$this->current_user_role] as $menu_option ){
161
162 if ( !isset($menu_option['original_link']) ) continue;
163 if ( !isset($menu_option['submenu']) || !$menu_option['submenu'] ){
164 if ( !isset($np_submenu_original[$menu_option['original_link']]) ) continue;
165 $submenu[$menu_option['link']] = $np_submenu_original[$menu_option['original_link']];
166 continue;
167 }
168 $new_submenu = [];
169 foreach ( $menu_option['submenu'] as $key => $menu ){
170 $index = ($key + 1) * 10;
171
172 // Items saved that no longer exist
173 if ( !isset($np_submenu_original[$menu_option['link']]) ) continue;
174 if ( !$this->submenuExists($np_submenu_original[$menu_option['link']], $menu['link'], $menu_option) ) continue;
175
176 $np_submenu_original[$index][0] = $menu['label'];
177 $np_submenu_original[$index][1] = $menu['role'];
178 $np_submenu_original[$index][2] = $menu['link'];
179 $np_submenu_original[$index][3] = $menu['label'];
180 $np_submenu_original[$index][4] = (isset($menu['hidden']) && $menu['hidden'] == 'true') ? true : false;
181
182 if ( isset($menu['hidden']) && $menu['hidden'] == 'true' ) continue;
183 $new_submenu[$index][0] = $menu['label'];
184 $new_submenu[$index][1] = $menu['role'];
185 $new_submenu[$index][2] = $menu['link'];
186 $new_submenu[$index][3] = $menu['label'];
187 }
188 $submenu[$menu_option['link']] = $new_submenu;
189 }
190
191 // Submenu pages added by plugins after saving customizations
192 foreach ( $original_submenu as $id => $submenu_original ){
193 foreach ( $submenu_original as $submenu_item ){
194 if ( !isset($original_submenu[$id]) || empty($original_submenu[$id]) ) continue;
195 if ( !isset($submenu[$id]) ) $submenu[$id] = [];
196 if ( !isset($menu_options[$this->current_user_role][$id]) ) $menu_options[$this->current_user_role][$id] = [
197 'submenu' => []
198 ];
199 if ( isset($menu_options[$this->current_user_role][$id]) && !$this->submenuExists($submenu[$id], $submenu_item[2])
200 && !$this->submenuHidden($menu_options[$this->current_user_role][$id]['submenu'], $submenu_item[2]) ) {
201 $submenu[$id][] = $submenu_item;
202 }
203 }
204 }
205 }
206
207 /**
208 * Does the submenu exist in the source menu?
209 */
210 private function submenuExists($source_menu, $link)
211 {
212 $exists = false;
213 foreach ( $source_menu as $menu_item ){
214 if ( $menu_item[2] == $link ) $exists = true;
215 }
216 return $exists;
217 }
218
219 private function submenuHidden($menu_options, $submenu_link)
220 {
221 $hidden = false;
222 foreach ( $menu_options as $option ){
223 if ( $option['link'] == $submenu_link && isset($option['hidden']) ) $hidden = true;
224 }
225 return $hidden;
226 }
227
228 /**
229 * Reorder Menu Items in the original, saved copy
230 */
231 public function buildNestedMenu()
232 {
233 global $np_menu_original;
234 global $np_submenu_original;
235 global $menu;
236
237 $menu_options = $this->settings->adminCustomEnabled('nav_menu_options');
238 if ( !$menu_options ) return $this->setDefaultMenu();
239
240 $np_menu_ordered = array();
241 $np_menu_ordered['default'] = $menu;
242
243 // Set each role's menu order
244 $user_roles = $this->user_repo->allRoles(array());
245 foreach( $user_roles as $role ){
246
247 if ( !array_key_exists($role['name'], $menu_options) ) continue;
248 $missing_submenus = [];
249 foreach ( $menu_options[$role['name']] as $key => $item ){
250 foreach ( $np_menu_original as $menu_key => $menu_item ){
251 if ( isset($menu_item[2]) && $menu_item[2] == $key ) {
252 if ( isset($np_submenu_original[$menu_item[2]]) ) {
253 $menu_item['submenu'] = $np_submenu_original[$menu_item[2]];
254 }
255 $np_menu_ordered[$role['name']][] = $menu_item;
256 } // submenu
257 } // np menu original
258 } // role
259 }
260
261 // Add the separators
262 foreach($user_roles as $role){
263 $role_name = $role['name'];
264 if ( !array_key_exists($role_name, $menu_options) ) continue;
265 $c = 0;
266 foreach ( $menu_options[$role_name] as $key => $options ){
267 if ( strpos($key, 'custom_sep') !== false ){
268 $menu_item = array('', 'read', $key, '', 'wp-menu-separator');
269 array_splice($np_menu_ordered[$role_name], $c, 0, array($menu_item));
270 }
271 $c++;
272 }
273 }
274
275 // Add missing items (added by other plugins after saving a custom menu)
276 $missing_top_items = [];
277 $missing_sub_items = [];
278 foreach ( $np_menu_ordered as $role => $ordered_menu ){
279 if ( $role == 'default' ) continue;
280 $all_items = [];
281 foreach ( $np_menu_ordered['default'] as $menu_key => $default_menu ){
282 if ( $default_menu[2] == 'edit-tags.php?taxonomy=link_category' ) continue;
283 $all_items[$default_menu[2]] = $menu_key;
284 }
285 foreach ( $ordered_menu as $ordered_item ){
286 if ( array_key_exists($ordered_item[2], $all_items) ) unset($all_items[$ordered_item[2]]);
287 }
288 $missing_top_items[$role] = $all_items;
289 }
290
291 foreach ( $missing_top_items as $role => $items ){
292 foreach ( $items as $item_id => $key ){
293 $new_item = $np_menu_ordered['default'][$key];
294 if ( array_key_exists($item_id, $np_submenu_original) ) :
295 $new_item['submenu'] = $np_submenu_original[$item_id];
296 endif;
297 $np_menu_ordered[$role][] = $new_item;
298 }
299 }
300
301 $np_menu_original = $np_menu_ordered;
302 }
303
304
305 /**
306 * Set the default menu/order
307 * This is used to display the nested admin settings view before a customized version has been saved
308 */
309 private function setDefaultMenu()
310 {
311 global $np_menu_original;
312 global $np_submenu_original;
313 $np_menu_ordered = array();
314 ksort($np_menu_original);
315
316 // Default menu (for new user roles)
317 foreach ( $np_menu_original as $menu_item ){
318 $np_menu_ordered['default'][] = $menu_item;
319 }
320
321 // Set each role's menu order
322 $user_roles = $this->user_repo->allRoles([]);
323
324 foreach( $user_roles as $role ){
325
326 $role_capabilities = $this->user_repo->getSingleRoleCapabilities($role['name']);
327
328 foreach ( $np_menu_original as $menu_item ){
329
330 if ( $menu_item[1] == 'list_users' && !array_key_exists('list_users', $role_capabilities) ){
331 $profile_menu_item = [
332 __('Profile', 'wp-nested-pages'),
333 'read',
334 'profile.php',
335 '',
336 'menu-icon-users',
337 'menu-users',
338 'dashicons-admin-users',
339 'custom-item',
340 'no-delete'
341 ];
342 $np_menu_ordered[$role['name']][] = $profile_menu_item;
343 continue;
344 }
345
346 if ( $menu_item[1] === '' || !array_key_exists($menu_item[1], $role_capabilities) || !$role_capabilities[$menu_item[1]] ) continue;
347 if ( isset($menu_item[5]) && $menu_item[5] == 'menu-links' ) continue;
348 if ( $role['name'] == 'subscriber' && $menu_item[2] == 'separator2') continue;
349 if ( isset($np_submenu_original[$menu_item[2]]) ) $menu_item['submenu'] = $np_submenu_original[$menu_item[2]];
350 $np_menu_ordered[$role['name']][] = $menu_item;
351 }
352
353 } // roles
354 $np_menu_original = $np_menu_ordered;
355 }
356 }