https://t.me/RX1948
Server : Apache
System : Linux server.lienzindia.com 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64
User : plutus ( 1007)
PHP Version : 7.4.33
Disable Function : NONE
Directory :  /home/plutus/public_html/wp-content/themes/vrm/inc/lib/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/plutus/public_html/wp-content/themes/vrm/inc/lib/wpex-breadcrumbs.php
<?php

defined( 'ABSPATH' ) || exit;

/**
 * WPEX_Breadcrumbs class.
 */
if ( ! class_exists( 'WPEX_Breadcrumbs' ) ) {

	class WPEX_Breadcrumbs {

		/**
		 * Breadcrumbs html output.
		 */
		public $output = '';

		/**
		 * Breadcrumbs args.
		 */
		protected static $args = null;

		/**
		 * Check if we are displaying custom crumbs.
		 */
		protected $has_custom_crumbs = false;

		/**
		 * Main constructor.
		 */
		public function __construct( $args = [] ) {
			self::$args = self::get_args( $args );

			// Generate trail.
			$gcrumbs = $this->generate_crumbs();

			if ( $gcrumbs ) {
				$has_container = wpex_has_breadcrumbs_container();
				$aria_landmark = wpex_get_aria_landmark( 'breadcrumbs' );
				$aria_label    = wpex_get_aria_label( 'breadcrumbs' );

				if ( $aria_label ) {
					$aria_label = ' aria-label="' . esc_attr( $aria_label ) .'"';
				}

				$this->output .= '<nav class="' . esc_attr( self::wrap_classes() ) . '"' . $aria_landmark . $aria_label . '>';

					if ( $has_container ) {
						$this->output .= '<div class="container">';
					}

					if ( $this->has_custom_crumbs() ) {
						$this->output .= '<span class="breadcrumb-trail wpex-clr">';
					} else {
						$this->output .= '<span class="breadcrumb-trail wpex-clr" itemscope itemtype="http://schema.org/BreadcrumbList">';
					}

						$this->output .= $gcrumbs;

					$this->output .= '</span>';

					if ( $has_container ) {
						$this->output .= '</div>';
					}

				$this->output .= '</nav>';

			}
		}

		/**
		 * Outputs the generated breadcrumbs.
		 *
		 * @deprecated 3.6.0 // Will be removed at some point since it's not needed
		 */
		public function display( $echo = true ) {
			return $this->output;
		}

		/**
		 * Check if custom breadcrumbs are being displayed instead of the theme crumbs.
		 */
		public function has_custom_crumbs() {
			return apply_filters( 'wpex_has_custom_breadcrumbs_trail', $this->has_custom_crumbs );
		}

		/**
		 * Returns custom breadcrumbs for 3rd party integration.
		 */
		public function get_custom_crumbs() {
			$custom_crumbs = null;

			if ( function_exists( 'rank_math_get_breadcrumbs' ) ) {
				if ( class_exists( '\RankMath\Helper' )
					&& is_callable( [ '\RankMath\Helper', 'get_settings' ] )
					&& \RankMath\Helper::get_settings( 'general.breadcrumbs' )
				) {
					$this->has_custom_crumbs = true;
					$custom_crumbs = rank_math_get_breadcrumbs();
				}
			}

			if ( function_exists( 'yoast_breadcrumb' )
				&& current_theme_supports( 'yoast-seo-breadcrumbs' ) // make sure it's enabled.
				&& true === wp_validate_boolean( get_theme_mod( 'enable_yoast_breadcrumbs', true ) )
			) {
				$this->has_custom_crumbs = true;
				$custom_crumbs = yoast_breadcrumb( '', '', false );
			}

			return (string) apply_filters( 'wpex_custom_breadcrumbs_trail', $custom_crumbs );
		}

		/**
		 * Returns breadcrumbs arguments.
		 */
		public static function get_args( $args = [] ) {
			$home_text = (string) wpex_get_translated_theme_mod( 'breadcrumbs_home_title' );
			$home_text = $home_text ?: esc_html__( 'Home', 'total' );
			$separator = (string) get_theme_mod( 'breadcrumbs_separator' ) ?: '&raquo;';

			$default_args = [
				'home_text'        => $home_text,
				'home_link'        => (string) home_url( '/' ),
				'separator'        => do_shortcode( sanitize_text_field( $separator ) ),
				'front_page'       => false,
				'cpt_find_parents' => false,
				'show_parents'     => (bool) get_theme_mod( 'breadcrumbs_show_parents', true ),
				'show_trail_end'   => (bool) get_theme_mod( 'breadcrumbs_show_trail_end', true ),
				'first_term_only'  => (bool) get_theme_mod( 'breadcrumbs_first_cat_only', true ),
			];

			$args = wp_parse_args( $args, $default_args );

			/**
			 * Filters the breadcrumbs args.
			 *
			 * @param array $args
			 */
			$args = (array) apply_filters( 'wpex_breadcrumbs_args', $args );

			return $args;
		}

		/**
		 * Returns specific breadcrumbs argument.
		 */
		public static function get_arg( $arg = '' ) {
			if ( array_key_exists( $arg, self::$args ) ) {
				return self::$args[$arg];
			}
			return self::get_args()[$arg] ?? null;
		}

		/**
		 * Generates the breadcrumbs and updates the $trail var.
		 *
		 * @todo separate into different methods to keep things cleaner.
		 */
		public function generate_crumbs() {
			$custom_crumbs = $this->get_custom_crumbs();

			if ( $this->has_custom_crumbs() ) {
				return $custom_crumbs;
			}

			// Globals.
			global $wp_query, $wp_rewrite;

			// Define main variables.
			$breadcrumb = '';

			/*-----------------------------------------------------------------------------------*/
			/*  - Homepage link
			/*  - Note: can't use get_crumb_html() because text must support shortcodes + html
			/*-----------------------------------------------------------------------------------*/
			$trail['trail_start'] = '<span class="trail-begin" ' . self::get_item_sd_markup() . '><a ' . self::get_link_sd_markup() . ' href="'. esc_url( self::$args['home_link'] ) .'" rel="home"><span itemprop="name">' . do_shortcode( wp_kses_post( self::$args['home_text'] ) ) . '</span></a><meta itemprop="position" content="1"></span>';

			/*-----------------------------------------------------------------------------------*/
			/*  - Front Page
			/*-----------------------------------------------------------------------------------*/
			if ( is_front_page() && false === self::$args['front_page'] ) {
				$trail = false;
			}

			/*-----------------------------------------------------------------------------------*/
			/*  - Homepage or posts page
			/*-----------------------------------------------------------------------------------*/
			elseif ( is_home() ) {
				$home_page = get_page( $wp_query->get_queried_object_id() );
				if ( is_object( $home_page ) ) {
					$trail = array_merge( $trail, self::get_post_parents( $home_page->post_parent, '' ) );
					$trail['trail_end'] = get_the_title( $home_page->ID );
				} else {
					$trail = false;
				}
			}

			/*-----------------------------------------------------------------------------------*/
			/*  - Singular: Page, Post, Attachment...etc
			/*-----------------------------------------------------------------------------------*/
			elseif ( $wp_query->is_singular ) {

				// Get singular vars.
				$post                       = $wp_query->get_queried_object();
				$post_id                    = absint( $wp_query->get_queried_object_id() );
				$post_type                  = $post->post_type;
				$post_type_obj              = get_post_type_object( $post_type );
				$parent                     = ( true === self::$args['show_parents'] ) ? $post->post_parent : '';
				$trail['post_type_archive'] = ''; // Add empty post type trail for custom types.

				// If parent is the same as front-page set to empty.
				if ( $parent == get_option( 'page_on_front' ) ) {
					$parent = '';
				}

				// Get Post types primary page.
				switch ( $post_type ) {

					case 'page':

						// Woo pages
						if ( defined( 'WPEX_WOOCOMMERCE_ACTIVE' ) && WPEX_WOOCOMMERCE_ACTIVE ) {

							// Add shop page to cart.
							if ( is_cart() || is_checkout() ) {

								// Get shop data.
								$shop_data  = self::get_shop_data();
								$shop_url   = $shop_data['url'];
								$shop_title = $shop_data['title'];

								// Add shop link.
								if ( $shop_url && $shop_title ) {
									$trail['shop'] = self::get_crumb_html( $shop_title, $shop_url, 'trail-shop' );
								}

							}

							// Add cart to checkout.
							if ( apply_filters( 'wpex_breadcrumbs_checkout_cart', false )
								&& is_checkout()
								&& $cart_id = wpex_parse_obj_id( wc_get_page_id( 'cart' ), 'page' )
							) {
								$trail['cart'] = self::get_crumb_html( get_the_title( $cart_id ), get_permalink( $cart_id ), 'trail-cart' );
							}

						}

						// Add page parents.
						if ( $parent ) {
							$trail = array_merge( $trail, self::get_post_parents( $parent ) );
						}

						break;

					case 'post';

						// Main Blog URL.
						if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'blog_page' ), 'page' ) ) {
							if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
								$trail = array_merge( $trail, $parents );
							} else {
								$trail['blog'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-blog-url' );
							}
						}

						// Add URL based on posts page.
						elseif ( $page_for_posts = get_option( 'page_for_posts' ) ) {
							$trail['blog'] = self::get_crumb_html( get_the_title( $page_for_posts ), get_permalink( $page_for_posts ), 'trail-blog-url' );
						}

						// Categories.
						if ( $terms = self::get_post_terms( 'category' ) ) {
							$trail['categories'] = '<span class="trail-post-categories">' . $terms . '</span>';
						}

						break;

					case 'tribe_events';

						if ( function_exists( 'tribe_get_events_link' ) ) {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'tribe_events_main_page' ), 'page' ) ) {
								$title = get_the_title( $page_id );
								$link  = get_permalink( $page_id );
							} else {
								$title = esc_html__( 'All Events', 'total' );
								$link  = tribe_get_events_link();
							}
							$trail['tribe_events'] = self::get_crumb_html( $title, $link, 'trail-all-events' );
						}

						break;

					case 'portfolio':

						// Portfolio main page.
						if ( ! empty( $post_type_obj->has_archive ) ) {
							$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						} else {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'portfolio_page' ), 'page' ) ) {
								if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
									$trail = array_merge( $trail, $parents );
								} else {
									$trail['portfolio'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-portfolio-url' );
								}
							}
						}

						// Portfolio Categories.
						if ( $terms = self::get_post_terms( 'portfolio_category' ) ) {
							$trail['categories'] = '<span class="trail-post-categories">' . $terms . '</span>';
						}

						break;

					case 'staff':

						// Staff main page.
						if ( ! empty( $post_type_obj->has_archive ) ) {
							$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						} else {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'staff_page' ), 'page' ) ) {
								if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
									$trail = array_merge( $trail, $parents );
								} else {
									$trail['staff'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-staff-url' );
								}
							}
						}

						// Staff Categories.
						if ( $terms = self::get_post_terms( 'staff_category' ) ) {
							$trail['categories'] = '<span class="trail-post-categories">' . $terms . '</span>';
						}

						break;

					case 'testimonials':

						// Testimonials main page.
						if ( ! empty( $post_type_obj->has_archive ) ) {
							$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						} else {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'testimonials_page' ), 'page' ) ) {
								if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
									$trail = array_merge( $trail, $parents );
								} else {
									$trail['testimonials'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-testimonials-url' );
								}
							}
						}

						// Testimonials Categories.
						if ( $terms = self::get_post_terms( 'testimonials_category' ) ) {
							$trail['categories'] = '<span class="trail-post-categories">' . $terms . '</span>';
						}

						break;

					case 'product':

						// Get shop data.
						$shop_data  = self::get_shop_data();
						$shop_id    = $shop_data['id'];
						$shop_url   = $shop_data['url'];
						$shop_title = $shop_data['title'];

						// Add shop page to product post.
						if ( $shop_url && $shop_title && $shop_id != get_option( 'page_on_front' ) ) {
							$trail['shop'] = self::get_crumb_html( $shop_title, $shop_url, 'trail-shop' );
						}

						// Add categories to product post.
						if ( $terms = self::get_post_terms( 'product_cat' ) ) {
							$trail['categories'] = '<span class="trail-post-categories">' . $terms . '</span>';
						}

						// Add cart to product post.
						if ( apply_filters( 'wpex_breadcrumbs_single_product_cart', false )
							&& $page_id = wpex_parse_obj_id( wc_get_page_id( 'cart' ) )
						) {
							$trail['cart'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-cart' );
						}

						break;

					default:

						// If archive page exists add to trail.
						if ( ! empty( $post_type_obj->has_archive ) ) {

							if ( ! is_singular( 'product' ) ) {
								$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
							}

						} elseif ( empty( $ptu_check ) && true === self::$args['cpt_find_parents'] ) {
							$trail = array_merge( $trail, self::cpt_find_parents( $post_type_obj ) );
						}

						// Check PTU settings which override the default post_type_archive.
						if ( WPEX_PTU_ACTIVE ) {
							$ptu_check = wpex_get_ptu_type_mod( $post_type, 'main_page' );
							if ( $ptu_check ) {
								$ptu_check = wpex_parse_obj_id( $ptu_check );
								if ( get_post_status( $ptu_check ) ) {
									$trail['post_type_archive'] = self::get_crumb_html( get_the_title( $ptu_check ), get_permalink( $ptu_check ) );
								}
							}
						}

						// CPTUI parent page.
						if ( empty( $trail['categories'] ) && defined( 'WPEX_CPTUI_INTEGRATION' ) ) {
							$cptui_main_page = TotalTheme\Integration\Custom_Post_Type_UI::get_setting_val( $post_type, 'main_page' );
							if ( $cptui_main_page ) {
								$cptui_main_page = wpex_parse_obj_id( $cptui_main_page );
								if ( get_post_status( $cptui_main_page ) ) {
									$trail['post_type_archive'] = self::get_crumb_html( get_the_title( $cptui_main_page ), get_permalink( $cptui_main_page ) );
								}
							}
						}

						// Add post type parent posts.
						if ( $parent ) {
							$trail = array_merge( $trail, self::get_post_parents( $parent ) );
						}

						// Get PTU categories/terms.
						if ( WPEX_PTU_ACTIVE ) {
							$ptu_main_tax = wpex_get_ptu_type_mod( $post_type, 'main_taxonomy' );
							if ( $ptu_main_tax && taxonomy_exists( $ptu_main_tax ) ) {
								if ( $terms = self::get_post_terms( $ptu_main_tax ) ) {
									$trail['categories'] = '<span class="trail-categories">' . $terms . '</span>';
								}
							}
						}

						// CPTUI terms.
						if ( empty( $trail['categories'] ) && defined( 'WPEX_CPTUI_INTEGRATION' ) ) {
							$cptui_tax = TotalTheme\Integration\Custom_Post_Type_UI::get_setting_val( $post_type, 'main_taxonomy' );
							if ( $cptui_tax && taxonomy_exists( $cptui_tax ) ) {
								if ( $terms = self::get_post_terms( $cptui_tax ) ) {
									$trail['categories'] = '<span class="trail-cptui-terms">' . $terms . '</span>';
								}
							}
						}

						// Add empty category to array for addition of taxonomies via filters.
						if ( empty( $trail['categories'] ) ) {
							$trail['categories'] = '';
						}

						break;

				} // End $post_type switch.

				// End trail with post title.
				if ( $post_title = get_the_title( $post_id ) ) {
					$trim_title = get_theme_mod( 'breadcrumbs_title_trim' );
					$show_title = true;
					if ( isset( $trim_title ) && '0' === $trim_title ) {
						$show_title = false;
					}
					if ( $show_title ) {
						if ( $trim_title ) {
							$post_title = wp_trim_words( $post_title, $trim_title );
						}
						$trail['trail_end'] = $post_title;
					}
				}

			}

			/*-----------------------------------------------------------------------------------*/
			/*  - ALL Archives
			/*-----------------------------------------------------------------------------------*/
			elseif ( is_archive() ) {

				/*-----------------------------------------------------------------------------------*/
				/*  - Post Type Archive
				/*-----------------------------------------------------------------------------------*/
				if ( is_post_type_archive() ) {

					// Shop Archive.
					if ( function_exists( 'is_shop' ) && is_shop() ) {

						if ( apply_filters( 'wpex_breadcrumbs_shop_cart', false ) ) {
							global $woocommerce;
							if ( sizeof( $woocommerce->cart->cart_contents ) > 0 ) {
								if ( $page_id = wpex_parse_obj_id( wc_get_page_id( 'cart' ), 'page' ) ) {
									$trail['cart'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-cart' );
								}
							}
						}

						// Store shop data.
						$shop_data = self::get_shop_data();

						// Add shop page title to trail end.
						if ( $shop_data['title'] ) {
							$trail['trail_end'] = $shop_data['title'];
						} else {
							$trail['trail_end'] = post_type_archive_title( '', false );
						}

					}

					// Topics Post Type Archive.
					elseif ( is_post_type_archive( 'topic' ) ) {

						if ( is_object( $forum_obj = get_post_type_object( 'forum' ) ) ) {

							if ( $forums_link = get_post_type_archive_link( 'forum' ) ) {
								$trail['forum'] = self::get_crumb_html( $forum_obj->labels->name, $forums_link, 'trail-forum' );
							}

							$trail['trail_end'] = $forum_obj->labels->name;

						}

					// All other post type archives.
					} else {

						// Add post type name to trail end
						$post_type_obj      = get_post_type_object( get_query_var( 'post_type' ) );
						$trail['trail_end'] = $post_type_obj->labels->name;

					}

				}

				/*-----------------------------------------------------------------------------------*/
				/*  - Taxonomy Archive
				/*-----------------------------------------------------------------------------------*/
				elseif ( ! is_search() && ( is_tax() || is_category() || is_tag() ) ) {

					$post_type     = get_post_type();
					$post_type_obj = isset( $post_type ) ? get_post_type_object( $post_type ) : '';

					// Link to main portfolio page.
					if ( wpex_is_portfolio_tax() ) {
						if ( ! empty( $post_type_obj->has_archive ) ) {
						$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						} else {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'portfolio_page' ), 'page' ) ) {
								if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
									$trail = array_merge( $trail, $parents );
								} else {
									$trail['portfolio'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-portfolio-url' );
								}
							}
						}
					}

					// Link to main staff page.
					elseif ( wpex_is_staff_tax() ) {
						if ( ! empty( $post_type_obj->has_archive ) ) {
						$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						} else {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'staff_page' ), 'page' ) ) {
								if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
									$trail = array_merge( $trail, $parents );
								} else {
									$trail['staff'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-staff-url' );
								}
							}
						}
					}

					// Testimonials Tax.
					elseif ( wpex_is_testimonials_tax() ) {
						if ( ! empty( $post_type_obj->has_archive ) ) {
						$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						} else {
							if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'testimonials_page' ), 'page' ) ) {
								if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
									$trail = array_merge( $trail, $parents );
								} else {
									$trail['testimonials'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-testimonials-url' );
								}
							}
						}
					}

					// Display main blog page on post archives.
					elseif ( is_category() || is_tag()  ) {
						$blog_page = wpex_parse_obj_id( get_theme_mod( 'blog_page' ), 'page' );
						if ( $blog_page ) {
							if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $blog_page ) ) {
								$trail = array_merge( $trail, $parents );
							} else {
								$trail['blog'] = self::get_crumb_html( get_the_title( $blog_page ), get_permalink( $blog_page ), 'trail-blog-url' );
							}
						} elseif ( $page_for_posts = get_option( 'page_for_posts' ) ) {
							$trail['blog'] = self::get_crumb_html( get_the_title( $page_for_posts ), get_permalink( $page_for_posts ), 'trail-blog-url' );
						}
					}

					// Woo Product Tax
					elseif ( wpex_is_woo_tax() ) {

						// Get shop data.
						$shop_data  = self::get_shop_data();
						$shop_url   = $shop_data['url'];
						$shop_title = $shop_data['title'];

						// Add shop page to product post.
						if ( $shop_url && $shop_title ) {
							$trail['shop'] = self::get_crumb_html( $shop_title, $shop_url, 'trail-shop' );
						}

					}

					// For all other taxonomies get post type archive URL or locate a page.
					else {

						if ( ! empty( $post_type_obj->has_archive ) ) {
							$trail['post_type_archive'] = self::get_crumb_html( $post_type_obj->labels->name, get_post_type_archive_link( $post_type ), 'trail-type-archive' );
						}

						// No archive defined so lets try and locate a parent cpt page.
						elseif ( true === self::$args['cpt_find_parents'] ) {
							$trail = array_merge( $trail, self::cpt_find_parents( $post_type_obj ) );
						}

						if ( WPEX_PTU_ACTIVE ) {
							$ptu_check = wpex_get_ptu_tax_mod( get_query_var( 'taxonomy' ), 'main_page' );
							if ( $ptu_check ) {
								$ptu_check = wpex_parse_obj_id( $ptu_check );
								if ( str_starts_with( $ptu_check, 'pt_archive_' ) ) {
									$pt_archive_link = get_post_type_archive_link( str_replace( 'pt_archive_', '', $ptu_check ) );
									if ( $pt_archive_link ) {
										$pt_obj = get_post_type_object( $post_type );
										if ( is_object( $pt_obj ) && ! empty( $pt_obj->labels->name ) ) {
											$trail['post_type_archive'] = self::get_crumb_html( $pt_obj->labels->name, $pt_archive_link );
										}
									}
								} else {
									if ( get_post_status( $ptu_check ) ) {
										$trail['post_type_archive'] = self::get_crumb_html( get_the_title( $ptu_check ), get_permalink( $ptu_check ) );
									}
								}
							}
						}

					}

					// Add term parents.
					$term = $wp_query->get_queried_object();
					if ( is_taxonomy_hierarchical( $term->taxonomy ) && $term->parent ) {
						$trail = array_merge( $trail, $this->get_term_parents( $term ) );
					}

					// Add term name to trail end.
					$trail['trail_end'] = $term->name;

				}

				/*-----------------------------------------------------------------------------------*/
				/*  - Author Archive
				/*-----------------------------------------------------------------------------------*/
				elseif ( is_author() ) {

					// Add main blog.
					if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'blog_page' ), 'page' ) ) {
						if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
							$trail = array_merge( $trail, $parents );
						} else {
							$trail['blog'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-blog-url' );
						}
					}

					// Add the author display name to end.
					$trail['trail_end'] = get_the_author_meta( 'display_name', get_query_var( 'author' ) );

				}

				/*-----------------------------------------------------------------------------------*/
				/*  - Time Archive
				/*-----------------------------------------------------------------------------------*/
				elseif ( is_time() ) {

					// Display minute and hour.
					if ( get_query_var( 'minute' ) && get_query_var( 'hour' ) ) {
						$trail['trail_end'] = get_the_time( 'g:i a' );
					}

					// Display minute only.
					elseif ( get_query_var( 'minute' ) ) {
						$trail['trail_end'] = sprintf( esc_html__( 'Minute %1$s', 'total' ), get_the_time( 'i' ) );
					}

					// Display hour only.
					elseif ( get_query_var( 'hour' ) ) {
						$trail['trail_end'] = get_the_time( 'g a' );
					}

				}

				/*-----------------------------------------------------------------------------------*/
				/*  - Date Archive
				/*-----------------------------------------------------------------------------------*/
				elseif ( is_date() ) {

					// Add main blog.
					if ( $page_id = wpex_parse_obj_id( get_theme_mod( 'blog_page' ), 'page' ) ) {
						if ( true === self::$args['show_parents'] && $parents = self::get_post_parents( $page_id ) ) {
							$trail = array_merge( $trail, $parents );
						} else {
							$trail['blog'] = self::get_crumb_html( get_the_title( $page_id ), get_permalink( $page_id ), 'trail-blog-url' );
						}
					} elseif ( $page_for_posts = get_option( 'page_for_posts' ) ) {
						$trail['blog'] = self::get_crumb_html( get_the_title( $page_for_posts ), get_permalink( $page_for_posts ), 'trail-blog-url' );
					}

					// If $front is set check for parents.
					if ( $wp_rewrite->front ) {
						$trail = array_merge( $trail, self::get_post_parents( '', $wp_rewrite->front ) );
					}

					// Day archive.
					if ( is_day() ) {

						// Link to year archive.
						$title = date_i18n( 'Y', strtotime( get_the_time( 'd.m.Y' ) ) );
						$link  = get_year_link( get_the_time( 'Y' ) );
						$trail['year'] = self::get_crumb_html( $title, $link, 'trail-year' );

						// Link to month archive.
						$title = date_i18n( 'F', strtotime( get_the_time( 'd.m.Y' ) ) );
						$link  = get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) );
						$trail['month'] = self::get_crumb_html( $title, $link, 'trail-month' );

						// Add time to end.
						$trail['trail_end'] = sprintf( esc_html__( 'Daily Archives: %s', 'total' ), get_the_date() );

					}

					// Week archive.
					if ( get_query_var( 'w' ) ) {

						// Link to year archive.
						$title = date_i18n( 'Y', strtotime( get_the_time( 'd.m.Y' ) ) );
						$link  = get_year_link( get_the_time( 'Y' ) );
						$trail['year'] = self::get_crumb_html( $title, $link, 'trail-year' );

						// Add week to end.
						$trail['trail_end'] = sprintf( esc_html__( 'Week %1$s', 'total' ), get_the_time( 'W' ) );

					}

					// Month archive.
					if ( is_month() ) {

						// Link to year archive.
						$title = date_i18n( 'Y', strtotime( get_the_time( 'd.m.Y' ) ) );
						$link  = get_year_link( get_the_time( 'Y' ) );
						$trail['year'] = self::get_crumb_html( $title, $link, 'trail-year' );

						// Add month to end.
						$trail['trail_end'] = esc_html( sprintf( esc_html__( 'Monthly Archives: %s', 'total' ), get_the_date( 'F Y' ) ) );

					}

					// Year archive.
					if ( is_year() ) {
						$trail['trail_end'] = esc_html( sprintf( esc_html__( 'Yearly Archives: %s', 'total' ), get_the_date( 'Y' ) ) );
					}

				}
			}

			/*-----------------------------------------------------------------------------------*/
			/*  - Search
			/*-----------------------------------------------------------------------------------*/
			elseif ( is_search() ) {
				$trail['trail_end'] = esc_html__( 'Search Results', 'total' );
			}

			/*-----------------------------------------------------------------------------------*/
			/*  - 404
			/*-----------------------------------------------------------------------------------*/
			elseif ( is_404() ) {
				$trail['trail_end'] = esc_html__( '404 Error Page', 'total' );;
			}

			/*-----------------------------------------------------------------------------------*/
			/*  - Tribe Calendar Month
			/*-----------------------------------------------------------------------------------*/
			elseif ( function_exists( 'tribe_is_month' ) && tribe_is_month() ) {
				$trail['trail_end'] = esc_html__( 'Events Calendar', 'total' );
			}

			/*-----------------------------------------------------------------------------------*/
			/*  - Create and return the breadcrumbs
			/*-----------------------------------------------------------------------------------*/

			// Add a before trail_end empty item for easier addition of items before the title.
			if ( isset( $trail['trail_end'] ) ) {
				$trail_end = $trail['trail_end'];
				unset( $trail['trail_end'] );
				$trail['pre_trail_end'] = '';
				$trail['trail_end'] = $trail_end;
			}

			/**
			 * Filters the breadcrumbs trail.
			 *
			 * @param array $trail
			 * @param array $args
			 */
			$trail = (array) apply_filters( 'wpex_breadcrumbs_trail', $trail, self::$args );

			$trail = array_filter( $trail ); // Remove dups.

			if ( ! $trail ) {
				return;
			}

			// Add to trail.
			if ( isset( $trail['trail_end'] ) ) {

				if ( false === self::$args['show_trail_end'] ) {
					unset( $trail['trail_end'] );
				} else {
					$trail_end_allowed_tags = apply_filters( 'wpex_breadcrumbs_trail_end_allowed_html_tags', [
						'abbr' => [],
					] );
					$trail['trail_end'] = '<span class="trail-end">' . wp_kses( $trail['trail_end'], $trail_end_allowed_tags ) . '</span>';
				}
			}

			// Count all trail items.
			$all_count = count( $trail );

			if ( 0 === $all_count || ( false === self::$args['show_trail_end'] && 1 === $all_count ) ) {
				return '';
			}

			// Loop through items and convert into a single string.
			$count = 0;
			foreach ( $trail as $key => $val ) {
				$count++;
				$val = str_replace( '</a></span>', '<meta itemprop="position" content="' . absint( $count ) . '"></a></span>', $val );
				$breadcrumb .= $val;
				if ( $all_count !== $count ) {
					$breadcrumb .= '<span class="sep sep-' . esc_attr( $count ) . '"> ' . self::$args['separator'] . ' </span>';
				}
			}

			return $breadcrumb;
		} // End generate_crumbs

		/**
		 * Generate single crumb html.
		 */
		public static function get_crumb_html( $label, $link, $class = '', $rel = '' ) {
			if ( ! $link ) {
				return; // Link required.
			}
			$item_markup = self::get_item_sd_markup();
			$class = $class ? ' class="' . esc_attr( $class ) . '"': '';
			$rel   = $rel ? ' rel="' . esc_attr( $rel ) . '"': '';
			return '<span ' . $item_markup . $class . $rel . '><a '. self::get_link_sd_markup() . ' href="' . esc_url( $link ) . '"><span itemprop="name">' . wp_strip_all_tags( $label ) . '</span></a></span>';
		}

		/**
		 * Returns item scope.
		 */
		public static function get_item_sd_markup() {
			return 'itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"';
		}

		/**
		 * Returns thing scope.
		 */
		public static function get_link_sd_markup() {
			return 'itemprop="item"';
		}

		/**
		 * Display terms.
		 */
		public static function get_post_terms( $taxonomy = '' ) {
			if ( ! get_theme_mod( 'breadcrumbs_show_terms', true ) ) {
				return null;
			}

			// Make sure taxonomy exists.
			if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) {
				return null;
			}

			// Make sure taxonomy is public.
			$taxonomy_obj = get_taxonomy( $taxonomy );

			if ( ! is_wp_error( $taxonomy_obj )
				&& is_object( $taxonomy_obj )
				&& false === $taxonomy_obj->publicly_queryable
			) {
				return null;
			}

			/**
			 * Filters the breadcrums terms before trying to locate terms.
			 *
			 * @param object $terms
			 */
			$terms = apply_filters( 'wpex_breadcrumbs_terms', null, $taxonomy );

			// Return terms if filtered.
			if ( $terms ) {
				return $terms;
			}

			// Get terms.
			$list_terms = [];

			/**
			 * Filters the breadcrums get_terms args.
			 *
			 * @param array $args
			 * @todo rename to "get_the_terms" instead of "wp_get_post_terms"
			 */
			$args = apply_filters( 'wpex_breadcrumbs_wp_get_post_terms_args', [] );

			$terms = get_the_terms( get_the_ID(), $taxonomy, $args );

			// Return if no terms are found.
			if ( ! $terms ) {
				return;
			}

			// Itemscope.
			$itemscope = self::get_item_sd_markup();

			// Check if it should display all terms or only first term.
			$show_all_terms  = ! self::get_arg( 'first_term_only' );

			/**
			 * Filters whether the breadcrumbs should display all terms.
			 *
			 * @param bool $show_all_terms
			 */
			$show_all_terms = (bool) apply_filters( 'wpex_breadcrumbs_terms_all', $show_all_terms );

			// Loop through terms.
			if ( $show_all_terms ) {

				foreach ( $terms as $term ) {

					// Translation fixes.
					$translated_term = wpex_parse_obj_id( $term->term_id, 'term', $taxonomy );
					if ( $term->term_id != $translated_term ) {
						$term = get_term( $translated_term, $taxonomy );
					}

					$list_terms[] = self::get_crumb_html( $term->name, get_term_link( $term->term_id, $taxonomy ), 'term-' . $term->term_id );

				}

			}

			// Return first term only
			// @todo update to check for primary category.
			else {

				$primary_term = wpex_get_post_primary_term( get_the_ID(), $taxonomy );

				if ( $primary_term && ! is_wp_error( $primary_term ) ) {
					$term = $primary_term;
				} else {
					$term = $terms[0];
				}

				$term_link = get_term_link( $term->term_id, $taxonomy );

				$term_class = 'term-' . sanitize_html_class( $term->term_id );

				$list_terms[] = self::get_crumb_html( $term->name, $term_link, $term_class );

			}

			// Sanitize terms.
			$terms = ! empty( $list_terms ) ? implode( wpex_inline_list_sep( 'breadcrumbs' ), $list_terms ) : '';

			return $terms;
		}

		/**
		 * Tries to locate a custom post type parent page based on the path.
		 */
		public static function cpt_find_parents( $post_type_obj = '' ) {
			if ( ! $post_type_obj ) {
				return $trail;
			}

			global $wp_query, $wp_rewrite;
			$trail = [];
			$path  = '';

			// Add $front to the path.
			if ( $post_type_obj->rewrite['with_front'] && $wp_rewrite->front ) {
				$path .= trailingslashit( $wp_rewrite->front );
			}

			// Add slug to $path.
			if ( ! empty( $post_type_obj->rewrite['slug'] ) ) {
				$path .= $post_type_obj->rewrite['slug'];
			}

			// If we can't find a path then return trail.
			if ( ! $path ) {
				return $trail;
			}

			// Get parent post by the path.
			$parent_page = get_page_by_path( $path );

			// Try to get by title with single word.
			if ( empty( $parent_page ) ) {
				$parent_page = self::get_page_by_title( $path );
			}

			// Try again based on title with multiple words.
			if ( empty( $parent_page ) ) {
				$parent_page = self::get_page_by_title( str_replace( [ '-', '_' ], ' ', $path ) );
			}

			// Parent is found so lets return the ID.
			if ( ! empty( $parent_page ) ) {
				$post_id = $parent_page->ID ?? 0;
			}

			if ( $parent_page ) {
				$trail[] = self::get_crumb_html( get_the_title( $post_id ), get_permalink( $post_id ), 'trail-parent' );
			}

			return $trail;
		}

		/**
		 * Searches for post parents and adds them to the trail.
		 */
		public static function get_post_parents( $post_id = '' ) {
			$trail = [];

			// Return empty array if the post id and path are both empty.
			if ( empty( $post_id ) ) {
				return $trail;
			}

			// Define empty parents array.
			$parents = [];

			// Loop through and add parents to parents array.
			while ( $post_id ) {

				// Get the post by ID.
				$post = get_post( $post_id );

				// Add the post link to the array.
				$parents[] = self::get_crumb_html( get_the_title( $post_id ), get_permalink( $post_id ), 'trail-parent' );

				// Set the parent post's parent to the post ID.
				$post_id = $post ? $post->post_parent : '';

			}

			// If parent pages are found reverse order so they are correct.
			if ( $parents ) {
				$trail = array_reverse( $parents );
			}

			return $trail;
		}

		/**
		 * Searches for term parents and adds them to the trail.
		 */
		private function get_term_parents( $term = '' ) {
			$trail = [];

			if ( empty( $term->taxonomy ) ) {
				return $trail;
			}

			$parents  = [];
			$taxonomy = $term->taxonomy;

			if ( is_taxonomy_hierarchical( $taxonomy ) && $term->parent != 0 ) {

				// While there is a parent ID, add the parent term link to the $parents array.
				$count = 0;
				while ( $term->parent != 0 ) {
					$count ++;

					// Get term
					$term = get_term( $term->parent, $taxonomy );

					// Add the formatted term link to the array of parent terms.
					$parents['parent_term_'. $count ] = self::get_crumb_html( $term->name, get_term_link( $term, $taxonomy ), 'trail-parent-term' );

				}

				// If we have parent terms, reverse the array to put them in the proper order for the trail.
				if ( ! empty( $parents ) ) {
					$trail = array_reverse( $parents );
				}

			}

			return $trail;
		}

		/**
		 * Get the parent category if only one term exists for the post.
		 */
		public static function get_singular_first_cat_parents( $taxonomy = '' ) {
			$trail = [];

			if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) {
				return null;
			}

			$terms = get_the_terms( get_the_ID(), $taxonomy );

			if ( $terms && isset( $terms[0] ) and 1 == count( $terms ) ) {
				$term = get_term( $terms[0] );
				$trail = self::get_term_parents( $term );
			}

			return $trail;
		}

		/**
		 * Gets Woo Shop data.
		 */
		public static function get_shop_data( $return = '' ) {
			$data = [
				'id'    => '',
				'url'   => '',
				'title' => esc_html__( 'Shop', 'total' ),
			];

			if ( ! function_exists( 'wc_get_page_id' ) ) {
				return $data;
			}

			$id = intval( wpex_parse_obj_id( wc_get_page_id( 'shop' ), 'page' ) );

			if ( $id ) {
				$data['id']    = $id;
				$data['url']   = get_permalink( $id );
				$data['title'] = get_the_title( $id );
			}

			/**
			 * Filters the breadcrums shop title.
			 *
			 * @param string $title
			 */
			$data['title'] = apply_filters( 'wpex_breadcrumbs_shop_title', $data['title'] );

			return $data;
		}

		/**
		 * Returns breadcrumbs classes.
		 *
		 * @todo convert into function wpex_breadcrumbs_class? (keep this method as legacy incase anyone used it)
		 */
		public static function wrap_classes() {
			$visibility = get_theme_mod( 'breadcrumbs_visibility' );
			$padding_y  = get_theme_mod( 'breadcrumbs_py' );
			$margin_t   = get_theme_mod( 'breadcrumbs_mt' );
			$margin_b   = get_theme_mod( 'breadcrumbs_mb' );

			// Breadcrumbs classes.
			$classes = [
				'site-breadcrumbs',
			];

			// Position class.
			$classes[] = 'position-' . sanitize_html_class( wpex_breadcrumbs_position() );

			// Visibility.
			if ( $visibility ) {
				$classes[] = sanitize_html_class( $visibility );
			}

			// Utility Classes start here.
			$classes[] = 'wpex-text-4';
			$classes[] = 'wpex-text-sm';

			// Add container settings.
			if ( wpex_has_breadcrumbs_container() ) {

				//$classes[] = 'wpex-surface-2';

				if ( ! $padding_y ) {
					$classes[] = 'wpex-py-15';
				}

			}

			// Vertical Padding.
			if ( $padding_y ) {
				$classes[] = 'wpex-py-' . sanitize_html_class( absint( $padding_y ) );
			}

			// Top margin.
			if ( $margin_t ) {
				$classes[] = 'wpex-mt-' . sanitize_html_class( absint( $margin_t ) );
			}

			// Bottom margin.
			if ( $margin_b ) {
				$classes[] = 'wpex-mb-' . sanitize_html_class( absint( $margin_b ) );
			}

			/**
			 * Filters the breadcrumbs element classes.
			 *
			 * @param array $classes
			 */
			$classes = (array) apply_filters( 'wpex_breadcrumbs_classes', $classes );

			return implode( ' ', array_unique( $classes ) );
		}

		/**
		 * Return a page based on a given title.
		 */
		protected static function get_page_by_title( $title = '' ) {
			$query = new WP_Query(
				[
					'post_type'              => 'page',
					'title'                  => sanitize_text_field( $title ),
					'post_status'            => 'all',
					'posts_per_page'         => 1,
					'no_found_rows'          => true,
					'ignore_sticky_posts'    => true,
					'update_post_term_cache' => false,
					'update_post_meta_cache' => false,
					'orderby'                => 'post_date ID',
					'order'                  => 'ASC',
				]
			);
			if ( ! empty( $query->post ) ) {
				return $query->post;
			}
		}

	}
}

https://t.me/RX1948 - 2025