PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 2.5.1
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v2.5.1
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Core / Query.php

Query.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 2.5.1, at includes/Core/Query.php

788 lines 25.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\Core;
4
5 use WP_Query;
6 use WPDeveloper\BetterDocs\Utils\Base;
7 use WPDeveloper\BetterDocs\Utils\Database;
8 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
9
10 class Query extends Base {
11 private $container;
12 protected $database;
13 protected $settings;
14
15 public function __construct( Container $container, Database $database, Settings $settings ) {
16 $this->container = $container;
17 $this->database = $database;
18 $this->settings = $settings;
19
20 add_action( 'parse_term_query', [$this, 'parse_term_query'] );
21 // add_action( 'parse_query', [$this, 'parse_query'], 1 );
22 add_action( 'pre_get_posts', [$this, 'pre_get_posts'], 1 );
23
24 /**
25 * These below filters are hooked for navigation only.
26 *
27 * For old version of this portion.
28 * @see `betterdocs_single_post_nav` filter
29 *
30 * For details:
31 * @see https://developer.wordpress.org/reference/functions/get_next_post/
32 * @see https://developer.wordpress.org/reference/functions/get_previous_post/
33 *
34 * @link https://developer.wordpress.org/reference/hooks/get_adjacent_post_where/
35 */
36 add_filter( 'get_next_post_where', [$this, 'next_post_where'], 99, 5 );
37 add_filter( 'get_previous_post_where', [$this, 'previous_post_where'], 99, 5 );
38
39 $this->init();
40 }
41
42 public function init() {
43 }
44
45 public function parse_term_query( $term_query ) {
46 if ( empty( $term_query->query_vars['taxonomy'] ) ) {
47 return;
48 }
49
50 if ( ! in_array( 'doc_category', $term_query->query_vars['taxonomy'], true ) ) {
51 return;
52 }
53
54 global $current_screen;
55
56 if ( $current_screen == null ) {
57 return;
58 }
59
60 if ( $current_screen->taxonomy !== 'doc_category' || $current_screen->id != 'edit-doc_category' ) {
61 return;
62 }
63
64 $term_query->query_vars['meta_query'] = [[
65 'key' => 'doc_category_order',
66 'type' => 'NUMERIC'
67 ]];
68
69 $term_query->query_vars['orderby'] = 'meta_value_num';
70 }
71
72 public function parse_query( &$query ) {
73 // dump( is_single(), $query->query_vars );
74 // if ( is_single() && isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'docs' ) {
75 // $query->is_single = false;
76 // $query->is_archive = true;
77 // $query->set( 'knowledge_base', $query->query_vars['docs'] );
78 // }
79 }
80
81 public function pre_get_posts( &$query ) {
82 if ( is_admin() || ! $query->is_main_query() ) {
83 return;
84 }
85
86 if ( is_tax( 'doc_category' ) ) {
87 $query->set( 'post_type', 'docs' );
88 $query->set( 'posts_per_archive_page', -1 );
89
90 $term = get_term_by( 'slug', $query->get( 'doc_category', '' ), 'doc_category' );
91
92 $post__in = $this->get_docs_order_by_terms( $term->term_id );
93 if ( ! empty( $post__in ) ) {
94 $query->set( 'orderby', 'post__in' );
95 $query->set( 'post__in', $post__in );
96 }
97
98 // if ( ! empty( $query->query_vars['knowledge_base'] ) ) {
99 // $query->betterdocs_terms = get_terms( [
100 // 'taxonomy' => 'doc_category',
101 // 'parent' => 0,
102 // 'hide_empty' => true,
103 // 'meta_query' => [
104 // 'relation' => 'OR',
105 // [
106 // 'key' => 'doc_category_knowledge_base',
107 // 'value' => $query->query_vars['knowledge_base'],
108 // 'compare' => 'LIKE'
109 // ]
110 // ]
111 // ] );
112 // }
113 }
114
115 // dump( is_archive(), $query->query_vars );
116 }
117
118 /**
119 * Get docs orders by term_id.
120 *
121 * @since 2.5.0
122 * @param int $term_id
123 *
124 * @return array
125 */
126 public function get_docs_order_by_terms( $term_id ) {
127 global $wpdb;
128 $_docs_order = get_term_meta( $term_id, '_docs_order', true );
129 $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}term_relationships WHERE term_taxonomy_id = %d", $term_id );
130 $query_key = "docs_order_by_terms_{$term_id}_" . md5( $query );
131
132 if ( ( $results = $this->database->get_cache( $query_key ) ) !== false ) {
133 return $results;
134 }
135
136 if ( ! empty( $_docs_order ) ) {
137 $_docs_order = explode( ',', $_docs_order );
138 $new_ids = [];
139
140 $results = $wpdb->get_results( $query );
141
142 if ( is_array( $results ) && ! empty( $results ) ) {
143 $object_ids = array_filter( $results, function ( $value ) use ( $_docs_order ) {
144 return ! in_array( $value->object_id, $_docs_order );
145 } );
146
147 if ( ! empty( $object_ids ) ) {
148 array_walk( $object_ids, function ( $value ) use ( &$new_ids ) {
149 $new_ids[] = $value->object_id;
150 } );
151 }
152 }
153
154 $_docs_order = array_merge( $new_ids, $_docs_order );
155 $this->database->set_cache( $query_key, $_docs_order, 1 );
156
157 return $_docs_order;
158 }
159
160 return [];
161 }
162
163 /**
164 * For determine the next post ID
165 *
166 * @link https://developer.wordpress.org/reference/hooks/get_adjacent_post_where/
167 *
168 * @param mixed $where
169 * @param mixed $in_same_term
170 * @param mixed $excluded_terms
171 * @param mixed $taxonomy
172 * @param mixed $post
173 * @return mixed
174 */
175 public function next_post_where( $where, $in_same_term, $excluded_terms, $taxonomy, $post ) {
176 return $this->get_adjacent_post_id( 'next', $where, $post, $taxonomy );
177 }
178
179 /**
180 * For determine the previous post ID
181 *
182 * @link https://developer.wordpress.org/reference/hooks/get_adjacent_post_where/
183 *
184 * @param mixed $where
185 * @param mixed $in_same_term
186 * @param mixed $excluded_terms
187 * @param mixed $taxonomy
188 * @param mixed $post
189 * @return mixed
190 */
191 public function previous_post_where( $where, $in_same_term, $excluded_terms, $taxonomy, $post ) {
192 return $this->get_adjacent_post_id( 'previous', $where, $post, $taxonomy );
193 }
194
195 /**
196 * Get where clause for next/previous post ID mainly used in post navigation.
197 *
198 * @see `previous_post_where` and `next_post_where` methods.
199 *
200 * @param mixed $adjacent
201 * @param mixed $where
202 * @param mixed $post
203 * @param mixed $taxonomy
204 * @return mixed
205 */
206 private function get_adjacent_post_id( $adjacent, $where, $post, $taxonomy ) {
207 if ( $taxonomy !== 'doc_category' ) {
208 return $where;
209 }
210
211 $_id = null;
212 $_terms = get_the_terms( $post->ID, 'doc_category' );
213 if ( empty( $_terms ) ) {
214 return $where;
215 }
216
217 global $wp_query, $wpdb;
218
219 $_docs_order = $this->get_docs_order_by_terms( $_terms[0]->term_id );
220
221 $_where = explode( 'AND', $where );
222 if ( is_array( $_where ) ) {
223 // $_where[0] = str_replace( 'WHERE ', '', $_where[0] );
224 unset( $_where[0] );
225 $_where = implode( 'AND', $_where );
226 }
227
228 $_orderby = $this->settings->get( 'alphabetically_order_post', 'betterdocs_order' );
229 $_order = $this->settings->get( 'docs_order', 'ASC' );
230 $_docs_order = $_orderby === 'betterdocs_order' ? $_docs_order : [];
231
232 if ( empty( $_docs_order ) ) {
233 $statuses = [ 'publish' ];
234
235 if( is_user_logged_in() ) {
236 $statuses[] = 'private';
237 }
238
239 $_args = [
240 'post_status' => $statuses
241 ];
242 if ( isset( $wp_query->query_vars['doc_category'] ) ) {
243 $_args['tax_query'][] = [
244 'taxonomy' => 'doc_category',
245 'field' => 'slug',
246 'terms' => $wp_query->query_vars['doc_category'],
247 'operator' => 'AND',
248 'include_children' => false
249 ];
250 }
251
252 $_args['orderby'] = $_orderby;
253 if ( $_orderby != 'betterdocs_order' ) {
254 $_args['order'] = $_order;
255 }
256
257 /**
258 * Before Query
259 */
260 do_action_ref_array( 'betterdocs_navigation_docs_query', [ &$_args] );
261 $docs = $this->get_posts( $this->docs_query_args( $_args ) );
262
263 $_docs = [];
264 if ( $docs->have_posts() ) {
265 array_map( function ( $post ) use ( &$_docs ) {
266 $_docs[] = $post->ID;
267 }, $docs->posts );
268 }
269
270 $_docs_order = $_docs;
271 }
272
273 $_docs_order = apply_filters( 'betterdocs_adjacent_docs_order', $_docs_order, $_terms );
274
275 $_id_index = array_search( $post->ID, $_docs_order );
276 $_id_index = $adjacent === 'next' ? $_id_index + 1 : $_id_index - 1;
277 $_id = isset( $_docs_order[$_id_index] ) ? (int) $_docs_order[$_id_index] : null;
278
279 return $wpdb->prepare( "WHERE p.ID = %s AND $_where", (int) $_id );
280 }
281
282 public function parse_terms_args( $args = [] ) {
283 $_default_args = [
284 'hide_empty' => true,
285 'taxonomy' => 'doc_category'
286 ];
287
288 // OrderBy & Order
289 $_orderby = ! empty( $args['orderby'] ) && $args['orderby'] != 1 ? $args['orderby'] : 'name';
290 $_order = ! empty( $args['order'] ) ? $args['order'] : '';
291
292 if ( $_orderby == 'betterdocs_order' ) {
293 $args['meta_key'] = 'doc_category_order';
294 $args['orderby'] = 'meta_value_num';
295 $args['order'] = 'ASC';
296 } else {
297 $args['orderby'] = $_orderby;
298 $args['order'] = $_order;
299 }
300
301 // Nested Sub Category
302 // $args['parent'] = 0;
303 // if ( $nested_subcategory == true ) {
304 // }
305
306 if ( ! isset( $args['number'] ) ) {
307 global $wp_query;
308 if ( $wp_query->query === NULL || ( isset( $wp_query->query['post_type'] ) && $wp_query->query['post_type'] != 'docs' ) ) {
309 $args['number'] = 4;
310 }
311 }
312
313 // Includes
314 if ( isset( $args['include'] ) ) {
315 $_include = ! is_array( $args['include'] ) ? explode( ',', $args['include'] ) : $args['include'];
316 $args['include'] = $_include;
317 $args['orderby'] = 'include';
318
319 unset( $args['parent'] );
320 }
321
322 $_meta_query = ! empty( $args['meta_query'] ) ? $args['meta_query'] : [];
323 $args['meta_query'] = apply_filters( 'betterdocs_taxonomy_object_meta_query', $_meta_query, $args );
324
325 return apply_filters( 'betterdocs_category_terms_object', wp_parse_args( $args, $_default_args ), $args );
326 }
327
328 public function get_terms( $args ) {
329 return get_terms( $this->parse_terms_args( $args ) );
330 }
331
332 public function get_child_terms( $args ) {
333 if ( ! isset( $args['number'] ) ) {
334 global $wp_query;
335 if ( $wp_query->query === NULL || ( isset( $wp_query->query['post_type'] ) && $wp_query->query['post_type'] != 'docs' ) ) {
336 $args['number'] = 1;
337 }
338 }
339
340 return $this->get_terms( $args );
341 }
342
343 /**
344 * Get POSTs of Docs type.
345 *
346 * @param mixed $args
347 * @return WP_Query
348 */
349 public function get_posts( $args, $ignore = false ) {
350 if ( ! $ignore ) {
351 $args = $this->docs_query_args( $args );
352 }
353
354 return new WP_Query( $args );
355 }
356
357 public function get_taxonomy( $tax = '' ) {
358 global $wp_query;
359 if ( is_tax( 'knowledge_base' ) ) {
360 $_tax = $wp_query->tax_query->queried_terms;
361 if ( array_key_exists( "doc_category", $_tax ) ) {
362 $tax = 'doc_category';
363 } else {
364 $tax = 'knowledge_base';
365 }
366 } elseif ( is_tax( 'doc_category' ) ) {
367 $tax = 'doc_category';
368 }
369
370 return $tax;
371 }
372
373 public function terms_query( $args = [] ) {
374 global $wp_query;
375 $_origin_args = $args;
376
377 $default_args = [
378 'hide_empty' => true,
379 'taxonomy' => 'doc_category',
380 'orderby' => 'name'
381 ];
382
383 /**
384 * number set
385 */
386 if ( $wp_query->query === NULL || ( isset( $wp_query->query['post_type'] ) && $wp_query->query['post_type'] != 'docs' ) ) {
387 $default_args['number'] = 1;
388 }
389
390 /**
391 * Nested Sub Category
392 */
393 if ( isset( $args['nested_subcategory'] ) && $args['nested_subcategory'] == true ) {
394 $default_args['parent'] = 0;
395 unset( $args['nested_subcategory'] );
396 if ( $wp_query->query === NULL || ( isset( $wp_query->query['post_type'] ) && $wp_query->query['post_type'] != 'docs' ) ) {
397 $default_args['number'] = 4;
398 }
399 }
400
401 /**
402 * OrderBy and Order
403 */
404 if ( ! isset( $args['orderby'] ) ) {
405 $_orderby = $this->settings->get( 'terms_orderby', 'name' );
406 $_order = $this->settings->get( 'terms_order', '' );
407 } else {
408 $_orderby = $args['orderby'];
409 $_order = ! empty( $args['order'] ) ? $args['order'] : '';
410 }
411
412 if ( 'betterdocs_order' === $_orderby ) {
413 $default_args['meta_key'] = 'doc_category_order';
414 $_orderby = 'meta_value_num';
415 $_order = 'ASC';
416 } elseif ( $_orderby === true ) {
417 $_orderby = 'name';
418 }
419
420 $args['orderby'] = $_orderby;
421 if( ! empty( $_order ) ) {
422 $args['order'] = $_order;
423 }
424
425 /**
426 * @todo old hook
427 * hook: betterdocs_child_taxonomy_meta_query
428 */
429 $_multiple_kb = apply_filters(
430 'betterdocs_query_args_multiple_kb_enabled',
431 isset( $args['multiple_kb'] ) ? (bool) $args['multiple_kb'] : false,
432 $_origin_args
433 );
434
435 $_kb_slug = isset( $args['kb_slug'] ) ? trim( $args['kb_slug'] ) : '';
436
437 unset( $args['multiple_kb'] );
438 unset( $args['kb_slug'] );
439
440 $meta_query = ! empty( $args['meta_query'] ) ? $args['meta_query'] : [];
441 $meta_query = apply_filters( 'betterdocs_terms_meta_query_args', $meta_query, $_multiple_kb, $_kb_slug, $_origin_args );
442
443 if ( ! empty( $meta_query ) ) {
444 $default_args['meta_query'] = $meta_query;
445 }
446
447 if ( ! empty( $args['terms'] ) ) {
448 $args['include'] = explode( ',', $args['terms'] );
449 $args['orderby'] = 'include';
450 $args['order'] = 'ASC';
451
452 unset( $args['parent'] );
453 unset( $args['terms'] );
454 }
455
456 $_query_args = wp_parse_args( $args, $default_args );
457 return apply_filters( 'betterdocs_terms_query_args', $_query_args, $_origin_args );
458 }
459
460 public function get_term_parents( $term_id, $taxonomy = 'doc_category', $args = [] ) {
461 $term = get_term( $term_id, $taxonomy );
462 if ( is_wp_error( $term ) ) {
463 return $term;
464 }
465
466 if ( ! $term ) {
467 return [];
468 }
469
470 $_lists = [];
471 $origin_term = $term_id;
472 $term_id = $term->term_id;
473
474 $defaults = [
475 'format' => 'name',
476 'inclusive' => true
477 ];
478
479 $args = wp_parse_args( $args, $defaults );
480
481 $args['inclusive'] = wp_validate_boolean( $args['inclusive'] );
482
483 $parents = get_ancestors( $term_id, $taxonomy );
484
485 if ( $args['inclusive'] ) {
486 array_unshift( $parents, $term_id );
487 }
488
489 foreach ( array_reverse( $parents ) as $term_id ) {
490 $parent = get_term( $term_id, $taxonomy );
491 $name = ( 'slug' === $args['format'] ) ? $parent->slug : $parent->name;
492 $term_permalink = get_term_link( $parent->term_id, $taxonomy );
493 $term_permalink = apply_filters( 'betterdocs_breadcrumb_term_permalink', $term_permalink, $term_id );
494
495 $_item = [
496 'url' => $term_permalink,
497 'text' => $name
498 ];
499
500 $_lists[] = $_item;
501 }
502
503 return apply_filters( 'betterdocs_breadcrumb_archive_lists', $_lists, $origin_term );
504 }
505
506 /**
507 * Summary of docs_query_args
508 * @param mixed $args
509 * @throws \Exception
510 * @return mixed
511 */
512 public function docs_query_args( $args, $filter = [] ) {
513 $_origin_args = $args;
514
515 $default_args = [
516 'post_type' => 'docs'
517 ];
518
519 if ( ! empty( $args['post_type'] ) && trim( $args['post_type'] ) === 'docs_any' ) {
520 $default_args['post_type'] = 'docs';
521 $default_args['post_status'] = 'any';
522
523 unset( $args['post_type'] );
524 }
525
526 /**
527 * OrderBy and Order
528 */
529 if ( ! isset( $args['orderby'] ) ) {
530 $_orderby = $this->settings->get( 'alphabetically_order_post' );
531 $_order = $this->settings->get( 'docs_order', 'ASC' );
532 } else {
533 $_orderby = $args['orderby'];
534 $_order = ! empty( $args['order'] ) ? $args['order'] : 'ASC';
535 }
536
537 if ( 'betterdocs_order' != $_orderby ) {
538 if ( $_orderby === true ) {
539 $args['orderby'] = 'title';
540 } else {
541 $args['orderby'] = $_orderby;
542 }
543
544 $args['order'] = $_order;
545 } elseif ( 'betterdocs_order' == $_orderby ) {
546 unset( $args['orderby'] );
547 }
548
549 if ( empty( $args['orderby'] ) ) {
550 unset( $args['order'] );
551 }
552
553 /**
554 * Term ID
555 */
556 $_term_id = null;
557 if ( ! empty( $args['term_id'] ) ) {
558 $_term_id = intval( $args['term_id'] );
559 unset( $args['term_id'] );
560 }
561
562 // if ( $_term_id == null ) {
563 // throw new \Exception( __( '$args["term_id"] cannot be null.', 'betterdocs' ) );
564 // }
565
566 /**
567 * Term Slug for tax_query
568 */
569 $_term_slug = '';
570 if ( ! empty( $args['term_slug'] ) ) {
571 $_term_slug = trim( $args['term_slug'] );
572 unset( $args['term_slug'] );
573 }
574
575 /**
576 * @todo old hook
577 * hook: betterdocs_cat_template_multikb
578 */
579
580 $_multiple_kb = apply_filters(
581 'betterdocs_enable_multiple_knowledge_base',
582 isset( $args['multiple_kb'] ) ? (bool) $args['multiple_kb'] : false,
583 $_origin_args
584 );
585
586 $_kb_slug = isset( $args['kb_slug'] ) ? trim( $args['kb_slug'] ) : '';
587
588 unset( $args['multiple_kb'] );
589 unset( $args['kb_slug'] );
590
591 $tax_query = [
592 [
593 'taxonomy' => 'doc_category',
594 'field' => 'slug',
595 'terms' => $_term_slug,
596 'operator' => 'AND',
597 'include_children' => false
598 ]
599 ];
600
601 if ( isset( $args['tax_query'] ) ) {
602 $tax_query = $args['tax_query'];
603 }
604
605 $args['tax_query'] = apply_filters(
606 'betterdocs_docs_tax_query_args',
607 $tax_query, $_multiple_kb, $_term_slug, $_kb_slug, $_origin_args
608 );
609 /**
610 * Final parse args
611 */
612 $args = wp_parse_args( $args, $default_args );
613
614 if ( ! empty( $filter ) ) {
615 $filter = array_flip( $filter );
616 $args = array_filter( $args, function ( $item ) use ( $filter ) {
617 return ! array_key_exists( $item, $filter );
618 }, ARRAY_FILTER_USE_KEY );
619 }
620
621 return apply_filters( 'betterdocs_articles_args', $args, $_term_id, $_origin_args );
622 }
623
624 public function faq_terms_query_args( $includes = '', $excludes = '', $args = [] ) {
625 $_args = [
626 'taxonomy' => 'betterdocs_faq_category',
627 'meta_key' => 'order',
628 'orderby' => 'meta_value_num',
629 'order' => 'ASC',
630 'include' => $includes,
631 'exclude' => $excludes,
632 'meta_query' => [
633 [
634 'key' => 'status',
635 'value' => 1,
636 'compare' => '=='
637 ]
638 ]
639 ];
640
641 if ( $_args['include'] == 'all' ) {
642 unset( $_args['include'] );
643 unset( $_args['exclude'] );
644 }
645
646 if ( empty( $_args['exclude'] ) ) {
647 unset( $_args['exclude'] );
648 }
649
650 if ( empty( $_args['include'] ) ) {
651 unset( $_args['include'] );
652 }
653
654 return wp_parse_args( $args, $_args );
655 }
656
657 public function get_faq_by_term( $term_id ) {
658 global $wpdb;
659
660 $args = [
661 'post_type' => 'betterdocs_faq',
662 'post_status' => 'publish',
663 'tax_query' => [
664 [
665 'taxonomy' => 'betterdocs_faq_category',
666 'field' => 'term_id',
667 'terms' => $term_id,
668 'operator' => 'AND'
669 ]
670 ],
671 'posts_per_page' => -1
672 ];
673
674 $args['orderby'] = 'post__in';
675 $args['post__in'] = $this->get_faq_orders( $term_id );
676
677 return new WP_Query( $args );
678 }
679
680 public function get_faq_orders( $term_id = null ) {
681 global $wpdb;
682 $faq_order = get_term_meta( $term_id, '_betterdocs_faq_order', true );
683 $faq_order = explode( ',', $faq_order );
684
685 $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}term_relationships WHERE term_taxonomy_id = %d", $term_id );
686 $query_key = "betterdocs_faq_order_" . md5( $query );
687
688 if ( ( $results = $this->database->get_cache( $query_key ) ) !== false ) {
689 return $results;
690 }
691
692 if ( ! empty( $faq_order ) ) {
693 $new_ids = [];
694 $results = $wpdb->get_results( $query );
695
696 if ( ! is_null( $results ) && ! empty( $results ) && is_array( $results ) ) {
697 $object_ids = array_filter( $results, function ( $value ) use ( $faq_order ) {
698 return ! in_array( $value->object_id, $faq_order );
699 } );
700
701 if ( ! empty( $object_ids ) ) {
702 array_walk( $object_ids, function ( $value ) use ( &$new_ids ) {
703 $new_ids[] = $value->object_id;
704 } );
705 }
706 }
707
708 $faq_order = array_merge( $new_ids, $faq_order );
709 }
710
711 $this->database->set_cache( $query_key, $faq_order, 1 );
712
713 return $faq_order;
714 }
715
716 public function get_faq_terms( $terms = [] ) {
717 $_terms = get_terms( [
718 'taxonomy' => 'betterdocs_faq_category',
719 'hide_empty' => true,
720 'orderby' => 'name',
721 'order' => 'ASC',
722 'meta_query' => [
723 [
724 'key' => 'status',
725 'value' => 1,
726 'compare' => '=='
727 ]
728 ]
729 ] );
730
731 if ( ! is_wp_error( $_terms ) ) {
732 foreach ( $_terms as $term ) {
733 $terms[$term->term_id] = $term->name;
734 }
735 }
736
737 return $terms;
738 }
739
740 public function get_docs_count( $term, $nested_subcategory = false, $args = [] ) {
741 $counts = isset( $term->count ) ? $term->count : 0;
742
743 if ( $nested_subcategory == false ) {
744 return apply_filters( 'betterdocs_docs_count', $counts, $term, $nested_subcategory, $args );
745 }
746
747 $_child_terms_docs_ids = $this->get_doc_ids_by_term( $term, null, $nested_subcategory );
748 if ( is_array( $_child_terms_docs_ids ) ) {
749 $counts = count( $_child_terms_docs_ids );
750 }
751
752 return apply_filters( 'betterdocs_docs_count', $counts, $term, $nested_subcategory, $args );
753 }
754
755 public function get_doc_ids_by_term( $term, $optional = null, $nested_subcategory = false ) {
756 $args = [ 'include' => $term->term_id ];
757 if( $nested_subcategory ) {
758 $args['child_of'] = $term->term_id;
759 unset( $args['include'] );
760 }
761 $_child_terms = get_terms( $term->taxonomy, $args );
762
763 if ( ! is_array( $_child_terms ) ) {
764 return false;
765 }
766
767 array_unshift( $_child_terms, $term );
768
769 $_child_terms_ids = array_column( $_child_terms, 'term_id' );
770 $_child_terms_taxs = array_column( $_child_terms, 'taxonomy' );
771 $_child_terms_docs_ids = get_objects_in_term( $_child_terms_ids, $_child_terms_taxs );
772
773 if ( $optional !== null ) {
774 $_optional_doc_ids = get_objects_in_term( $optional->term_id, $optional->taxonomy );
775 $_child_terms_docs_ids = array_intersect( $_child_terms_docs_ids, $_optional_doc_ids );
776 }
777
778 return array_filter( $_child_terms_docs_ids, function ( $doc_id ) {
779 if ( ! is_user_logged_in() ) {
780 return is_post_publicly_viewable( $doc_id );
781 }
782
783 $_status = get_post_status( $doc_id );
784 return $_status == 'private' || is_post_publicly_viewable( $doc_id );
785 } );
786 }
787 }
788