Advertisement
boenicke

nav-menue.php

Jun 22nd, 2023
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.43 KB | Help | 0 0
  1. <?php
  2. /**
  3. * Navigation Menu functions
  4. *
  5. * @package WordPress
  6. * @subpackage Nav_Menus
  7. * @since 3.0.0
  8. */
  9.  
  10. /**
  11. * Returns a navigation menu object.
  12. *
  13. * @since 3.0.0
  14. *
  15. * @uses get_term
  16. * @uses get_term_by
  17. *
  18. * @param string $menu Menu id, slug or name
  19. * @return mixed false if $menu param isn't supplied or term does not exist, menu object if successful.
  20. */
  21. function wp_get_nav_menu_object( $menu ) {
  22. if ( ! $menu )
  23. return false;
  24.  
  25. $menu_obj = get_term( $menu, 'nav_menu' );
  26.  
  27. if ( ! $menu_obj )
  28. $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
  29.  
  30. if ( ! $menu_obj )
  31. $menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
  32.  
  33. if ( ! $menu_obj )
  34. $menu_obj = false;
  35.  
  36. return $menu_obj;
  37. }
  38.  
  39. /**
  40. * Check if the given ID is a navigation menu.
  41. *
  42. * Returns true if it is; false otherwise.
  43. *
  44. * @since 3.0.0
  45. *
  46. * @param int|string $menu The menu to check (id, slug, or name)
  47. * @return bool Whether the menu exists.
  48. */
  49. function is_nav_menu( $menu ) {
  50. if ( ! $menu )
  51. return false;
  52.  
  53. $menu_obj = wp_get_nav_menu_object( $menu );
  54.  
  55. if (
  56. $menu_obj &&
  57. ! is_wp_error( $menu_obj ) &&
  58. ! empty( $menu_obj->taxonomy ) &&
  59. 'nav_menu' == $menu_obj->taxonomy
  60. )
  61. return true;
  62.  
  63. return false;
  64. }
  65.  
  66. /**
  67. * Register navigation menus for a theme.
  68. *
  69. * @since 3.0.0
  70. *
  71. * @param array $locations Associative array of menu location identifiers (like a slug) and descriptive text.
  72. */
  73. function register_nav_menus( $locations = array() ) {
  74. global $_wp_registered_nav_menus;
  75.  
  76. add_theme_support( 'menus' );
  77.  
  78. $_wp_registered_nav_menus = array_merge( (array) $_wp_registered_nav_menus, $locations );
  79. }
  80.  
  81. /**
  82. * Unregisters a navigation menu for a theme.
  83. *
  84. * @param array $location the menu location identifier
  85. *
  86. * @return bool True on success, false on failure.
  87. */
  88. function unregister_nav_menu( $location ) {
  89. global $_wp_registered_nav_menus;
  90.  
  91. if ( is_array( $_wp_registered_nav_menus ) && isset( $_wp_registered_nav_menus[$location] ) ) {
  92. unset( $_wp_registered_nav_menus[$location] );
  93. return true;
  94. }
  95. return false;
  96. }
  97.  
  98. /**
  99. * Register a navigation menu for a theme.
  100. *
  101. * @since 3.0.0
  102. *
  103. * @param string $location Menu location identifier, like a slug.
  104. * @param string $description Menu location descriptive text.
  105. */
  106. function register_nav_menu( $location, $description ) {
  107. register_nav_menus( array( $location => $description ) );
  108. }
  109. /**
  110. * Returns an array of all registered navigation menus in a theme
  111. *
  112. * @since 3.0.0
  113. * @return array
  114. */
  115. function get_registered_nav_menus() {
  116. global $_wp_registered_nav_menus;
  117. if ( isset( $_wp_registered_nav_menus ) )
  118. return $_wp_registered_nav_menus;
  119. return array();
  120. }
  121.  
  122. /**
  123. * Returns an array with the registered navigation menu locations and the menu assigned to it
  124. *
  125. * @since 3.0.0
  126. * @return array
  127. */
  128.  
  129. function get_nav_menu_locations() {
  130. $locations = get_theme_mod( 'nav_menu_locations' );
  131. return ( is_array( $locations ) ) ? $locations : array();
  132. }
  133.  
  134. /**
  135. * Whether a registered nav menu location has a menu assigned to it.
  136. *
  137. * @since 3.0.0
  138. * @param string $location Menu location identifier.
  139. * @return bool Whether location has a menu.
  140. */
  141. function has_nav_menu( $location ) {
  142. $locations = get_nav_menu_locations();
  143. return ( ! empty( $locations[ $location ] ) );
  144. }
  145.  
  146. /**
  147. * Determine whether the given ID is a nav menu item.
  148. *
  149. * @since 3.0.0
  150. *
  151. * @param int $menu_item_id The ID of the potential nav menu item.
  152. * @return bool Whether the given ID is that of a nav menu item.
  153. */
  154. function is_nav_menu_item( $menu_item_id = 0 ) {
  155. return ( ! is_wp_error( $menu_item_id ) && ( 'nav_menu_item' == get_post_type( $menu_item_id ) ) );
  156. }
  157.  
  158. /**
  159. * Create a Navigation Menu.
  160. *
  161. * @since 3.0.0
  162. *
  163. * @param string $menu_name Menu Name
  164. * @return mixed Menu object on success|WP_Error on failure
  165. */
  166. function wp_create_nav_menu( $menu_name ) {
  167. return wp_update_nav_menu_object( 0, array( 'menu-name' => $menu_name ) );
  168. }
  169.  
  170. /**
  171. * Delete a Navigation Menu.
  172. *
  173. * @since 3.0.0
  174. *
  175. * @param string $menu name|id|slug
  176. * @return mixed Menu object on success|WP_Error on failure
  177. */
  178. function wp_delete_nav_menu( $menu ) {
  179. $menu = wp_get_nav_menu_object( $menu );
  180. if ( ! $menu )
  181. return false;
  182.  
  183. $menu_objects = get_objects_in_term( $menu->term_id, 'nav_menu' );
  184. if ( ! empty( $menu_objects ) ) {
  185. foreach ( $menu_objects as $item ) {
  186. wp_delete_post( $item );
  187. }
  188. }
  189.  
  190. $result = wp_delete_term( $menu->term_id, 'nav_menu' );
  191.  
  192. // Remove this menu from any locations.
  193. $locations = get_nav_menu_locations();
  194. foreach ( $locations as $location => $menu_id ) {
  195. if ( $menu_id == $menu->term_id )
  196. $locations[ $location ] = 0;
  197. }
  198. set_theme_mod( 'nav_menu_locations', $locations );
  199.  
  200. if ( $result && !is_wp_error($result) )
  201. do_action( 'wp_delete_nav_menu', $menu->term_id );
  202.  
  203. return $result;
  204. }
  205.  
  206. /**
  207. * Save the properties of a menu or create a new menu with those properties.
  208. *
  209. * @since 3.0.0
  210. *
  211. * @param int $menu_id The ID of the menu or "0" to create a new menu.
  212. * @param array $menu_data The array of menu data.
  213. * @return int|error object The menu's ID or WP_Error object.
  214. */
  215. function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
  216. $menu_id = (int) $menu_id;
  217.  
  218. $_menu = wp_get_nav_menu_object( $menu_id );
  219.  
  220. $args = array(
  221. 'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ),
  222. 'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
  223. 'parent' => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ),
  224. 'slug' => null,
  225. );
  226.  
  227. // double-check that we're not going to have one menu take the name of another
  228. $_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
  229. if (
  230. $_possible_existing &&
  231. ! is_wp_error( $_possible_existing ) &&
  232. isset( $_possible_existing->term_id ) &&
  233. $_possible_existing->term_id != $menu_id
  234. )
  235. return new WP_Error( 'menu_exists', sprintf( __('The menu name <strong>%s</strong> conflicts with another menu name. Please try another.'), esc_html( $menu_data['menu-name'] ) ) );
  236.  
  237. // menu doesn't already exist, so create a new menu
  238. if ( ! $_menu || is_wp_error( $_menu ) ) {
  239. $menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
  240.  
  241. if ( $menu_exists )
  242. return new WP_Error( 'menu_exists', sprintf( __('The menu name <strong>%s</strong> conflicts with another menu name. Please try another.'), esc_html( $menu_data['menu-name'] ) ) );
  243.  
  244. $_menu = wp_insert_term( $menu_data['menu-name'], 'nav_menu', $args );
  245.  
  246. if ( is_wp_error( $_menu ) )
  247. return $_menu;
  248.  
  249. do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data );
  250.  
  251. return (int) $_menu['term_id'];
  252. }
  253.  
  254. if ( ! $_menu || ! isset( $_menu->term_id ) )
  255. return 0;
  256.  
  257. $menu_id = (int) $_menu->term_id;
  258.  
  259. $update_response = wp_update_term( $menu_id, 'nav_menu', $args );
  260.  
  261. if ( is_wp_error( $update_response ) )
  262. return $update_response;
  263.  
  264. do_action( 'wp_update_nav_menu', $menu_id, $menu_data );
  265. return $menu_id;
  266. }
  267.  
  268. /**
  269. * Save the properties of a menu item or create a new one.
  270. *
  271. * @since 3.0.0
  272. *
  273. * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan.
  274. * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
  275. * @param array $menu_item_data The menu item's data.
  276. * @return int The menu item's database ID or WP_Error object on failure.
  277. */
  278. function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
  279. $menu_id = (int) $menu_id;
  280. $menu_item_db_id = (int) $menu_item_db_id;
  281.  
  282. // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
  283. if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) )
  284. return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
  285.  
  286. $menu = wp_get_nav_menu_object( $menu_id );
  287.  
  288. if ( ( ! $menu && 0 !== $menu_id ) || is_wp_error( $menu ) )
  289. return $menu;
  290.  
  291. $defaults = array(
  292. 'menu-item-db-id' => $menu_item_db_id,
  293. 'menu-item-object-id' => 0,
  294. 'menu-item-object' => '',
  295. 'menu-item-parent-id' => 0,
  296. 'menu-item-position' => 0,
  297. 'menu-item-type' => 'custom',
  298. 'menu-item-title' => '',
  299. 'menu-item-url' => '',
  300. 'menu-item-description' => '',
  301. 'menu-item-attr-title' => '',
  302. 'menu-item-target' => '',
  303. 'menu-item-classes' => '',
  304. 'menu-item-xfn' => '',
  305. 'menu-item-status' => '',
  306. );
  307.  
  308. $args = wp_parse_args( $menu_item_data, $defaults );
  309.  
  310. if ( 0 == $menu_id ) {
  311. $args['menu-item-position'] = 1;
  312. } elseif ( 0 == (int) $args['menu-item-position'] ) {
  313. $menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
  314. $last_item = array_pop( $menu_items );
  315. $args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : count( $menu_items );
  316. }
  317.  
  318. $original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0;
  319.  
  320. if ( 'custom' != $args['menu-item-type'] ) {
  321. /* if non-custom menu item, then:
  322. * use original object's URL
  323. * blank default title to sync with original object's
  324. */
  325.  
  326. $args['menu-item-url'] = '';
  327.  
  328. $original_title = '';
  329. if ( 'taxonomy' == $args['menu-item-type'] ) {
  330. $original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
  331. $original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
  332. } elseif ( 'post_type' == $args['menu-item-type'] ) {
  333.  
  334. $original_object = get_post( $args['menu-item-object-id'] );
  335. $original_parent = (int) $original_object->post_parent;
  336. $original_title = $original_object->post_title;
  337. }
  338.  
  339. if ( $args['menu-item-title'] == $original_title )
  340. $args['menu-item-title'] = '';
  341.  
  342. // hack to get wp to create a post object when too many properties are empty
  343. if ( '' == $args['menu-item-title'] && '' == $args['menu-item-description'] )
  344. $args['menu-item-description'] = ' ';
  345. }
  346.  
  347. // Populate the menu item object
  348. $post = array(
  349. 'menu_order' => $args['menu-item-position'],
  350. 'ping_status' => 0,
  351. 'post_content' => $args['menu-item-description'],
  352. 'post_excerpt' => $args['menu-item-attr-title'],
  353. 'post_parent' => $original_parent,
  354. 'post_title' => $args['menu-item-title'],
  355. 'post_type' => 'nav_menu_item',
  356. );
  357.  
  358. $update = 0 != $menu_item_db_id;
  359.  
  360. // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
  361. if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) )
  362. $post['tax_input'] = array( 'nav_menu' => array( intval( $menu->term_id ) ) );
  363.  
  364. // New menu item. Default is draft status
  365. if ( ! $update ) {
  366. $post['ID'] = 0;
  367. $post['post_status'] = 'publish' == $args['menu-item-status'] ? 'publish' : 'draft';
  368. $menu_item_db_id = wp_insert_post( $post );
  369. if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) )
  370. return $menu_item_db_id;
  371. }
  372.  
  373. if ( 'custom' == $args['menu-item-type'] ) {
  374. $args['menu-item-object-id'] = $menu_item_db_id;
  375. $args['menu-item-object'] = 'custom';
  376. }
  377.  
  378. $menu_item_db_id = (int) $menu_item_db_id;
  379.  
  380. update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) );
  381. update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', strval( (int) $args['menu-item-parent-id'] ) );
  382. update_post_meta( $menu_item_db_id, '_menu_item_object_id', strval( (int) $args['menu-item-object-id'] ) );
  383. update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) );
  384. update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']) );
  385.  
  386. $args['menu-item-classes'] = array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-classes'] ) );
  387. $args['menu-item-xfn'] = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) );
  388. update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] );
  389. update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] );
  390. update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) );
  391.  
  392. if ( 0 == $menu_id )
  393. update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() );
  394. elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) )
  395. delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' );
  396.  
  397. // Update existing menu item. Default is publish status
  398. if ( $update ) {
  399. $post['ID'] = $menu_item_db_id;
  400. $post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish';
  401. wp_update_post( $post );
  402. }
  403.  
  404. do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args );
  405.  
  406. return $menu_item_db_id;
  407. }
  408.  
  409. /**
  410. * Returns all navigation menu objects.
  411. *
  412. * @since 3.0.0
  413. *
  414. * @param array $args Array of arguments passed on to get_terms().
  415. * @return array menu objects
  416. */
  417. function wp_get_nav_menus( $args = array() ) {
  418. $defaults = array( 'hide_empty' => false, 'orderby' => 'none' );
  419. $args = wp_parse_args( $args, $defaults );
  420. return apply_filters( 'wp_get_nav_menus', get_terms( 'nav_menu', $args), $args );
  421. }
  422.  
  423. /**
  424. * Sort menu items by the desired key.
  425. *
  426. * @since 3.0.0
  427. * @access private
  428. *
  429. * @param object $a The first object to compare
  430. * @param object $b The second object to compare
  431. * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
  432. */
  433. function _sort_nav_menu_items( $a, $b ) {
  434. global $_menu_item_sort_prop;
  435.  
  436. if ( empty( $_menu_item_sort_prop ) )
  437. return 0;
  438.  
  439. if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) )
  440. return 0;
  441.  
  442. $_a = (int) $a->$_menu_item_sort_prop;
  443. $_b = (int) $b->$_menu_item_sort_prop;
  444.  
  445. if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop )
  446. return 0;
  447. elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop )
  448. return $_a < $_b ? -1 : 1;
  449. else
  450. return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
  451. }
  452.  
  453. /**
  454. * Returns if a menu item is valid. Bug #13958
  455. *
  456. * @since 3.2.0
  457. * @access private
  458. *
  459. * @param object $menu_item The menu item to check
  460. * @return bool false if invalid, else true.
  461. */
  462. function _is_valid_nav_menu_item( $item ) {
  463. if ( ! empty( $item->_invalid ) )
  464. return false;
  465.  
  466. return true;
  467. }
  468.  
  469. /**
  470. * Returns all menu items of a navigation menu.
  471. *
  472. * @since 3.0.0
  473. *
  474. * @param string $menu menu name, id, or slug
  475. * @param string $args
  476. * @return mixed $items array of menu items, else false.
  477. */
  478. function wp_get_nav_menu_items( $menu, $args = array() ) {
  479. $menu = wp_get_nav_menu_object( $menu );
  480.  
  481. if ( ! $menu )
  482. return false;
  483.  
  484. static $fetched = array();
  485.  
  486. $items = get_objects_in_term( $menu->term_id, 'nav_menu' );
  487.  
  488. if ( empty( $items ) )
  489. return $items;
  490.  
  491. $defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item',
  492. 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true );
  493. $args = wp_parse_args( $args, $defaults );
  494. if ( count( $items ) > 1 )
  495. $args['include'] = implode( ',', $items );
  496. else
  497. $args['include'] = $items[0];
  498.  
  499. $items = get_posts( $args );
  500.  
  501. if ( is_wp_error( $items ) || ! is_array( $items ) )
  502. return false;
  503.  
  504. // Get all posts and terms at once to prime the caches
  505. if ( empty( $fetched[$menu->term_id] ) || wp_using_ext_object_cache() ) {
  506. $fetched[$menu->term_id] = true;
  507. $posts = array();
  508. $terms = array();
  509. foreach ( $items as $item ) {
  510. $object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
  511. $object = get_post_meta( $item->ID, '_menu_item_object', true );
  512. $type = get_post_meta( $item->ID, '_menu_item_type', true );
  513.  
  514. if ( 'post_type' == $type )
  515. $posts[$object][] = $object_id;
  516. elseif ( 'taxonomy' == $type)
  517. $terms[$object][] = $object_id;
  518. }
  519.  
  520. if ( ! empty( $posts ) ) {
  521. foreach ( array_keys($posts) as $post_type ) {
  522. get_posts( array('post__in' => $posts[$post_type], 'post_type' => $post_type, 'nopaging' => true, 'update_post_term_cache' => false) );
  523. }
  524. }
  525. unset($posts);
  526.  
  527. if ( ! empty( $terms ) ) {
  528. foreach ( array_keys($terms) as $taxonomy ) {
  529. get_terms($taxonomy, array('include' => $terms[$taxonomy]) );
  530. }
  531. }
  532. unset($terms);
  533. }
  534.  
  535. $items = array_map( 'wp_setup_nav_menu_item', $items );
  536.  
  537. if ( ! is_admin() ) // Remove invalid items only in frontend
  538. $items = array_filter( $items, '_is_valid_nav_menu_item' );
  539.  
  540. if ( ARRAY_A == $args['output'] ) {
  541. $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
  542. usort($items, '_sort_nav_menu_items');
  543. $i = 1;
  544. foreach( $items as $k => $item ) {
  545. $items[$k]->$args['output_key'] = $i++;
  546. }
  547. }
  548.  
  549. return apply_filters( 'wp_get_nav_menu_items', $items, $menu, $args );
  550. }
  551.  
  552. /**
  553. * Decorates a menu item object with the shared navigation menu item properties.
  554. *
  555. * Properties:
  556. * - db_id: The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
  557. * - object_id: The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
  558. * - type: The family of objects originally represented, such as "post_type" or "taxonomy."
  559. * - object: The type of object originally represented, such as "category," "post", or "attachment."
  560. * - type_label: The singular label used to describe this type of menu item.
  561. * - post_parent: The DB ID of the original object's parent object, if any (0 otherwise).
  562. * - menu_item_parent: The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
  563. * - url: The URL to which this menu item points.
  564. * - title: The title of this menu item.
  565. * - target: The target attribute of the link element for this menu item.
  566. * - attr_title: The title attribute of the link element for this menu item.
  567. * - classes: The array of class attribute values for the link element of this menu item.
  568. * - xfn: The XFN relationship expressed in the link of this menu item.
  569. * - description: The description of this menu item.
  570. *
  571. * @since 3.0.0
  572. *
  573. * @param object $menu_item The menu item to modify.
  574. * @return object $menu_item The menu item with standard menu item properties.
  575. */
  576. function wp_setup_nav_menu_item( $menu_item ) {
  577. if ( isset( $menu_item->post_type ) ) {
  578. if ( 'nav_menu_item' == $menu_item->post_type ) {
  579. $menu_item->db_id = (int) $menu_item->ID;
  580. $menu_item->menu_item_parent = empty( $menu_item->menu_item_parent ) ? get_post_meta( $menu_item->ID, '_menu_item_menu_item_parent', true ) : $menu_item->menu_item_parent;
  581. $menu_item->object_id = empty( $menu_item->object_id ) ? get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) : $menu_item->object_id;
  582. $menu_item->object = empty( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object;
  583. $menu_item->type = empty( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type;
  584.  
  585. if ( 'post_type' == $menu_item->type ) {
  586. $object = get_post_type_object( $menu_item->object );
  587. if ( $object ) {
  588. $menu_item->type_label = $object->labels->singular_name;
  589. } else {
  590. $menu_item->type_label = $menu_item->object;
  591. $menu_item->_invalid = true;
  592. }
  593.  
  594. $menu_item->url = get_permalink( $menu_item->object_id );
  595.  
  596. $original_object = get_post( $menu_item->object_id );
  597. $original_title = $original_object->post_title;
  598. $menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
  599.  
  600. } elseif ( 'taxonomy' == $menu_item->type ) {
  601. $object = get_taxonomy( $menu_item->object );
  602. if ( $object ) {
  603. $menu_item->type_label = $object->labels->singular_name;
  604. } else {
  605. $menu_item->type_label = $menu_item->object;
  606. $menu_item->_invalid = true;
  607. }
  608.  
  609. $term_url = get_term_link( (int) $menu_item->object_id, $menu_item->object );
  610. $menu_item->url = !is_wp_error( $term_url ) ? $term_url : '';
  611.  
  612. $original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' );
  613. if ( is_wp_error( $original_title ) )
  614. $original_title = false;
  615. $menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
  616.  
  617. } else {
  618. $menu_item->type_label = __('Custom');
  619. $menu_item->title = $menu_item->post_title;
  620. $menu_item->url = empty( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url;
  621. }
  622.  
  623. $menu_item->target = empty( $menu_item->target ) ? get_post_meta( $menu_item->ID, '_menu_item_target', true ) : $menu_item->target;
  624.  
  625. $menu_item->attr_title = empty( $menu_item->attr_title ) ? apply_filters( 'nav_menu_attr_title', $menu_item->post_excerpt ) : $menu_item->attr_title;
  626.  
  627. if ( empty( $menu_item->description ) )
  628. $menu_item->description = apply_filters( 'nav_menu_description', wp_trim_words( $menu_item->post_content, 200 ) );
  629.  
  630. $menu_item->classes = empty( $menu_item->classes ) ? (array) get_post_meta( $menu_item->ID, '_menu_item_classes', true ) : $menu_item->classes;
  631. $menu_item->xfn = empty( $menu_item->xfn ) ? get_post_meta( $menu_item->ID, '_menu_item_xfn', true ) : $menu_item->xfn;
  632. } else {
  633. $menu_item->db_id = 0;
  634. $menu_item->menu_item_parent = 0;
  635. $menu_item->object_id = (int) $menu_item->ID;
  636. $menu_item->type = 'post_type';
  637.  
  638. $object = get_post_type_object( $menu_item->post_type );
  639. $menu_item->object = $object->name;
  640. $menu_item->type_label = $object->labels->singular_name;
  641.  
  642. if ( '' === $menu_item->post_title )
  643. $menu_item->post_title = sprintf( __( '#%d (no title)' ), $menu_item->ID );
  644.  
  645. $menu_item->title = $menu_item->post_title;
  646. $menu_item->url = get_permalink( $menu_item->ID );
  647. $menu_item->target = '';
  648.  
  649. $menu_item->attr_title = apply_filters( 'nav_menu_attr_title', '' );
  650. $menu_item->description = apply_filters( 'nav_menu_description', '' );
  651. $menu_item->classes = array();
  652. $menu_item->xfn = '';
  653. }
  654. } elseif ( isset( $menu_item->taxonomy ) ) {
  655. $menu_item->ID = $menu_item->term_id;
  656. $menu_item->db_id = 0;
  657. $menu_item->menu_item_parent = 0;
  658. $menu_item->object_id = (int) $menu_item->term_id;
  659. $menu_item->post_parent = (int) $menu_item->parent;
  660. $menu_item->type = 'taxonomy';
  661.  
  662. $object = get_taxonomy( $menu_item->taxonomy );
  663. $menu_item->object = $object->name;
  664. $menu_item->type_label = $object->labels->singular_name;
  665.  
  666. $menu_item->title = $menu_item->name;
  667. $menu_item->url = get_term_link( $menu_item, $menu_item->taxonomy );
  668. $menu_item->target = '';
  669. $menu_item->attr_title = '';
  670. $menu_item->description = get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy );
  671. $menu_item->classes = array();
  672. $menu_item->xfn = '';
  673.  
  674. }
  675.  
  676. return apply_filters( 'wp_setup_nav_menu_item', $menu_item );
  677. }
  678.  
  679. /**
  680. * Get the menu items associated with a particular object.
  681. *
  682. * @since 3.0.0
  683. *
  684. * @param int $object_id The ID of the original object.
  685. * @param string $object_type The type of object, such as "taxonomy" or "post_type."
  686. * @param string $taxonomy If $object_type is "taxonomy", $taxonomy is the name of the tax that $object_id belongs to
  687. * @return array The array of menu item IDs; empty array if none;
  688. */
  689. function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type', $taxonomy = '' ) {
  690. $object_id = (int) $object_id;
  691. $menu_item_ids = array();
  692.  
  693. $query = new WP_Query;
  694. $menu_items = $query->query(
  695. array(
  696. 'meta_key' => '_menu_item_object_id',
  697. 'meta_value' => $object_id,
  698. 'post_status' => 'any',
  699. 'post_type' => 'nav_menu_item',
  700. 'posts_per_page' => -1,
  701. )
  702. );
  703. foreach( (array) $menu_items as $menu_item ) {
  704. if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) {
  705. if ( get_post_meta( $menu_item->ID, '_menu_item_type', true ) !== $object_type ||
  706. get_post_meta( $menu_item->ID, '_menu_item_object', true ) !== $taxonomy )
  707. continue;
  708.  
  709. $menu_item_ids[] = (int) $menu_item->ID;
  710. }
  711. }
  712.  
  713. return array_unique( $menu_item_ids );
  714. }
  715.  
  716. /**
  717. * Callback for handling a menu item when its original object is deleted.
  718. *
  719. * @since 3.0.0
  720. * @access private
  721. *
  722. * @param int $object_id The ID of the original object being trashed.
  723. *
  724. */
  725. function _wp_delete_post_menu_item( $object_id = 0 ) {
  726. $object_id = (int) $object_id;
  727.  
  728. $menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'post_type' );
  729.  
  730. foreach( (array) $menu_item_ids as $menu_item_id ) {
  731. wp_delete_post( $menu_item_id, true );
  732. }
  733. }
  734.  
  735. /**
  736. * Callback for handling a menu item when its original object is deleted.
  737. *
  738. * @since 3.0.0
  739. * @access private
  740. *
  741. * @param int $object_id The ID of the original object being trashed.
  742. *
  743. */
  744. function _wp_delete_tax_menu_item( $object_id = 0, $tt_id, $taxonomy ) {
  745. $object_id = (int) $object_id;
  746.  
  747. $menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'taxonomy', $taxonomy );
  748.  
  749. foreach( (array) $menu_item_ids as $menu_item_id ) {
  750. wp_delete_post( $menu_item_id, true );
  751. }
  752. }
  753.  
  754. /**
  755. * Automatically add newly published page objects to menus with that as an option.
  756. *
  757. * @since 3.0.0
  758. * @access private
  759. *
  760. * @param string $new_status The new status of the post object.
  761. * @param string $old_status The old status of the post object.
  762. * @param object $post The post object being transitioned from one status to another.
  763. * @return void
  764. */
  765. function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) {
  766. if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type )
  767. return;
  768. if ( ! empty( $post->post_parent ) )
  769. return;
  770. $auto_add = get_option( 'nav_menu_options' );
  771. if ( empty( $auto_add ) || ! is_array( $auto_add ) || ! isset( $auto_add['auto_add'] ) )
  772. return;
  773. $auto_add = $auto_add['auto_add'];
  774. if ( empty( $auto_add ) || ! is_array( $auto_add ) )
  775. return;
  776.  
  777. $args = array(
  778. 'menu-item-object-id' => $post->ID,
  779. 'menu-item-object' => $post->post_type,
  780. 'menu-item-type' => 'post_type',
  781. 'menu-item-status' => 'publish',
  782. );
  783.  
  784. foreach ( $auto_add as $menu_id ) {
  785. $items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
  786. if ( ! is_array( $items ) )
  787. continue;
  788. foreach ( $items as $item ) {
  789. if ( $post->ID == $item->object_id )
  790. continue 2;
  791. }
  792. wp_update_nav_menu_item( $menu_id, 0, $args );
  793. }
  794. }
  795.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement