8763dba9 by Kevin Burton

added customizer class

1 parent b8858a91
1 <?php
2 /* wp-admin-menu-classes.php
3
4 Classes to encapsulate access to admin menu global arrays $menu and $submenu
5
6 See:
7 -- http://core.trac.wordpress.org/ticket/12718
8 -- http://core.trac.wordpress.org/ticket/11517
9
10 version: 1.05 - Renamed "delete_*" functions to "remove_*" (Oct 6 2010)
11 version: 1.04 - Another significant update. Attempted to make PHP 4.x compatible (Sept 30 2010)
12 Added hookname property to both section and item
13 Renamed property with list of items to be "items" instead of "submenus"
14 version: 1.03 - Major Rewrite over v1.02. Designed for hopeful inclusion within WordPress v3.1 (Sept 29 2010)
15 version: 1.02 - Added remove_admin_menu_item(), changed "find-by"=="title" to search on RegEx (Sept 27 2010)
16
17 Designed for hopeful inclusion within WordPress v3.1
18
19 Examples of use:
20 // This example creates one menu in place of Dashboard called "My Menu", adds a few things, and removes all else.
21 // This example assumes this might only be done for end users, not administrators
22
23 $dashboard = rename_admin_menu_section('Dashboard','My Menu');
24
25 // // Alternate approach
26 // remove_admin_menu_item('index.php'); // Dashboard
27 // $dashboard = add_admin_menu_section(array(
28 // 'title' => 'My Menu',
29 // 'slug' => 'index.php',
30 // ));
31
32 remove_admin_menu_item($dashboard,'index.php'); // Dashboard
33 remove_admin_menu_item($dashboard,'update-core.php'); // Updates
34
35 $movies = "edit.php?post_type=movie";
36 copy_admin_menu_item($dashboard,$movies);
37 $movie_genre = 'edit-tags.php?taxonomy=movie-genre&post_type=movie';
38 copy_admin_menu_item($dashboard,$movies,$movie_genre);
39 rename_admin_menu_item($dashboard,$movie_genre,'Movie Genre');
40 remove_admin_menu_item($movies);
41 remove_admin_menu_item($movies,$movie_genre);
42 remove_admin_menu_item($movies,'post-new.php?post_type=movie');
43 remove_admin_menu_section($movies);
44
45 $actors = "edit.php?post_type=actor";
46 copy_admin_menu_item($dashboard,$actors);
47 remove_admin_menu_item($actors);
48 remove_admin_menu_item($actors,'post-new.php?post_type=actor');
49 //remove_admin_menu_section($actors);
50
51 rename_admin_menu_item($dashboard,'Pages','Other Pages');
52
53 remove_admin_menu_section('edit.php'); // Posts
54 remove_admin_menu_section('upload.php'); // Media
55 remove_admin_menu_section('link-manager.php'); // Links
56 remove_admin_menu_section('edit-comments.php'); // Comments
57 remove_admin_menu_section('edit.php?post_type=page'); // Pages
58 remove_admin_menu_section('plugins.php'); // Plugins
59 remove_admin_menu_section('themes.php'); // Appearance
60 remove_admin_menu_section('users.php'); // Users
61 remove_admin_menu_section('tools.php'); // Tools
62 remove_admin_menu_section('options-general.php'); // Settings
63
64 */
65
66
67 function add_admin_menu_section($section,$args=array()) {
68 $new_section = new WP_AdminMenuSection();
69 return $new_section->initialize($section,$args);
70 }
71
72 function add_admin_menu_item($section,$item,$args=array()) {
73 $section = $temp = get_admin_menu_section($section);
74 $item = ($section ? $section->add_item($item,$args) : false);
75 return $item;
76 }
77 function remove_admin_menu_item($section,$item=false) {
78 if (!$item)
79 $item = $section; // These slugs are often identical
80 $section = get_admin_menu_section($section);
81 if ($section)
82 $section->remove_item($item);
83 }
84 function remove_admin_menu_section($section) {
85 $section = get_admin_menu_section($section);
86 if ($section)
87 $section->delete();
88 }
89 function rename_admin_menu_section($section,$new_title) {
90 $section = get_admin_menu_section($section);
91 if ($section)
92 $section->set_title($new_title);
93 return $section;
94 }
95 function rename_admin_menu_item($section,$item,$new_title) {
96 $item = get_admin_menu_item($section,$item);
97 if ($item)
98 $item->set_title($new_title);
99 return $item;
100 }
101 function swap_admin_menu_sections($from_section,$to_section) {
102 $from_section = get_admin_menu_section($from_section);
103 if ($from_section)
104 $from_section->swap_with($to_section);
105 return $section;
106 }
107 function get_admin_menu_section($section) {
108 if (!is_a($section,'WP_AdminMenuSection'))
109 $section = new WP_AdminMenuSection($section);
110 return $section;
111 }
112 function get_admin_menu_item($section,$item) {
113 $section = get_admin_menu_section($section);
114 if (!is_a($item,'WP_AdminMenuItem')) {
115 $item = $section->find_item($item);
116 }
117 return $item;
118 }
119 function copy_admin_menu_item($to_section,$from_section,$item=false) {
120 if (!$item)
121 $item = $from_section; // These slugs are often identical
122 $to_section = get_admin_menu_section($to_section);
123 $item = get_admin_menu_item($from_section,$item);
124 add_admin_menu_item($to_section,$item);
125 }
126
127 class WP_AdminMenuSection {
128 var $index = 0;
129 var $items=array();
130 var $hookname;
131 function __construct($section=false) {
132 $this->WP_AdminMenuSection($section);
133 }
134 function WP_AdminMenuSection($section=false) {
135 if ($section) { // $section=false when we need to add one. Static methods would be nicer.
136 if (is_a($section,'WP_AdminMenuSection')) {
137 $this->index = &$section->index;
138 $this->items = &$section->items;
139 $this->hookname = &$section->hookname;
140 } else {
141 global $menu;
142 global $submenu;
143 $found = false;
144 foreach($menu as $index => $section_array) {
145 if ($section==$section_array[2] || // Find by File/Slug
146 $section==$section_array[0] || // Find by Title
147 @preg_match("#^{$section}$#",$section_array[0])) { // Find by Title via RegEx
148 $found = $index;
149 } else {
150 continue;
151 }
152 break;
153 }
154 $this->index = $found;
155 if ($found)
156 $this->refresh();
157 }
158 }
159 }
160 function initialize($section,$args=array()) {
161 $args = wp_parse_args($args,array(
162 'where' => 'bottom' // top or bottom
163 ));
164 $section = wp_parse_args($section,array(
165 'title' => false,
166 'slug' => false,
167 'page_title' => false,
168 'icon_src' => false,
169 'function' => false,
170 'capability' => 'edit_posts',
171 ));
172 if (!$section['page_title'])
173 $section['page_title'] = strip_tags($section['title']);
174 switch ($args['where']) {
175 case 'bottom':
176 $this->hookname = add_menu_page(
177 $section['page_title'],
178 $section['title'],
179 $section['capability'],
180 $section['slug'],
181 $section['function'],
182 $section['icon_src'] );
183 break;
184 case 'after': // TODO: Implement this
185 case 'before': // TODO: Implement this
186 case 'top': // TODO: Implement this
187 default:
188 wp_die("where='{$args['where']}' not yet implemented in WP_AdminMenuSection->initialize().");
189 }
190 $this->refresh($section['slug']);
191 return $this;
192 }
193
194 function add_item($item,$args=array()) {
195 $args = wp_parse_args($args,array(
196 'where' => 'bottom' // top or bottom
197 ));
198 global $submenu;
199 $slug = $this->get_slug();
200 if (!isset($submenu[$slug]))
201 $submenu[$slug] = array();
202 $item_list = &$submenu[$slug];
203 if (is_a($item,'WP_AdminMenuItem')) {
204 $item_type = OBJECT;
205 $item_array = $item->get_array();
206 } else if ($this->is_item_array($item)) {
207 $item_type = ARRAY_N;
208 $item_array = $item;
209 } else {
210 $item_type = ARRAY_A;
211 $item = wp_parse_args($item,array(
212 'title' => false,
213 'slug' => false,
214 'page_title' => false,
215 'function' => false,
216 'capability' => 'edit_posts',
217 ));
218 if (!$item['page_title'])
219 $item['page_title'] = $item['title'];
220 $item['hookname'] = add_submenu_page( $slug, $item['page_title'], $item['title'], $item['capability'], $item['slug'], $item['function']);
221 if ($args['where']!='bottom') // If 'bottom', do nothing more./
222 $item_array = array_pop($item_list);
223 }
224 switch ($args['where']) {
225 case 'top': // No, array_unshift() won't do this instead.
226 $last_index = $this->get_last_item_index()+5; // Menus typically go in increments of 5.
227 $item_list[$last_index] = null; // Create a placeholder at end to allow us to shift them all up
228 $item_indexes = array_keys($item_list);
229 $new_item_list = array();
230 $new_item_list[$item_indexes[0]] = $item_array; // Finally add the item array to the beginning.
231 for($i = 1; $i<count($item_indexes); $i++) {
232 $new_item_list[$item_indexes[$i]] = $item_list[$item_indexes[$i-1]];
233 }
234 $item_list = $new_item_list;
235 break;
236 case 'bottom':
237 if ($item_type != ARRAY_A) {
238 // If it's an associative array we need to add it, otherwise it's already part of the menu.
239 $last_index = $this->get_last_item_index()+5;
240 $item_list[$last_index] = $item_array;
241 }
242 break;
243 case 'after': // TODO: Implement this
244 case 'before': // TODO: Implement this
245 default:
246 wp_die("where='{$args['where']}' not yet implemented in WP_AdminMenuSection->add_item().");
247 }
248 $this->refresh();
249 return new WP_AdminMenuItem($slug,$last_index);
250 }
251 function rename_item($item,$new_title) {
252 $this->find_item($item)->set_title($new_title);
253 }
254 function swap_with($section) {
255 $with = get_admin_menu_section($section);
256 global $menu;
257 $temp = $menu[$this->index];
258 $menu[$this->index] = $menu[$with->index];
259 $menu[$with->index] = $temp;
260 $temp = $this->index;
261 $this->index = $with->index;
262 $with->index = $temp;
263 $temp = $this->items;
264 $this->items = $with->items;
265 $with->items = $temp;
266 }
267 function delete() {
268 global $submenu;
269 unset($submenu[$this->get_slug()]);
270 global $menu;
271 unset($menu[$this->index]);
272 }
273 function remove_item($item) {
274 global $submenu;
275 $index = $this->find_item_index($item);
276 $item = $this->find_item($index);
277 unset($submenu[$item->parent_slug][$index]);
278 unset($this->items[$index]);
279
280 }
281 function find_item($item) {
282 if (!is_a($item,'WP_AdminMenuItem')) {
283 $index = (is_numeric($item) ? $item : $this->find_item_index($item));
284 $item = ($index!==false ? $this->items[$index] : false);
285 }
286 return $item;
287 }
288 function find_item_index($item) {
289 if (is_a($item,'WP_AdminMenuSection')) {
290 wp_die('Unexpected: WP_AdminMenuSection passed when WP_AdminMenuItem or WP_AdminMenuItem->slug expected.');
291 }
292 if (is_a($item,'WP_AdminMenuItem')) {
293 $item = $item->get_slug();
294 }
295 foreach($this->items as $index => $item_obj) {
296 if ($item==$item_obj->get_slug()) {
297 break;
298 } else if (preg_match("#^{$item}$#",$item_obj->get_title())) {
299 break;
300 } else {
301 $index = false;
302 }
303 }
304 return $index;
305 }
306 function get_title() {
307 return $GLOBALS['menu'][$this->index][0];
308 }
309 function set_title($new_title) {
310 $GLOBALS['menu'][$this->index][0] = $new_title;
311 }
312 function get_capability() {
313 return $GLOBALS['menu'][$this->index][1];
314 }
315 function set_capability($new_capability) {
316 $GLOBALS['menu'][$this->index][1] = $new_capability;
317 }
318 function get_file() { // 'slug' & 'file' are synonyms for admin menu
319 return $GLOBALS['menu'][$this->index][2];
320 }
321 function set_file($new_file) {
322 $GLOBALS['menu'][$this->index][2] = $new_file;
323 }
324 function get_slug() { // 'slug' & 'file' are synonyms for admin menu
325 return $this->get_file();
326 }
327 function set_slug($new_slug) {
328 $this->set_file($new_slug);
329 }
330 function get_unused() {
331 return $GLOBALS['menu'][$this->index][3];
332 }
333 function set_unused($new_unused) {
334 $GLOBALS['menu'][$this->index][3] = $new_unused;
335 }
336 function get_class() {
337 return $GLOBALS['menu'][$this->index][4];
338 }
339 function set_class($new_class) {
340 $GLOBALS['menu'][$this->index][4] = $new_class;
341 }
342 function get_id() {
343 return $GLOBALS['menu'][$this->index][5];
344 }
345 function set_id($new_id) {
346 $GLOBALS['menu'][$this->index][5] = $new_id;
347 }
348 function get_icon_src() {
349 return $GLOBALS['menu'][$this->index][6];
350 }
351 function set_icon_src($new_icon_src) {
352 $GLOBALS['menu'][$this->index][6] = $new_icon_src;
353 }
354 function is_item_array($item) {
355 $is_item_array = true;
356 if (!is_array($item)) {
357 $is_item_array = false;
358 } else {
359 foreach(array_keys($item) as $key) {
360 if (!is_numeric($key)) {
361 $is_item_array = false;
362 break;
363 }
364 }
365 }
366 return $is_item_array;
367 }
368 function get_last_item_index() {
369 global $submenu;
370 $slug = $this->get_slug();
371 return ($slug ? end(array_keys($submenu[$slug])) : false);
372 }
373 function refresh($section=false) { // This in case something external changes the submenu indexes
374 if (!$section) {
375 $this->items = $this->get_items($this);
376 } else {
377 $this->items = $this->get_items($section);
378 $this->hookname = get_plugin_page_hookname($section,'');
379 $this->index = $this->find_index($section);
380 }
381 }
382 function find_index($section) {
383 global $menu;
384 $found = false;
385 foreach($menu as $index => $section_array) {
386 if ($section==$section_array[2]) {
387 $found = true;
388 break;
389 }
390 }
391 return ($found ? $index : false);
392 }
393 function get_items($section) {
394 if (is_a($section,'WP_AdminMenuSection'))
395 $slug = $section->get_slug();
396 else if (is_string($section))
397 $slug = $section;
398 global $submenu;
399 $items = array();
400 if (isset($submenu[$slug])) {
401 foreach($submenu[$slug] as $index => $item) {
402 $items[$index] = new WP_AdminMenuItem($slug,$index);
403 }
404 }
405 return $items;
406 }
407 }
408 class WP_AdminMenuItem {
409 var $index;
410 var $parent_slug;
411 var $hookname;
412 function __construct($parent_slug,$slug) {
413 $this->WP_AdminMenuItem($parent_slug,$slug);
414 }
415 function WP_AdminMenuItem($parent_slug,$slug) {
416 $this->parent_slug = $parent_slug;
417 if (is_numeric($slug)) { // $slug is designed for future non-legacy use
418 $this->index = $slug;
419 $slug = $this->get_slug();
420 } else {
421 $section = new WP_AdminMenuSection($parent_slug);
422 $item = $section->find_item($slug);
423 if ($item)
424 $this->index = $item->index;
425 }
426 $this->hookname = get_plugin_page_hookname($slug,$parent_slug);
427 }
428 function get_array() { // Only here because WP_AdminMenuSection really needed it.
429 return $GLOBALS['submenu'][$this->parent_slug][$this->index];
430 }
431 function get_title() {
432 return $GLOBALS['submenu'][$this->parent_slug][$this->index][0];
433 }
434 function set_title($new_title) {
435 $GLOBALS['submenu'][$this->parent_slug][$this->index][0] = $new_title;
436 }
437 function get_capability() {
438 return $GLOBALS['submenu'][$this->parent_slug][$this->index][1];
439 }
440 function set_capability($new_capability) {
441 $GLOBALS['submenu'][$this->parent_slug][$this->index][1] = $new_capability;
442 }
443 function get_slug() { // 'slug' & 'file' are synonyms for admin menu
444 return html_entity_decode($GLOBALS['submenu'][$this->parent_slug][$this->index][2]);
445 }
446 function set_slug($new_slug) {
447 $GLOBALS['submenu'][$this->parent_slug][$this->index][2] = $new_slug;
448 }
449 function get_file() { // 'slug' & 'file' are synonyms for admin menu
450 return $this->get_slug();
451 }
452 function set_file($new_file) {
453 $this->set_slug($new_slug);
454 }
455 }