<?php /**
 * Kadence\Breadcrumbs\Component class
 *
 * @package kadence
 */

namespace Kadence\Breadcrumbs;

use Kadence\Component_Interface;
use Kadence\Templating_Component_Interface;
use function Kadence\kadence;
use WPSEO_Primary_Term;
use WPSEO_Taxonomy_Meta;
use WP_Post;
use function add_action;
use function add_filter;
use function wp_enqueue_script;
use function get_theme_file_uri;
use function get_theme_file_path;
use function wp_script_add_data;
use function wp_localize_script;
use function rank_math_the_breadcrumbs;
use function yoast_breadcrumb;
use function seopress_display_breadcrumbs;
use function is_bbpress;
use function bbp_breadcrumb;

/**
 * Class for adding custom header support.
 *
 * Exposes template tags:
 * * `kadence()->get_breadcrumb()`
 */
class Component implements Component_Interface, Templating_Component_Interface {
	/**
	 * Instance Control
	 *
	 * @var array
	 */
	protected static $instance = null;

	/**
	 * Breadcrumb separator.
	 *
	 * @var string/null
	 */
	private $sep = null;

	/**
	 * Breadcrumb link.
	 *
	 * @var string/null
	 */
	private $link = null;

	/**
	 * Breadcrumb settings.
	 *
	 * @var array
	 */
	private $settings = array();

	/**
	 * Local breadcrumb args.
	 *
	 * @var array
	 */
	private $args = array();

	/**
	 * Breadcrumb post types.
	 *
	 * @var array
	 */
	private $post_types = array();
	/**
	 * Gets the unique identifier for the theme component.
	 *
	 * @return string Component slug.
	 */
	public function get_slug() : string {
		return 'breadcrumbs';
	}

	/**
	 * Adds the action and filter hooks to integrate with WordPress.
	 */
	public function initialize() {
	}

