PageRenderTime 66ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/msw/dev/wp-admin/includes/nav-menu.php

https://github.com/chrissiebrodigan/USC
PHP | 970 lines | 735 code | 104 blank | 131 comment | 107 complexity | d803dc293e6a52469aef03b136daa7ca MD5 | raw file
  1. <?php
  2. /**
  3. * Create HTML list of nav menu input items.
  4. *
  5. * @package WordPress
  6. * @since 3.0.0
  7. * @uses Walker_Nav_Menu
  8. */
  9. class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
  10. /**
  11. * @see Walker_Nav_Menu::start_lvl()
  12. * @since 3.0.0
  13. *
  14. * @param string $output Passed by reference.
  15. * @param int $depth Depth of page.
  16. */
  17. function start_lvl(&$output) {}
  18. /**
  19. * @see Walker_Nav_Menu::end_lvl()
  20. * @since 3.0.0
  21. *
  22. * @param string $output Passed by reference.
  23. * @param int $depth Depth of page.
  24. */
  25. function end_lvl(&$output) {
  26. }
  27. /**
  28. * @see Walker::start_el()
  29. * @since 3.0.0
  30. *
  31. * @param string $output Passed by reference. Used to append additional content.
  32. * @param object $item Menu item data object.
  33. * @param int $depth Depth of menu item. Used for padding.
  34. * @param int $current_page Menu item ID.
  35. * @param object $args
  36. */
  37. function start_el(&$output, $item, $depth, $args) {
  38. $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
  39. ob_start();
  40. $item_id = esc_attr( $item->ID );
  41. $removed_args = array(
  42. 'action',
  43. 'customlink-tab',
  44. 'edit-menu-item',
  45. 'menu-item',
  46. 'page-tab',
  47. '_wpnonce',
  48. );
  49. $original_title = '';
  50. if ( 'taxonomy' == $item->type ) {
  51. $original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
  52. } elseif ( 'post_type' == $item->type ) {
  53. $original_object = get_post( $item->object_id );
  54. $original_title = $original_object->post_title;
  55. }
  56. ?>
  57. <li id="menu-item-<?php echo $item_id; ?>" class="menu-item menu-item-depth-<?php echo $depth; ?> menu-item-<?php echo strtolower(esc_attr( $item->append )); ?>">
  58. <dl class="menu-item-bar <?php
  59. if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] )
  60. echo 'menu-item-edit-active';
  61. else
  62. echo 'menu-item-edit-inactive';
  63. ?>">
  64. <dt class="menu-item-handle">
  65. <span class="item-title"><?php echo esc_html( $item->title ); ?></span>
  66. <span class="item-controls">
  67. <span class="item-type"><?php echo esc_html( $item->append ); ?></span>
  68. <span class="item-order">
  69. <a href="<?php
  70. echo wp_nonce_url(
  71. add_query_arg(
  72. array(
  73. 'action' => 'move-up-menu-item',
  74. 'menu-item' => $item_id,
  75. ),
  76. remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
  77. ),
  78. 'move-menu_item'
  79. );
  80. ?>" class="item-move-up"><abbr title="<?php esc_attr_e('Move up'); ?>">&#8593;</abbr></a>
  81. |
  82. <a href="<?php
  83. echo wp_nonce_url(
  84. add_query_arg(
  85. array(
  86. 'action' => 'move-down-menu-item',
  87. 'menu-item' => $item_id,
  88. ),
  89. remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
  90. ),
  91. 'move-menu_item'
  92. );
  93. ?>" class="item-move-down"><abbr title="<?php esc_attr_e('Move down'); ?>">&#8595;</abbr></a>
  94. </span>
  95. <a class="item-edit" id="edit-<?php echo $item_id; ?>" title="<?php _e('Edit Menu Item'); ?>" href="<?php
  96. echo add_query_arg('edit-menu-item', $item_id, remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) ) );
  97. ?>#menu-item-settings-<?php echo $item_id; ?>">Edit Menu Item</a>
  98. </span>
  99. </dt>
  100. </dl>
  101. <div class="menu-item-settings <?php
  102. if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] )
  103. echo 'menu-item-edit-active';
  104. else
  105. echo 'menu-item-edit-inactive';
  106. ?>" id="menu-item-settings-<?php echo $item_id; ?>">
  107. <?php if( 'custom' == $item->type ) : ?>
  108. <p class="field-url description description-wide">
  109. <label for="edit-menu-item-url-<?php echo $item_id; ?>">
  110. <?php _e( 'URL' ); ?><br />
  111. <input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>" class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->url ); ?>" />
  112. </label>
  113. </p>
  114. <?php endif; ?>
  115. <p class="description description-thin">
  116. <label for="edit-menu-item-title-<?php echo $item_id; ?>">
  117. <?php _e( 'Navigation Label' ); ?><br />
  118. <input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->title ); ?>" />
  119. </label>
  120. </p>
  121. <p class="description description-thin">
  122. <label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
  123. <?php _e( 'Title Attribute' ); ?><br />
  124. <input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_excerpt ); ?>" />
  125. </label>
  126. </p>
  127. <p class="field-link-target description description-thin">
  128. <label for="edit-menu-item-target-<?php echo $item_id; ?>">
  129. <?php _e( 'Link Target' ); ?><br />
  130. <select id="edit-menu-item-target-<?php echo $item_id; ?>" class="widefat edit-menu-item-target" name="menu-item-target[<?php echo $item_id; ?>]">
  131. <option value="" <?php selected( $item->target, ''); ?>><?php _e('Same window or tab'); ?></option>
  132. <option value="_blank" <?php selected( $item->target, '_blank'); ?>><?php _e('New window or tab'); ?></option>
  133. </select>
  134. </label>
  135. </p>
  136. <p class="field-css-classes description description-thin">
  137. <label for="edit-menu-item-classes-<?php echo $item_id; ?>">
  138. <?php _e( 'CSS Classes (optional)' ); ?><br />
  139. <input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>" class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->classes ); ?>" />
  140. </label>
  141. </p>
  142. <p class="field-xfn description description-thin">
  143. <label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
  144. <?php _e( 'Link Relationship (XFN)' ); ?><br />
  145. <input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->xfn ); ?>" />
  146. </label>
  147. </p>
  148. <p class="field-description description description-wide">
  149. <label for="edit-menu-item-description-<?php echo $item_id; ?>">
  150. <?php _e( 'Description' ); ?><br />
  151. <textarea id="edit-menu-item-description-<?php echo $item_id; ?>" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html( $item->description ); ?></textarea>
  152. <span class="description"><?php _e('The description will be displayed in the menu if the current theme supports it.'); ?></span>
  153. </label>
  154. </p>
  155. <div class="menu-item-actions description-wide submitbox">
  156. <?php if( 'custom' != $item->type ) : ?>
  157. <p class="link-to-original"><?php
  158. _e('Original ');
  159. echo esc_html( $item->append );
  160. echo ":"; ?>
  161. <a href="<?php echo esc_attr( $item->url ); ?>">
  162. <?php echo esc_html($original_title); ?>
  163. </a>
  164. </p>
  165. <?php endif; ?>
  166. <a class="item-delete submitdelete deletion" id="delete-<?php echo $item_id; ?>" href="<?php
  167. echo wp_nonce_url(
  168. add_query_arg(
  169. array(
  170. 'action' => 'delete-menu-item',
  171. 'menu-item' => $item_id,
  172. ),
  173. remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
  174. ),
  175. 'delete-menu_item_' . $item_id
  176. ); ?>"><?php _e('Remove'); ?></a> | <a class="item-close submitclose" id="close-<?php echo $item_id; ?>" href="<?php echo admin_url( 'nav-menus.php' ); ?>"><?php _e('Close'); ?></a>
  177. <input class="button-primary save-menu-item" name="save_menu_item" type="submit" value="<?php esc_attr_e('Save Menu Item'); ?>" />
  178. </div>
  179. <input class="menu-item-data-append" type="hidden" name="menu-item-append[<?php echo $item_id; ?>]" value="<?php echo $item->append; ?>" />
  180. <input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
  181. <input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" />
  182. <input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" />
  183. <input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_item_parent ); ?>" />
  184. <input class="menu-item-data-position" type="hidden" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" />
  185. <input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" />
  186. </div><!-- .menu-item-settings-->
  187. <ul class="menu-item-transport"></ul>
  188. <?php
  189. $output .= ob_get_clean();
  190. }
  191. }
  192. /**
  193. * Prints the appropriate response to a menu quick search.
  194. *
  195. * @since 3.0.0
  196. *
  197. * @param array $request The unsanitized request values.
  198. */
  199. function _wp_ajax_menu_quick_search( $request = array() ) {
  200. $args = array();
  201. $type = isset( $request['type'] ) ? $request['type'] : '';
  202. $object_type = isset( $request['object_type'] ) ? $request['object_type'] : '';
  203. $query = isset( $request['q'] ) ? $request['q'] : '';
  204. $response_format = isset( $request['response-format'] ) && in_array( $request['response-format'], array( 'json', 'markup' ) ) ? $request['response-format'] : 'json';
  205. if ( 'markup' == $response_format ) {
  206. $args['walker'] = new Walker_Nav_Menu_Checklist;
  207. }
  208. if ( 'get-post-item' == $type ) {
  209. if ( get_post_type_object( $object_type ) ) {
  210. if ( isset( $request['ID'] ) ) {
  211. $object_id = (int) $request['ID'];
  212. if ( 'markup' == $response_format ) {
  213. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $object_id ) ) ), 0, (object) $args );
  214. } elseif ( 'json' == $response_format ) {
  215. $post_obj = get_post( $object_id );
  216. echo json_encode(
  217. array(
  218. 'ID' => $object_id,
  219. 'post_title' => get_the_title( $object_id ),
  220. 'post_type' => get_post_type( $object_id ),
  221. )
  222. );
  223. echo "\n";
  224. }
  225. }
  226. } elseif ( is_taxonomy( $object_type ) ) {
  227. if ( isset( $request['ID'] ) ) {
  228. $object_id = (int) $request['ID'];
  229. if ( 'markup' == $response_format ) {
  230. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_term( $object_id, $object_type ) ) ), 0, (object) $args );
  231. } elseif ( 'json' == $response_format ) {
  232. $post_obj = get_term( $object_id, $object_type );
  233. echo json_encode(
  234. array(
  235. 'ID' => $object_id,
  236. 'post_title' => $post_obj->name,
  237. 'post_type' => $object_type,
  238. )
  239. );
  240. echo "\n";
  241. }
  242. }
  243. }
  244. } elseif ( preg_match('/quick-search-(posttype|taxonomy)-([a-zA-Z_-]*\b)/', $type, $matches) ) {
  245. if ( 'posttype' == $matches[1] && get_post_type_object( $matches[2] ) ) {
  246. query_posts(array(
  247. 'posts_per_page' => 10,
  248. 'post_type' => $matches[2],
  249. 's' => $query,
  250. ));
  251. if ( ! have_posts() )
  252. return;
  253. while ( have_posts() ) {
  254. the_post();
  255. if ( 'markup' == $response_format ) {
  256. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( get_the_ID() ) ) ), 0, (object) $args );
  257. } elseif ( 'json' == $response_format ) {
  258. echo json_encode(
  259. array(
  260. 'ID' => get_the_ID(),
  261. 'post_title' => get_the_title(),
  262. 'post_type' => get_post_type(),
  263. )
  264. );
  265. echo "\n";
  266. }
  267. }
  268. } elseif ( 'taxonomy' == $matches[1] ) {
  269. $terms = get_terms( $matches[2], array(
  270. 'name__like' => $query,
  271. 'number' => 10,
  272. ));
  273. if ( empty( $terms ) || is_wp_error( $terms ) )
  274. return;
  275. foreach( (array) $terms as $term ) {
  276. if ( 'markup' == $response_format ) {
  277. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( $term ) ), 0, (object) $args );
  278. } elseif ( 'json' == $response_format ) {
  279. echo json_encode(
  280. array(
  281. 'ID' => $term->term_id,
  282. 'post_title' => $term->name,
  283. 'post_type' => $matches[2],
  284. )
  285. );
  286. echo "\n";
  287. }
  288. }
  289. }
  290. }
  291. }
  292. /**
  293. * Register nav menu metaboxes and advanced menu items
  294. *
  295. * @since 3.0.0
  296. **/
  297. function wp_nav_menu_setup() {
  298. // Register meta boxes
  299. add_meta_box( 'add-custom-links', __('Custom Links'), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' );
  300. wp_nav_menu_post_type_meta_boxes();
  301. wp_nav_menu_taxonomy_meta_boxes();
  302. // Register advanced menu items (columns)
  303. add_filter( 'manage_nav-menus_columns', 'wp_nav_menu_manage_columns');
  304. add_filter( 'columns_prefs_header', create_function( '', "return __('Show advanced menu properties');" ));
  305. // If first time editing, disable advanced items by default.
  306. if( false === get_user_option( 'managenav-menuscolumnshidden' ) ) {
  307. $user = wp_get_current_user();
  308. update_user_option($user->ID, 'managenav-menuscolumnshidden',
  309. array( 0 => 'link-target', 1 => 'css-classes', 2 => 'xfn', 3 => 'description', ),
  310. true);
  311. }
  312. }
  313. /**
  314. * Limit the amount of meta boxes to just links, pages and cats for first time users.
  315. *
  316. * @since 3.0.0
  317. **/
  318. function wp_initial_nav_menu_meta_boxes() {
  319. global $wp_meta_boxes;
  320. if ( get_user_option( 'metaboxhidden_nav-menus' ) || ! is_array($wp_meta_boxes) )
  321. return;
  322. $initial_meta_boxes = array( 'manage-menu', 'create-menu', 'add-custom-links', 'add-page', 'add-category' );
  323. $hidden_meta_boxes = array();
  324. foreach ( array_keys($wp_meta_boxes['nav-menus']) as $context ) {
  325. foreach ( array_keys($wp_meta_boxes['nav-menus'][$context]) as $priority ) {
  326. foreach ( $wp_meta_boxes['nav-menus'][$context][$priority] as $box ) {
  327. if ( in_array( $box['id'], $initial_meta_boxes ) ) {
  328. unset( $box['id'] );
  329. } else {
  330. $hidden_meta_boxes[] = $box['id'];
  331. }
  332. }
  333. }
  334. }
  335. $user = wp_get_current_user();
  336. update_user_option( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true );
  337. }
  338. /**
  339. * Creates metaboxes for any post type menu item.
  340. *
  341. * @since 3.0.0
  342. */
  343. function wp_nav_menu_post_type_meta_boxes() {
  344. $post_types = get_post_types( array( 'public' => true ), 'object' );
  345. if ( ! $post_types )
  346. return;
  347. foreach ( $post_types as $post_type ) {
  348. $post_type = apply_filters( 'nav_menu_meta_box_object', $post_type );
  349. if ( $post_type ) {
  350. $id = $post_type->name;
  351. add_meta_box( "add-{$id}", $post_type->label, 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type );
  352. }
  353. }
  354. }
  355. /**
  356. * Creates metaboxes for any taxonomy menu item.
  357. *
  358. * @since 3.0.0
  359. */
  360. function wp_nav_menu_taxonomy_meta_boxes() {
  361. $taxonomies = get_taxonomies( array( 'show_ui' => true ), 'object' );
  362. if ( !$taxonomies )
  363. return;
  364. foreach ( $taxonomies as $tax ) {
  365. $tax = apply_filters( 'nav_menu_meta_box_object', $tax );
  366. if ( $tax ) {
  367. $id = $tax->name;
  368. add_meta_box( "add-{$id}", $tax->label, 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax );
  369. }
  370. }
  371. }
  372. /**
  373. * Displays a metabox for the custom links menu item.
  374. *
  375. * @since 3.0.0
  376. */
  377. function wp_nav_menu_item_link_meta_box() {
  378. global $_nav_menu_placeholder;
  379. $_nav_menu_placeholder = 0 > $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1;
  380. // @note: hacky query, see #12660
  381. $args = array( 'post_type' => 'nav_menu_item', 'post_status' => 'any', 'meta_key' => '_menu_item_type', 'numberposts' => -1, 'orderby' => 'title', );
  382. // @todo transient caching of these results with proper invalidation on updating links
  383. $links = get_posts( $args );
  384. $current_tab = 'create';
  385. if ( isset( $_REQUEST['customlink-tab'] ) && in_array( $_REQUEST['customlink-tab'], array('create', 'all') ) ) {
  386. $current_tab = $_REQUEST['customlink-tab'];
  387. }
  388. $removed_args = array(
  389. 'action',
  390. 'customlink-tab',
  391. 'edit-menu-item',
  392. 'menu-item',
  393. 'page-tab',
  394. '_wpnonce',
  395. );
  396. ?>
  397. <div class="customlinkdiv">
  398. <input type="hidden" value="custom" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-type]" />
  399. <p id="menu-item-url-wrap">
  400. <label class="howto" for="custom-menu-item-url">
  401. <span><?php _e('URL'); ?></span>
  402. <input id="custom-menu-item-url" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-url]" type="text" class="code menu-item-textbox" value="http://" />
  403. </label>
  404. </p>
  405. <p id="menu-item-name-wrap">
  406. <label class="howto" for="custom-menu-item-name">
  407. <span><?php _e('Label'); ?></span>
  408. <input id="custom-menu-item-name" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e('Menu Item'); ?>" />
  409. </label>
  410. </p>
  411. <p class="button-controls">
  412. <span class="list-controls">
  413. <a href="#" class="select-all add-home-link"><?php _e('Add Home Link'); ?></a>
  414. </span>
  415. <span class="add-to-menu">
  416. <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
  417. <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" />
  418. </span>
  419. </p>
  420. <div class="clear"></div>
  421. </div><!-- /.customlinkdiv -->
  422. <?php
  423. }
  424. /**
  425. * Displays a metabox for a post type menu item.
  426. *
  427. * @since 3.0.0
  428. *
  429. * @param string $object Not used.
  430. * @param string $post_type The post type object.
  431. */
  432. function wp_nav_menu_item_post_type_meta_box( $object, $post_type ) {
  433. $post_type_name = $post_type['args']->name;
  434. // paginate browsing for large numbers of post objects
  435. $per_page = 50;
  436. $pagenum = isset( $_REQUEST[$post_type_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1;
  437. $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0;
  438. $args = array(
  439. 'offset' => $offset,
  440. 'order' => 'ASC',
  441. 'orderby' => 'title',
  442. 'posts_per_page' => $per_page,
  443. 'post_type' => $post_type_name,
  444. 'suppress_filters' => true,
  445. );
  446. if ( isset( $post_type['args']->_default_query ) )
  447. $args = array_merge($args, (array) $post_type['args']->_default_query );
  448. // @todo transient caching of these results with proper invalidation on updating of a post of this type
  449. $get_posts = new WP_Query;
  450. $posts = $get_posts->query( $args );
  451. $count_posts = (int) @count( $posts );
  452. if ( ! $count_posts ) {
  453. echo '<p>' . __( 'No items.' ) . '</p>';
  454. return;
  455. }
  456. $post_type_object = get_post_type_object($post_type_name);
  457. $num_pages = $get_posts->max_num_pages;
  458. if ( isset( $get_posts->found_posts ) && ( $get_posts->found_posts > $count_posts ) ) {
  459. // somewhat like display_page_row(), let's make sure ancestors show up on paged display
  460. $parent_ids = array();
  461. $child_ids = array();
  462. foreach( (array) $posts as $post ) {
  463. $parent_ids[] = (int) $post->post_parent;
  464. $child_ids[] = (int) $post->ID;
  465. }
  466. $parent_ids = array_unique($parent_ids);
  467. $child_ids = array_unique($child_ids);
  468. $missing_parents = array();
  469. do {
  470. foreach( (array) $missing_parents as $missing_parent_id ) {
  471. $missing_parent = get_post($missing_parent_id);
  472. $posts[] = $missing_parent;
  473. $child_ids[] = $missing_parent_id;
  474. $parent_ids[] = $missing_parent->post_parent;
  475. }
  476. $missing_parents = array_filter( array_diff( array_unique( $parent_ids ), array_unique( $child_ids ) ) );
  477. } while( 0 < count( $missing_parents ) );
  478. }
  479. $page_links = paginate_links( array(
  480. 'base' => add_query_arg(
  481. array(
  482. $post_type_name . '-tab' => 'all',
  483. 'paged' => '%#%',
  484. )
  485. ),
  486. 'format' => '',
  487. 'prev_text' => __('&laquo;'),
  488. 'next_text' => __('&raquo;'),
  489. 'total' => $num_pages,
  490. 'current' => $pagenum
  491. ));
  492. if ( !$posts )
  493. $error = '<li id="error">'. sprintf( __( 'No %s exists' ), $post_type['args']->label ) .'</li>';
  494. $current_tab = 'all';
  495. if ( isset( $_REQUEST[$post_type_name . '-tab'] ) && in_array( $_REQUEST[$post_type_name . '-tab'], array('all', 'search') ) ) {
  496. $current_tab = $_REQUEST[$post_type_name . '-tab'];
  497. }
  498. if ( ! empty( $_REQUEST['quick-search-posttype-' . $post_type_name] ) ) {
  499. $current_tab = 'search';
  500. }
  501. $removed_args = array(
  502. 'action',
  503. 'customlink-tab',
  504. 'edit-menu-item',
  505. 'menu-item',
  506. 'page-tab',
  507. '_wpnonce',
  508. );
  509. ?>
  510. <div id="posttype-<?php echo $post_type_name; ?>" class="posttypediv">
  511. <ul id="posttype-<?php echo $post_type_name; ?>-tabs" class="posttype-tabs add-menu-item-tabs">
  512. <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php echo esc_url(add_query_arg($post_type_name . '-tab', 'all', remove_query_arg($removed_args))); ?>#<?php echo $post_type_name; ?>-all"><?php _e('View All'); ?></a></li>
  513. <li <?php echo ( 'search' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php echo esc_url(add_query_arg($post_type_name . '-tab', 'search', remove_query_arg($removed_args))); ?>#tabs-panel-posttype-<?php echo $post_type_name; ?>-search"><?php _e('Search'); ?></a></li>
  514. </ul>
  515. <div class="tabs-panel <?php
  516. echo ( 'search' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
  517. ?>" id="tabs-panel-posttype-<?php echo $post_type_name; ?>-search">
  518. <?php
  519. if ( isset( $_REQUEST['quick-search-posttype-' . $post_type_name] ) ) {
  520. $searched = esc_attr( $_REQUEST['quick-search-posttype-' . $post_type_name] );
  521. $search_results = get_posts( array( 's' => $searched, 'post_type' => $post_type_name, 'fields' => 'all', 'order' => 'DESC', ) );
  522. } else {
  523. $searched = '';
  524. $search_results = array();
  525. }
  526. ?>
  527. <p class="quick-search-wrap">
  528. <input type="text" class="quick-search regular-text" value="<?php echo $searched; ?>" name="quick-search-posttype-<?php echo $post_type_name; ?>" />
  529. <input type="submit" class="quick-search-submit button-secondary" value="<?php esc_attr_e('Search'); ?>" />
  530. </p>
  531. <ul id="<?php echo $post_type_name; ?>-search-checklist" class="list:<?php echo $post_type_name?> categorychecklist form-no-clear">
  532. <?php if ( ! empty( $search_results ) && ! is_wp_error( $search_results ) ) : ?>
  533. <?php
  534. $args['walker'] = new Walker_Nav_Menu_Checklist;
  535. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $search_results), 0, (object) $args );
  536. ?>
  537. <?php elseif ( is_wp_error( $search_results ) ) : ?>
  538. <li><?php echo $search_results->get_error_message(); ?></li>
  539. <?php elseif ( ! empty( $searched ) ) : ?>
  540. <li><?php _e('No results found.'); ?></li>
  541. <?php endif; ?>
  542. </ul>
  543. </div><!-- /.tabs-panel -->
  544. <div id="<?php echo $post_type_name; ?>-all" class="tabs-panel tabs-panel-view-all <?php
  545. echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
  546. ?>">
  547. <div class="add-menu-item-pagelinks">
  548. <?php echo $page_links; ?>
  549. </div>
  550. <ul id="<?php echo $post_type_name; ?>checklist" class="list:<?php echo $post_type_name?> categorychecklist form-no-clear">
  551. <?php
  552. $args['walker'] = new Walker_Nav_Menu_Checklist;
  553. $checkbox_items = walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $posts), 0, (object) $args );
  554. if ( 'all' == $current_tab && ! empty( $_REQUEST['selectall'] ) ) {
  555. $checkbox_items = preg_replace('/(type=(.)checkbox(\2))/', '$1 checked=$2checked$2', $checkbox_items);
  556. }
  557. echo $checkbox_items;
  558. ?>
  559. </ul>
  560. <div class="add-menu-item-pagelinks">
  561. <?php echo $page_links; ?>
  562. </div>
  563. </div><!-- /.tabs-panel -->
  564. <p class="button-controls">
  565. <span class="list-controls">
  566. <a href="<?php
  567. echo esc_url(add_query_arg(
  568. array(
  569. $post_type_name . '-tab' => 'all',
  570. 'selectall' => 1,
  571. ),
  572. remove_query_arg($removed_args)
  573. ));
  574. ?>#posttype-<?php echo $post_type_name; ?>" class="select-all"><?php _e('Select All'); ?></a>
  575. </span>
  576. <span class="add-to-menu">
  577. <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
  578. <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-post-type-menu-item" />
  579. </span>
  580. </p>
  581. <br class="clear" />
  582. </div><!-- /.posttypediv -->
  583. <?php
  584. }
  585. /**
  586. * Displays a metabox for a taxonomy menu item.
  587. *
  588. * @since 3.0.0
  589. *
  590. * @param string $object Not used.
  591. * @param string $taxonomy The taxonomy object.
  592. */
  593. function wp_nav_menu_item_taxonomy_meta_box( $object, $taxonomy ) {
  594. $taxonomy_name = $taxonomy['args']->name;
  595. if ( ! $term_count = wp_count_terms( $taxonomy_name ) ) {
  596. echo '<p>' . __( 'No items.' ) . '</p>';
  597. return;
  598. }
  599. // paginate browsing for large numbers of objects
  600. $per_page = 50;
  601. $pagenum = isset( $_REQUEST[$taxonomy_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1;
  602. $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0;
  603. $args = array(
  604. 'child_of' => 0,
  605. 'exclude' => '',
  606. 'hide_empty' => false,
  607. 'hierarchical' => 1,
  608. 'include' => '',
  609. 'include_last_update_time' => false,
  610. 'number' => $per_page,
  611. 'offset' => $offset,
  612. 'order' => 'ASC',
  613. 'orderby' => 'name',
  614. 'pad_counts' => false,
  615. );
  616. $num_pages = ceil( $term_count / $per_page );
  617. $page_links = paginate_links( array(
  618. 'base' => add_query_arg(
  619. array(
  620. $taxonomy_name . '-tab' => 'all',
  621. 'paged' => '%#%',
  622. )
  623. ),
  624. 'format' => '',
  625. 'prev_text' => __('&laquo;'),
  626. 'next_text' => __('&raquo;'),
  627. 'total' => $num_pages,
  628. 'current' => $pagenum
  629. ));
  630. $walker = new Walker_Nav_Menu_Checklist;
  631. // @todo transient caching of these results with proper invalidation on updating of a tax of this type
  632. $terms = get_terms( $taxonomy_name, $args );
  633. if ( ! $terms || is_wp_error($terms) )
  634. $error = '<li id="error">'. sprintf( __( 'No %s exists' ), $taxonomy['args']->label ) .'</li>';
  635. $current_tab = 'most-used';
  636. if ( isset( $_REQUEST[$taxonomy_name . '-tab'] ) && in_array( $_REQUEST[$taxonomy_name . '-tab'], array('all', 'most-used', 'search') ) ) {
  637. $current_tab = $_REQUEST[$taxonomy_name . '-tab'];
  638. }
  639. if ( ! empty( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] ) ) {
  640. $current_tab = 'search';
  641. }
  642. $removed_args = array(
  643. 'action',
  644. 'customlink-tab',
  645. 'edit-menu-item',
  646. 'menu-item',
  647. 'page-tab',
  648. '_wpnonce',
  649. );
  650. ?>
  651. <div id="taxonomy-<?php echo $taxonomy_name; ?>" class="taxonomydiv">
  652. <ul id="taxonomy-<?php echo $taxonomy_name; ?>-tabs" class="taxonomy-tabs add-menu-item-tabs">
  653. <li <?php echo ( 'most-used' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php echo esc_url(add_query_arg($taxonomy_name . '-tab', 'most-used', remove_query_arg($removed_args))); ?>#tabs-panel-<?php echo $taxonomy_name; ?>-pop"><?php _e('Most Used'); ?></a></li>
  654. <li <?php echo ( 'search' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php echo esc_url(add_query_arg($taxonomy_name . '-tab', 'search', remove_query_arg($removed_args))); ?>#tabs-panel-search-taxonomy-<?php echo $taxonomy_name; ?>"><?php _e('Search'); ?></a></li>
  655. <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php echo esc_url(add_query_arg($taxonomy_name . '-tab', 'all', remove_query_arg($removed_args))); ?>#tabs-panel-<?php echo $taxonomy_name; ?>-all"><?php _e('View All'); ?></a></li>
  656. </ul>
  657. <div id="tabs-panel-<?php echo $taxonomy_name; ?>-pop" class="tabs-panel <?php
  658. echo ( 'most-used' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
  659. ?>">
  660. <ul id="<?php echo $taxonomy_name; ?>checklist-pop" class="categorychecklist form-no-clear" >
  661. <?php
  662. $popular_terms = get_terms( $taxonomy_name, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) );
  663. $args['walker'] = $walker;
  664. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $popular_terms), 0, (object) $args );
  665. ?>
  666. <?php
  667. ?>
  668. </ul>
  669. </div><!-- /.tabs-panel -->
  670. <div class="tabs-panel <?php
  671. echo ( 'search' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
  672. ?>" id="tabs-panel-search-taxonomy-<?php echo $taxonomy_name; ?>">
  673. <?php
  674. if ( isset( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] ) ) {
  675. $searched = esc_attr( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] );
  676. $search_results = get_terms( $taxonomy_name, array( 'name__like' => $searched, 'fields' => 'all', 'orderby' => 'count', 'order' => 'DESC', 'hierarchical' => false ) );
  677. } else {
  678. $searched = '';
  679. $search_results = array();
  680. }
  681. ?>
  682. <p class="quick-search-wrap">
  683. <input type="text" class="quick-search regular-text" value="<?php echo $searched; ?>" name="quick-search-taxonomy-<?php echo $taxonomy_name; ?>" />
  684. <input type="submit" class="quick-search-submit button-secondary" value="<?php esc_attr_e('Search'); ?>" />
  685. </p>
  686. <ul id="<?php echo $taxonomy_name; ?>-search-checklist" class="list:<?php echo $taxonomy_name?> categorychecklist form-no-clear">
  687. <?php if ( ! empty( $search_results ) && ! is_wp_error( $search_results ) ) : ?>
  688. <?php
  689. $args['walker'] = $walker;
  690. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $search_results), 0, (object) $args );
  691. ?>
  692. <?php elseif ( is_wp_error( $search_results ) ) : ?>
  693. <li><?php echo $search_results->get_error_message(); ?></li>
  694. <?php elseif ( ! empty( $searched ) ) : ?>
  695. <li><?php _e('No results found.'); ?></li>
  696. <?php endif; ?>
  697. </ul>
  698. </div><!-- /.tabs-panel -->
  699. <div id="tabs-panel-<?php echo $taxonomy_name; ?>-all" class="tabs-panel tabs-panel-view-all <?php
  700. echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
  701. ?>">
  702. <div class="add-menu-item-pagelinks">
  703. <?php echo $page_links; ?>
  704. </div>
  705. <ul id="<?php echo $taxonomy_name; ?>checklist" class="list:<?php echo $taxonomy_name?> categorychecklist form-no-clear">
  706. <?php
  707. $args['walker'] = $walker;
  708. echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $terms), 0, (object) $args );
  709. ?>
  710. </ul>
  711. <div class="add-menu-item-pagelinks">
  712. <?php echo $page_links; ?>
  713. </div>
  714. </div><!-- /.tabs-panel -->
  715. <p class="button-controls">
  716. <span class="list-controls">
  717. <a href="<?php
  718. echo esc_url(add_query_arg(
  719. array(
  720. $taxonomy_name . '-tab' => 'all',
  721. 'selectall' => 1,
  722. ),
  723. remove_query_arg($removed_args)
  724. ));
  725. ?>#taxonomy-<?php echo $taxonomy_name; ?>" class="select-all"><?php _e('Select All'); ?></a>
  726. </span>
  727. <span class="add-to-menu">
  728. <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
  729. <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-taxonomy-menu-item" />
  730. </span>
  731. </p>
  732. <br class="clear" />
  733. </div><!-- /.taxonomydiv -->
  734. <?php
  735. }
  736. /**
  737. * Save posted nav menu item data.
  738. *
  739. * @since 3.0.0
  740. *
  741. * @param int $menu_id The menu ID for which to save this item.
  742. * @param array $menu_data The unsanitized posted menu item data.
  743. * @return array The database IDs of the items saved
  744. */
  745. function wp_save_nav_menu_item( $menu_id = 0, $menu_data = array() ) {
  746. $menu_id = (int) $menu_id;
  747. $items_saved = array();
  748. if ( is_nav_menu( $menu_id ) ) {
  749. // Loop through all the menu items' POST values
  750. foreach( (array) $menu_data as $_possible_db_id => $_item_object_data ) {
  751. if (
  752. empty( $_item_object_data['menu-item-object-id'] ) && // checkbox is not checked
  753. (
  754. ! isset( $_item_object_data['menu-item-type'] ) || // and item type either isn't set
  755. in_array( $_item_object_data['menu-item-url'], array( 'http://', '' ) ) || // or URL is the default
  756. 'custom' != $_item_object_data['menu-item-type'] || // or it's not a custom menu item
  757. ! empty( $_item_object_data['menu-item-db-id'] ) // or it *is* a custom menu item that already exists
  758. )
  759. ) {
  760. continue; // then this potential menu item is not getting added to this menu
  761. }
  762. // if this possible menu item doesn't actually have a menu database ID yet
  763. if (
  764. empty( $_item_object_data['menu-item-db-id'] ) ||
  765. ( 0 > $_possible_db_id ) ||
  766. $_possible_db_id != $_item_object_data['menu-item-db-id']
  767. ) {
  768. $_actual_db_id = 0;
  769. } else {
  770. $_actual_db_id = (int) $_item_object_data['menu-item-db-id'];
  771. }
  772. $args = array(
  773. 'menu-item-db-id' => ( isset( $_item_object_data['menu-item-db-id'] ) ? $_item_object_data['menu-item-db-id'] : '' ),
  774. 'menu-item-object-id' => ( isset( $_item_object_data['menu-item-object-id'] ) ? $_item_object_data['menu-item-object-id'] : '' ),
  775. 'menu-item-object' => ( isset( $_item_object_data['menu-item-object'] ) ? $_item_object_data['menu-item-object'] : '' ),
  776. 'menu-item-parent-id' => ( isset( $_item_object_data['menu-item-parent-id'] ) ? $_item_object_data['menu-item-parent-id'] : '' ),
  777. 'menu-item-position' => ( isset( $_item_object_data['menu-item-position'] ) ? $_item_object_data['menu-item-position'] : '' ),
  778. 'menu-item-type' => ( isset( $_item_object_data['menu-item-type'] ) ? $_item_object_data['menu-item-type'] : '' ),
  779. 'menu-item-append' => ( isset( $_item_object_data['menu-item-append'] ) ? $_item_object_data['menu-item-append'] : '' ),
  780. 'menu-item-title' => ( isset( $_item_object_data['menu-item-title'] ) ? $_item_object_data['menu-item-title'] : '' ),
  781. 'menu-item-url' => ( isset( $_item_object_data['menu-item-url'] ) ? $_item_object_data['menu-item-url'] : '' ),
  782. 'menu-item-description' => ( isset( $_item_object_data['menu-item-description'] ) ? $_item_object_data['menu-item-description'] : '' ),
  783. 'menu-item-attr-title' => ( isset( $_item_object_data['menu-item-attr-title'] ) ? $_item_object_data['menu-item-attr-title'] : '' ),
  784. 'menu-item-target' => ( isset( $_item_object_data['menu-item-target'] ) ? $_item_object_data['menu-item-target'] : '' ),
  785. 'menu-item-classes' => ( isset( $_item_object_data['menu-item-classes'] ) ? $_item_object_data['menu-item-classes'] : '' ),
  786. 'menu-item-xfn' => ( isset( $_item_object_data['menu-item-xfn'] ) ? $_item_object_data['menu-item-xfn'] : '' ),
  787. );
  788. $items_saved[] = wp_update_nav_menu_item( $menu_id, $_actual_db_id, $args );
  789. }
  790. }
  791. return $items_saved;
  792. }
  793. /**
  794. * Adds custom arguments to some of the meta box object types.
  795. *
  796. * @since 3.0.0
  797. *
  798. * @access private
  799. *
  800. * @param object $object The post type or taxonomy meta-object.
  801. * @return object The post type of taxonomy object.
  802. */
  803. function _wp_nav_menu_meta_box_object( $object = null ) {
  804. if ( isset( $object->name ) ) {
  805. // don't show media meta box
  806. if ( 'attachment' == $object->name )
  807. return false;
  808. // pages should show most recent
  809. if ( 'page' == $object->name ) {
  810. $object->_default_query = array(
  811. 'orderby' => 'post_date',
  812. 'order' => 'DESC',
  813. 'post_status' => 'publish',
  814. );
  815. // posts should show only published items
  816. } elseif ( 'post' == $object->name ) {
  817. $object->_default_query = array(
  818. 'post_status' => 'publish',
  819. );
  820. // cats should be in reverse chronological order
  821. } elseif ( 'category' == $object->name ) {
  822. $object->_default_query = array(
  823. 'orderby' => 'id',
  824. 'order' => 'DESC',
  825. );
  826. }
  827. }
  828. return $object;
  829. }
  830. /**
  831. * Returns the menu item formatted to edit.
  832. *
  833. * @since 3.0.0
  834. *
  835. * @param string $menu_item_id The ID of the menu item to format.
  836. * @return string|WP_Error $output The menu formatted to edit or error object on failure.
  837. */
  838. function wp_get_nav_menu_to_edit( $menu_item_id = 0 ) {
  839. $menu = wp_get_nav_menu_object( $menu_item_id );
  840. // If the menu exists, get its items.
  841. if ( is_nav_menu( $menu ) ) {
  842. $menu_items = wp_get_nav_menu_items( $menu->term_id, array('post_status' => 'any') );
  843. $walker = new Walker_Nav_Menu_Edit;
  844. return walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $menu_items), 0, (object) array('walker' => $walker ) );
  845. } elseif ( is_wp_error( $menu ) ) {
  846. return $menu;
  847. }
  848. }
  849. /**
  850. * Returns the columns for the nav menus page.
  851. *
  852. * @since 3.0.0
  853. *
  854. * @param string $menu_item_id The ID of the menu item to format.
  855. * @return string|WP_Error $output The menu formatted to edit or error object on failure.
  856. */
  857. function wp_nav_menu_manage_columns() {
  858. return array(
  859. 'cb' => '<input type="checkbox" />',
  860. 'link-target' => __('Link Target'),
  861. 'css-classes' => __('CSS Classes'),
  862. 'xfn' => __('Link Relationship (XFN)'),
  863. 'description' => __('Description'),
  864. );
  865. }
  866. ?>