11<?php
22/**
3- * Admin columns class
4- *
5- * @since 2.3.0
3+ * Admin Columns.
64 *
75 * @package WebberZone\Knowledge_Base
86 */
1513}
1614
1715/**
18- * Class to register the Better Search Admin Area .
16+ * Admin Columns class .
1917 *
2018 * @since 2.3.0
2119 */
@@ -28,12 +26,19 @@ class Admin_Columns {
2826 */
2927 public function __construct () {
3028 add_filter ( 'manage_edit-wzkb_category_columns ' , array ( $ this , 'tax_columns ' ) );
31- add_filter ( 'manage_edit-wzkb_category_sortable_columns ' , array ( $ this , 'tax_columns ' ) );
29+ add_filter ( 'manage_edit-wzkb_category_sortable_columns ' , array ( $ this , 'tax_sortable_columns ' ) );
3230 add_filter ( 'manage_edit-wzkb_tag_columns ' , array ( $ this , 'tax_columns ' ) );
33- add_filter ( 'manage_edit-wzkb_tag_sortable_columns ' , array ( $ this , 'tax_columns ' ) );
31+ add_filter ( 'manage_edit-wzkb_tag_sortable_columns ' , array ( $ this , 'tax_sortable_columns ' ) );
3432
3533 add_filter ( 'manage_wzkb_category_custom_column ' , array ( $ this , 'tax_id ' ), 10 , 3 );
3634 add_filter ( 'manage_wzkb_tag_custom_column ' , array ( $ this , 'tax_id ' ), 10 , 3 );
35+
36+ // Register Product filter for Articles admin screen.
37+ add_action ( 'restrict_manage_posts ' , array ( $ this , 'add_product_filter_dropdown ' ) );
38+ add_action ( 'pre_get_posts ' , array ( $ this , 'filter_articles_by_product ' ) );
39+
40+ // Add sorting.
41+ add_filter ( 'terms_clauses ' , array ( $ this , 'sort_terms_by_product ' ), 10 , 2 );
3742 }
3843
3944 /**
@@ -45,19 +50,37 @@ public function __construct() {
4550 * @return array Updated columns.
4651 */
4752 public static function tax_columns ( $ columns ) {
48-
4953 // Remove the description column.
5054 unset( $ columns ['description ' ] );
5155
5256 $ new_columns = array (
5357 'tax_id ' => 'ID ' ,
5458 );
5559
60+ // Only add Product column for wzkb_category taxonomy.
61+ $ screen = get_current_screen ();
62+ if ( isset ( $ screen ->taxonomy ) && 'wzkb_category ' === $ screen ->taxonomy ) {
63+ $ new_columns ['product ' ] = __ ( 'Product ' , 'knowledgebase ' );
64+ }
65+
5666 return array_merge ( $ columns , $ new_columns );
5767 }
5868
5969 /**
60- * Add taxonomy ID to the admin column.
70+ * Make the Product column sortable.
71+ *
72+ * @since 3.0.0
73+ *
74+ * @param array $columns Array of sortable columns.
75+ * @return array Modified array of sortable columns.
76+ */
77+ public function tax_sortable_columns ( $ columns ) {
78+ $ columns ['product ' ] = 'product ' ;
79+ return $ columns ;
80+ }
81+
82+ /**
83+ * Add taxonomy ID and Product to the admin column.
6184 *
6285 * @since 2.3.0
6386 *
@@ -67,6 +90,156 @@ public static function tax_columns( $columns ) {
6790 * @return int|string
6891 */
6992 public static function tax_id ( $ value , $ name , $ id ) {
70- return 'tax_id ' === $ name ? $ id : $ value ;
93+ if ( 'tax_id ' === $ name ) {
94+ return $ id ;
95+ }
96+ if ( 'product ' === $ name ) {
97+ // Get linked product for this section.
98+ $ product_id = get_term_meta ( $ id , 'product_id ' , true );
99+ if ( $ product_id ) {
100+ $ product = get_term ( $ product_id , 'wzkb_product ' );
101+ if ( $ product && ! is_wp_error ( $ product ) ) {
102+ return sprintf (
103+ '<a href="%s">%s</a> ' ,
104+ esc_url ( admin_url ( 'edit.php?post_type=wz_knowledgebase&wzkb_product= ' . $ product ->slug ) ),
105+ esc_html ( $ product ->name )
106+ );
107+ }
108+ }
109+ return '— ' ; // Em dash if not linked.
110+ }
111+ return $ value ;
112+ }
113+
114+ /**
115+ * Sort wzkb_category terms by wzkb_product name.
116+ *
117+ * @since 3.0.0
118+ *
119+ * @param array $pieces Array of query SQL clauses.
120+ * @param array $taxonomies Array of taxonomy names.
121+ * @return array Modified clauses.
122+ */
123+ public function sort_terms_by_product ( $ pieces , $ taxonomies ) {
124+ global $ wpdb ;
125+
126+ // Only run for wzkb_category in admin.
127+ if ( ! is_admin () || ! in_array ( 'wzkb_category ' , $ taxonomies , true ) ) {
128+ return $ pieces ;
129+ }
130+
131+ // Check if sorting by product.
132+ $ orderby = isset ( $ _GET ['orderby ' ] ) ? sanitize_text_field ( wp_unslash ( $ _GET ['orderby ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
133+ if ( 'product ' !== $ orderby ) {
134+ return $ pieces ;
135+ }
136+
137+ // Get sort order.
138+ $ order = isset ( $ _GET ['order ' ] ) ? strtoupper ( sanitize_text_field ( wp_unslash ( $ _GET ['order ' ] ) ) ) : 'ASC ' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
139+ $ order = in_array ( $ order , array ( 'ASC ' , 'DESC ' ), true ) ? $ order : 'ASC ' ;
140+
141+ // Join with termmeta to get product_id.
142+ $ pieces ['join ' ] .= " LEFT JOIN {$ wpdb ->termmeta } AS tm ON t.term_id = tm.term_id AND tm.meta_key = 'product_id' " ;
143+
144+ // Join with terms and term_taxonomy to get wzkb_product name.
145+ $ pieces ['join ' ] .= " LEFT JOIN {$ wpdb ->terms } AS pt ON tm.meta_value = pt.term_id " ;
146+ $ pieces ['join ' ] .= " LEFT JOIN {$ wpdb ->term_taxonomy } AS ptt ON pt.term_id = ptt.term_id AND ptt.taxonomy = 'wzkb_product' " ;
147+
148+ // Set the ORDER BY clause with the "ORDER BY" prefix.
149+ $ pieces ['orderby ' ] = "ORDER BY COALESCE(pt.name, '') $ order, t.name $ order " ;
150+
151+ // Prevent WordPress from appending the order.
152+ $ pieces ['order ' ] = '' ;
153+
154+ return $ pieces ;
155+ }
156+
157+ /**
158+ * Add product filter dropdown to Knowledgebase admin screen.
159+ *
160+ * @since 3.0.0
161+ */
162+ public function add_product_filter_dropdown () {
163+ global $ pagenow ;
164+
165+ // Only run on the edit.php page for wz_knowledgebase post type.
166+ if ( 'edit.php ' !== $ pagenow || ! isset ( $ _GET ['post_type ' ] ) || 'wz_knowledgebase ' !== $ _GET ['post_type ' ] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
167+ return ;
168+ }
169+
170+ // Get all wzkb_product terms.
171+ $ terms = get_terms (
172+ array (
173+ 'taxonomy ' => 'wzkb_product ' ,
174+ 'hide_empty ' => false ,
175+ )
176+ );
177+
178+ if ( empty ( $ terms ) || is_wp_error ( $ terms ) ) {
179+ return ;
180+ }
181+
182+ // Get the currently selected product filter.
183+ $ selected = isset ( $ _GET ['wzkb_product ' ] ) ? sanitize_text_field ( wp_unslash ( $ _GET ['wzkb_product ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
184+
185+ // Output the dropdown.
186+ ?>
187+ <select name="wzkb_product" id="wzkb_product_filter">
188+ <option value=""><?php esc_html_e ( 'All Products ' , 'knowledgebase ' ); ?> </option>
189+ <?php
190+ foreach ( $ terms as $ term ) {
191+ printf (
192+ '<option value="%s" %s>%s</option> ' ,
193+ esc_attr ( $ term ->slug ),
194+ selected ( $ selected , $ term ->slug , false ),
195+ esc_html ( $ term ->name )
196+ );
197+ }
198+ ?>
199+ </select>
200+ <?php
201+ }
202+
203+ /**
204+ * Apply Product filter to Articles admin query.
205+ *
206+ * @since 3.0.0
207+ *
208+ * @param \WP_Query $query The current WP_Query instance (passed by reference).
209+ */
210+ public function filter_articles_by_product ( $ query ) {
211+ global $ pagenow ;
212+
213+ // Only run in admin post list, main query, and correct post type.
214+ if ( ! is_admin () || 'edit.php ' !== $ pagenow || ! $ query ->is_main_query () ) {
215+ return ;
216+ }
217+
218+ $ post_type = isset ( $ _GET ['post_type ' ] ) ? sanitize_text_field ( wp_unslash ( $ _GET ['post_type ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
219+ if ( 'wz_knowledgebase ' !== $ post_type ) {
220+ return ;
221+ }
222+
223+ // Get the product filter value.
224+ $ product = isset ( $ _GET ['wzkb_product ' ] ) ? sanitize_text_field ( wp_unslash ( $ _GET ['wzkb_product ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
225+ if ( empty ( $ product ) ) {
226+ return ;
227+ }
228+
229+ // Ensure the taxonomy exists.
230+ if ( ! taxonomy_exists ( 'wzkb_product ' ) ) {
231+ return ;
232+ }
233+
234+ // Add the tax query.
235+ $ tax_query = array (
236+ array (
237+ 'taxonomy ' => 'wzkb_product ' ,
238+ 'field ' => is_numeric ( $ product ) ? 'term_id ' : 'slug ' ,
239+ 'terms ' => is_numeric ( $ product ) ? absint ( $ product ) : $ product ,
240+ ),
241+ );
242+
243+ $ query ->set ( 'tax_query ' , $ tax_query );
71244 }
72245}
0 commit comments