PluginProbe
Knowledge Base documentation & wiki plugin – BasePress Docs / trunk
Knowledge Base documentation & wiki plugin – BasePress Docs vtrunk
basepress / includes / class-basepress-utils.php

class-basepress-utils.php in Knowledge Base documentation & wiki plugin – BasePress Docs trunk, at includes/class-basepress-utils.php

1,711 lines 44.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This is the class contains core functions used by all other classes
4 */
5
6 // Exit if called directly
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10
11 if ( ! class_exists( 'Basepress_Utils' ) ) {
12
13 class Basepress_Utils {
14
15 private $kb_slug = null;
16 private $products = null;
17 private $product = null;
18 private $sections = null;
19 private $single_section = null;
20 private $tag = null;
21 public $is_knowledgebase = false;
22 public $is_single_product_mode = false;
23 public $is_products_page = false;
24 public $is_product = false;
25 public $is_section = false;
26 public $is_tag = false;
27 public $is_search = false;
28 public $is_global_search = false;
29 public $is_article = false;
30 public $is_kb_404 = false;
31 private $options = false;
32 private $icons_options = false;
33 public $icons = '';
34 public $icons_form = '';
35 private $regex_word_boundary = null;
36
37
38 /**
39 * basepress_utils constructor.
40 *
41 * @since 1.0.0
42 *
43 * @updated 1.7.8
44 */
45 public function __construct() {
46
47 //Add knowledge base custom template
48 add_filter( 'template_include', array( $this, 'basepress_page_template' ), 99 );
49
50 //Set knowledge base variables
51 add_filter( 'request', array( $this, 'set_page_variables' ), 10 );
52
53 //Initialize options variables;
54 $this->load_options();
55 add_action( 'init', array( $this, 'load_options' ), 10 );
56
57 //Change WP query for sections
58 add_action( 'pre_get_posts', array( $this, 'sections_query' ), 999 );
59
60 //Changes the request for knowledgebase entry page to different ones depending on cases.
61 add_filter( 'request', array( $this, 'change_request' ), 30 );
62
63 //Load icons
64 add_action( 'init', array( $this, 'load_icons' ));
65
66 //Enable comments for knowledge base
67 add_filter( 'comments_open', array( $this, 'enable_comments' ) );
68
69 //Redirect comments template for knowledge base
70 add_filter( 'comments_template', array( $this, 'comments_template' ), 90 );
71
72 //Include theme functions.php if it exists
73 add_action( 'setup_theme', array( $this, 'load_theme_functions' ) );
74
75 //Load theme settings in admin
76 if ( is_admin() ) {
77 $this->load_theme_settings();
78 }
79
80 //Enqueue public scripts and styles
81 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_public_scripts' ), 10 );
82
83
84 add_filter( 'document_title_parts', array( $this, 'set_title' ), 10 );
85
86 //Make KB menu item active when visiting any KB page
87 add_filter( 'nav_menu_css_class', array( $this, 'set_menu_item_active') , 10, 2 );
88
89 //If Build Mode is enabled load our class
90 if( isset( $this->options['build_mode'] ) ){
91 require_once BASEPRESS_DIR . 'includes/class-basepress-build-mode.php';
92 }
93 }
94
95
96
97 /**
98 * Fixes titles for entry page and global searches
99 *
100 * @since 1.7.6
101 * @updated 1.7.7
102 *
103 * @param mixed $parts
104 * @return mixed
105 */
106 public function set_title( $parts ){
107 if( ( isset( $this->options['single_product_mode'] ) && $this->is_product ) || $this->is_global_search ){
108 $options = $this->get_options();
109 $entry_page = $options['entry_page'];
110 /**
111 * This filter allows to modify the entry page ID
112 */
113 $entry_page = apply_filters( 'basepress_entry_page', $entry_page );
114
115 $title = $entry_page ? get_the_title( $options['entry_page'] ) : '';
116
117 $parts['title'] = $title;
118 }
119 return $parts;
120 }
121
122
123 /**
124 * Loads and caches plugin options
125 *
126 * @since 1.5.0
127 */
128 public function load_options() {
129 $options = get_option( 'basepress_settings' );
130 if ( ! $options && is_multisite() ) {
131 $options = get_site_option( 'basepress_settings' );
132 }
133 $this->options = $options;
134 }
135
136 public function is_breadcrumbs_enabled(){
137
138 if(isset( $this->options['hide_breadcrumbs'] )){
139 return false;
140 }else{
141 return true;
142 }
143
144 }
145
146 /**
147 * Loads the active theme functions.php if it exists
148 *
149 * @since 1.3.0
150 */
151 public function load_theme_functions() {
152 //Include theme functions.php if it exists
153 $theme_functions = $this->get_theme_file_path( 'functions.php' );
154 if ( $theme_functions ) {
155 include_once( $theme_functions );
156 }
157 }
158
159
160 /**
161 * Loads the theme settings page on admin screen
162 *
163 * @since 1.3.1
164 */
165 private function load_theme_settings() {
166 //Include theme theme-settings.php if it exists
167 $theme_settings = $this->get_theme_file_path( 'settings/theme-settings.php' );
168 if ( $theme_settings ) {
169 include_once( $theme_settings );
170 }
171 }
172
173
174 /**
175 * Enqueue scripts for front end
176 *
177 * @since 1.0.0
178 *
179 * @updated 1.7.8, 1.7.10, 1.7.12
180 */
181 public function enqueue_public_scripts() {
182
183 global $basepress, $post;
184
185 //Retrieve the active theme css and icons URLs.
186 /**
187 * This filter allows to change the css file name
188 */
189 $stylesheet = apply_filters( 'basepress_theme_style', 'style.css' );
190
191 $theme_css = $this->get_theme_file_uri( 'css/' . $stylesheet );
192
193 $theme_icons = $this->get_icons_uri();
194
195 $theme_path = $this->get_theme_file_path( 'css/' . $stylesheet );
196 $theme_ver = filemtime( $theme_path );
197
198 //Always register scripts and styles as they might be needed for shortcodes as well
199 $minified = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_REQUEST['script_debug'] ) ? '' : 'min.';
200 $front_js_ver = filemtime( BASEPRESS_DIR . "public/js/basepress.{$minified}js");
201 wp_register_script( 'basepress-js', plugins_url( "public/js/basepress.{$minified}js", __DIR__ ), array( 'jquery' ), $front_js_ver, true );
202
203 wp_register_style( 'basepress-styles', $theme_css, array(), $theme_ver );
204 wp_register_style( 'basepress-icons', $theme_icons, array(), $basepress->ver );
205
206 //Enqueue scripts and styles inside the knowledge base pages
207 if( $this->is_knowledgebase || apply_filters( 'basepress_force_script_loading', false ) ){
208
209 $kb_post_id = is_singular('knowledgebase') ? $kb_post_id = $post->ID : '';
210 $product = $this->get_product();
211 $minimum_char_length = $this->get_option( 'search_min_chars' );
212 $minimum_char_length = $minimum_char_length ? $minimum_char_length : 3;
213
214 //Enqueue scripts
215 wp_enqueue_script( 'basepress-js' );
216
217 $js_vars = array(
218 'ajax_url' => admin_url( 'admin-ajax.php' ),
219 'postID' => $kb_post_id,
220 'productID' => $product->id,
221 'premium' => BASEPRESS_PLAN == 'premium' ? true : '',
222 'log_search' => isset( $this->options['activate_insights'] ),
223 'min_chars' => apply_filters( 'basepress_search_min_char_length', $minimum_char_length )
224 );
225
226 wp_localize_script( 'basepress-js', 'basepress_vars', $js_vars );
227
228 //Enqueue the theme styles
229 wp_enqueue_style( 'basepress-styles', $theme_css );
230
231 if( ! isset( $this->icons_options['form']['skip-enqueue'] ) ){
232 wp_enqueue_style( 'basepress-icons', $theme_icons );
233 }
234
235 }
236 }
237
238
239 /**
240 * Get the icon URI for enqueueing
241 *
242 * @since 1.7.8
243 *
244 * @return bool|string
245 */
246 public function get_icons_uri(){
247 $icons_options = $this->icons_options;
248 $css_uri = $icons_options && !apply_filters( 'basepress_legacy_icons', false ) ? $icons_options['form']['css-uri'] : '';
249 $is_default_font = empty( $css_uri ) ? true : false;
250 $is_cdn = filter_var( $css_uri, FILTER_VALIDATE_URL ) !== false;
251
252 if( $is_cdn && !apply_filters( 'basepress_legacy_icons', false )){
253 $theme_icons = $css_uri;
254 }
255 else{
256 $theme_icons = $is_default_font ? $this->get_default_icons_css_uri() : get_template_directory_uri() . '/' . $css_uri;
257 }
258
259 return $theme_icons;
260 }
261
262
263 /**
264 * Loads xml icons file from active theme
265 *
266 * @since 1.0.0
267 *
268 * @updated 1.7.8
269 */
270 public function load_icons(){
271
272 $icons_options = $this->get_icons_options();
273
274 if( $icons_options && !apply_filters( 'basepress_legacy_icons', false )){
275 $this->icons = json_decode( json_encode( $icons_options['icons-sets'] ));
276 $this->icons_form = $icons_options['form'];
277 }
278 else{
279 $icons = $this->get_default_icons_xml_path();
280 if( $icons ){
281 $this->icons = simplexml_load_file( $icons );
282 }
283 else{
284 $this->icons = basepress_icons_manager::get_empty_icons_data();
285 }
286 $this->icons_form = array( 'css-uri' => '', 'extra-classes' => '' );
287 }
288 }
289
290
291 /**
292 * Returns the icons options from DB
293 *
294 * @since 1.7.8
295 *
296 * @return bool
297 */
298 public function get_icons_options(){
299 if( ! $this->icons_options ){
300 $icons_options = get_option( 'basepress_icons_sets' );
301 $this->icons_options = $icons_options;
302 }
303 return $this->icons_options;
304 }
305
306
307 /**
308 * Returns the icons css uri
309 *
310 * @since 1.7.8
311 *
312 * @return string
313 */
314 public function get_default_icons_css_uri(){
315 if( apply_filters( 'basepress_legacy_icons', false ) ){
316 $css_uri = $this->get_theme_file_uri( 'css/icons.css' );
317 }
318 else{
319 $css_uri = BASEPRESS_URI . 'icons/icons.css';
320 }
321 return $css_uri;
322 }
323
324
325 /**
326 * Returns the icons css path
327 *
328 * @since 1.7.8
329 *
330 * @return string
331 */
332 public function get_default_icons_css_path(){
333 if( apply_filters( 'basepress_legacy_icons', false ) ){
334 $css_path = $this->get_theme_file_path( 'css/icons.css' );
335 }
336 else{
337 $css_path = BASEPRESS_DIR . 'icons/icons.css';
338 }
339 return $css_path;
340 }
341
342
343
344 /**
345 * Returns the icons xml path
346 *
347 * @since 1.7.8
348 *
349 * @return string
350 */
351 public function get_default_icons_xml_path(){
352 if( apply_filters( 'basepress_legacy_icons', false ) ){
353 $xml_path = $this->get_theme_file_path( 'icons/icons.xml' );
354 $xml_path = $xml_path ? $xml_path : BASEPRESS_DIR . 'icons/fonts/icons.xml';
355 }
356 else{
357 $xml_path = BASEPRESS_DIR . 'icons/fonts/icons.xml';
358 }
359 return $xml_path;
360 }
361
362
363 /**
364 * Gets the KB slug including parents pages if exists
365 *
366 * @since 1.7.9
367 *
368 * @return string
369 */
370 public function get_kb_slug( $refresh = false ){
371
372 if( ! $refresh && $this->kb_slug ){
373 return $this->kb_slug;
374 }
375
376 $entry_page = isset( $this->options['entry_page'] ) ? $this->options['entry_page'] : 0;
377
378 /**
379 * Filters the entry page ID before use
380 */
381 $entry_page = apply_filters( 'basepress_entry_page', $entry_page );
382
383 $parents = get_ancestors( $entry_page, 'page' );
384 $kb_slug = get_post_field( 'post_name', $entry_page );
385
386 foreach( $parents as $parent ){
387 $parent_slug = get_post_field( 'post_name', $parent );
388 $kb_slug = $parent_slug . '/' . $kb_slug;
389 }
390 $this->kb_slug = $kb_slug;
391 return $kb_slug;
392 }
393
394 /**
395 * Gets the KB slug including parents pages if exists
396 *
397 * @since 2.6
398 *
399 * @return string
400 */
401
402 public function get_kb_title( $refresh = false ){
403
404 if( ! $refresh && $this->kb_title ){
405 return $this->kb_title;
406 }
407
408 $entry_page = isset( $this->options['entry_page'] ) ? $this->options['entry_page'] : 0;
409
410 /**
411 * Filters the entry page ID before use
412 */
413 $entry_page = apply_filters( 'basepress_entry_page', $entry_page );
414
415 $parents = get_ancestors( $entry_page, 'page' );
416 $kb_title = get_post_field( 'post_title', $entry_page );
417
418 foreach( $parents as $parent ){
419 $parent_slug = get_post_field( 'post_title', $parent );
420 $kb_title = $parent_slug . '/' . $kb_slug;
421 }
422 $this->kb_title = $kb_title;
423 return $kb_title;
424 }
425
426
427
428 /**
429 * Sets all the variables for the Knowledge base pages
430 *
431 * @since 2.2.0
432 *
433 * @param $query
434 * @return mixed
435 */
436 public function set_page_variables( $query ){
437 new Basepress_Variables( $query );
438 return $query;
439 }
440
441
442 /**
443 * Changes the request for knowledgebase entry page to different ones depending on cases.
444 *
445 * @since 1.0.0
446 *
447 * @param $value
448 * @return mixed
449 */
450 public function change_request( $request ) {
451
452 $options = $this->get_options();
453
454 //Unset unwanted variables for global searches. This is necessary if the search var is used in the URL
455 //If page_id is left unset the pagination won't work
456 if( $this->is_global_search ){
457 if( isset( $request['page_id'] ) ){
458 unset( $request['page_id'] );
459 }
460 }
461
462 //If in single product mode change the request to show the list of sections
463 if ( ! isset( $options['single_product_mode'] ) ) {
464 return $request;
465 }
466
467 if ( $this->is_product || ( empty( $request ) && $this->is_kb_on_front_page() ) ) {
468
469 $product = get_terms(
470 array(
471 'taxonomy' => 'knowledgebase_cat',
472 'parent' => 0,
473 'hide_empty' => false,
474 'meta_key' => 'basepress_position',
475 'orderby' => 'meta_value_num',
476 'order' => 'ASC',
477 'number' => 1,
478 )
479 );
480
481 if( isset( $request['page_id'] ) ){
482 unset( $request['page_id'] );
483 }
484 $request['knowledgebase_cat'] = $product[0]->slug;
485 }
486
487 return $request;
488 }
489
490
491 /**
492 * Returns an array of orderby and order for sections list
493 *
494 * @since 2.10.0
495 *
496 * @return array
497 */
498 public function get_posts_order(){
499
500 $posts_order = isset( $this->options['posts_orderby'] ) ? $this->options['posts_orderby'] : 'date_asc';
501
502 switch( $posts_order ){
503 case 'date_asc':
504 $orderby = array( 'menu_order' => 'ASC', 'date' => 'ASC' );
505 break;
506 case 'date_desc':
507 $orderby = array( 'menu_order' => 'ASC', 'date' => 'DESC' );;
508 break;
509 case 'alpha_asc':
510 $orderby = array( 'menu_order' => 'ASC', 'title' => 'ASC' );;
511 break;
512 case 'alpha_desc':
513 $orderby = array( 'menu_order' => 'ASC', 'title' => 'DESC' );;
514 break;
515 }
516 return apply_filters( 'basepress_posts_order', array( 'orderby' => $orderby, 'order' => '' ) );
517 }
518
519
520 /**
521 * Limit the number of posts in the main query for archive pages.
522 *
523 * @since 1.0.0
524 * @updated 1.6.0, 2.0.1
525 *
526 * @param $query
527 */
528 public function sections_query( $query ) {
529 if ( is_admin() || ! $query->is_main_query()) {
530 return;
531 }
532
533 //Check if we are on a basepress archive page
534 if( $this->is_section || $this->is_product || $this->is_search || $this->is_global_search || $this->is_tag ){
535
536 $posts_per_page = isset( $this->options['section_post_limit'] ) ? $this->options['section_post_limit'] : -1;
537
538 //If this is a search result page
539 if ( isset( $query->query['s'] ) ) {
540
541 $query->set( 'post_type', 'knowledgebase' );
542 $query->set( 'posts_per_page', $posts_per_page );
543
544 return;
545 }
546
547 $queried_object = get_queried_object();
548
549 //If we have no queried object return. This can happen if articles have not product or sections.
550 if ( ! $queried_object ) {
551 return;
552 }
553
554 if ( $this->is_section || $this->is_tag ) {
555 $posts_order = $this->get_posts_order();
556 $orderby = $posts_order['orderby'];
557 $order = $posts_order['order'];
558
559 $query->set( 'posts_per_page', $posts_per_page );
560 $query->set( 'orderby', $orderby );
561 $query->set( 'order', $order );
562
563 // if section_post_limit value is 0 then result will be 0.
564 if ( empty( $this->options['section_post_limit'] ) ) {
565 $query->set( 'post__in', [0] );
566 }
567
568 if( $this->is_section ){
569 $query->set(
570 'tax_query',
571 array(
572 array(
573 'taxonomy' => 'knowledgebase_cat',
574 'field' => 'slug',
575 'terms' => $query->query_vars['knowledgebase_cat'],
576 'include_children' => false,
577 ),
578 )
579 );
580 /**
581 * Action filter to modify the query for a single section
582 */
583 do_action( 'basepress_single_section_query', $query );
584 }
585 if( $this->is_tag ){
586 /**
587 * Action filter to modify the query for a tag
588 */
589 do_action( 'basepress_tag_query', $query );
590 }
591 } else {
592 //If this is a multi section page (is_product) we don't need posts from the main query so we reduce it to 0 results
593 //since the main query cannot be eliminated completely without side effects
594 $query->set( 'posts_per_page', 1 );
595 $query->set( 'post__in', array(0) );
596 }
597 }
598 }
599
600
601
602 /**
603 * Get list of all products with their data
604 *
605 * @since 1.0.0
606 * @updated 1.7.10.1
607 *
608 * @return array
609 */
610 public function get_products() {
611
612 if( $this->products ){
613 return $this->products;
614 }
615
616 $products = array();
617
618 $terms_args = array(
619 'taxonomy' => 'knowledgebase_cat',
620 'hide_empty' => true,
621 'parent' => 0,
622 'meta_key' => 'basepress_position',
623 'orderby' => 'meta_value_num',
624 'order' => 'ASC',
625 );
626
627 /**
628 * Filters the list of found knowledge bases
629 */
630 $terms_args = apply_filters( 'basepress_products_terms_args', $terms_args );
631
632 $products_terms = get_terms( $terms_args );
633
634 foreach ( $products_terms as $product ) {
635
636 //If the product has visibility off skip it
637 $visibility = get_term_meta( $product->term_id, 'visibility', true );
638 if ( ! $visibility ) {
639 continue;
640 }
641
642 //Get product image
643 $image = get_term_meta( $product->term_id, 'image', true );
644
645 $image_url = isset( $image['image_url'] ) ? $image['image_url'] : '';
646 $image_width = isset( $image['image_width'] ) ? $image['image_width'] : '';
647 $image_height = isset( $image['image_height'] ) ? $image['image_height'] : '';
648
649 //Get product permalink
650 $permalink = get_term_link( $product->term_id, 'knowledgebase_cat' );
651
652 $products[] = (object) array(
653 'id' => $product->term_id,
654 'name' => $product->name,
655 'slug' => $product->slug,
656 'permalink' => $permalink,
657 'description' => $product->description,
658 'image' => (object) array(
659 'url' => set_url_scheme( $image_url ),
660 'width' => $image_width,
661 'height' => $image_height,
662 ),
663 );
664 }
665
666 $this->products = $products;
667
668 return $products;
669 }
670
671 /**
672 * Outputs the message for when there are no products yet in the KB
673 *
674 * @since 2.1.0
675 *
676 * @return string
677 */
678 public function no_products_message(){
679 $output = '<div style="padding:15px;background:#c92c2c;color:white;font-family:sans-serif;font-size:16px">';
680 $output .= __( 'There are no Knowledge Bases yet!<br>Once you have at least a Knowledge Base with some content it will appear here.' , 'basepress');
681 $output .= '</div>';
682 return $output;
683 }
684
685
686 /**
687 * This function collects and returns all data for the current product
688 *
689 * @since 1.0.0
690 *
691 * @param $term_id
692 *
693 * @return null|object|void
694 */
695 public function get_product( $term_id = '' ) {
696 global $wp_query;
697
698 if( empty( $term_id ) && !isset($_POST['form_key'])){
699
700 // If we already created the product we return the cached copy
701 if( $this->product ){
702 return $this->product;
703 }
704
705 $queried_object = get_queried_object();
706
707 $term = null;
708
709 if( is_a( $queried_object, 'WP_Term' ) ){
710 $term = $this->get_top_term( $queried_object );
711 }
712
713 if( is_a( $queried_object, 'WP_Post' ) ){
714 $terms = wp_get_post_terms( get_the_ID(), 'knowledgebase_cat' );
715
716 if( ! empty( $terms ) && ! is_wp_error( $terms ) ){
717 $term = $this->get_top_term( $terms[0] );
718 }
719 }
720
721 if( is_search() && isset( $wp_query->query['knowledgebase_cat'] ) ){
722 $term = get_terms(
723 array(
724 'taxonomy' => 'knowledgebase_cat',
725 'slug' => $wp_query->query['knowledgebase_cat'],
726 'number' => 1,
727 )
728 );
729 $term = ! is_wp_error( $term ) && isset( $term[0] ) ? $term[0] : '';
730 }
731 }
732 else{
733 $term = get_term( $term_id, 'knowledgebase_cat' );
734 if( empty( $term ) || is_wp_error( $term ) || 0 != $term->parent ){
735 $term = null;
736 }
737 }
738
739 if( ! $term || is_wp_error( $term ) ){
740 $product = (object) array(
741 'id' => '',
742 'name' => '',
743 'slug' => '',
744 'permalink' => '',
745 'description' => '',
746 'image' => (object) array(
747 'url' => '',
748 'width' => '',
749 'height' => '',
750 ),
751 );
752 return $product;
753 }
754
755 //We also need to get the image for the product
756 $image = get_term_meta( $term->term_id, 'image', true );
757 $image = $image ? $image : array(
758 'image_url' => '',
759 'image_width' => '',
760 'image_height' => '',
761 );
762
763 //Once we have all data we can join it in a single object
764 $product = (object) array(
765 'id' => $term->term_id,
766 'name' => $term->name,
767 'slug' => $term->slug,
768 'permalink' => get_term_link( $term->term_id, 'knowledgebase_cat' ),
769 'description' => $term->description,
770 'image' => (object) array(
771 'url' => set_url_scheme( $image['image_url'] ),
772 'width' => $image['image_width'],
773 'height' => $image['image_height'],
774 ),
775 );
776
777 $this->product = $product;
778 return $product;
779 }
780
781
782 /**
783 * Returns the active product on single product mode
784 *
785 * @since 1.7.6
786 *
787 * @return mixed
788 */
789 public function get_active_product_id(){
790
791 $active_product_id = false;
792
793 if( isset( $this->options['single_product_mode'] ) ){
794 $active_product = get_terms(
795 array(
796 'taxonomy' => 'knowledgebase_cat',
797 'parent' => 0,
798 'hide_empty' => false,
799 'meta_key' => 'basepress_position',
800 'orderby' => 'meta_value',
801 'order' => 'ASC',
802 'number' => 1,
803 'fields' => 'ids',
804 )
805 );
806 if( $active_product && ! is_wp_error( $active_product )){
807 $active_product_id = $active_product[0];
808 }
809 }
810
811 return $active_product_id;
812 }
813
814
815 /**
816 * Recursive function to find the top level term which is the Product
817 *
818 * @since 1.0.0
819 * @updated 1.7.6
820 *
821 * @param $term
822 * @return mixed
823 */
824 public function get_top_term( $term ) {
825 if( ! is_a( $term, 'WP_Term' ) ){
826 return null;
827 }
828
829 if( 'knowledgebase_cat' != $term->taxonomy ){
830 return null;
831 }
832
833 if( 0 == $term->parent ) return $term;
834
835 while( 0 != $term->parent ){
836 $term = get_term( $term->parent, 'knowledgebase_cat' );
837 }
838
839 return $term;
840 }
841
842
843
844
845 /**
846 * This function collects and returns all sections for a product including the posts for each section.
847 * The posts collected will be no more than the limit set on the option screen.
848 *
849 * @since 1.0.0
850 *
851 * @return array|null
852 */
853 public function get_sections() {
854
855 //Get the queried object
856 $queried_object = get_queried_object();
857
858 if ( $this->is_product ) {
859 if ( $this->sections ) {
860 return $this->sections;
861 }
862 return $this->get_multi_sections( $queried_object );
863 } else {
864 if ( $this->single_section ) {
865 return $this->sections;
866 }
867 return $this->get_single_section( $queried_object );
868 }
869 }
870
871
872
873 /**
874 * Builds the sections for a multi sections view.
875 *
876 * @since 1.0.0
877 *
878 * @updated 1.7.8, 1.7.11, 1.8.10, 2.0.1
879 *
880 * @param $term
881 * @return array
882 */
883 public function get_multi_sections( $term ){
884
885 if( ! $term ){
886 return array();
887 }
888
889 $sections = array();
890 $options = get_option( 'basepress_settings' );
891
892 //Get the sections(s)
893 $terms_args = array(
894 'taxonomy' => 'knowledgebase_cat',
895 'hide_empty' => true,
896 'parent' => $term->term_id,
897 'meta_query' => array(
898 'relation' => 'OR',
899 array(
900 'key' => 'basepress_position',
901 ),
902 array(
903 'key' => 'basepress_position',
904 'compare' => 'NOT EXISTS'
905 )
906 ),
907 'orderby' => 'meta_value_num',
908 'order' => 'ASC'
909 );
910
911 /**
912 * Filters the list of found knowledge bases
913 */
914 $terms_args = apply_filters( 'basepress_sections_terms_args', $terms_args );
915
916 $terms = get_terms( $terms_args );
917
918 //We can now iterate over each section and load its data
919 foreach( $terms as $section ){
920
921 $sections[$section->slug] = $this->get_section_data( $section );
922 $posts_order = $this->get_posts_order();
923 $orderby = $posts_order['orderby'];
924 $order = $posts_order['order'];
925
926 //Get section's posts
927 $args = array(
928 'post_type' => 'knowledgebase',
929 'posts_per_page' => $options[ 'sections_post_limit' ],
930 'orderby' => $orderby,
931 'order' => $order,
932 'tax_query' => array(
933 array(
934 'taxonomy' => 'knowledgebase_cat',
935 'field' => 'term_id',
936 'terms' => $section->term_id,
937 'include_children' => false,
938 )
939 )
940 );
941
942 // if sections_post_limit value is 0 then result will be 0.
943 if ( empty( $options[ 'sections_post_limit' ] ) ) {
944 $args['post__in'] = [0];
945 }
946
947 /**
948 * Filter to modify the query for multi sections
949 */
950 $args = apply_filters( 'basepress_multi_section_query', $args );
951
952 $section_posts = new WP_Query( $args );
953
954 //Get section's posts count including sub-sections
955 $sections[$section->slug]->posts_count = $this->get_section_post_count( $section );
956
957 //Determine the number of sub-sections to list
958 $children_terms_count_limit = ( ! empty( $options['sections_post_limit'] ) ? $options['sections_post_limit'] - $section_posts->found_posts : 0 );
959
960 if( $children_terms_count_limit > 0 ){
961 //Get direct sub-sections
962 $children_terms = get_terms(
963 array(
964 'taxonomy' => 'knowledgebase_cat',
965 'hide_empty' => true,
966 'parent' => $section->term_id,
967 'meta_query' => array(
968 'relation' => 'OR',
969 array(
970 'key' => 'basepress_position',
971 ),
972 array(
973 'key' => 'basepress_position',
974 'compare' => 'NOT EXISTS'
975 )
976 ),
977 'orderby' => 'meta_value_num',
978 'order' => 'ASC',
979 'number' => $children_terms_count_limit
980 )
981 );
982 }
983 else{
984 $children_terms = array();
985 }
986
987 //Add the list of sub-sections to the parent section
988 $sub_sections = array();
989 foreach( $children_terms as $sub_section ){
990 $sub_section_post_count = $this->get_section_post_count( $sub_section );
991 if( $sub_section_post_count ){
992 //Get the sub-section data
993 $sub_sections[ $sub_section->slug ] = $this->get_section_data( $sub_section );
994 }
995 }
996
997 $sections[ $section->slug ]->subsections = $sub_sections;
998
999 if( empty( $sections[$section->slug]->posts_count ) && empty( $sections[ $section->slug ]->subsections ) ){
1000 unset( $sections[$section->slug] );
1001 continue;
1002 }
1003
1004 //Get section's posts
1005 if( $section_posts->have_posts() ){
1006
1007 while( $section_posts->have_posts() ){
1008 $section_posts->the_post();
1009
1010 //Get the post object
1011 $the_post = get_post();
1012
1013 //Add the icon to the post object
1014 $post_icon = get_post_meta( get_the_ID(), 'basepress_post_icon', true );
1015 $the_post->icon = $post_icon ? $post_icon : $this->icons->post->default;
1016 //Add the post object to the section
1017 $sections[ $section->slug ]->posts[] = $the_post;
1018 }
1019 }
1020 wp_reset_postdata();
1021 }
1022
1023 return $this->sections = $sections;
1024 }
1025
1026
1027
1028 /**
1029 * Builds the section for a single section view
1030 *
1031 * @since 1.0.0
1032 *
1033 * @updated 1.7.8, 1.7.11, 1.8.10, 2.0.1
1034 */
1035 public function get_single_section( $term ){
1036
1037 //If the term is a product return. This can happen if articles have no section set.
1038 if( ! $term || $term->parent == 0 ){
1039 return array();
1040 }
1041
1042 $section[$term->slug] = $this->get_section_data( $term );
1043 $section[$term->slug]->sub_sections = $this->get_multi_sections( $term );
1044 $section[$term->slug]->posts_count = $term->count;
1045
1046 if( have_posts() ){
1047 while( have_posts() ){
1048 the_post();
1049 //Get the post object
1050 $the_post = get_post();
1051
1052 //Add the icon to the post object
1053 $post_icon = get_post_meta( get_the_ID(), 'basepress_post_icon', true );
1054 $the_post->icon = $post_icon ? $post_icon : $this->icons->post->default;
1055
1056 //Add the post object to the section
1057 $section[$term->slug]->posts[] = $the_post;
1058 }
1059 wp_reset_postdata();
1060 }
1061 $this->sections = $section[$term->slug]->sub_sections;
1062 return $this->single_section = $section;
1063 }
1064
1065
1066 /**
1067 * Retrives the WP_Term for the current tag
1068 *
1069 * @since 2.7.0
1070 *
1071 * @return array|false|WP_Term
1072 */
1073 public function get_tag(){
1074 $tag_slug = get_query_var( 'knowledgebase_tag' );
1075 $term = get_term_by( 'slug', $tag_slug, 'knowledgebase_tag' );
1076
1077 return $term;
1078 }
1079
1080 /**
1081 * Builds the Tag for a single tag view
1082 *
1083 * @since 2.7.0
1084 *
1085 * @return object|null
1086 */
1087 public function get_articles_by_tag(){
1088
1089 if( $this->is_tag ){
1090
1091 if( isset( $this->tag ) ){
1092 return $this->tag;
1093 }
1094
1095 $term = $this->get_tag();
1096
1097 if( $term ){
1098 $tag = ( object )array(
1099 'id' => $term->term_id,
1100 'name' => $term->name,
1101 'slug' => $term->slug,
1102 'permalink' => get_term_link( $term->term_id, 'knowledgebase_tag' ),
1103 'description' => $term->description,
1104 'posts_count' => $term->count,
1105 'posts' => array(),
1106 );
1107
1108 $args = array(
1109 'post_type' => 'knowledgebase',
1110 'tax_query' => array(
1111 array(
1112 'taxonomy' => 'knowledgebase_tag',
1113 'field' => 'term_id',
1114 'terms' => $term->term_id
1115 )
1116 )
1117 );
1118 $term_posts = new WP_Query( $args );
1119
1120 if( $term_posts->have_posts() ){
1121 while( $term_posts->have_posts() ){
1122 $term_posts->the_post();
1123 //Get the post object
1124 $the_post = get_post();
1125
1126 //Add the icon to the post object
1127 $post_icon = get_post_meta( get_the_ID(), 'basepress_post_icon', true );
1128 $the_post->icon = $post_icon ? $post_icon : $this->icons->post->default;
1129
1130 //Add the post object to the section
1131 $tag->posts[] = $the_post;
1132 }
1133 wp_reset_postdata();
1134 }
1135 }
1136 else{
1137 $tag = ( object )array(
1138 'id' => '',
1139 'name' => '',
1140 'slug' => '',
1141 'permalink' => '',
1142 'description' => '',
1143 'posts_count' => '',
1144 'posts' => array(),
1145 );
1146 }
1147 return $this->tag = $tag;
1148 }
1149
1150 }
1151
1152
1153 /**
1154 * Get all section data in one object
1155 *
1156 * @since 1.8.10
1157 *
1158 * @param $section
1159 * @return object
1160 */
1161 private function get_section_data( $section ){
1162
1163 $meta = get_term_meta( $section->term_id );
1164 $icon = isset( $meta['icon'][0] ) && $meta['icon'][0] ? $meta['icon'][0] : $this->icons->sections->default;
1165 $image = isset( $meta['image'][0] ) ? $meta['image'][0] : '';
1166 $image = maybe_unserialize( $image);
1167 $image['image_url'] = isset( $image['image_url'] ) ? set_url_scheme( $image['image_url'] ) : [];
1168
1169 return ( object ) array(
1170 'id' => $section->term_id,
1171 'name' => $section->name,
1172 'slug' => $section->slug,
1173 'permalink' => get_term_link( $section->term_id, 'knowledgebase_cat'),
1174 'description' => $section->description,
1175 'icon' => $icon,
1176 'default_icon' => $this->icons->sections->default,
1177 'image' => $image,
1178 'posts_count' => $section->count,
1179 'posts' => array(),
1180 );
1181
1182 }
1183
1184
1185
1186 /**
1187 * Returns the amount of posts in a section including the sub-sections articles
1188 *
1189 * @since 1.8.10
1190 *
1191 * @param $section
1192 * @return mixed
1193 */
1194 private function get_section_post_count( $section ){
1195 //Count section's posts including sub-sections
1196 $post_count_args = array(
1197 'post_type' => 'knowledgebase',
1198 'posts_per_page' => -1,
1199 'fields' => 'ids',
1200 'tax_query' => array(
1201 array(
1202 'taxonomy' => 'knowledgebase_cat',
1203 'field' => 'term_id',
1204 'terms' => $section->term_id,
1205 'include_children' => true,
1206 )
1207 )
1208 );
1209
1210 $posts_count_query = new WP_Query( $post_count_args );
1211 $post_count = $posts_count_query->found_posts;
1212
1213 /**
1214 * Filter the number of posts for the current query
1215 * @since 2.3.0
1216 */
1217 $post_count = apply_filters( 'get_section_post_count_args', $post_count, $section );
1218 return $post_count;
1219 }
1220
1221
1222 /**
1223 * Generates the breadcrumbs
1224 *
1225 * @since 1.0.0
1226 *
1227 * @updated 2.5.0
1228 */
1229 public function get_breadcrumbs(){
1230
1231 //if the breadcrumbs are used outside of the knowledge base return;
1232 if( ! $this->is_knowledgebase ) return;
1233
1234 $entry_page_id = isset( $this->options['entry_page'] ) ? $this->options['entry_page'] : false;
1235
1236 $breadcrumbs_list = array();
1237 $entry_page_link = $entry_page_id ? get_page_link( $entry_page_id ) : '';
1238 $entry_page_title = isset( $this->options['breadcrumbs_kb_name'] ) ? sanitize_text_field( $this->options['breadcrumbs_kb_name'] ) : '';
1239 $separator = isset( $this->icons->breadcrumbs->icon ) ? $this->icons->breadcrumbs->icon : '';
1240 if( is_array( $separator ) ){
1241 $separator = ! empty( $separator ) ? $separator[0] : '';
1242 }
1243
1244 //Home link
1245 if( isset( $this->options['breadcrumbs_include_home'] ) ){
1246 $home_link = get_home_url();
1247 $home_title = isset( $this->options['breadcrumbs_home_text'] ) && $this->options['breadcrumbs_home_text'] ? $this->options['breadcrumbs_home_text'] : 'Home';
1248 $breadcrumbs_list[] = array( 'link' => $home_link, 'title' => $home_title, 'context' => 'home' );
1249 }
1250
1251 //Parent pages
1252 if( isset( $this->options['breadcrumbs_include_parent'] ) ){
1253 $parents = get_ancestors( $entry_page_id, 'page' );
1254
1255 foreach( $parents as $parent_id ){
1256 $parent_link = get_permalink( $parent_id );
1257 $parent_title = get_post_field( 'post_title', $parent_id );
1258 $breadcrumbs_list[] = array( 'link' => $parent_link, 'title' => $parent_title, 'context' => 'parent-pages' );
1259 }
1260 }
1261
1262 //Entry page
1263 $breadcrumbs_list[] = array( 'link' => $entry_page_link, 'title' => $entry_page_title, 'context' => 'entry-page' );
1264
1265 //Taxonomies Terms
1266 $queried_object = get_queried_object();
1267
1268 if( $queried_object ){
1269 if( is_a( $queried_object, 'WP_Term' ) && 'knowledgebase_tag' !== $queried_object->taxonomy ){
1270 $tax_term = $queried_object;
1271 }
1272 if( is_a( $queried_object, 'WP_Post' ) ){
1273 $tax_term = get_the_terms( get_the_ID(), 'knowledgebase_cat' );
1274 $tax_term = ! empty( $tax_term )? $tax_term[0] : false;
1275 }
1276
1277 if( ! empty( $tax_term ) ){
1278 $terms = $this->get_sections_tree( $tax_term );
1279
1280 foreach( $terms as $index => $term ){
1281 //If single product mode is used skip the product
1282 if( $term->parent == 0 && isset( $this->options['single_product_mode'] ) )
1283 continue;
1284 $term_link = get_term_link( $term->term_id, 'knowledgebase_cat' );
1285 $term_title = $term->name;
1286 $term_context = $term->parent == 0 ? 'kb' : 'section-' . $index;
1287 $breadcrumbs_list[] = array( 'link' => $term_link, 'title' => $term_title, 'context' => $term_context );
1288 }
1289 }
1290 }
1291
1292 //Articles
1293 if( is_single() ){
1294 $breadcrumbs_list[] = array( 'link' => get_the_permalink(), 'title' => get_the_title(), 'context' => 'article' );
1295 }
1296
1297 //Tags
1298 if( $this->is_tag ){
1299 $tag = $this->get_tag();
1300 if( ! empty ( $tag) ){
1301 $tag_link = get_term_link( $tag->term_id, 'knowledgebase_tag' );
1302 $breadcrumbs_list[] = array( 'link' => $tag_link, 'title' => $tag->name, 'context' => 'tag' );
1303 }
1304 }
1305
1306 /**
1307 * Filter the breadcrumbs items
1308 */
1309 $breadcrumbs_list = apply_filters( 'basepress_breadcrumbs_items', $breadcrumbs_list );
1310
1311 /**
1312 * Action to output the breadcrumbs with custom functions. If the output is empty we'll use our default.
1313 */
1314 ob_start();
1315 do_action( 'basepress_breadcrumbs_output', $breadcrumbs_list, $separator );
1316 $breadcrumbs_output = ob_get_clean();
1317
1318 //Output the breadcrumbs
1319 if( ! empty( $breadcrumbs_output ) ){
1320 echo wp_kses_post( $breadcrumbs_output );
1321 }
1322 else{
1323 echo '<ul class="bpress-crumbs">';
1324
1325 foreach( $breadcrumbs_list as $index => $breadcrumb ){
1326 echo '<li>';
1327 if( $index ){
1328 echo '<span class="bpress-breadcrumb-arrow ' . esc_html( $separator ) . '"></span>';
1329 }
1330 echo '<a href="' . esc_url( $breadcrumb['link'] ) . '">' . esc_html( $breadcrumb['title'] ) . '</a>';
1331 echo '</li>';
1332 }
1333
1334 echo '</ul>';
1335 }
1336 }
1337
1338
1339
1340 /**
1341 * Generates an array of sections from product to subsections
1342 *
1343 * @since 1.0.0
1344 */
1345 public function get_sections_tree( $term ) {
1346 $tree = array();
1347 $tree[] = $term;
1348
1349 while ( 0 != $term->parent ) {
1350 $term = get_term( $term->parent, 'knowledgebase_cat' );
1351 $tree[] = $term;
1352 }
1353 return array_reverse( $tree );
1354 }
1355
1356
1357
1358 /**
1359 * Replaces theme template with BasePress custom template
1360 * This is a router function which will determine the correct template
1361 *
1362 * @since 1.0.0
1363 * @updated 1.4.0
1364 *
1365 * @param $template
1366 * @return bool|mixed
1367 */
1368 public function basepress_page_template( $template ) {
1369 global $post;
1370 $template_name = '';
1371
1372 if( ! $this->is_knowledgebase ){
1373 return $template;
1374 }
1375
1376 if( $this->is_kb_404 || is_404() ){
1377 $template_name = '404';
1378 }
1379 else{
1380
1381 $product = $this->get_product();
1382
1383 //Set the template if it is an archive page
1384 if( $this->is_product && ! $this->is_search ){
1385 $sections_style = get_term_meta( $product->id, 'sections_style', true );
1386 if( 'list' == $sections_style['sections'] ){
1387 $template_name = 'sections';
1388 }else{
1389 $template_name = 'sections-boxed';
1390 }
1391 }
1392
1393 if( $this->is_section && ! $this->is_search ){
1394 //This is the template to list all articles in a section
1395 $template_name = 'single-section';
1396 }
1397
1398 if( $this->is_tag ){
1399 $template_name = 'tag';
1400 }
1401
1402 if( $this->is_article || isset( $_REQUEST['preview'] ) ){
1403 //Set the template if is a post page
1404 //Get template name from post meta field
1405 //If it was not set we will use the full width template
1406 $template_name = get_post_meta( $post->ID, 'basepress_template_name', true ) ?: 'full-width';
1407 $options = $this->get_options();
1408 if( isset( $options['sidebar_position'] ) && isset( $options['force_sidebar_position'] ) ){
1409 $sidebar_position = $options['sidebar_position'];
1410 switch( $sidebar_position ){
1411 case 'right':
1412 $template_name = 'two-columns-right';
1413 break;
1414 case 'left':
1415 $template_name = 'two-columns-left';
1416 break;
1417 case 'none':
1418 $template_name = 'full-width';
1419 break;
1420 }
1421 }
1422
1423 }
1424 if( $this->is_search ){
1425 //Set the template if is a search result page
1426 if( $this->is_global_search ){
1427 $template_name = 'global-search';
1428 }else{
1429 $template_name = 'search';
1430 }
1431 }
1432 }
1433
1434 /**
1435 * Filter to modify the template file
1436 */
1437 $template_name = apply_filters( 'basepress_page_template', $template_name, $template );
1438
1439 //If the template file exists we can load it
1440 $basepress_template = $this->get_theme_file_path( $template_name . '.php' );
1441
1442 if ( $basepress_template ) {
1443 return $basepress_template;
1444 } else {
1445 return $template;
1446 }
1447 }
1448
1449
1450
1451 /**
1452 * Enables comment on articles
1453 *
1454 * @since 1.3.0
1455 *
1456 * @param $open
1457 * @return bool
1458 */
1459 public function enable_comments( $open ) {
1460 if ( ! ( is_singular( 'knowledgebase' ) || is_page( 'knowledgebase' )) ) {
1461 return $open;
1462 }
1463
1464 if ( isset( $this->options['enable_comments'] ) ) {
1465 return $open;
1466 }
1467 return false;
1468 }
1469
1470
1471
1472 /**
1473 * Replaces theme template with BasePress custom template for comments
1474 *
1475 * @since 1.3.0
1476 *
1477 * @param $theme_template
1478 * @return bool|mixed|void
1479 */
1480 public function comments_template( $theme_template ) {
1481
1482 if ( ! ( is_singular( 'knowledgebase' ) || is_page( 'knowledgebase' )) ) {
1483 return $theme_template;
1484 }
1485
1486 if ( isset( $this->options['use_default_comments_template'] ) ) {
1487 return $theme_template;
1488 }
1489
1490 $template = $this->get_theme_file_path( 'comments.php' );
1491 if ( $template ) {
1492 $theme_template = $template;
1493 }
1494 return $theme_template;
1495 }
1496
1497 /*
1498 *
1499 * Utility functions
1500 *
1501 */
1502
1503
1504 /**
1505 * Get Basepress template part
1506 *
1507 * @since 1.0.0
1508 *
1509 * @param $slug
1510 * @param null $name
1511 * @return bool
1512 */
1513 public function get_template_part( $slug, $name = null ) {
1514 //Check if there is a slug for the template
1515 if ( $slug ) {
1516
1517 $templates = array();
1518 $name = (string) $name;
1519 if ( '' !== $name ) {
1520 $templates[] = "{$slug}-{$name}.php";
1521 }
1522
1523 $templates[] = "{$slug}.php";
1524
1525 foreach ( $templates as $template ) {
1526 $template_part = $this->get_theme_file_path( 'template-parts/' . $template );
1527 if ( $template_part ) {
1528 require $template_part;
1529 break;
1530 }
1531 }
1532 }
1533 }
1534
1535
1536 /**
1537 * Finds the path for the file
1538 * It looks first in the main theme directory and then in the plugin theme directory
1539 *
1540 * @since 1.3.0
1541 *
1542 * @param $file_name
1543 * @return bool|mixed
1544 */
1545 public function get_theme_file_path( $file_name ) {
1546 $options = $this->options;
1547 $theme_name = isset( $options['theme_style'] ) ? $options['theme_style'] : '';
1548 $theme_file_paths = array();
1549 $upload_dir = wp_upload_dir();
1550
1551 //Collect the possible file path for the files
1552 //First we check if it exists in the main theme directory then in the plugin themes directory
1553 $theme_file_paths [] = get_stylesheet_directory() . '/basepress/' . $theme_name . '/' . $file_name;
1554 $theme_file_paths [] = $upload_dir['basedir'] . '/basepress/' . $theme_name . '/' . $file_name;
1555 $theme_file_paths [] = BASEPRESS_DIR . 'themes/' . $theme_name . '/' . $file_name;
1556
1557 foreach ( $theme_file_paths as $theme_file_path ) {
1558 if ( file_exists( $theme_file_path ) ) {
1559 return $theme_file_path;
1560 }
1561 }
1562
1563 return false;
1564 }
1565
1566
1567 /**
1568 * Finds the url for the file
1569 * It looks first in the main theme directory and then in the plugin theme directory
1570 *
1571 * @since 1.3.0
1572 *
1573 * @param $file_name
1574 * @return bool
1575 */
1576 public function get_theme_file_uri( $file_name ) {
1577 $options = $this->options;
1578 $theme_name = isset( $options['theme_style'] ) ? $options['theme_style'] : '';
1579 $theme_file_paths = array();
1580 $upload_dir = wp_upload_dir();
1581
1582 //Collect the possible file path for the files
1583 //First we check if it exists in the main theme directory then in the plugin themes directory
1584 $theme_file_paths [] = array( get_stylesheet_directory() . '/basepress/' . $theme_name . '/' . $file_name, get_stylesheet_directory_uri() . '/basepress/' . $theme_name . '/' . $file_name );
1585 $theme_file_paths [] = array( $upload_dir['basedir'] . '/basepress/' . $theme_name . '/' . $file_name, $upload_dir['baseurl'] . '/basepress/' . $theme_name . '/' . $file_name );
1586 $theme_file_paths [] = array( BASEPRESS_DIR . 'themes/' . $theme_name . '/' . $file_name, BASEPRESS_URI . 'themes/' . $theme_name . '/' . $file_name );
1587
1588 foreach ( $theme_file_paths as $theme_file_path ) {
1589 if ( file_exists( $theme_file_path[0] ) ) {
1590 return $theme_file_path[1];
1591 }
1592 }
1593
1594 return false;
1595 }
1596
1597 /**
1598 * Returns BasePress options array
1599 *
1600 * @since 1.0.0
1601 */
1602 public function get_options() {
1603 return $this->options;
1604 }
1605
1606
1607 /**
1608 * Returns a single option value requested by name
1609 *
1610 * @since 2.7.0
1611 *
1612 * @param $option_name
1613 * @return null
1614 */
1615 public function get_option( $option_name ){
1616 if( ! empty( $option_name ) ){
1617 return isset( $this->options[ $option_name ] ) ? $this->options[ $option_name ] : null;
1618 }
1619 return null;
1620 }
1621
1622 /**
1623 * Sets a BasePress option value
1624 *
1625 * @since 2.7.0
1626 *
1627 * @param $name
1628 * @param $value
1629 */
1630 public function set_option( $name, $value ){
1631 if( ! empty( $name ) ){
1632 $this->options[$name] = $value;
1633 }
1634 }
1635
1636 /**
1637 * Make KB menu item active when visiting any KB page
1638 *
1639 * @since 1.8.3
1640 *
1641 * @param $classes
1642 * @param $item
1643 * @return array
1644 */
1645 public function set_menu_item_active( $classes, $item ){
1646
1647 //Get Knowledge base main page ID
1648 $options = $this->get_options();
1649 $entry_page = isset( $options['entry_page'] ) ? $options['entry_page'] : '';
1650 $entry_page = apply_filters( 'basepress_entry_page', $entry_page );
1651
1652 //If we are in any KB page
1653 if( $this->is_knowledgebase ){
1654 //Make KB menu active
1655 if( $item->object_id == $entry_page ){
1656 $classes[] = 'current-menu-item';
1657 }
1658 else{
1659 //And make sure no other menu item is active
1660 $classes = array_diff( $classes, array( 'current_page_parent' ) );
1661 }
1662 }
1663
1664 // Return the corrected set of classes to be added to the menu item
1665 return $classes;
1666 }
1667
1668
1669 /**
1670 * Returns true if the KB is running from the front page
1671 *
1672 * @since 2.0.0
1673 *
1674 * @return bool
1675 */
1676 public function is_kb_on_front_page(){
1677 return isset( $this->options['entry_page'] ) && (int)apply_filters( 'basepress_entry_page', $this->options['entry_page'] ) == (int)get_option('page_on_front');
1678 }
1679
1680
1681 /**
1682 * Get word boundary to use on search queries
1683 * Since version 8.0.4 MySQL REGEX has changed so we need to test which implementation is using
1684 *
1685 * @since 2.3.0
1686 *
1687 * @return mixed|string|void|null
1688 */
1689 public function get_regex_word_boundary(){
1690 if( $this->regex_word_boundary ){
1691 return $this->regex_word_boundary;
1692 }
1693
1694 global $wpdb;
1695
1696 $this->regex_word_boundary = get_option( 'basepress_regex_word_boundary', false );
1697 if( ! $this->regex_word_boundary ){
1698 $is_icu_regexp = $wpdb->query("SELECT 1 FROM DUAL WHERE 'icu regex' REGEXP '\\\\bregex';");
1699 $this->regex_word_boundary = $is_icu_regexp ? '\\\\b' : '[[:<:]]';
1700 update_option( 'basepress_regex_word_boundary', $this->regex_word_boundary, true );
1701 }
1702 return $this->regex_word_boundary;
1703 }
1704
1705 }
1706
1707
1708 global $basepress_utils;
1709 $basepress_utils = new Basepress_Utils();
1710 }
1711