@@ -34,6 +34,45 @@ private static function unicode_to_char( $unicode ) {
3434 return html_entity_decode ( '&#x ' . $ unicode . '; ' , ENT_COMPAT , 'UTF-8 ' );
3535 }
3636
37+ /**
38+ * Get the product term for the current context.
39+ *
40+ * @return \WP_Term|false
41+ */
42+ private static function get_product_for_context () {
43+ if ( is_tax ( 'wzkb_category ' ) || is_tax ( 'wzkb_tag ' ) ) {
44+ $ tax = get_queried_object ();
45+ if ( $ tax && isset ( $ tax ->term_id ) ) {
46+ $ product_id = get_term_meta ( $ tax ->term_id , 'product_id ' , true );
47+ if ( $ product_id ) {
48+ $ product = get_term ( $ product_id , 'wzkb_product ' );
49+ if ( $ product && ! is_wp_error ( $ product ) ) {
50+ return $ product ;
51+ }
52+ }
53+ }
54+ }
55+ if ( is_singular ( 'wz_knowledgebase ' ) ) {
56+ $ post = get_queried_object ();
57+ $ terms = get_the_terms ( $ post , 'wzkb_category ' );
58+ if ( is_array ( $ terms ) && ! empty ( $ terms ) ) {
59+ $ primary_term = $ terms [0 ];
60+ $ ancestor = $ primary_term ;
61+ while ( $ ancestor ->parent ) {
62+ $ ancestor = get_term ( $ ancestor ->parent , $ ancestor ->taxonomy );
63+ }
64+ $ product_id = get_term_meta ( $ ancestor ->term_id , 'product_id ' , true );
65+ if ( $ product_id ) {
66+ $ product = get_term ( $ product_id , 'wzkb_product ' );
67+ if ( $ product && ! is_wp_error ( $ product ) ) {
68+ return $ product ;
69+ }
70+ }
71+ }
72+ }
73+ return false ;
74+ }
75+
3776 /**
3877 * Creates the breadcrumb.
3978 *
@@ -48,15 +87,12 @@ public static function get_breadcrumb( $args = array() ) {
4887 'separator ' => '» ' ,
4988 );
5089
51- // Parse incoming $args into an array and merge it with $defaults.
5290 $ args = wp_parse_args ( $ args , $ defaults );
5391
54- // Convert Unicode sequence if provided.
5592 if ( strpos ( $ args ['separator ' ], '\\' ) === 0 ) {
5693 $ args ['separator ' ] = self ::unicode_to_char ( $ args ['separator ' ] );
5794 }
5895
59- // Return if not a WZKB post type archive or single page.
6096 if ( ( ! is_admin () && ! wp_is_json_request () ) &&
6197 ! is_post_type_archive ( 'wz_knowledgebase ' ) &&
6298 ! is_singular ( 'wz_knowledgebase ' ) &&
@@ -66,95 +102,111 @@ public static function get_breadcrumb( $args = array() ) {
66102 return '' ;
67103 }
68104
69- $ output = '<nav class="wzkb_breadcrumb" aria-label=" ' . esc_attr__ ( 'Breadcrumb ' , 'knowledgebase ' ) . '"> ' ;
70- $ output .= '<ol class="wzkb_breadcrumb-list" itemscope itemtype="https://schema.org/BreadcrumbList"> ' ;
105+ $ items = array ();
106+ $ items [] = array (
107+ 'url ' => home_url (),
108+ 'label ' => esc_html__ ( 'Home ' , 'knowledgebase ' ),
109+ 'position ' => 1 ,
110+ 'current ' => false ,
111+ );
112+ $ items [] = array (
113+ 'url ' => wzkb_get_kb_url (),
114+ 'label ' => esc_html ( wzkb_get_option ( 'kb_title ' ) ),
115+ 'position ' => 2 ,
116+ 'current ' => false ,
117+ );
118+
119+ $ position = 3 ;
120+ if ( wzkb_get_option ( 'multi_product ' ) ) {
121+ $ product = self ::get_product_for_context ();
122+ if ( $ product ) {
123+ $ items [] = array (
124+ 'url ' => get_term_link ( $ product ),
125+ 'label ' => esc_html ( $ product ->name ),
126+ 'position ' => $ position ,
127+ 'current ' => false ,
128+ );
129+ ++$ position ;
130+ }
131+ }
71132
72- // First output the link to home page.
73- $ output .= '<li class="wzkb_breadcrumb-item" data-separator=" ' . esc_attr ( $ args ['separator ' ] ) . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> ' ;
74- $ output .= '<a href=" ' . esc_url ( home_url () ) . '" itemprop="item"> ' ;
75- $ output .= '<span itemprop="name"> ' . esc_html__ ( 'Home ' , 'knowledgebase ' ) . '</span> ' ;
76- $ output .= '</a> ' ;
77- $ output .= '<meta itemprop="position" content="1" /> ' ;
78- $ output .= '</li> ' ;
79-
80- // Link to the knowledge base.
81- $ output .= '<li class="wzkb_breadcrumb-item" data-separator=" ' . esc_attr ( $ args ['separator ' ] ) . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> ' ;
82- $ output .= '<a href=" ' . esc_url ( wzkb_get_kb_url () ) . '" itemprop="item"> ' ;
83- $ output .= '<span itemprop="name"> ' . esc_html ( wzkb_get_option ( 'kb_title ' ) ) . '</span> ' ;
84- $ output .= '</a> ' ;
85- $ output .= '<meta itemprop="position" content="2" /> ' ;
86- $ output .= '</li> ' ;
87-
88- // Output the category or tag.
89133 if ( is_tax ( 'wzkb_category ' ) || is_tax ( 'wzkb_tag ' ) ) {
90- $ tax = get_queried_object ();
91- $ output .= self ::get_hierarchical_term_trail ( $ tax , $ args , 3 );
134+ $ tax = get_queried_object ();
135+ $ trail = self ::get_hierarchical_term_trail_array ( $ tax , $ args , $ position );
136+ foreach ( $ trail as $ item ) {
137+ $ items [] = $ item ;
138+ ++$ position ;
139+ }
92140 }
93141
94- // Output link to single post.
95142 if ( is_singular ( 'wz_knowledgebase ' ) ) {
96- $ post = get_queried_object ();
97-
143+ $ post = get_queried_object ();
98144 $ terms = get_the_terms ( $ post , 'wzkb_category ' );
99145 if ( is_array ( $ terms ) && ! empty ( $ terms ) ) {
100- $ tax = $ terms [0 ];
101- $ output .= self ::get_hierarchical_term_trail ( $ tax , $ args , 3 );
146+ $ tax = $ terms [0 ];
147+ $ trail = self ::get_hierarchical_term_trail_array ( $ tax , $ args , $ position );
148+ foreach ( $ trail as $ item ) {
149+ $ items [] = $ item ;
150+ ++$ position ;
151+ }
102152 }
153+ $ items [] = array (
154+ 'url ' => get_permalink ( $ post ),
155+ 'label ' => esc_html ( $ post ->post_title ),
156+ 'position ' => $ position ,
157+ 'current ' => true ,
158+ );
159+ }
103160
104- $ output .= '<li class="wzkb_breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> ' ;
105- $ output .= '<a href=" ' . esc_url ( get_permalink ( $ post ) ) . '" itemprop="item"> ' ;
106- $ output .= '<span itemprop="name"> ' . esc_html ( $ post ->post_title ) . '</span> ' ;
161+ $ items = apply_filters ( 'wzkb_breadcrumb_items ' , $ items , $ args );
162+
163+ $ output = '<nav class="wzkb_breadcrumb" aria-label=" ' . esc_attr__ ( 'Breadcrumb ' , 'knowledgebase ' ) . '"> ' ;
164+ $ output .= '<ol class="wzkb_breadcrumb-list" itemscope itemtype="https://schema.org/BreadcrumbList"> ' ;
165+ $ sep = esc_attr ( $ args ['separator ' ] );
166+ foreach ( $ items as $ item ) {
167+ $ output .= '<li class="wzkb_breadcrumb-item" data-separator=" ' . $ sep . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> ' ;
168+ $ output .= '<a href=" ' . esc_url ( $ item ['url ' ] ) . '" itemprop="item" ' . ( ! empty ( $ item ['current ' ] ) ? ' aria-current="page" ' : '' ) . '> ' ;
169+ $ output .= '<span itemprop="name"> ' . $ item ['label ' ] . '</span> ' ;
107170 $ output .= '</a> ' ;
108- $ output .= '<meta itemprop="position" content="4 " /> ' ;
171+ $ output .= '<meta itemprop="position" content=" ' . intval ( $ item [ ' position ' ] ) . ' " /> ' ;
109172 $ output .= '</li> ' ;
110173 }
111-
112174 $ output .= '</ol> ' ;
113175 $ output .= '</nav> ' ;
114176
115- /**
116- * Filter the formatted shortcode output.
117- *
118- * @since 1.6.0
119- *
120- * @param string $output Formatted HTML output.
121- * @param array $args Parameters array.
122- */
123177 return apply_filters ( 'wzkb_get_breadcrumb ' , $ output , $ args );
124178 }
125179
126180 /**
127- * Generates the HTML for the taxonomy and its children for the breadcrumb.
128- *
129- * @since 2.3.0
181+ * Returns the hierarchical term trail as an array of breadcrumb items.
130182 *
131183 * @param \WP_Term $taxonomy Taxonomy object.
132184 * @param array $args Parameters array.
133185 * @param int $position Current position in breadcrumb.
134- * @return string HTML output .
186+ * @return array Array of breadcrumb items .
135187 */
136- private static function get_hierarchical_term_trail ( \WP_Term $ taxonomy , $ args = array (), $ position = 2 ) {
188+ private static function get_hierarchical_term_trail_array ( \WP_Term $ taxonomy , $ args = array (), $ position = 2 ) {
137189 $ defaults = array (
138190 'separator ' => '» ' ,
139191 );
140-
141- $ args = wp_parse_args ( $ args , $ defaults );
142-
143- $ output = '<li class="wzkb_breadcrumb-item" data-separator=" ' . esc_attr ( $ args ['separator ' ] ) . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> ' ;
144- $ output .= '<a href=" ' . esc_url ( get_term_link ( $ taxonomy ) ) . '" itemprop="item" title=" ' . esc_attr ( $ taxonomy ->name ) . '"> ' ;
145- $ output .= '<span itemprop="name"> ' . esc_html ( $ taxonomy ->name ) . '</span> ' ;
146- $ output .= '</a> ' ;
147- $ output .= '<meta itemprop="position" content=" ' . intval ( $ position ) . '" /> ' ;
148- $ output .= '</li> ' ;
149-
192+ $ args = wp_parse_args ( $ args , $ defaults );
193+ $ trail = array ();
150194 if ( ! empty ( $ taxonomy ->parent ) ) {
151- $ output = self ::get_hierarchical_term_trail (
152- get_term ( $ taxonomy ->parent , $ taxonomy ->taxonomy ),
153- $ args ,
154- $ position - 1
155- ) . $ output ;
195+ $ trail = array_merge (
196+ self ::get_hierarchical_term_trail_array (
197+ get_term ( $ taxonomy ->parent , $ taxonomy ->taxonomy ),
198+ $ args ,
199+ $ position
200+ ),
201+ );
202+ $ position += count ( $ trail );
156203 }
157-
158- return $ output ;
204+ $ trail [] = array (
205+ 'url ' => get_term_link ( $ taxonomy ),
206+ 'label ' => esc_html ( $ taxonomy ->name ),
207+ 'position ' => $ position ,
208+ 'current ' => false ,
209+ );
210+ return $ trail ;
159211 }
160212}
0 commit comments