	/**
	 * Gets template tags to expose as methods on the Template_Tags class instance, accessible through `kadence()`.
	 *
	 * @return array Associative array of $method_name =&gt; $callback_info pairs. Each $callback_info must either be
	 *               a callable or an array with key 'callable'. This approach is used to reserve the possibility of
	 *               adding support for further arguments in the future.
	 */
	public function template_tags() : array {
		return array(
			'get_breadcrumb' =&gt; array( $this, 'get_breadcrumb' ),
			'print_breadcrumb' =&gt; array( $this, 'print_breadcrumb' ),
		);
	}
	/**
	 * Get the breadcrumbs.
	 *
	 * @param array $args Arguments.
	 */
	public function print_breadcrumb( $args = array() ) {
		if ( 'rankmath' === kadence()-&gt;option( 'breadcrumb_engine' ) ) {
			if ( function_exists( 'rank_math_the_breadcrumbs' ) ) {
				echo '<div class="kadence-breadcrumbs rankmath-bc-wrap">';
				rank_math_the_breadcrumbs();
				echo '</div>';
			}
		} elseif ( 'yoast' === kadence()-&gt;option( 'breadcrumb_engine' ) ) {
			if ( function_exists( 'yoast_breadcrumb' ) ) {
				yoast_breadcrumb( '<div class="kadence-breadcrumbs yoast-bc-wrap">','</div>' );
			}
		} elseif ( 'seopress' === kadence()-&gt;option( 'breadcrumb_engine' ) ) {
			if ( function_exists( 'seopress_display_breadcrumbs' ) ) {
				echo '<div class="kadence-breadcrumbs seopress-bc-wrap">';
				seopress_display_breadcrumbs();
				echo '</div>';
			}
		} else {
			if ( function_exists( 'is_bbpress' ) &amp;&amp; is_bbpress() &amp;&amp; function_exists( 'bbp_breadcrumb' ) ) {
				echo '<div class="kadence-breadcrumbs bbpress-topic-meta">';
				bbp_breadcrumb();
				echo '</div>';
			} else {
				echo kadence()-&gt;get_breadcrumb( $args );
			}
		}
	}
	/**
	 * Get the breadcrumbs.
	 *
	 * @param array $args Arguments.
	 * @return string
	 */
	public function get_breadcrumb( $args = array() ) {
		$this-&gt;args = apply_filters(
			'kadence_local_breadcrumb_args',
			wp_parse_args(
				$args,
				array(
					'home_title'     =&gt; __( 'Home', 'kadence' ),
					'404_title'      =&gt; __( 'Error 404', 'kadence' ),
					'search_title'   =&gt; __( 'Search results for', 'kadence' ),
					'page'           =&gt; __( 'Page', 'kadence' ),
					'show_shop'      =&gt; true,
					'show_title'     =&gt; true,
					'color_style'    =&gt; '',
					'blog_id'        =&gt; '',
					'portfolio_id'   =&gt; '',
					'staff_id'       =&gt; '',
					'testimonial_id' =&gt; '',
					'gallery_id'     =&gt; 'none',
				)
			)
		);
		$this-&gt;settings = wp_parse_args(
			apply_filters( 'kadence_breadcrumb_args', array() ),
			array(
				'home'             =&gt; true,
				'home_icon'        =&gt; kadence()-&gt;option( 'breadcrumb_home_icon' ),
				'before'           =&gt; '<span class="kadence-bread-current">',
				'after'            =&gt; '</span>',
				'home_link'        =&gt; home_url( '/' ),
				'wrap_before'      =&gt; '<nav id="kadence-breadcrumbs" aria-label="' . esc_attr__( 'Breadcrumbs', 'kadence' ) . '" class="kadence-breadcrumbs"><div class="kadence-breadcrumb-container" .>args['color_style'] ? ' style="' . esc_attr( $this-&gt;args['color_style'] ) . '"' : '' ) . '&gt;',
				'wrap_after'       =&gt; '</div></nav>',
				'delimiter'        =&gt; apply_filters( 'kadence_breadcrumb_delimiter', '/' ),
				'delimiter_before' =&gt; '<span class="bc-delimiter">',
				'delimiter_after'  =&gt; '</span>',
				'link_before'      =&gt; '<span>',
				'link_after'       =&gt; '</span>',
				'link_in_before'   =&gt; '<span>',
				'link_in_after'    =&gt; '</span>',
			)
		);
		$this-&gt;post_types = wp_parse_args(
			apply_filters( 'kadence_breadcrumb_post_types', array() ),
			array(
				'product'      =&gt; array(
					'post_type'     =&gt; 'product',
					'taxonomy'      =&gt; 'product_cat',
					'archive_page'  =&gt; 'shop',
					'archive_label' =&gt; '',
				),
				'portfolio'    =&gt; array(
					'post_type'     =&gt; 'portfolio',
					'taxonomy'      =&gt; 'portfolio-type',
					'archive_page'  =&gt; $this-&gt;args['portfolio_id'],
					'archive_label' =&gt; '',
				),
				'post'         =&gt; array(
					'post_type'     =&gt; 'post',
					'taxonomy'      =&gt; 'category',
					'archive_page'  =&gt; $this-&gt;args['blog_id'],
					'archive_label' =&gt; '',
				),
				'staff'        =&gt; array(
					'post_type'     =&gt; 'staff',
					'taxonomy'      =&gt; 'staff-group',
					'archive_page'  =&gt; $this-&gt;args['staff_id'],
					'archive_label' =&gt; '',
				),
				'testimonial'  =&gt; array(
					'post_type'     =&gt; 'testimonial',
					'taxonomy'      =&gt; 'testimonial-group',
					'archive_page'  =&gt; $this-&gt;args['testimonial_id'],
					'archive_label' =&gt; '',
				),
				'kt_gallery'  =&gt; array(
					'post_type'     =&gt; 'kt_gallery',
					'taxonomy'      =&gt; 'kt_album',
					'archive_page'  =&gt; $this-&gt;args['gallery_id'],
					'archive_label' =&gt; '',
				),
				'tribe_events' =&gt; array(
					'post_type'     =&gt; 'tribe_events',
					'taxonomy'      =&gt; 'tribe_events_cat',
					'archive_page'  =&gt; 'tribe_events',
					'archive_label' =&gt; '',
				),
				'event'        =&gt; array(
					'post_type'     =&gt; 'event',
					'taxonomy'      =&gt; 'event-category',
					'archive_page'  =&gt; '',
					'archive_label' =&gt; '',
				),
				'podcast'      =&gt; array(
					'post_type'     =&gt; 'podcast',
					'taxonomy'      =&gt; 'series',
					'archive_page'  =&gt; '',
					'archive_label' =&gt; '',
				),
				'course'      =&gt; array(
					'post_type'     =&gt; 'course',
					'taxonomy'      =&gt; 'course_cat',
					'archive_page'  =&gt; get_option( 'lifterlms_shop_page_id' ),
					'archive_label' =&gt; '',
				),
				'lesson'      =&gt; array(
					'post_type'     =&gt; 'lesson',
					'taxonomy'      =&gt; '',
					'custom'        =&gt; 'liferlms',
					'archive_page'  =&gt; get_option( 'lifterlms_shop_page_id' ),
					'archive_label' =&gt; '',
				),
				'ht_kb'      =&gt; array(
					'post_type'     =&gt; 'ht_kb',
					'taxonomy'      =&gt; 'ht_kb_category',
					'archive_page'  =&gt; 'archive',
					'archive_label' =&gt; esc_html__( 'Knowledge Base', 'kadence' ),
				),
			)
		);
		$html = '';

		if ( ! is_front_page() ) {
			$html .= $this-&gt;settings['wrap_before'];
			if ( $this-&gt;settings['home'] ) {
				$html .= $this-&gt;get_crumbs_frontpage() . $this-&gt;get_sep();
			}
			$html = apply_filters( 'kadence_breadcrumbs_after_home', $html );
			if ( is_home() ) {
				$html .= $this-&gt;get_crumbs_home();
			} elseif ( is_404() ) {
				$html .= $this-&gt;get_crumbs_404();
			} elseif ( is_search() ) {
				$html .= $this-&gt;get_crumbs_search();
			} elseif ( is_attachment() ) {
				$html .= $this-&gt;get_crumbs_attachment();
			} elseif ( function_exists( 'is_shop' ) &amp;&amp; is_shop() ) {
				$html .= $this-&gt;get_crumbs_shop();
			} elseif ( is_single() ) {
				$html .= $this-&gt;get_crumbs_single();
			} elseif ( is_page() ) {
				$html .= $this-&gt;get_crumbs_page();
			} elseif ( is_singular() &amp;&amp; ! is_attachment() ) {
				$html .= $this-&gt;get_crumbs_single();
			} elseif ( function_exists( 'is_product_category' ) &amp;&amp; is_product_category() ) {
				$html .= $this-&gt;get_crumbs_product_category();
			} elseif ( function_exists( 'is_product_tag' ) &amp;&amp; is_product_tag() ) {
				$html .= $this-&gt;get_crumbs_product_tag();
			} elseif ( $this-&gt;is_wc_attribute() ) {
				$html .= $this-&gt;get_crumbs_product_attribute();
			}  elseif ( function_exists( 'dokan_is_store_page' ) &amp;&amp; dokan_is_store_page() ) {
				$html .= $this-&gt;get_crumbs_dokan_store();
			} elseif ( is_category() ) {
				$html .= $this-&gt;get_crumbs_category();
			} elseif ( is_tag() ) {
				$html .= $this-&gt;get_crumbs_tag();
			} elseif ( is_tax() ) {
				$html .= $this-&gt;get_crumbs_tax();
			} elseif ( is_date() ) {
				$html .= $this-&gt;get_crumbs_date();
			} elseif ( is_author() ) {
				$html .= $this-&gt;get_crumbs_author();
			} elseif ( is_archive() ) {
				$html .= $this-&gt;get_crumbs_archive();
			} else {
				$html .= $this-&gt;settings['before'] . get_the_title() . $this-&gt;settings['after'];
			}

			if ( get_query_var( 'paged' ) ) {
				$html .= ' - ' . $this-&gt;args['page'] . ' ' . esc_html( get_query_var( 'paged' ) );
			}

			$html .= $this-&gt;settings['wrap_after'];
		}
		/**
		 * Change the breadcrumbs HTML output.
		 *
		 * @param string      $html   HTML output.
		 */
		return apply_filters( 'kadence_breadcrumb_html', $html );
	}
	/**
	 * Check for wc_attribute_archive.
	 */
	public function is_wc_attribute() {

		/** 
		 * Attributes are proper taxonomies, therefore first thing is 
		 * to check if we are on a taxonomy page using the is_tax(). 
		 * Also, a further check if the taxonomy_is_product_attribute 
		 * function exists is necessary, in order to ensure that this 
		 * function does not produce fatal errors when the WooCommerce 
		 * is not  activated
		 */
		if ( is_tax() &amp;&amp; function_exists( 'taxonomy_is_product_attribute') ) { 
			// now we know for sure that the queried object is a taxonomy
			$tax_obj = get_queried_object();
			return taxonomy_is_product_attribute( $tax_obj-&gt;taxonomy );
		}
		return false;
	}
	/**
	 * Get Separator
	 */
	public function get_sep() {
		if ( is_null( $this-&gt;sep ) ) {
			$this-&gt;sep = ' ' . $this-&gt;settings['delimiter_before'] . $this-&gt;settings['delimiter'] . $this-&gt;settings['delimiter_after'] . ' ';
		}
		return $this-&gt;sep;
	}
	/**
	 * Get link string
	 */
	public function get_link() {
		if ( is_null( $this-&gt;link ) ) {
			$this-&gt;link = $this-&gt;settings['link_before'] . '<a href="%1%24s" itemprop="url" .>args['color_style'] ? 'style="' . esc_attr( $this-&gt;args['color_style'] ) . '"' : '' ) . '&gt;' . $this-&gt;settings['link_in_before'] . '%2$s' . $this-&gt;settings['link_in_after'] . '</a>' . $this-&gt;settings['link_after'];
		}
		return $this-&gt;link;
	}
	/**
	 * Get Breadcrumb Term Title
	 *
	 * @param object $term the current term.
	 */
	private function get_breadcrumb_term_title( $term ) {
		$title = '';
		if ( class_exists( 'WPSEO_Taxonomy_Meta' ) ) {
			$title = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term-&gt;taxonomy, 'bctitle' );
		} elseif ( class_exists( 'RankMath' ) ) {
			$title = get_metadata( 'term', $term-&gt;term_id, 'rank_math_breadcrumb_title', false );
			if ( is_array( $title ) &amp;&amp; ! empty( $title ) ) {
				$title = $title[0];
			}
		}
		if ( ! is_string( $title ) || '' === $title ) {
			$title = $term-&gt;name;
		}

