Advertisement
IgorGal

Untitled

Dec 3rd, 2019
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 40.88 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Breadcrumb Trail - A breadcrumb menu script for WordPress.
  4.  *
  5.  * Breadcrumb Trail is a script for showing a breadcrumb trail for any type of page.  It tries to
  6.  * anticipate any type of structure and display the best possible trail that matches your site's
  7.  * permalink structure.  While not perfect, it attempts to fill in the gaps left by many other
  8.  * breadcrumb scripts.
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
  11.  * General Public License as published by the Free Software Foundation; either version 2 of the License,
  12.  * or (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  15.  * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * @package   BreadcrumbTrail
  18.  * @version   1.1.0
  19.  * @author    Justin Tadlock <justin@justintadlock.com>
  20.  * @copyright Copyright (c) 2008 - 2017, Justin Tadlock
  21.  * @link      https://themehybrid.com/plugins/breadcrumb-trail
  22.  * @license   http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23.  */
  24.  
  25. /**
  26.  * Shows a breadcrumb for all types of pages.  This is a wrapper function for the Breadcrumb_Trail class,
  27.  * which should be used in theme templates.
  28.  *
  29.  * @since  0.1.0
  30.  * @access public
  31.  * @param  array $args Arguments to pass to Breadcrumb_Trail.
  32.  * @return string html output.
  33.  */
  34. function breadcrumb_trail( $args = array() ) {
  35.  
  36.     $breadcrumb = apply_filters( 'breadcrumb_trail_object', null, $args );
  37.  
  38.     if ( ! is_object( $breadcrumb ) ) {
  39.         $breadcrumb = new Breadcrumb_Trail( $args );
  40.     }
  41.     return $breadcrumb->trail();
  42. }
  43.  
  44. /**
  45.  * Creates a breadcrumbs menu for the site based on the current page that's being viewed by the user.
  46.  *
  47.  * @since  0.6.0
  48.  * @access public
  49.  */
  50. class Breadcrumb_Trail {
  51.  
  52.     /**
  53.      * Array of items belonging to the current breadcrumb trail.
  54.      *
  55.      * @since  0.1.0
  56.      * @access public
  57.      * @var    array
  58.      */
  59.     public $items = array();
  60.  
  61.     /**
  62.      * Arguments used to build the breadcrumb trail.
  63.      *
  64.      * @since  0.1.0
  65.      * @access public
  66.      * @var    array
  67.      */
  68.     public $args = array();
  69.  
  70.     /**
  71.      * Array of text labels.
  72.      *
  73.      * @since  1.0.0
  74.      * @access public
  75.      * @var    array
  76.      */
  77.     public $labels = array();
  78.  
  79.     /**
  80.      * Array of post types (key) and taxonomies (value) to use for single post views.
  81.      *
  82.      * @since  1.0.0
  83.      * @access public
  84.      * @var    array
  85.      */
  86.     public $post_taxonomy = array();
  87.  
  88.     /* ====== Magic Methods ====== */
  89.  
  90.     /**
  91.      * Magic method to use in case someone tries to output the layout object as a string.
  92.      * We'll just return the trail HTML.
  93.      *
  94.      * @since  1.0.0
  95.      * @access public
  96.      * @return string
  97.      */
  98.     public function __toString() {
  99.         return $this->trail();
  100.     }
  101.  
  102.     /**
  103.      * Sets up the breadcrumb trail properties.  Calls the `Breadcrumb_Trail::add_items()` method
  104.      * to creat the array of breadcrumb items.
  105.      *
  106.      * @since  0.6.0
  107.      * @access public
  108.      * @param array $args {.
  109.      *     @type string    $container      Container HTML element. nav|div
  110.      *     @type string    $before         String to output before breadcrumb menu.
  111.      *     @type string    $after          String to output after breadcrumb menu.
  112.      *     @type string    $browse_tag     The HTML tag to use to wrap the "Browse" header text.
  113.      *     @type string    $list_tag       The HTML tag to use for the list wrapper.
  114.      *     @type string    $item_tag       The HTML tag to use for the item wrapper.
  115.      *     @type bool      $show_on_front  Whether to show when `is_front_page()`.
  116.      *     @type bool      $network        Whether to link to the network main site (multisite only).
  117.      *     @type bool      $show_title     Whether to show the title (last item) in the trail.
  118.      *     @type bool      $show_browse    Whether to show the breadcrumb menu header.
  119.      *     @type array     $labels         Text labels. @see Breadcrumb_Trail::set_labels()
  120.      *     @type array     $post_taxonomy  Taxonomies to use for post types. @see Breadcrumb_Trail::set_post_taxonomy()
  121.      *     @type bool      $echo           Whether to print or return the breadcrumbs.
  122.      * }
  123.      * @return void
  124.      */
  125.     public function __construct( $args = array() ) {
  126.  
  127.         $defaults = array(
  128.             'container'     => 'nav',
  129.             'before'        => '',
  130.             'after'         => '',
  131.             'browse_tag'    => 'h2',
  132.             'list_tag'      => 'ul',
  133.             'item_tag'      => 'li',
  134.             'show_on_front' => true,
  135.             'network'       => false,
  136.             'show_title'    => true,
  137.             'show_browse'   => true,
  138.             'labels'        => array(),
  139.             'post_taxonomy' => array(),
  140.             'echo'          => true,
  141.         );
  142.  
  143.         // Parse the arguments with the deaults.
  144.         $this->args = apply_filters( 'breadcrumb_trail_args', wp_parse_args( $args, $defaults ) );
  145.  
  146.         // Set the labels and post taxonomy properties.
  147.         $this->set_labels();
  148.         $this->set_post_taxonomy();
  149.  
  150.         // Let's find some items to add to the trail!
  151.         $this->add_items();
  152.     }
  153.  
  154.     /* ====== Public Methods ====== */
  155.  
  156.     /**
  157.      * Formats the HTML output for the breadcrumb trail.
  158.      *
  159.      * @since  0.6.0
  160.      * @access public
  161.      * @return string
  162.      */
  163.     public function trail() {
  164.  
  165.         // Set up variables that we'll need.
  166.         $breadcrumb    = '';
  167.         $item_count    = count( $this->items );
  168.         $item_position = 0;
  169.  
  170.         // Connect the breadcrumb trail if there are items in the trail.
  171.         if ( 0 < $item_count ) {
  172.  
  173.             // Add 'browse' label if it should be shown.
  174.             if ( true === $this->args['show_browse'] ) {
  175.  
  176.                 $breadcrumb .= sprintf(
  177.                     '<%1$s class="trail-browse">%2$s</%1$s>',
  178.                     tag_escape( $this->args['browse_tag'] ),
  179.                     $this->labels['browse']
  180.                 );
  181.             }
  182.  
  183.             // Open the unordered list.
  184.             $breadcrumb .= sprintf(
  185.                 '<%s class="trail-items" itemscope itemtype="http://schema.org/BreadcrumbList">',
  186.                 tag_escape( $this->args['list_tag'] )
  187.             );
  188.  
  189.             // Add the number of items and item list order schema.
  190.             $breadcrumb .= sprintf( '<meta name="numberOfItems" content="%d" />', absint( $item_count ) );
  191.             $breadcrumb .= '<meta name="itemListOrder" content="Ascending" />';
  192.  
  193.             // Loop through the items and add them to the list.
  194.             foreach ( $this->items as $item ) {
  195.  
  196.                 // Iterate the item position.
  197.                 ++$item_position;
  198.  
  199.                 // Check if the item is linked.
  200.                 preg_match( '/(<a.*?>)(.*?)(<\/a>)/i', $item, $matches );
  201.  
  202.                 // Wrap the item text with appropriate itemprop.
  203.                 $item = ! empty( $matches ) ? sprintf( '%s<span itemprop="name">%s</span>%s', $matches[1], $matches[2], $matches[3] ) : sprintf( '<span itemprop="name">%s</span>', $item );
  204.  
  205.                 // Wrap the item with its itemprop.
  206.                 $item = ! empty( $matches )
  207.                     ? preg_replace( '/(<a.*?)([\'"])>/i', '$1$2 itemprop=$2item$2>', $item )
  208.                     : sprintf( '<span itemprop="item">%s</span>', $item );
  209.  
  210.                 // Add list item classes.
  211.                 $item_class = 'trail-item';
  212.  
  213.                 if ( 1 === $item_position && 1 < $item_count ) {
  214.                     $item_class .= ' trail-begin';
  215.                 } elseif ( $item_count === $item_position ) {
  216.                     $item_class .= ' trail-end';
  217.                 }
  218.                 // Create list item attributes.
  219.                 $attributes = 'itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="' . $item_class . '"';
  220.  
  221.                 // Build the meta position HTML.
  222.                 $meta = sprintf( '<meta itemprop="position" content="%s" />', absint( $item_position ) );
  223.  
  224.                 // Build the list item.
  225.                 $breadcrumb .= sprintf( '<%1$s %2$s>%3$s%4$s</%1$s>', tag_escape( $this->args['item_tag'] ), $attributes, $item, $meta );
  226.             }
  227.  
  228.             // Close the unordered list.
  229.             $breadcrumb .= sprintf( '</%s>', tag_escape( $this->args['list_tag'] ) );
  230.  
  231.             // Wrap the breadcrumb trail.
  232.             $breadcrumb = sprintf(
  233.                 '<%1$s role="navigation" aria-label="%2$s" class="breadcrumb-trail breadcrumbs" itemprop="breadcrumb">%3$s%4$s%5$s</%1$s>',
  234.                 tag_escape( $this->args['container'] ),
  235.                 esc_attr( $this->labels['aria_label'] ),
  236.                 $this->args['before'],
  237.                 $breadcrumb,
  238.                 $this->args['after']
  239.             );
  240.         }
  241.  
  242.         // Allow developers to filter the breadcrumb trail HTML.
  243.         $breadcrumb = apply_filters( 'breadcrumb_trail', $breadcrumb, $this->args );
  244.  
  245.         if ( false === $this->args['echo'] ) {
  246.             return $breadcrumb;
  247.         }
  248.  
  249.         echo $breadcrumb; // WPCS xss ok.
  250.     }
  251.  
  252.     /* ====== Protected Methods ====== */
  253.  
  254.     /**
  255.      * Sets the labels property.  Parses the inputted labels array with the defaults.
  256.      *
  257.      * @since  1.0.0
  258.      * @access protected
  259.      * @return void
  260.      */
  261.     protected function set_labels() {
  262.  
  263.         $defaults = array(
  264.             'browse'              => esc_html__( 'Browse:', 'cenote' ),
  265.             'aria_label'          => esc_attr_x( 'Breadcrumbs', 'breadcrumbs aria label', 'cenote' ),
  266.             'home'                => esc_html__( 'Во все тяжкие', 'cenote' ),
  267.             'error_404'           => esc_html__( '404 Not Found', 'cenote' ),
  268.             'archives'            => esc_html__( 'Archives', 'cenote' ),
  269.             // Translators: %s is the search query.
  270.             'search'              => esc_html__( 'Search results for: %s', 'cenote' ),
  271.             // Translators: %s is the page number.
  272.             'paged'               => esc_html__( 'Page %s', 'cenote' ),
  273.             // Translators: %s is the page number.
  274.             'paged_comments'      => esc_html__( 'Comment Page %s', 'cenote' ),
  275.             // Translators: Minute archive title. %s is the minute time format.
  276.             'archive_minute'      => esc_html__( 'Minute %s', 'cenote' ),
  277.             // Translators: Weekly archive title. %s is the week date format.
  278.             'archive_week'        => esc_html__( 'Week %s', 'cenote' ),
  279.  
  280.             // "%s" is replaced with the translated date/time format.
  281.             'archive_minute_hour' => '%s',
  282.             'archive_hour'        => '%s',
  283.             'archive_day'         => '%s',
  284.             'archive_month'       => '%s',
  285.             'archive_year'        => '%s',
  286.         );
  287.  
  288.         $this->labels = apply_filters( 'breadcrumb_trail_labels', wp_parse_args( $this->args['labels'], $defaults ) );
  289.     }
  290.  
  291.     /**
  292.      * Sets the `$post_taxonomy` property.  This is an array of post types (key) and taxonomies (value).
  293.      * The taxonomy's terms are shown on the singular post view if set.
  294.      *
  295.      * @since  1.0.0
  296.      * @access protected
  297.      * @return void
  298.      */
  299.     protected function set_post_taxonomy() {
  300.  
  301.         $defaults = array();
  302.  
  303.         // If post permalink is set to `%postname%`, use the `category` taxonomy.
  304.         if ( '%postname%' === trim( get_option( 'permalink_structure' ), '/' ) ) {
  305.             $defaults['post'] = 'category';
  306.         }
  307.  
  308.         $this->post_taxonomy = apply_filters( 'breadcrumb_trail_post_taxonomy', wp_parse_args( $this->args['post_taxonomy'], $defaults ) );
  309.     }
  310.  
  311.     /**
  312.      * Runs through the various WordPress conditional tags to check the current page being viewed.  Once
  313.      * a condition is met, a specific method is launched to add items to the `$items` array.
  314.      *
  315.      * @since  1.0.0
  316.      * @access protected
  317.      * @return void
  318.      */
  319.     protected function add_items() {
  320.  
  321.         // If viewing the front page.
  322.         if ( is_front_page() ) {
  323.             $this->add_front_page_items();
  324.         } else { // If not viewing the front page.
  325.  
  326.             // Add the network and site home links.
  327.             $this->add_network_home_link();
  328.             $this->add_site_home_link();
  329.  
  330.             // If viewing the home/blog page.
  331.             if ( is_home() ) {
  332.                 $this->add_blog_items();
  333.             } elseif ( is_singular() ) { // If not viewing the front page.
  334.                 $this->add_singular_items();
  335.             } elseif ( is_archive() ) { // If viewing an archive page.
  336.  
  337.                 if ( is_post_type_archive() ) {
  338.                     $this->add_post_type_archive_items();
  339.                 } elseif ( is_category() || is_tag() || is_tax() ) {
  340.                     $this->add_term_archive_items();
  341.                 } elseif ( is_author() ) {
  342.                     $this->add_user_archive_items();
  343.                 } elseif ( get_query_var( 'minute' ) && get_query_var( 'hour' ) ) {
  344.                     $this->add_minute_hour_archive_items();
  345.                 } elseif ( get_query_var( 'minute' ) ) {
  346.                     $this->add_minute_archive_items();
  347.                 } elseif ( get_query_var( 'hour' ) ) {
  348.                     $this->add_hour_archive_items();
  349.                 } elseif ( is_day() ) {
  350.                     $this->add_day_archive_items();
  351.                 } elseif ( get_query_var( 'w' ) ) {
  352.                     $this->add_week_archive_items();
  353.                 } elseif ( is_month() ) {
  354.                     $this->add_month_archive_items();
  355.                 } elseif ( is_year() ) {
  356.                     $this->add_year_archive_items();
  357.                 } else {
  358.                     $this->add_default_archive_items();
  359.                 }
  360.             } elseif ( is_search() ) { // If viewing a search results page.
  361.                 $this->add_search_items();
  362.             } elseif ( is_404() ) { // If viewing the 404 page.
  363.                 $this->add_404_items();
  364.             }
  365.         }
  366.  
  367.         // Add paged items if they exist.
  368.         $this->add_paged_items();
  369.  
  370.         // Allow developers to overwrite the items for the breadcrumb trail.
  371.         $this->items = array_unique( apply_filters( 'breadcrumb_trail_items', $this->items, $this->args ) );
  372.     }
  373.  
  374.     /**
  375.      * Gets front items based on $wp_rewrite->front.
  376.      *
  377.      * @since  1.0.0
  378.      * @access protected
  379.      * @return void
  380.      */
  381.     protected function add_rewrite_front_items() {
  382.         global $wp_rewrite;
  383.  
  384.         if ( $wp_rewrite->front ) {
  385.             $this->add_path_parents( $wp_rewrite->front );
  386.         }
  387.     }
  388.  
  389.     /**
  390.      * Adds the page/paged number to the items array.
  391.      *
  392.      * @since  1.0.0
  393.      * @access protected
  394.      * @return void
  395.      */
  396.     protected function add_paged_items() {
  397.  
  398.         // If viewing a paged singular post.
  399.         if ( is_singular() && 1 < get_query_var( 'page' ) && true === $this->args['show_title'] ) {
  400.             $this->items[] = sprintf( $this->labels['paged'], number_format_i18n( absint( get_query_var( 'page' ) ) ) );
  401.         } elseif ( is_singular() && get_option( 'page_comments' ) && 1 < get_query_var( 'cpage' ) ) { // If viewing a singular post with paged comments.
  402.             $this->items[] = sprintf( $this->labels['paged_comments'], number_format_i18n( absint( get_query_var( 'cpage' ) ) ) );
  403.         } elseif ( is_paged() && true === $this->args['show_title'] ) { // If viewing a paged archive-type page.
  404.             $this->items[] = sprintf( $this->labels['paged'], number_format_i18n( absint( get_query_var( 'paged' ) ) ) );
  405.         }
  406.     }
  407.  
  408.     /**
  409.      * Adds the network (all sites) home page link to the items array.
  410.      *
  411.      * @since  1.0.0
  412.      * @access protected
  413.      * @return void
  414.      */
  415.     protected function add_network_home_link() {
  416.  
  417.         if ( is_multisite() && ! is_main_site() && true === $this->args['network'] ) {
  418.             $this->items[] = sprintf( '<a href="%s" rel="home">%s</a>', esc_url( network_home_url() ), $this->labels['home'] );
  419.         }
  420.     }
  421.  
  422.     /**
  423.      * Adds the current site's home page link to the items array.
  424.      *
  425.      * @since  1.0.0
  426.      * @access protected
  427.      * @return void
  428.      */
  429.     protected function add_site_home_link() {
  430.  
  431.         $network = is_multisite() && ! is_main_site() && true === $this->args['network'];
  432.         $label   = $network ? get_bloginfo( 'name' ) : $this->labels['home'];
  433.         $rel     = $network ? '' : ' rel="home"';
  434.  
  435.         $this->items[] = sprintf( '<a href="%s"%s>%s</a>', esc_url( user_trailingslashit( home_url() ) ), $rel, $label );
  436.     }
  437.  
  438.     /**
  439.      * Adds items for the front page to the items array.
  440.      *
  441.      * @since  1.0.0
  442.      * @access protected
  443.      * @return void
  444.      */
  445.     protected function add_front_page_items() {
  446.  
  447.         // Only show front items if the 'show_on_front' argument is set to 'true'.
  448.         if ( true === $this->args['show_on_front'] || is_paged() || ( is_singular() && 1 < get_query_var( 'page' ) ) ) {
  449.  
  450.             // Add network home link.
  451.             $this->add_network_home_link();
  452.  
  453.             // If on a paged view, add the site home link.
  454.             if ( is_paged() ) {
  455.                 $this->add_site_home_link();
  456.             } elseif ( true === $this->args['show_title'] ) { // If on the main front page, add the network home title.
  457.                 $this->items[] = is_multisite() && true === $this->args['network'] ? get_bloginfo( 'name' ) : $this->labels['home'];
  458.             }
  459.         }
  460.     }
  461.  
  462.     /**
  463.      * Adds items for the posts page (i.e., is_home()) to the items array.
  464.      *
  465.      * @since  1.0.0
  466.      * @access protected
  467.      * @return void
  468.      */
  469.     protected function add_blog_items() {
  470.  
  471.         // Get the post ID and post.
  472.         $post_id = get_queried_object_id();
  473.         $post    = get_post( $post_id );
  474.  
  475.         // If the post has parents, add them to the trail.
  476.         if ( 0 < $post->post_parent ) {
  477.             $this->add_post_parents( $post->post_parent );
  478.         }
  479.         // Get the page title.
  480.         $title = get_the_title( $post_id );
  481.  
  482.         // Add the posts page item.
  483.         if ( is_paged() ) {
  484.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_permalink( $post_id ) ), $title );
  485.         } elseif ( $title && true === $this->args['show_title'] ) {
  486.             $this->items[] = $title;
  487.         }
  488.     }
  489.  
  490.     /**
  491.      * Adds singular post items to the items array.
  492.      *
  493.      * @since  1.0.0
  494.      * @access protected
  495.      * @return void
  496.      */
  497.     protected function add_singular_items() {
  498.  
  499.         // Get the queried post.
  500.         $post       = get_queried_object();
  501.         $post_id    = get_queried_object_id();
  502.         $post_title = single_post_title( '', false );
  503.  
  504.         // If the post has a parent, follow the parent trail.
  505.         if ( 0 < $post->post_parent ) {
  506.             $this->add_post_parents( $post->post_parent );
  507.         } else { // If the post doesn't have a parent, get its hierarchy based off the post type.
  508.             $this->add_post_hierarchy( $post_id );
  509.         }
  510.  
  511.         // Display terms for specific post type taxonomy if requested.
  512.         if ( ! empty( $this->post_taxonomy[ $post->post_type ] ) ) {
  513.             $this->add_post_terms( $post_id, $this->post_taxonomy[ $post->post_type ] );
  514.         }
  515.  
  516.         // End with the post title.
  517.         if ( $post_title ) {
  518.  
  519.             if ( ( 1 < get_query_var( 'page' ) || is_paged() ) || ( get_option( 'page_comments' ) && 1 < absint( get_query_var( 'cpage' ) ) ) ) {
  520.                 $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_permalink( $post_id ) ), $post_title );
  521.             } elseif ( true === $this->args['show_title'] ) {
  522.                 $this->items[] = $post_title;
  523.             }
  524.         }
  525.     }
  526.  
  527.     /**
  528.      * Adds the items to the trail items array for taxonomy term archives.
  529.      *
  530.      * @since  1.0.0
  531.      * @access protected
  532.      * @global object $wp_rewrite
  533.      * @return void
  534.      */
  535.     protected function add_term_archive_items() {
  536.         global $wp_rewrite;
  537.  
  538.         // Get some taxonomy and term variables.
  539.         $term           = get_queried_object();
  540.         $taxonomy       = get_taxonomy( $term->taxonomy );
  541.         $done_post_type = false;
  542.  
  543.         // If there are rewrite rules for the taxonomy.
  544.         if ( false !== $taxonomy->rewrite ) {
  545.  
  546.             // If 'with_front' is true, dd $wp_rewrite->front to the trail.
  547.             if ( isset( $taxonomy->rewrite['with_front'] ) && $wp_rewrite->front ) {
  548.                 $this->add_rewrite_front_items();
  549.             }
  550.  
  551.             // Get parent pages by path if they exist.
  552.             $this->add_path_parents( $taxonomy->rewrite['slug'] );
  553.  
  554.             // Add post type archive if its 'has_archive' matches the taxonomy rewrite 'slug'.
  555.             if ( $taxonomy->rewrite['slug'] ) {
  556.  
  557.                 $slug = trim( $taxonomy->rewrite['slug'], '/' );
  558.  
  559.                 // Deals with the situation if the slug has a '/' between multiple
  560.                 // strings. For example, "movies/genres" where "movies" is the post
  561.                 // type archive.
  562.                 $matches = explode( '/', $slug );
  563.  
  564.                 // If matches are found for the path.
  565.                 if ( isset( $matches ) ) {
  566.  
  567.                     // Reverse the array of matches to search for posts in the proper order.
  568.                     $matches = array_reverse( $matches );
  569.  
  570.                     // Loop through each of the path matches.
  571.                     foreach ( $matches as $match ) {
  572.  
  573.                         // If a match is found.
  574.                         $slug = $match;
  575.  
  576.                         // Get public post types that match the rewrite slug.
  577.                         $post_types = $this->get_post_types_by_slug( $match );
  578.  
  579.                         if ( ! empty( $post_types ) ) {
  580.  
  581.                             $post_type_object = $post_types[0];
  582.  
  583.                             // Add support for a non-standard label of 'archive_title' (special use case).
  584.                             $label = ! empty( $post_type_object->labels->archive_title ) ? $post_type_object->labels->archive_title : $post_type_object->labels->name;
  585.  
  586.                             // Core filter hook.
  587.                             $label = apply_filters( 'post_type_archive_title', $label, $post_type_object->name );
  588.  
  589.                             // Add the post type archive link to the trail.
  590.                             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_post_type_archive_link( $post_type_object->name ) ), $label );
  591.  
  592.                             $done_post_type = true;
  593.  
  594.                             // Break out of the loop.
  595.                             break;
  596.                         }
  597.                     }
  598.                 }
  599.             }
  600.         }
  601.  
  602.         // If there's a single post type for the taxonomy, use it.
  603.         if ( false === $done_post_type && 1 === count( $taxonomy->object_type ) && post_type_exists( $taxonomy->object_type[0] ) ) {
  604.  
  605.             // If the post type is 'post'.
  606.             if ( 'post' === $taxonomy->object_type[0] ) {
  607.                 $post_id = get_option( 'page_for_posts' );
  608.  
  609.                 if ( 'posts' !== get_option( 'show_on_front' ) && 0 < $post_id ) {
  610.                     $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_permalink( $post_id ) ), get_the_title( $post_id ) );
  611.                 }
  612.  
  613.                 // If the post type is not 'post'.
  614.             } else {
  615.                 $post_type_object = get_post_type_object( $taxonomy->object_type[0] );
  616.  
  617.                 $label = ! empty( $post_type_object->labels->archive_title ) ? $post_type_object->labels->archive_title : $post_type_object->labels->name;
  618.  
  619.                 // Core filter hook.
  620.                 $label = apply_filters( 'post_type_archive_title', $label, $post_type_object->name );
  621.  
  622.                 $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_post_type_archive_link( $post_type_object->name ) ), $label );
  623.             }
  624.         }
  625.  
  626.         // If the taxonomy is hierarchical, list its parent terms.
  627.         if ( is_taxonomy_hierarchical( $term->taxonomy ) && $term->parent ) {
  628.             $this->add_term_parents( $term->parent, $term->taxonomy );
  629.         }
  630.  
  631.         // Add the term name to the trail end.
  632.         if ( is_paged() ) {
  633.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_term_link( $term, $term->taxonomy ) ), single_term_title( '', false ) );
  634.         } elseif ( true === $this->args['show_title'] ) {
  635.             $this->items[] = single_term_title( '', false );
  636.         }
  637.     }
  638.  
  639.     /**
  640.      * Adds the items to the trail items array for post type archives.
  641.      *
  642.      * @since  1.0.0
  643.      * @access protected
  644.      * @return void
  645.      */
  646.     protected function add_post_type_archive_items() {
  647.  
  648.         // Get the post type object.
  649.         $post_type_object = get_post_type_object( get_query_var( 'post_type' ) );
  650.  
  651.         if ( false !== $post_type_object->rewrite ) {
  652.  
  653.             // If 'with_front' is true, add $wp_rewrite->front to the trail.
  654.             if ( $post_type_object->rewrite['with_front'] ) {
  655.                 $this->add_rewrite_front_items();
  656.             }
  657.  
  658.             // If there's a rewrite slug, check for parents.
  659.             if ( ! empty( $post_type_object->rewrite['slug'] ) ) {
  660.                 $this->add_path_parents( $post_type_object->rewrite['slug'] );
  661.             }
  662.         }
  663.  
  664.         // Add the post type [plural] name to the trail end.
  665.         if ( is_paged() || is_author() ) {
  666.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_post_type_archive_link( $post_type_object->name ) ), post_type_archive_title( '', false ) );
  667.         } elseif ( true === $this->args['show_title'] ) {
  668.             $this->items[] = post_type_archive_title( '', false );
  669.         }
  670.  
  671.         // If viewing a post type archive by author.
  672.         if ( is_author() ) {
  673.             $this->add_user_archive_items();
  674.         }
  675.     }
  676.  
  677.     /**
  678.      * Adds the items to the trail items array for user (author) archives.
  679.      *
  680.      * @since  1.0.0
  681.      * @access protected
  682.      * @global object $wp_rewrite
  683.      * @return void
  684.      */
  685.     protected function add_user_archive_items() {
  686.         global $wp_rewrite;
  687.  
  688.         // Add $wp_rewrite->front to the trail.
  689.         $this->add_rewrite_front_items();
  690.  
  691.         // Get the user ID.
  692.         $user_id = get_query_var( 'author' );
  693.  
  694.         // If $author_base exists, check for parent pages.
  695.         if ( ! empty( $wp_rewrite->author_base ) && ! is_post_type_archive() ) {
  696.             $this->add_path_parents( $wp_rewrite->author_base );
  697.         }
  698.  
  699.         // Add the author's display name to the trail end.
  700.         if ( is_paged() ) {
  701.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_author_posts_url( $user_id ) ), get_the_author_meta( 'display_name', $user_id ) );
  702.         } elseif ( true === $this->args['show_title'] ) {
  703.             $this->items[] = get_the_author_meta( 'display_name', $user_id );
  704.         }
  705.     }
  706.  
  707.     /**
  708.      * Adds the items to the trail items array for minute + hour archives.
  709.      *
  710.      * @since  1.0.0
  711.      * @access protected
  712.      * @return void
  713.      */
  714.     protected function add_minute_hour_archive_items() {
  715.  
  716.         // Add $wp_rewrite->front to the trail.
  717.         $this->add_rewrite_front_items();
  718.  
  719.         // Add the minute + hour item.
  720.         if ( true === $this->args['show_title'] ) {
  721.             $this->items[] = sprintf( $this->labels['archive_minute_hour'], get_the_time( esc_html_x( 'g:i a', 'minute and hour archives time format', 'cenote' ) ) );
  722.         }
  723.     }
  724.  
  725.     /**
  726.      * Adds the items to the trail items array for minute archives.
  727.      *
  728.      * @since  1.0.0
  729.      * @access protected
  730.      * @return void
  731.      */
  732.     protected function add_minute_archive_items() {
  733.  
  734.         // Add $wp_rewrite->front to the trail.
  735.         $this->add_rewrite_front_items();
  736.  
  737.         // Add the minute item.
  738.         if ( true === $this->args['show_title'] ) {
  739.             $this->items[] = sprintf( $this->labels['archive_minute'], get_the_time( esc_html_x( 'i', 'minute archives time format', 'cenote' ) ) );
  740.         }
  741.     }
  742.  
  743.     /**
  744.      * Adds the items to the trail items array for hour archives.
  745.      *
  746.      * @since  1.0.0
  747.      * @access protected
  748.      * @return void
  749.      */
  750.     protected function add_hour_archive_items() {
  751.  
  752.         // Add $wp_rewrite->front to the trail.
  753.         $this->add_rewrite_front_items();
  754.  
  755.         // Add the hour item.
  756.         if ( true === $this->args['show_title'] ) {
  757.             $this->items[] = sprintf( $this->labels['archive_hour'], get_the_time( esc_html_x( 'g a', 'hour archives time format', 'cenote' ) ) );
  758.         }
  759.     }
  760.  
  761.     /**
  762.      * Adds the items to the trail items array for day archives.
  763.      *
  764.      * @since  1.0.0
  765.      * @access protected
  766.      * @return void
  767.      */
  768.     protected function add_day_archive_items() {
  769.  
  770.         // Add $wp_rewrite->front to the trail.
  771.         $this->add_rewrite_front_items();
  772.  
  773.         // Get year, month, and day.
  774.         $year  = sprintf( $this->labels['archive_year'], get_the_time( esc_html_x( 'Y', 'yearly archives date format', 'cenote' ) ) );
  775.         $month = sprintf( $this->labels['archive_month'], get_the_time( esc_html_x( 'F', 'monthly archives date format', 'cenote' ) ) );
  776.         $day   = sprintf( $this->labels['archive_day'], get_the_time( esc_html_x( 'j', 'daily archives date format', 'cenote' ) ) );
  777.  
  778.         // Add the year and month items.
  779.         $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_year_link( get_the_time( 'Y' ) ) ), $year );
  780.         $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_month_link( get_the_time( 'Y' ), get_the_time( 'm' ) ) ), $month );
  781.  
  782.         // Add the day item.
  783.         if ( is_paged() ) {
  784.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_day_link( get_the_time( 'Y' ) ), get_the_time( 'm' ), get_the_time( 'd' ) ), $day );
  785.         } elseif ( true === $this->args['show_title'] ) {
  786.             $this->items[] = $day;
  787.         }
  788.     }
  789.  
  790.     /**
  791.      * Adds the items to the trail items array for week archives.
  792.      *
  793.      * @since  1.0.0
  794.      * @access protected
  795.      * @return void
  796.      */
  797.     protected function add_week_archive_items() {
  798.  
  799.         // Add $wp_rewrite->front to the trail.
  800.         $this->add_rewrite_front_items();
  801.  
  802.         // Get the year and week.
  803.         $year = sprintf( $this->labels['archive_year'], get_the_time( esc_html_x( 'Y', 'yearly archives date format', 'cenote' ) ) );
  804.         $week = sprintf( $this->labels['archive_week'], get_the_time( esc_html_x( 'W', 'weekly archives date format', 'cenote' ) ) );
  805.  
  806.         // Add the year item.
  807.         $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_year_link( get_the_time( 'Y' ) ) ), $year );
  808.  
  809.         // Add the week item.
  810.         if ( is_paged() ) {
  811.             $this->items[] = esc_url(
  812.                 get_archives_link(
  813.                     add_query_arg(
  814.                         array(
  815.                             'm' => get_the_time( 'Y' ),
  816.                             'w' => get_the_time( 'W' ),
  817.                         ),
  818.                         home_url()
  819.                     ),
  820.                     $week,
  821.                     false
  822.                 )
  823.             );
  824.         } elseif ( true === $this->args['show_title'] ) {
  825.             $this->items[] = $week;
  826.         }
  827.     }
  828.  
  829.     /**
  830.      * Adds the items to the trail items array for month archives.
  831.      *
  832.      * @since  1.0.0
  833.      * @access protected
  834.      * @return void
  835.      */
  836.     protected function add_month_archive_items() {
  837.  
  838.         // Add $wp_rewrite->front to the trail.
  839.         $this->add_rewrite_front_items();
  840.  
  841.         // Get the year and month.
  842.         $year  = sprintf( $this->labels['archive_year'], get_the_time( esc_html_x( 'Y', 'yearly archives date format', 'cenote' ) ) );
  843.         $month = sprintf( $this->labels['archive_month'], get_the_time( esc_html_x( 'F', 'monthly archives date format', 'cenote' ) ) );
  844.  
  845.         // Add the year item.
  846.         $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_year_link( get_the_time( 'Y' ) ) ), $year );
  847.  
  848.         // Add the month item.
  849.         if ( is_paged() ) {
  850.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_month_link( get_the_time( 'Y' ), get_the_time( 'm' ) ) ), $month );
  851.         } elseif ( true === $this->args['show_title'] ) {
  852.             $this->items[] = $month;
  853.         }
  854.     }
  855.  
  856.     /**
  857.      * Adds the items to the trail items array for year archives.
  858.      *
  859.      * @since  1.0.0
  860.      * @access protected
  861.      * @return void
  862.      */
  863.     protected function add_year_archive_items() {
  864.  
  865.         // Add $wp_rewrite->front to the trail.
  866.         $this->add_rewrite_front_items();
  867.  
  868.         // Get the year.
  869.         $year = sprintf( $this->labels['archive_year'], get_the_time( esc_html_x( 'Y', 'yearly archives date format', 'cenote' ) ) );
  870.  
  871.         // Add the year item.
  872.         if ( is_paged() ) {
  873.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_year_link( get_the_time( 'Y' ) ) ), $year );
  874.         } elseif ( true === $this->args['show_title'] ) {
  875.             $this->items[] = $year;
  876.         }
  877.     }
  878.  
  879.     /**
  880.      * Adds the items to the trail items array for archives that don't have a more specific method
  881.      * defined in this class.
  882.      *
  883.      * @since  1.0.0
  884.      * @access protected
  885.      * @return void
  886.      */
  887.     protected function add_default_archive_items() {
  888.  
  889.         // If this is a date-/time-based archive, add $wp_rewrite->front to the trail.
  890.         if ( is_date() || is_time() ) {
  891.             $this->add_rewrite_front_items();
  892.         } if ( true === $this->args['show_title'] ) {
  893.             $this->items[] = $this->labels['archives'];
  894.         }
  895.     }
  896.  
  897.     /**
  898.      * Adds the items to the trail items array for search results.
  899.      *
  900.      * @since  1.0.0
  901.      * @access protected
  902.      * @return void
  903.      */
  904.     protected function add_search_items() {
  905.  
  906.         if ( is_paged() ) {
  907.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_search_link() ), sprintf( $this->labels['search'], get_search_query() ) );
  908.         } elseif ( true === $this->args['show_title'] ) {
  909.             $this->items[] = sprintf( $this->labels['search'], get_search_query() );
  910.         }
  911.     }
  912.  
  913.     /**
  914.      * Adds the items to the trail items array for 404 pages.
  915.      *
  916.      * @since  1.0.0
  917.      * @access protected
  918.      * @return void
  919.      */
  920.     protected function add_404_items() {
  921.  
  922.         if ( true === $this->args['show_title'] ) {
  923.             $this->items[] = $this->labels['error_404'];
  924.         }
  925.     }
  926.  
  927.     /**
  928.      * Adds a specific post's parents to the items array.
  929.      *
  930.      * @since  1.0.0
  931.      * @access protected
  932.      * @param int $post_id post id.
  933.      * @return void
  934.      */
  935.     protected function add_post_parents( $post_id ) {
  936.         $parents = array();
  937.  
  938.         while ( $post_id ) {
  939.  
  940.             // Get the post by ID.
  941.             $post = get_post( $post_id );
  942.  
  943.             // If we hit a page that's set as the front page, bail.
  944.             if ( 'page' === $post->post_type && 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) === $post_id ) {
  945.                 break;
  946.             }
  947.  
  948.             // Add the formatted post link to the array of parents.
  949.             $parents[] = sprintf( '<a href="%s">%s</a>', esc_url( get_permalink( $post_id ) ), get_the_title( $post_id ) );
  950.  
  951.             // If there's no longer a post parent, break out of the loop.
  952.             if ( 0 >= $post->post_parent ) {
  953.                 break;
  954.             }
  955.  
  956.             // Change the post ID to the parent post to continue looping.
  957.             $post_id = $post->post_parent;
  958.         }
  959.  
  960.         // Get the post hierarchy based off the final parent post.
  961.         $this->add_post_hierarchy( $post_id );
  962.  
  963.         // Display terms for specific post type taxonomy if requested.
  964.         if ( ! empty( $this->post_taxonomy[ $post->post_type ] ) ) {
  965.             $this->add_post_terms( $post_id, $this->post_taxonomy[ $post->post_type ] );
  966.         }
  967.  
  968.         // Merge the parent items into the items array.
  969.         $this->items = array_merge( $this->items, array_reverse( $parents ) );
  970.     }
  971.  
  972.     /**
  973.      * Adds a specific post's hierarchy to the items array.  The hierarchy is determined by post type's
  974.      * rewrite arguments and whether it has an archive page.
  975.      *
  976.      * @since  1.0.0
  977.      * @access protected
  978.      * @param int $post_id post id.
  979.      * @return void
  980.      */
  981.     protected function add_post_hierarchy( $post_id ) {
  982.  
  983.         // Get the post type.
  984.         $post_type        = get_post_type( $post_id );
  985.         $post_type_object = get_post_type_object( $post_type );
  986.  
  987.         // If this is the 'post' post type, get the rewrite front items and map the rewrite tags.
  988.         if ( 'post' === $post_type ) {
  989.  
  990.             // Add $wp_rewrite->front to the trail.
  991.             $this->add_rewrite_front_items();
  992.  
  993.             // Map the rewrite tags.
  994.             $this->map_rewrite_tags( $post_id, get_option( 'permalink_structure' ) );
  995.         } elseif ( false !== $post_type_object->rewrite ) { // If the post type has rewrite rules.
  996.  
  997.             // If 'with_front' is true, add $wp_rewrite->front to the trail.
  998.             if ( $post_type_object->rewrite['with_front'] ) {
  999.                 $this->add_rewrite_front_items();
  1000.             }
  1001.  
  1002.             // If there's a path, check for parents.
  1003.             if ( ! empty( $post_type_object->rewrite['slug'] ) ) {
  1004.                 $this->add_path_parents( $post_type_object->rewrite['slug'] );
  1005.             }
  1006.         }
  1007.  
  1008.         // If there's an archive page, add it to the trail.
  1009.         if ( $post_type_object->has_archive ) {
  1010.  
  1011.             // Add support for a non-standard label of 'archive_title' (special use case).
  1012.             $label = ! empty( $post_type_object->labels->archive_title ) ? $post_type_object->labels->archive_title : $post_type_object->labels->name;
  1013.  
  1014.             // Core filter hook.
  1015.             $label = apply_filters( 'post_type_archive_title', $label, $post_type_object->name );
  1016.  
  1017.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_post_type_archive_link( $post_type ) ), $label );
  1018.         }
  1019.  
  1020.         // Map the rewrite tags if there's a `%` in the slug.
  1021.         if ( 'post' !== $post_type && ! empty( $post_type_object->rewrite['slug'] ) && false !== strpos( $post_type_object->rewrite['slug'], '%' ) ) {
  1022.             $this->map_rewrite_tags( $post_id, $post_type_object->rewrite['slug'] );
  1023.         }
  1024.     }
  1025.  
  1026.     /**
  1027.      * Gets post types by slug.  This is needed because the get_post_types() function doesn't exactly
  1028.      * match the 'has_archive' argument when it's set as a string instead of a boolean.
  1029.      *
  1030.      * @since  0.6.0
  1031.      * @access protected
  1032.      * @param int $slug The post type archive slug to search for.
  1033.      * @return array $return post type.
  1034.      */
  1035.     protected function get_post_types_by_slug( $slug ) {
  1036.  
  1037.         $return = array();
  1038.  
  1039.         $post_types = get_post_types( array(), 'objects' );
  1040.  
  1041.         foreach ( $post_types as $type ) {
  1042.  
  1043.             if ( $slug === $type->has_archive || ( true === $type->has_archive && $slug === $type->rewrite['slug'] ) ) {
  1044.                 $return[] = $type;
  1045.             }
  1046.         }
  1047.  
  1048.         return $return;
  1049.     }
  1050.  
  1051.     /**
  1052.      * Adds a post's terms from a specific taxonomy to the items array.
  1053.      *
  1054.      * @since  1.0.0
  1055.      * @access protected
  1056.      * @param  int    $post_id The ID of the post to get the terms for.
  1057.      * @param string $taxonomy The taxonomy to get the terms from.
  1058.      * @return void
  1059.      */
  1060.     protected function add_post_terms( $post_id, $taxonomy ) {
  1061.  
  1062.         // Get the post type.
  1063.         $post_type = get_post_type( $post_id );
  1064.  
  1065.         // Get the post categories.
  1066.         $terms = get_the_terms( $post_id, $taxonomy );
  1067.  
  1068.         // Check that categories were returned.
  1069.         if ( $terms && ! is_wp_error( $terms ) ) {
  1070.  
  1071.             // Sort the terms by ID and get the first category.
  1072.             if ( function_exists( 'wp_list_sort' ) ) {
  1073.                 $terms = wp_list_sort( $terms, 'term_id' );
  1074.             } else {
  1075.                 usort( $terms, '_usort_terms_by_ID' );
  1076.             }
  1077.             $term = get_term( $terms[0], $taxonomy );
  1078.  
  1079.             // If the category has a parent, add the hierarchy to the trail.
  1080.             if ( 0 < $term->parent ) {
  1081.                 $this->add_term_parents( $term->parent, $taxonomy );
  1082.             }
  1083.  
  1084.             // Add the category archive link to the trail.
  1085.             $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_term_link( $term, $taxonomy ) ), $term->name );
  1086.         }
  1087.     }
  1088.  
  1089.     /**
  1090.      * Get parent posts by path.  Currently, this method only supports getting parents of the 'page'
  1091.      * post type.  The goal of this function is to create a clear path back to home given what would
  1092.      * normally be a "ghost" directory.  If any page matches the given path, it'll be added.
  1093.      *
  1094.      * @since  1.0.0
  1095.      * @access protected
  1096.      * @param  string $path The path (slug) to search for posts by.
  1097.      * @return void
  1098.      */
  1099.     protected function add_path_parents( $path ) {
  1100.  
  1101.         // Trim '/' off $path in case we just got a simple '/' instead of a real path.
  1102.         $path = trim( $path, '/' );
  1103.  
  1104.         // If there's no path, return.
  1105.         if ( empty( $path ) ) {
  1106.             return;
  1107.         }
  1108.  
  1109.         // Get parent post by the path.
  1110.         $post = get_page_by_path( $path );
  1111.  
  1112.         if ( ! empty( $post ) ) {
  1113.             $this->add_post_parents( $post->ID );
  1114.         } elseif ( is_null( $post ) ) {
  1115.  
  1116.             // Separate post names into separate paths by '/'.
  1117.             $path = trim( $path, '/' );
  1118.             preg_match_all( '/\/.*?\z/', $path, $matches );
  1119.  
  1120.             // If matches are found for the path.
  1121.             if ( isset( $matches ) ) {
  1122.  
  1123.                 // Reverse the array of matches to search for posts in the proper order.
  1124.                 $matches = array_reverse( $matches );
  1125.  
  1126.                 // Loop through each of the path matches.
  1127.                 foreach ( $matches as $match ) {
  1128.  
  1129.                     // If a match is found.
  1130.                     if ( isset( $match[0] ) ) {
  1131.  
  1132.                         // Get the parent post by the given path.
  1133.                         $path = str_replace( $match[0], '', $path );
  1134.                         $post = get_page_by_path( trim( $path, '/' ) );
  1135.  
  1136.                         // If a parent post is found, set the $post_id and break out of the loop.
  1137.                         if ( ! empty( $post ) && 0 < $post->ID ) {
  1138.                             $this->add_post_parents( $post->ID );
  1139.                             break;
  1140.                         }
  1141.                     }
  1142.                 }
  1143.             }
  1144.         }
  1145.     }
  1146.  
  1147.     /**
  1148.      * Searches for term parents of hierarchical taxonomies.  This function is similar to the WordPress
  1149.      * function get_category_parents() but handles any type of taxonomy.
  1150.      *
  1151.      * @since  1.0.0
  1152.      * @param  int    $term_id  ID of the term to get the parents of.
  1153.      * @param  string $taxonomy Name of the taxonomy for the given term.
  1154.      * @return void
  1155.      */
  1156.     protected function add_term_parents( $term_id, $taxonomy ) {
  1157.  
  1158.         // Set up some default arrays.
  1159.         $parents = array();
  1160.  
  1161.         // While there is a parent ID, add the parent term link to the $parents array.
  1162.         while ( $term_id ) {
  1163.  
  1164.             // Get the parent term.
  1165.             $term = get_term( $term_id, $taxonomy );
  1166.  
  1167.             // Add the formatted term link to the array of parent terms.
  1168.             $parents[] = sprintf( '<a href="%s">%s</a>', esc_url( get_term_link( $term, $taxonomy ) ), $term->name );
  1169.  
  1170.             // Set the parent term's parent as the parent ID.
  1171.             $term_id = $term->parent;
  1172.         }
  1173.  
  1174.         // If we have parent terms, reverse the array to put them in the proper order for the trail.
  1175.         if ( ! empty( $parents ) ) {
  1176.             $this->items = array_merge( $this->items, array_reverse( $parents ) );
  1177.         }
  1178.     }
  1179.  
  1180.     /**
  1181.      * Turns %tag% from permalink structures into usable links for the breadcrumb trail.  This feels kind of
  1182.      * hackish for now because we're checking for specific %tag% examples and only doing it for the 'post'
  1183.      * post type.  In the future, maybe it'll handle a wider variety of possibilities, especially for custom post
  1184.      * types.
  1185.      *
  1186.      * @since  0.6.0
  1187.      * @access protected
  1188.      * @param  int    $post_id ID of the post whose parents we want.
  1189.      * @param  string $path Path of a potential parent page.
  1190.      */
  1191.     protected function map_rewrite_tags( $post_id, $path ) {
  1192.  
  1193.         $post = get_post( $post_id );
  1194.  
  1195.         // Trim '/' from both sides of the $path.
  1196.         $path = trim( $path, '/' );
  1197.  
  1198.         // Split the $path into an array of strings.
  1199.         $matches = explode( '/', $path );
  1200.  
  1201.         // If matches are found for the path.
  1202.         if ( is_array( $matches ) ) {
  1203.  
  1204.             // Loop through each of the matches, adding each to the $trail array.
  1205.             foreach ( $matches as $match ) {
  1206.  
  1207.                 // Trim any '/' from the $match.
  1208.                 $tag = trim( $match, '/' );
  1209.  
  1210.                 // If using the %year% tag, add a link to the yearly archive.
  1211.                 if ( '%year%' === $tag ) {
  1212.                     $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_year_link( get_the_time( 'Y', $post_id ) ) ), sprintf( $this->labels['archive_year'], get_the_time( esc_html_x( 'Y', 'yearly archives date format', 'cenote' ) ) ) );
  1213.                 } elseif ( '%monthnum%' === $tag ) { // If using the %monthnum% tag, add a link to the monthly archive.
  1214.                     $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_month_link( get_the_time( 'Y', $post_id ), get_the_time( 'm', $post_id ) ) ), sprintf( $this->labels['archive_month'], get_the_time( esc_html_x( 'F', 'monthly archives date format', 'cenote' ) ) ) );
  1215.                 } elseif ( '%day%' === $tag ) { // If using the %day% tag, add a link to the daily archive.
  1216.                     $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_day_link( get_the_time( 'Y', $post_id ), get_the_time( 'm', $post_id ), get_the_time( 'd', $post_id ) ) ), sprintf( $this->labels['archive_day'], get_the_time( esc_html_x( 'j', 'daily archives date format', 'cenote' ) ) ) );
  1217.                 } elseif ( '%author%' === $tag ) { // If using the %author% tag, add a link to the post author archive.
  1218.                     $this->items[] = sprintf( '<a href="%s">%s</a>', esc_url( get_author_posts_url( $post->post_author ) ), get_the_author_meta( 'display_name', $post->post_author ) );
  1219.                 } elseif ( taxonomy_exists( trim( $tag, '%' ) ) ) { // If using the %category% tag, add a link to the first category archive to match permalinks.
  1220.  
  1221.                     // Force override terms in this post type.
  1222.                     $this->post_taxonomy[ $post->post_type ] = false;
  1223.  
  1224.                     // Add the post categories.
  1225.                     $this->add_post_terms( $post_id, trim( $tag, '%' ) );
  1226.                 }
  1227.             }
  1228.         }
  1229.     }
  1230. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement