[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> nav-menu.php (source)

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


Generated: Fri May 25 03:56:23 2012 Hosted by follow the white rabbit.