		return $title;
	}
	/**
	 * Get Home Breadcrumb
	 */
	private function get_crumbs_frontpage() {
		if ( $this-&gt;settings['home_icon'] ) {
			$output = $this-&gt;settings['link_before'] . '<a href="'%20.%20esc_url(%20%24this-&gt;settings%5B'home_link'%5D%20)%20.%20'" title="'. esc_attr( $this-&gt;args['home_title'] ) . '" itemprop="url" class="kadence-bc-home kadence-bc-home-icon" .>args['color_style'] ? 'style="' . esc_attr( $this-&gt;args['color_style'] ) . '"' : '' ) . '&gt;' . $this-&gt;settings['link_in_before'] . kadence()-&gt;get_icon( 'home' ) . $this-&gt;settings['link_in_after'] . '</a>' . $this-&gt;settings['link_after'];
		} else {
			$output = $this-&gt;settings['link_before'] . '<a href="'%20.%20esc_url(%20%24this-&gt;settings%5B'home_link'%5D%20)%20.%20'" itemprop="url" class="kadence-bc-home" .>args['color_style'] ? 'style="' . esc_attr( $this-&gt;args['color_style'] ) . '"' : '' ) . '&gt;' . $this-&gt;settings['link_in_before'] . esc_html( $this-&gt;args['home_title'] ) . $this-&gt;settings['link_in_after'] . '</a>' . $this-&gt;settings['link_after'];
		}
		return $output;
	}

	/**
	 * Get Home Breadcrumb
	 */
	private function get_crumbs_home() {
		return $this-&gt;settings['before'] . get_the_title( get_option( 'page_for_posts' ) ) . $this-&gt;settings['after'];
	}

	/**
	 * Get 404 Breadcrumb
	 */
	private function get_crumbs_404() {
		return $this-&gt;settings['before'] . $this-&gt;args['404_title'] . $this-&gt;settings['after'];
	}

	/**
	 * Get search Breadcrumb
	 */
	private function get_crumbs_search() {
		$html = '';
		if ( array_key_exists( 'ht-kb-search', $_REQUEST ) ) {
			if ( $this-&gt;post_types['ht_kb']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['ht_kb']['archive_page'], $this-&gt;post_types['ht_kb']['archive_label'] );
			}
		}
		return $html . $this-&gt;settings['before'] . $this-&gt;args['search_title'] . ' "' . get_search_query() . '"' . $this-&gt;settings['after'];
	}

	/**
	 * Get attachment Breadcrumb
	 */
	private function get_crumbs_attachment() {
		global $post;
		$parent_id    = $post-&gt;post_parent;
		$html         = '';
		$parentcrumbs = array();

		if ( $parent_id ) {
			while ( $parent_id ) {
				$page           = get_page( $parent_id );
				$parentcrumbs[] = sprintf( $this-&gt;get_link(), get_permalink( $page-&gt;ID ), get_the_title( $page-&gt;ID ) ) . $this-&gt;get_sep();
				$parent_id      = $page-&gt;post_parent;
			}
		}
		$parentcrumbs = array_reverse( $parentcrumbs );
		foreach ( $parentcrumbs as $parentcrumb ) {
			$html .= $parentcrumb;
		}
		$html .= $this-&gt;settings['before'] . get_the_title() . $this-&gt;settings['after'];
		return $html;
	}

	/**
	 * Get shop page Breadcrumb
	 */
	private function get_crumbs_shop() {
		$shop_page_id = wc_get_page_id( 'shop' );
		$page_title   = get_the_title( $shop_page_id );
		return $this-&gt;settings['before'] . $page_title . $this-&gt;settings['after'];
	}

	/**
	 * Get shop Breadcrumb
	 */
	private function get_shop_crumb() {
		$shop_page_id = wc_get_page_id( 'shop' );
		$shop_page    = get_post( $shop_page_id );
		$shop_bread   = '';
		if ( get_option( 'page_on_front' ) !== $shop_page_id ) {
			$shop_bread = sprintf( $this-&gt;get_link(), get_permalink( $shop_page ), get_the_title( $shop_page_id ) ) . $this-&gt;get_sep();
		}
		return $shop_bread;
	}

	/**
	 * Get product category
	 */
	private function get_crumbs_product_category() {
		$html = '';
		if ( $this-&gt;args['show_shop'] ) {
			$html .= $this-&gt;get_shop_crumb();
		}
		$ancestors = get_ancestors( get_queried_object()-&gt;term_id, 'product_cat' );
		$ancestors = array_reverse( $ancestors );
		foreach ( $ancestors as $ancestor ) {
			$ancestor = get_term( $ancestor, 'product_cat' );
			$html    .= sprintf( $this-&gt;get_link(), get_term_link( $ancestor-&gt;slug, 'product_cat' ), $this-&gt;get_breadcrumb_term_title( $ancestor ) ) . $this-&gt;get_sep();
		}
		return $html . $this-&gt;settings['before'] . $this-&gt;get_breadcrumb_term_title( get_queried_object() ) . $this-&gt;settings['after'];
	}
	/**
	 * Get product tag
	 */
	private function get_crumbs_product_tag() {
		$html = '';
		if ( $this-&gt;args['show_shop'] ) {
			$html .= $this-&gt;get_shop_crumb();
		}
		return $html . $this-&gt;settings['before'] . $this-&gt;get_breadcrumb_term_title( get_queried_object() ) . $this-&gt;settings['after'];
	}
	/**
	 * Get product attributes.
	 */
	private function get_crumbs_product_attribute() {
		$html = '';
		if ( $this-&gt;args['show_shop'] ) {
			$html .= $this-&gt;get_shop_crumb();
		}
		return $html . $this-&gt;settings['before'] . $this-&gt;get_breadcrumb_term_title( get_queried_object() ) . $this-&gt;settings['after'];
	}
	/**
	 * Get dokan store.
	 */
	private function get_crumbs_dokan_store() {
		$html = '';
		$store_user = dokan()-&gt;vendor-&gt;get( get_query_var( 'author' ) );
		return $html . $this-&gt;settings['before'] . $store_user-&gt;get_shop_name() . $this-&gt;settings['after'];
	}
	/**
	 * Check if has post archive.
	 *
	 * @param string $post_type the post type.
	 */
	private function check_has_archive( $post_type ) {
		if ( ! isset( $post_type ) ) {
			return false;
		}
		// find custom post types with archives.
		$args = array(
			'has_archive' =&gt; true,
			'_builtin'    =&gt; false,
		);
		$output = 'names';
		$archived_custom_post_types = get_post_types( $args, $output );

		// if there are no custom post types, then the current post can't be one.
		if ( empty( $archived_custom_post_types ) ) {
			return false;
		}
		// check if post type is a supports archives.
		if ( in_array( $post_type, $archived_custom_post_types ) ) {
			return true;
		} else {
			return false;
		}
		// if all else fails, return false.
		return false;
	}
	/**
	 * Get archive Breadcrumb
	 *
	 * @param mixed  $archive_page the archive page for breadcrumbs.
	 * @param string $archive_label the archive page label for breadcrumbs.
	 */
	private function get_archive_crumb( $archive_page, $archive_label = '' ) {
		$html = '';
		if ( is_numeric( $archive_page ) ) {
			// Check if page ID.
			$parent_page_link = get_page_link( $archive_page );
			if ( $parent_page_link ) {
				$html .= sprintf( $this-&gt;get_link(), $parent_page_link, get_the_title( $archive_page ) ) . $this-&gt;get_sep();
			}
		} elseif ( 'shop' === $archive_page ) {
			if ( ! is_archive() &amp;&amp; ! $this-&gt;args['show_shop'] ) {
				$html .= '';
			} else {
				$html .= $this-&gt;get_shop_crumb();
			}
		} elseif ( 'tribe_events' === $archive_page ) {
			// Check for tribe.
			$html .= sprintf( $this-&gt;get_link(), tribe_get_events_link(), tribe_get_event_label_plural() ) . $this-&gt;get_sep();
		} elseif ( 'none' === $archive_page ) {
			// Check for none.
			$html .= '';
		} elseif ( 'archive' === $archive_page ) {
			$parent_title = ( ! empty( $archive_label ) ? $archive_label : 'Archive' );
			$html        .= sprintf( $this-&gt;get_link(), get_post_type_archive_link( get_post_type() ), $parent_title ) . $this-&gt;get_sep();
		} elseif ( filter_var( $archive_page, FILTER_VALIDATE_URL ) ) {
			// Check if url.
			$parent_title = ( ! empty( $archive_label ) ? $archive_label : 'Archive' );
			$html        .= sprintf( $this-&gt;get_link(), $archive_page, $parent_title ) . $this-&gt;get_sep();
		} elseif ( $this-&gt;check_has_archive( get_post_type() ) ) {
			$post_type_obj = get_post_type_object( get_post_type() );
			$parent_title  = apply_filters( 'post_type_archive_title', $post_type_obj-&gt;labels-&gt;name, get_post_type() );
			$html        .= sprintf( $this-&gt;get_link(), get_post_type_archive_link( get_post_type() ), $parent_title ) . $this-&gt;get_sep();
		}
		return $html;
	}
	/**
	 * Get main tax.
	 *
	 * @param string $taxonomy the taxonomy name.
	 * @param number $post_id the post id.
	 */
	private function get_taxonomy_main( $taxonomy, $post_id ) {
		$main_term = '';
		$terms     = wp_get_post_terms(
			$post_id,
			$taxonomy,
			array(
				'orderby' =&gt; 'parent',
				'order'   =&gt; 'DESC',
			)
		);
		if ( $terms &amp;&amp; ! is_wp_error( $terms ) ) {
			if ( is_array( $terms ) ) {
				$main_term = $terms[0];
			}
		}
		return $main_term;
	}

	/**
	 * Get tax Breadcrumb
	 *
	 * @param string $taxonomy the taxonomy type for breadcrumbs.
	 */
	private function get_taxonomy_crumb( $taxonomy ) {
		global $post;
		$html      = '';
		$main_term = '';
		if ( class_exists( 'WPSEO_Primary_Term' ) ) {
			$wpseo_term = new WPSEO_Primary_Term( $taxonomy, $post-&gt;ID );
			$wpseo_term = $wpseo_term-&gt;get_primary_term();
			$wpseo_term = get_term( $wpseo_term );
			if ( is_wp_error( $wpseo_term ) ) {
				$main_term = $this-&gt;get_taxonomy_main( $taxonomy, $post-&gt;ID );
			} else {
				$main_term = $wpseo_term;
			}
		} elseif ( class_exists( 'RankMath' ) ) {
			$wpseo_term = get_post_meta( $post-&gt;ID, 'rank_math_primary_' . $taxonomy, true );
			if ( $wpseo_term ) {
				$wpseo_term = get_term( $wpseo_term );
				if ( is_wp_error( $wpseo_term ) ) {
					$main_term = $this-&gt;get_taxonomy_main( $taxonomy, $post-&gt;ID );
				} else {
					$main_term = $wpseo_term;
				}
			} else {
				$main_term = $this-&gt;get_taxonomy_main( $taxonomy, $post-&gt;ID );
			}
		} else {
			$main_term = $this-&gt;get_taxonomy_main( $taxonomy, $post-&gt;ID );
		}
		if ( $main_term &amp;&amp; ! is_wp_error( $main_term ) ) {
			$ancestors = get_ancestors( $main_term-&gt;term_id, $taxonomy );
			$ancestors = array_reverse( $ancestors );
			foreach ( $ancestors as $ancestor ) {
				$ancestor = get_term( $ancestor, $taxonomy );
				$html    .= sprintf( $this-&gt;get_link(), get_term_link( $ancestor-&gt;slug, $taxonomy ), $this-&gt;get_breadcrumb_term_title( $ancestor ) ) . $this-&gt;get_sep();
			}
			$term_link = get_term_link( $main_term-&gt;slug, $taxonomy );
			if ( $term_link &amp;&amp; ! is_wp_error( $term_link ) ) {
				$html .= sprintf( $this-&gt;get_link(), $term_link, $this-&gt;get_breadcrumb_term_title( $main_term ) ) . $this-&gt;get_sep();
			}
		}
		return $html;
	}


	/**
	 * Get Custom Breadcrumb
	 *
	 * @param string $custom the custom string for breadcrumbs.
	 */
	private function get_custom_crumb( $custom ) {
		global $post;
		$html      = '';
		if ( 'liferlms' === $custom ) {
			$parent_course = get_post_meta( $post-&gt;ID, '_llms_parent_course', true );
			if ( $parent_course ) {
				$html .= sprintf( $this-&gt;get_link(), get_permalink( $parent_course ), get_the_title( $parent_course ) ) . $this-&gt;get_sep();
			}
		}
		return $html;
	}

	/**
	 * Get category
	 */
	private function get_crumbs_category() {
		$html = '';
		if ( $this-&gt;post_types['post']['archive_page'] ) {
			$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['post']['archive_page'], $this-&gt;post_types['post']['archive_label'] );
		}
		$ancestors = get_ancestors( get_queried_object()-&gt;term_id, 'category' );
		$ancestors = array_reverse( $ancestors );
		foreach ( $ancestors as $ancestor ) {
			$ancestor = get_term( $ancestor, 'category' );
			$html    .= sprintf( $this-&gt;get_link(), get_term_link( $ancestor-&gt;slug, 'category' ), $this-&gt;get_breadcrumb_term_title( $ancestor ) ) . $this-&gt;get_sep();
		}
		$title_output = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . $this-&gt;get_breadcrumb_term_title( get_queried_object() ) . $this-&gt;settings['after'] : '' );
		return $html . $title_output;
	}

	/**
	 * Get tag
	 */
	private function get_crumbs_tag() {
		$html = '';
		if ( $this-&gt;post_types['post']['archive_page'] ) {
			$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['post']['archive_page'], $this-&gt;post_types['post']['archive_label'] );
		}
		$title_output = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . $this-&gt;get_breadcrumb_term_title( get_queried_object() ) . $this-&gt;settings['after'] : '' );
		return $html . $title_output;
	}

	/**
	 * Get author
	 */
	private function get_crumbs_author() {
		global $author;
		$html = '';
		if ( $this-&gt;post_types['post']['archive_page'] ) {
			$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['post']['archive_page'], $this-&gt;post_types['post']['archive_label'] );
		}
		$userdata = get_userdata( $author );
		$title_output = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . $userdata-&gt;display_name . $this-&gt;settings['after'] : '' );
		return $html . $title_output;
	}
	/**
	 * Get author
	 */
	private function get_crumbs_archive() {
		$html = '';
		$title_output = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . get_the_archive_title() . $this-&gt;settings['after'] : '' );
		return $html . $title_output;
	}
	/**
	 * Get date
	 */
	private function get_crumbs_date() {
		$html = '';
		if ( $this-&gt;post_types['post']['archive_page'] ) {
			$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['post']['archive_page'], $this-&gt;post_types['post']['archive_label'] );
		}
		if ( is_day() ) {
			$html .= sprintf( $this-&gt;get_link(), get_year_link( get_the_time( 'Y' ) ), get_the_time( 'Y' ) ) . $this-&gt;get_sep();
			$html .= sprintf( $this-&gt;get_link(), get_month_link( get_the_time( 'Y' ), get_the_time( 'm' ) ), get_the_time( 'F' ) ) . $this-&gt;get_sep();
			$title = get_the_time( 'd' );
		} elseif ( is_month() ) {
			$html .= sprintf( $this-&gt;get_link(), get_year_link( get_the_time( 'Y' ) ), get_the_time( 'Y' ) ) . $this-&gt;get_sep();
			$title = get_the_time( 'F' );
		} else {
			$title = get_the_time( 'Y' );
		}
		$title_output = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . $title . $this-&gt;settings['after'] : '' );
		return $html . $title_output;
	}
	/**
	 * Get tax
	 */
	private function get_crumbs_tax() {
		$html = '';
		if ( is_tax( 'portfolio-type' ) || is_tax( 'portfolio-tag' ) ) {
			if ( $this-&gt;post_types['portfolio']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['portfolio']['archive_page'], $this-&gt;post_types['portfolio']['archive_label'] );
			}
		} elseif ( is_tax( 'staff-group' ) ) {
			if ( $this-&gt;post_types['staff']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['staff']['archive_page'], $this-&gt;post_types['staff']['archive_label'] );
			}
		} elseif ( is_tax( 'testimonial-group' ) ) {
			if ( $this-&gt;post_types['testimonial']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['testimonial']['archive_page'], $this-&gt;post_types['testimonial']['archive_label'] );
			}
		} elseif ( is_tax( 'event-category' ) ) {
			if ( $this-&gt;post_types['event']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['event']['archive_page'], $this-&gt;post_types['event']['archive_label'] );
			}
		} elseif ( is_tax( 'series' ) ) {
			if ( $this-&gt;post_types['podcast']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['podcast']['archive_page'], $this-&gt;post_types['podcast']['archive_label'] );
			}
		} elseif ( is_tax( 'ht_kb_category' ) ) {
			if ( $this-&gt;post_types['ht_kb']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['ht_kb']['archive_page'], $this-&gt;post_types['ht_kb']['archive_label'] );
			}
		} elseif ( is_tax( 'course_cat' ) || is_tax( 'course_tag' ) || is_tax( 'course_track' ) ) {
			if ( $this-&gt;post_types['course']['archive_page'] ) {
				$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types['course']['archive_page'], $this-&gt;post_types['course']['archive_label'] );
			}
		}
		$title = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . $this-&gt;get_breadcrumb_term_title( get_queried_object() ) . $this-&gt;settings['after'] : '' );
		return $html . $title;
	}
	/**
	 * Get page
	 */
	private function get_crumbs_page() {
		global $post;
		$html         = '';
		$parent_id    = $post-&gt;post_parent;
		$parentcrumbs = array();
		if ( $parent_id ) {
			while ( $parent_id ) {
				$page           = get_page( $parent_id );
				$parentcrumbs[] = sprintf( $this-&gt;get_link(), get_permalink( $page-&gt;ID ), get_the_title( $page-&gt;ID ) ) . $this-&gt;get_sep();
				$parent_id      = $page-&gt;post_parent;
			}
		}
		$parentcrumbs = array_reverse( $parentcrumbs );
		foreach ( $parentcrumbs as $parentcrumb ) {
			$html .= $parentcrumb;
		}
		$title = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . get_the_title() . $this-&gt;settings['after'] : '' );
		return $html . $title;
	}
	/**
	 * Get single
	 */
	private function get_crumbs_single() {
		$html      = '';
		$post_type = get_post_type();
		if ( isset( $this-&gt;post_types[ $post_type ] ) ) {
			// Archive Page.
			$html .= $this-&gt;get_archive_crumb( $this-&gt;post_types[ $post_type ]['archive_page'], $this-&gt;post_types[ $post_type ]['archive_label'] );
			// Tax Page.
			$html .= $this-&gt;get_taxonomy_crumb( $this-&gt;post_types[ $post_type ]['taxonomy'] );
			// Custom Parent.
			if ( isset( $this-&gt;post_types[ $post_type ]['custom'] ) ) {
				$html .= $this-&gt;get_custom_crumb( $this-&gt;post_types[ $post_type ]['custom'] );
			}
		} else {
			// Archive Page.
			$html .= $this-&gt;get_archive_crumb( '', '' );
		}
		$title = ( $this-&gt;args['show_title'] ? $this-&gt;settings['before'] . get_the_title() . $this-&gt;settings['after'] : '' );
		return $html . $title;
	}
}
