/** * Re-apply the tail logic also applied on $items by wp_get_nav_menu_items(). * * @since 4.3.0 * @access public * @static * * @see wp_get_nav_menu_items() * * @param array $items An array of menu item post objects. * @param object $menu The menu object. * @param array $args An array of arguments used to retrieve menu item objects. * @return array Array of menu items, */ public static function sort_wp_get_nav_menu_items($items, $menu, $args) { // @todo We should probably re-apply some constraints imposed by $args. unset($args['include']); // Remove invalid items only in front end. if (!is_admin()) { $items = array_filter($items, '_is_valid_nav_menu_item'); } if (ARRAY_A === $args['output']) { $items = wp_list_sort($items, array($args['output_key'] => 'ASC')); $i = 1; foreach ($items as $k => $item) { $items[$k]->{$args['output_key']} = $i++; } } return $items; }
/** * @dataProvider data_test_wp_list_sort_preserve_keys * * @param string|array $orderby Either the field name to order by or an array * of multiple orderby fields as $orderby => $order. * @param string $order Either 'ASC' or 'DESC'. */ public function test_wp_list_sort_preserve_keys($list, $orderby, $order, $expected) { $this->assertEquals($expected, wp_list_sort($list, $orderby, $order, true)); }
/** * Filter to allow product_cat in the permalinks for products. * * @param string $permalink The existing permalink URL. * @param WP_Post $post * @return string */ function wc_product_post_type_link($permalink, $post) { // Abort if post is not a product. if ('product' !== $post->post_type) { return $permalink; } // Abort early if the placeholder rewrite tag isn't in the generated URL. if (false === strpos($permalink, '%')) { return $permalink; } // Get the custom taxonomy terms in use by this post. $terms = get_the_terms($post->ID, 'product_cat'); if (!empty($terms)) { if (function_exists('wp_list_sort')) { $terms = wp_list_sort($terms, 'term_id', 'ASC'); } else { usort($terms, '_usort_terms_by_ID'); } $category_object = apply_filters('wc_product_post_type_link_product_cat', $terms[0], $terms, $post); $category_object = get_term($category_object, 'product_cat'); $product_cat = $category_object->slug; if ($category_object->parent) { $ancestors = get_ancestors($category_object->term_id, 'product_cat'); foreach ($ancestors as $ancestor) { $ancestor_object = get_term($ancestor, 'product_cat'); $product_cat = $ancestor_object->slug . '/' . $product_cat; } } } else { // If no terms are assigned to this post, use a string instead (can't leave the placeholder there) $product_cat = _x('uncategorized', 'slug', 'woocommerce'); } $find = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%category%', '%product_cat%'); $replace = array(date_i18n('Y', strtotime($post->post_date)), date_i18n('m', strtotime($post->post_date)), date_i18n('d', strtotime($post->post_date)), date_i18n('H', strtotime($post->post_date)), date_i18n('i', strtotime($post->post_date)), date_i18n('s', strtotime($post->post_date)), $post->ID, $product_cat, $product_cat); $permalink = str_replace($find, $replace, $permalink); return $permalink; }
/** * Returns a list of fields. * * The fields can optionally be filtered and sorted by specific properties. * * @since 1.0.0 * @access public * * @param array $filter Optional. Array of property names as keys and their values to filter as values. * Default empty array. * @param array $sort Optional. Array of property names as keys and either 'ASC' or 'DESC' as values, * in the priority order the fields should be sorted by. * Default empty array. * @return array Array of field objects. */ public function get_fields($filter = array(), $sort = array()) { $fields = array_merge($this->default_fields, $this->fields); if (!empty($filter)) { $fields = wp_list_filter($fields, $filter); } if (!empty($sort)) { $fields = wp_list_sort($fields, $sort); } return $fields; }
/** * Prepare panels, sections, and controls. * * For each, check if required related components exist, * whether the user has the necessary capabilities, * and sort by priority. * * @since 3.4.0 */ public function prepare_controls() { $controls = array(); $this->controls = wp_list_sort($this->controls, array('priority' => 'ASC', 'instance_number' => 'ASC'), 'ASC', true); foreach ($this->controls as $id => $control) { if (!isset($this->sections[$control->section]) || !$control->check_capabilities()) { continue; } $this->sections[$control->section]->controls[] = $control; $controls[$id] = $control; } $this->controls = $controls; // Prepare sections. $this->sections = wp_list_sort($this->sections, array('priority' => 'ASC', 'instance_number' => 'ASC'), 'ASC', true); $sections = array(); foreach ($this->sections as $section) { if (!$section->check_capabilities()) { continue; } $section->controls = wp_list_sort($section->controls, array('priority' => 'ASC', 'instance_number' => 'ASC')); if (!$section->panel) { // Top-level section. $sections[$section->id] = $section; } else { // This section belongs to a panel. if (isset($this->panels[$section->panel])) { $this->panels[$section->panel]->sections[$section->id] = $section; } } } $this->sections = $sections; // Prepare panels. $this->panels = wp_list_sort($this->panels, array('priority' => 'ASC', 'instance_number' => 'ASC'), 'ASC', true); $panels = array(); foreach ($this->panels as $panel) { if (!$panel->check_capabilities()) { continue; } $panel->sections = wp_list_sort($panel->sections, array('priority' => 'ASC', 'instance_number' => 'ASC'), 'ASC', true); $panels[$panel->id] = $panel; } $this->panels = $panels; // Sort panels and top-level sections together. $this->containers = array_merge($this->panels, $this->sections); $this->containers = wp_list_sort($this->containers, array('priority' => 'ASC', 'instance_number' => 'ASC'), 'ASC', true); }
/** * Retrieves the full permalink for the current post or post ID. * * @since 1.0.0 * * @param int|WP_Post $post Optional. Post ID or post object. Default is the global `$post`. * @param bool $leavename Optional. Whether to keep post name or page name. Default false. * @return string|false The permalink URL or false if post does not exist. */ function get_permalink($post = 0, $leavename = false) { $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%'); if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) { $sample = true; } else { $post = get_post($post); $sample = false; } if (empty($post->ID)) { return false; } if ($post->post_type == 'page') { return get_page_link($post, $leavename, $sample); } elseif ($post->post_type == 'attachment') { return get_attachment_link($post, $leavename); } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) { return get_post_permalink($post, $leavename, $sample); } $permalink = get_option('permalink_structure'); /** * Filters the permalink structure for a post before token replacement occurs. * * Only applies to posts with post_type of 'post'. * * @since 3.0.0 * * @param string $permalink The site's permalink structure. * @param WP_Post $post The post in question. * @param bool $leavename Whether to keep the post name. */ $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename); if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) { $unixtime = strtotime($post->post_date); $category = ''; if (strpos($permalink, '%category%') !== false) { $cats = get_the_category($post->ID); if ($cats) { $cats = wp_list_sort($cats, array('term_id' => 'ASC')); /** * Filters the category that gets used in the %category% permalink token. * * @since 3.5.0 * * @param WP_Term $cat The category to use in the permalink. * @param array $cats Array of all categories (WP_Term objects) associated with the post. * @param WP_Post $post The post in question. */ $category_object = apply_filters('post_link_category', $cats[0], $cats, $post); $category_object = get_term($category_object, 'category'); $category = $category_object->slug; if ($parent = $category_object->parent) { $category = get_category_parents($parent, false, '/', true) . $category; } } // show default category in permalinks, without // having to assign it explicitly if (empty($category)) { $default_category = get_term(get_option('default_category'), 'category'); if ($default_category && !is_wp_error($default_category)) { $category = $default_category->slug; } } } $author = ''; if (strpos($permalink, '%author%') !== false) { $authordata = get_userdata($post->post_author); $author = $authordata->user_nicename; } $date = explode(" ", date('Y m d H i s', $unixtime)); $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name); $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink)); $permalink = user_trailingslashit($permalink, 'single'); } else { // if they're not using the fancy permalink option $permalink = home_url('?p=' . $post->ID); } /** * Filters the permalink for a post. * * Only applies to posts with post_type of 'post'. * * @since 1.5.0 * * @param string $permalink The post's permalink. * @param WP_Post $post The post in question. * @param bool $leavename Whether to keep the post name. */ return apply_filters('post_link', $permalink, $post, $leavename); }
/** * Filters the wp_get_nav_menus() result to ensure the inserted menu object is included, and the deleted one is removed. * * @since 4.3.0 * @access public * * @see wp_get_nav_menus() * * @param array $menus An array of menu objects. * @param array $args An array of arguments used to retrieve menu objects. * @return array */ public function filter_wp_get_nav_menus($menus, $args) { if (get_current_blog_id() !== $this->_previewed_blog_id) { return $menus; } $setting_value = $this->value(); $is_delete = false === $setting_value; $index = -1; // Find the existing menu item's position in the list. foreach ($menus as $i => $menu) { if ((int) $this->term_id === (int) $menu->term_id || (int) $this->previous_term_id === (int) $menu->term_id) { $index = $i; break; } } if ($is_delete) { // Handle deleted menu by removing it from the list. if (-1 !== $index) { array_splice($menus, $index, 1); } } else { // Handle menus being updated or inserted. $menu_obj = (object) array_merge(array('term_id' => $this->term_id, 'term_taxonomy_id' => $this->term_id, 'slug' => sanitize_title($setting_value['name']), 'count' => 0, 'term_group' => 0, 'taxonomy' => self::TAXONOMY, 'filter' => 'raw'), $setting_value); array_splice($menus, $index, -1 === $index ? 0 : 1, array($menu_obj)); } // Make sure the menu objects get re-sorted after an update/insert. if (!$is_delete && !empty($args['orderby'])) { $menus = wp_list_sort($menus, array($args['orderby'] => 'ASC')); } // @todo add support for $args['hide_empty'] === true return $menus; }
/** * Return all menu items of a navigation menu. * * @since 3.0.0 * * @global string $_menu_item_sort_prop * @staticvar array $fetched * * @param string $menu Menu name, ID, or slug. * @param array $args Optional. Arguments to pass to get_posts(). * @return false|array $items Array of menu items, otherwise false. */ function wp_get_nav_menu_items($menu, $args = array()) { $menu = wp_get_nav_menu_object($menu); if (!$menu) { return false; } static $fetched = array(); $items = get_objects_in_term($menu->term_id, 'nav_menu'); if (is_wp_error($items)) { return false; } $defaults = array('order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true); $args = wp_parse_args($args, $defaults); $args['include'] = $items; if (!empty($items)) { $items = get_posts($args); } else { $items = array(); } // Get all posts and terms at once to prime the caches if (empty($fetched[$menu->term_id]) || wp_using_ext_object_cache()) { $fetched[$menu->term_id] = true; $posts = array(); $terms = array(); foreach ($items as $item) { $object_id = get_post_meta($item->ID, '_menu_item_object_id', true); $object = get_post_meta($item->ID, '_menu_item_object', true); $type = get_post_meta($item->ID, '_menu_item_type', true); if ('post_type' == $type) { $posts[$object][] = $object_id; } elseif ('taxonomy' == $type) { $terms[$object][] = $object_id; } } if (!empty($posts)) { foreach (array_keys($posts) as $post_type) { get_posts(array('post__in' => $posts[$post_type], 'post_type' => $post_type, 'nopaging' => true, 'update_post_term_cache' => false)); } } unset($posts); if (!empty($terms)) { foreach (array_keys($terms) as $taxonomy) { get_terms($taxonomy, array('include' => $terms[$taxonomy], 'hierarchical' => false)); } } unset($terms); } $items = array_map('wp_setup_nav_menu_item', $items); if (!is_admin()) { // Remove invalid items only in front end $items = array_filter($items, '_is_valid_nav_menu_item'); } if (ARRAY_A == $args['output']) { $items = wp_list_sort($items, array($args['output_key'] => 'ASC')); $i = 1; foreach ($items as $k => $item) { $items[$k]->{$args['output_key']} = $i++; } } /** * Filters the navigation menu items being returned. * * @since 3.0.0 * * @param array $items An array of menu item post objects. * @param object $menu The menu object. * @param array $args An array of arguments used to retrieve menu item objects. */ return apply_filters('wp_get_nav_menu_items', $items, $menu, $args); }