PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 2.3.6
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v2.3.6
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 / class-betterdocs-helpers.php

class-betterdocs-helpers.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 2.3.6, at includes/class-betterdocs-helpers.php

980 lines 34.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This class will provide all kind of helper methods.
4 */
5 class BetterDocs_Helper
6 {
7 /**
8 * This function is responsible for the data sanitization
9 *
10 * @param array $field
11 * @param string|array $value
12 * @return string|array
13 */
14 public static function sanitize_field($field, $value)
15 {
16 if (isset($field['sanitize']) && !empty($field['sanitize'])) {
17 if (function_exists($field['sanitize'])) {
18 $value = call_user_func($field['sanitize'], $value);
19 }
20 return $value;
21 }
22
23 if (is_array($field) && isset($field['type'])) {
24 switch ($field['type']) {
25 case 'text':
26 $value = sanitize_text_field(stripslashes($value));
27 break;
28 case 'textarea':
29 $value = sanitize_textarea_field(stripslashes($value));
30 break;
31 case 'email':
32 $value = sanitize_email($value);
33 break;
34 default:
35 return $value;
36 break;
37 }
38 } else {
39 $value = sanitize_text_field(stripslashes($value));
40 }
41
42 return $value;
43 }
44
45 /**
46 * This function is responsible for making an array sort by their key
47 * @param array $data
48 * @param string $using
49 * @param string $way
50 * @return array
51 */
52 public static function sorter($data, $using = 'time_date', $way = 'DESC')
53 {
54 if (!is_array($data)) {
55 return $data;
56 }
57
58 $new_array = [];
59
60 if ($using === 'key') {
61 if ($way !== 'ASC') {
62 krsort($data);
63 } else {
64 ksort($data);
65 }
66 } else {
67 foreach ($data as $key => $value) {
68 if (!is_array($value)) continue;
69 foreach ($value as $inner_key => $single) {
70 if ($inner_key == $using) {
71 $value['tempid'] = $key;
72 $single = self::numeric_key_gen($new_array, $single);
73 $new_array[$single] = $value;
74 }
75 }
76 }
77
78 if ($way !== 'ASC') {
79 krsort($new_array);
80 } else {
81 ksort($new_array);
82 }
83
84 if (!empty($new_array)) {
85 foreach ($new_array as $array) {
86 $index = $array['tempid'];
87 unset($array['tempid']);
88 $new_data[$index] = $array;
89 }
90 $data = $new_data;
91 }
92 }
93
94 return $data;
95 }
96
97 /**
98 * This function is responsible for generate unique numeric key for a given array.
99 *
100 * @param array $data
101 * @param integer $index
102 * @return integer
103 */
104 private static function numeric_key_gen($data, $index = 0)
105 {
106 if (isset($data[$index])) {
107 $index += 1;
108 return self::numeric_key_gen($data, $index);
109 }
110 return $index;
111 }
112
113 /**
114 * Sorting Data
115 * by their type
116 *
117 * @param array $value
118 * @param string $key
119 * @return void
120 */
121 public static function sortBy(&$value, $key = 'comments')
122 {
123 switch ($key) {
124 case 'comments':
125 return self::sorter($value, 'key', 'DESC');
126 break;
127 default:
128 return self::sorter($value, 'timestamp', 'DESC');
129 break;
130 }
131 }
132
133 /**
134 * Human Readable Time Diff
135 *
136 * @param boolean $time
137 * @return void
138 */
139 public static function get_timeago_html($time = false)
140 {
141 if (!$time) {
142 return;
143 }
144
145 $offset = get_option('gmt_offset'); // Time offset in hours
146 $local_time = $time + ($offset * 60 * 60); // added offset in seconds
147 $time = human_time_diff($local_time, current_time('timestamp'));
148 ob_start();
149 echo '<small> ' . esc_html__('About', 'betterdocs') . ' ' . esc_html($time) . ' ' . esc_html__('ago', 'betterdocs') . ' </small>';
150 $time_ago = ob_get_clean();
151 return $time_ago;
152 }
153
154 /**
155 * Get all post types
156 *
157 * @param array $exclude
158 * @return void
159 */
160 public static function post_types($exclude = array())
161 {
162 $post_types = get_post_types(array(
163 'public' => true,
164 'show_ui' => true
165 ), 'objects');
166
167 unset($post_types['attachment']);
168
169 if (count($exclude)) {
170 foreach ($exclude as $type) {
171 if (isset($post_types[$type])) {
172 unset($post_types[$type]);
173 }
174 }
175 }
176
177 return apply_filters('betterdocs_post_types', $post_types);
178 }
179
180 /**
181 * Get all taxonomies
182 *
183 * @param string $post_type
184 * @param array $exclude
185 * @return void
186 */
187 public static function taxonomies($post_type = '', $exclude = array())
188 {
189 if (empty($post_type)) {
190 $taxonomies = get_taxonomies(
191 array(
192 'public' => true,
193 '_builtin' => false
194 ),
195 'objects'
196 );
197 } else {
198
199 $taxonomies = get_object_taxonomies($post_type, 'objects');
200 }
201
202 $data = array();
203
204 if (is_array($taxonomies)) {
205 foreach ($taxonomies as $tax_slug => $tax) {
206 if (!$tax->public || !$tax->show_ui) {
207 continue;
208 }
209 if (in_array($tax_slug, $exclude)) {
210 continue;
211 }
212 $data[$tax_slug] = $tax;
213 }
214 }
215
216 return apply_filters('betterdocs_loop_taxonomies', $data, $taxonomies, $post_type);
217 }
218
219 public static function list_svg()
220 {
221 $html = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="0.86em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 1536 1792"><path d="M1468 380q28 28 48 76t20 88v1152q0 40-28 68t-68 28H96q-40 0-68-28t-28-68V96q0-40 28-68T96 0h896q40 0 88 20t76 48zm-444-244v376h376q-10-29-22-41l-313-313q-12-12-41-22zm384 1528V640H992q-40 0-68-28t-28-68V128H128v1536h1280zM384 800q0-14 9-23t23-9h704q14 0 23 9t9 23v64q0 14-9 23t-23 9H416q-14 0-23-9t-9-23v-64zm736 224q14 0 23 9t9 23v64q0 14-9 23t-23 9H416q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h704zm0 256q14 0 23 9t9 23v64q0 14-9 23t-23 9H416q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h704z"/></svg>';
222 return $html;
223 }
224
225 public static function arrow_right_svg()
226 {
227 $html = '<svg class="toggle-arrow arrow-right" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="0.48em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 608 1280"><g transform="translate(608 0) scale(-1 1)"><path d="M595 288q0 13-10 23L192 704l393 393q10 10 10 23t-10 23l-50 50q-10 10-23 10t-23-10L23 727q-10-10-10-23t10-23l466-466q10-10 23-10t23 10l50 50q10 10 10 23z"/></g></svg>';
228 return $html;
229 }
230
231 public static function arrow_down_svg()
232 {
233 $html = '<svg class="toggle-arrow arrow-down" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="0.8em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 1024 1280"><path d="M1011 480q0 13-10 23L535 969q-10 10-23 10t-23-10L23 503q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393l393-393q10-10 23-10t23 10l50 50q10 10 10 23z"/></svg>';
234 return $html;
235 }
236
237 public static function get_tax($tax = '')
238 {
239 global $wp_query;
240 if (is_tax('knowledge_base')) {
241 $get_tax = $wp_query->tax_query->queried_terms;
242 if (array_key_exists("doc_category", $get_tax)) {
243 $tax = 'doc_category';
244 } else {
245 $tax = 'knowledge_base';
246 }
247 } elseif (is_tax('doc_category')) {
248 $tax = 'doc_category';
249 }
250
251 return $tax;
252 }
253
254 public static function list_query_arg($post_type, $multiple_kb, $tax_slug, $posts_per_grid, $orderby, $order = 'ASC', $kb_slug='')
255 {
256 if ($post_type === 'docs_any') {
257 $args = array(
258 'post_type' => 'docs',
259 'post_status' => 'any',
260 );
261 } else {
262 $args = array(
263 'post_type' => $post_type
264 );
265 }
266
267 $tax_query = array(
268 array(
269 'taxonomy' => 'doc_category',
270 'field' => 'slug',
271 'terms' => $tax_slug,
272 'operator' => 'AND',
273 'include_children' => false
274 ),
275 );
276
277 $args['tax_query'] = apply_filters('betterdocs_list_tax_query_arg', $tax_query, $multiple_kb, $tax_slug, $kb_slug);
278
279 if ($posts_per_grid) {
280 $args['posts_per_page'] = $posts_per_grid;
281 }
282
283 if ($orderby != 'betterdocs_order') {
284 if ($orderby == '1') {
285 $args['orderby'] = 'title';
286 } else {
287 $args['orderby'] = $orderby;
288 }
289 $args['order'] = $order;
290 }
291 return $args;
292 }
293
294 public static function count_kb()
295 {
296 $result = array();
297 $kbs = get_terms(array(
298 'taxonomy' => 'knowledge_base',
299 'hide_empty' => false,
300 'fields' => 'id=>slug'
301 ));
302
303 $cats = get_terms(array(
304 'taxonomy' => 'doc_category',
305 'hide_empty' => false,
306 'fields' => 'id=>slug'
307 ));
308
309 foreach ($kbs as $kb) {
310 foreach ($cats as $cat) {
311 $args = array(
312 'post_type' => 'docs',
313 'post_status' => 'publish',
314 'tax_query' => array(
315 'relation' => 'AND',
316 array(
317 'taxonomy' => 'knowledge_base',
318 'field' => 'slug',
319 'terms' => array($kb),
320 ),
321 array(
322 'taxonomy' => 'doc_category',
323 'field' => 'slug',
324 'terms' => array($cat),
325 ),
326 ),
327 );
328 $query = new WP_Query($args);
329 $result[$kb][$cat] = $query->post_count;
330 }
331 }
332 return $result;
333 }
334
335 public static function count_category($kb_slug, $cat_slug)
336 {
337 $args = array(
338 'post_type' => 'docs',
339 'post_status' => 'publish',
340 );
341
342 $taxes = array('knowledge_base', 'doc_category');
343 foreach ($taxes as $tax) {
344 $terms = get_terms($tax);
345
346 foreach ($terms as $term)
347 $tax_map[$tax][$term->slug] = $term->term_taxonomy_id;
348 }
349
350 $args['tax_query'] = array(
351 'relation' => 'AND',
352 array(
353 'taxonomy' => 'knowledge_base',
354 'field' => 'term_taxonomy_id',
355 'terms' => array($tax_map['knowledge_base'][$kb_slug]),
356 'operator' => 'IN',
357 'include_children' => false,
358 ),
359 array(
360 'taxonomy' => 'doc_category',
361 'field' => 'term_taxonomy_id',
362 'operator' => 'IN',
363 'terms' => array($tax_map['doc_category'][$cat_slug]),
364 'include_children' => false,
365 ),
366 );
367
368 $query = new WP_Query($args);
369 $count = $query->found_posts;
370 return $count;
371 }
372
373 public static function taxonomy_object($multiple_kb, $terms, $order, $orderby = "name", $kb_slug='', $nested_subcategory=false)
374 {
375 global $wp_query;
376 $terms_object = array(
377 'hide_empty' => true,
378 'taxonomy' => 'doc_category'
379 );
380
381 if ( $orderby == 'betterdocs_order' ) {
382 $terms_object['meta_key'] = 'doc_category_order';
383 $terms_object['orderby'] = 'meta_value_num';
384 $terms_object['order'] = 'ASC';
385 } else if ($orderby == 1) {
386 $terms_object['orderby'] = 'name';
387 $terms_object['order'] = $order;
388 } else {
389 $terms_object['orderby'] = $orderby;
390 $terms_object['order'] = $order;
391 }
392
393 if ($nested_subcategory == true) {
394 $terms_object['parent'] = 0;
395 }
396
397 if ($wp_query->query === NULL || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] != 'docs')) {
398 $terms_object['number'] = 4;
399 }
400
401 $meta_query = '';
402 $terms_object['meta_query'] = apply_filters('betterdocs_taxonomy_object_meta_query', $meta_query, $multiple_kb, $kb_slug);
403
404 if ($terms) {
405 unset($terms_object['parent']);
406 }
407
408 if ($terms) {
409 $terms_object['include'] = explode(',', $terms);
410 $terms_object['orderby'] = 'include';
411 }
412
413 return get_terms(apply_filters('betterdocs_category_terms_object', $terms_object));
414 }
415
416 public static function child_taxonomy_terms($term_id, $multiple_kb, $orderby = "name", $order = "", $kb_slug = '')
417 {
418 global $wp_query;
419 $terms_object = array(
420 'parent' => $term_id
421 );
422
423 if ( $orderby == 'betterdocs_order' ) {
424 $terms_object['meta_key'] = 'doc_category_order';
425 $terms_object['orderby'] = 'meta_value_num';
426 $terms_object['order'] = 'ASC';
427 } else if ( $orderby == 1 ) {
428 $terms_object['orderby'] = 'name';
429 $terms_object['order'] = $order;
430 } else {
431 $terms_object['orderby'] = $orderby;
432 $terms_object['order'] = $order;
433 }
434
435 if ($wp_query->query === NULL || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] != 'docs')) {
436 $terms_object['number'] = 1;
437 }
438
439 $meta_query = '';
440 $terms_object['meta_query'] = apply_filters('betterdocs_child_taxonomy_meta_query', $meta_query, $multiple_kb, $kb_slug);
441 return get_terms('doc_category', apply_filters('betterdocs_category_terms_object', $terms_object));
442 }
443
444 public static function term_permalink($texanomy, $term_slug) {
445 $get_term_link = get_term_link( $term_slug, $texanomy );
446 return apply_filters( 'betterdocs_cat_term_permalink', $get_term_link, $term_slug, $texanomy );
447 }
448
449 public static function get_prev($array, $key) {
450 $currentKey = array_search($key, $array);
451 if ($currentKey > 0 || $currentKey != 0) {
452 $nextKey = $currentKey - 1;
453 $prev_post = $array[$nextKey];
454 $nav = '<a rel="prev" class="next-post" href="'.get_post_permalink($prev_post).'"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="42px" viewBox="0 0 50 50" version="1.1"><g id="surface1"><path style=" " d="M 11.957031 13.988281 C 11.699219 14.003906 11.457031 14.117188 11.28125 14.308594 L 1.015625 25 L 11.28125 35.691406 C 11.527344 35.953125 11.894531 36.0625 12.242188 35.976563 C 12.589844 35.890625 12.867188 35.625 12.964844 35.28125 C 13.066406 34.933594 12.972656 34.5625 12.71875 34.308594 L 4.746094 26 L 48 26 C 48.359375 26.003906 48.695313 25.816406 48.878906 25.503906 C 49.058594 25.191406 49.058594 24.808594 48.878906 24.496094 C 48.695313 24.183594 48.359375 23.996094 48 24 L 4.746094 24 L 12.71875 15.691406 C 13.011719 15.398438 13.09375 14.957031 12.921875 14.582031 C 12.753906 14.203125 12.371094 13.96875 11.957031 13.988281 Z "></path></g></svg>'.wp_kses(get_the_title($prev_post), BETTERDOCS_KSES_ALLOWED_HTML).'</a>';
455 } else {
456 $nav = '';
457 }
458 return $nav;
459 }
460
461 public static function get_next($array, $key) {
462 $currentKey = array_search($key, $array);
463 if (end($array) != $array[$currentKey]) {
464 $nextKey = $currentKey + 1;
465 $next_post = $array[$nextKey];
466 $nav = '<a rel="next" class="next-post" href="'.get_post_permalink($next_post).'">'.wp_kses(get_the_title($next_post), BETTERDOCS_KSES_ALLOWED_HTML).'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="42px" viewBox="0 0 50 50" version="1.1"><g id="surface1"><path style=" " d="M 38.035156 13.988281 C 37.628906 13.980469 37.257813 14.222656 37.09375 14.59375 C 36.933594 14.96875 37.015625 15.402344 37.300781 15.691406 L 45.277344 24 L 2.023438 24 C 1.664063 23.996094 1.328125 24.183594 1.148438 24.496094 C 0.964844 24.808594 0.964844 25.191406 1.148438 25.503906 C 1.328125 25.816406 1.664063 26.003906 2.023438 26 L 45.277344 26 L 37.300781 34.308594 C 36.917969 34.707031 36.933594 35.339844 37.332031 35.722656 C 37.730469 36.105469 38.363281 36.09375 38.746094 35.691406 L 49.011719 25 L 38.746094 14.308594 C 38.5625 14.109375 38.304688 13.996094 38.035156 13.988281 Z "></path></g></svg></a>';
467 } else {
468 $nav = '';
469 }
470 return $nav;
471 }
472
473 public static function get_postcount($term, $multiple_kb, $total_term_count = 0)
474 {
475 $taxonomy = 'doc_category';
476 $args = array(
477 'child_of' => $term->term_id,
478 );
479 $tax_terms = get_terms($taxonomy, $args);
480
481 if ( ! is_wp_error( $tax_terms ) && $tax_terms) {
482 foreach ($tax_terms as $tax_term) {
483 $total_term_count += $tax_term->count;
484 }
485 }
486
487 return apply_filters('betterdocs_postcount', $total_term_count, $multiple_kb, $term->term_id, $term->slug, $term->count);
488 }
489
490 public static function faq_category_terms( $terms_include, $terms_exclude = '' )
491 {
492 $args = array(
493 'taxonomy' => 'betterdocs_faq_category',
494 'hide_empty' => true,
495 'include' => $terms_include,
496 'exclude' => $terms_exclude,
497 'meta_key' => 'order',
498 'orderby' => 'meta_value_num',
499 'order' => 'ASC',
500 'meta_query' => array(
501 array(
502 'key' => 'status',
503 'value' => 1,
504 'compare' => '=='
505 )
506 )
507 );
508
509 if( $terms_include === 'all' ) {
510 unset($args['include']);
511 unset($args['exclude']);
512 }
513
514 if( empty( $terms_exclude ) ){
515 unset($args['exclude']);
516 }
517
518 if( empty( $terms_include ) ) {
519 unset($args['include']);
520 }
521
522 return get_terms(apply_filters('betterdocs_faq_category_terms_object', $args));
523 }
524
525 public static function faq_args( $term_id )
526 {
527 global $wpdb;
528
529 $args = array(
530 'post_type' => 'betterdocs_faq',
531 'post_status' => 'publish',
532 'tax_query' => array(
533 array(
534 'taxonomy' => 'betterdocs_faq_category',
535 'field' => 'term_id',
536 'terms' => $term_id,
537 'operator' => 'AND'
538 )
539 ),
540 'posts_per_page' => -1,
541 );
542
543 $faq_order = get_term_meta($term_id, '_betterdocs_faq_order', true);
544
545 if ( !empty( $faq_order ) ) {
546 $faq_order = explode(',', $faq_order);
547
548 $new_ids = [];
549 $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}term_relationships WHERE term_taxonomy_id = $term_id");
550
551 if ( !is_null( $results ) && !empty( $results ) && is_array( $results ) ) {
552 $object_ids = array_filter( $results, function ( $value ) use ( $faq_order ) {
553 return !in_array( $value->object_id, $faq_order );
554 });
555
556 if ( ! empty( $object_ids ) ) {
557 array_walk( $object_ids, function ( $value ) use ( &$new_ids ) {
558 $new_ids[] = $value->object_id;
559 });
560 }
561 }
562
563 $args['orderby'] = 'post__in';
564 $args['post__in'] = array_merge($new_ids, $faq_order);
565 }
566
567 return $args;
568 }
569
570 const ALLOWED_HTML_TAGS = [
571 'article',
572 'aside',
573 'div',
574 'footer',
575 'h1',
576 'h2',
577 'h3',
578 'h4',
579 'h5',
580 'h6',
581 'header',
582 'main',
583 'nav',
584 'p',
585 'section',
586 'span',
587 ];
588
589 /**
590 * validate_html_tag
591 * @param $tag
592 * @return mixed|string
593 */
594 public static function html_tag( $tag ){
595 return in_array( strtolower( $tag ), self::ALLOWED_HTML_TAGS ) ? $tag : 'div';
596 }
597
598 public static function feedback_form(){
599 $fform_title = BetterDocs_DB::get_settings('feedback_form_title');
600 $output = betterdocs_generate_output();
601 $html = '<'. $output['betterdocs_feedback_form_title_tag'] .' class="feedback-form-title">';
602 $html .= ( $fform_title ) ? stripslashes($fform_title) : esc_html__( 'How can we help?', 'betterdocs' );
603 $html .= '</'. $output['betterdocs_feedback_form_title_tag'] .'>';
604 $html .= '<div class="modal-content-inner">';
605 $html .= do_shortcode('[betterdocs_feedback_form]');
606 $html .= '</div>';
607 echo $html;
608 }
609
610 /**
611 * return true if templates from BetterDocs to load assets
612 */
613 public static function is_templates() {
614 if(is_plugin_active('elementor/elementor.php') && is_plugin_active('elementor-pro/elementor-pro.php')){
615 $document = \Elementor\Plugin::$instance->documents->get( get_the_ID() );
616 if (\Elementor\Plugin::instance()->editor->is_edit_mode() || (( get_post_meta(get_the_ID(), '_elementor_template_type', true)) && \Elementor\Plugin::$instance->documents->get( get_the_ID() )->is_built_with_elementor() )) {
617 return true;
618 }
619 }
620
621 $tax = self::get_tax();
622 if (is_post_type_archive('docs') || $tax === 'knowledge_base' || $tax === 'doc_category' || is_singular('docs')) {
623 return true;
624 }
625 return false;
626 }
627
628 public static function term_options( $taxonomy, $selected='', $exclude_child_terms = 'false' )
629 {
630 $html = '';
631
632 $terms_object = array(
633 'taxonomy' => $taxonomy,
634 'hide_empty' => false
635 );
636
637 if( $exclude_child_terms === 'true' ) {
638 $terms_object['parent'] = 0;
639 }
640
641 $taxonomy_objects = get_terms(apply_filters('betterdocs_category_terms_object', $terms_object));
642
643 if ($taxonomy_objects && !is_wp_error($taxonomy_objects)) :
644 foreach ($taxonomy_objects as $term) :
645 $sel = ($term->slug === $selected) ? ' selected' : '';
646 $html .= '<option value="' . $term->slug . '"' . $sel . '>' . $term->name . '</option>';
647 endforeach;
648 endif;
649 return $html;
650 }
651
652 public static function permalink_stracture($docs_slug, $permalink)
653 {
654 $permalink_arr = explode('%', $permalink);
655 if ($permalink_arr[0] == '/') {
656 $permalink = $docs_slug . $permalink;
657 flush_rewrite_rules(); // this rewrite rules is temporary for some specific existing user data
658 } else if ($permalink_arr[0] == '') {
659 $permalink = $docs_slug . '/' . $permalink;
660 flush_rewrite_rules(); // this rewrite rules is temporary for some specific existing user data
661 }
662 return $permalink;
663 }
664
665 public static function search_insert($search_input, $input_not_found)
666 {
667 global $wpdb;
668 $search = $wpdb->get_results(
669 $wpdb->prepare(
670 "SELECT *
671 FROM {$wpdb->prefix}betterdocs_search_keyword
672 WHERE keyword = %s",
673 $search_input
674 )
675 );
676
677 if (!empty($search)) {
678 $search_log = $wpdb->get_results(
679 $wpdb->prepare(
680 "SELECT *
681 FROM {$wpdb->prefix}betterdocs_search_log
682 WHERE created_at = %s AND keyword_id = %d",
683 date('Y-m-d'), $search[0]->id
684 )
685 );
686
687 if ( !empty($search_log) ) {
688 if (!empty($input_not_found)) {
689 $tbl_field = 'not_found_count';
690 $count = $search_log[0]->not_found_count + 1;
691 } else {
692 $tbl_field = 'count';
693 $count = $search_log[0]->count + 1;
694 }
695 $wpdb->query(
696 $wpdb->prepare(
697 "UPDATE {$wpdb->prefix}betterdocs_search_log
698 SET ".$tbl_field." = ".$count."
699 WHERE created_at = %s AND keyword_id = %d",
700 $search_log[0]->created_at, $search_log[0]->keyword_id
701 )
702 );
703 } else {
704 if (!empty($input_not_found)) {
705 $count = 0;
706 $not_found_count = 1;
707 } else {
708 $count = 1;
709 $not_found_count = 0;
710 }
711 $wpdb->query(
712 $wpdb->prepare(
713 "INSERT INTO {$wpdb->prefix}betterdocs_search_log
714 ( keyword_id, count, not_found_count, created_at )
715 VALUES ( %d, %d, %d, %s )",
716 array(
717 $search[0]->id,
718 $count,
719 $not_found_count,
720 date('Y-m-d')
721 )
722 )
723 );
724 }
725 } else {
726 $insert = $wpdb->query(
727 $wpdb->prepare(
728 "INSERT INTO {$wpdb->prefix}betterdocs_search_keyword
729 ( keyword )
730 VALUES ( %s )",
731 array(
732 $search_input
733 )
734 )
735 );
736
737 if ($insert) {
738 if (!empty($input_not_found)) {
739 $count = 0;
740 $not_found_count = 1;
741 } else {
742 $count = 1;
743 $not_found_count = 0;
744 }
745 $wpdb->query(
746 $wpdb->prepare(
747 "INSERT INTO {$wpdb->prefix}betterdocs_search_log
748 ( keyword_id, count, not_found_count, created_at )
749 VALUES ( %d, %d, %d, %s )",
750 array(
751 $wpdb->insert_id,
752 $count,
753 $not_found_count,
754 date('Y-m-d')
755 )
756 )
757 );
758 }
759 }
760 }
761
762 /**
763 * This function returns doc tags markup
764 *
765 * @param int $post_id
766 * @param string $taxonomy
767 * @return string | array
768 */
769 public static function get_post_tags_markup( $post_id, $taxonomy = 'doc_tag' ) {
770 $tag_links = array();
771 $post_tags = wp_get_object_terms( $post_id, $taxonomy );
772
773 if( ! empty( $post_tags ) || ! is_wp_error( $post_tags ) ) {
774 foreach( $post_tags as $term ) {
775 $term_link = get_term_link( $term->slug, 'doc_tag' );
776 $term_name = isset( $term->name ) ? esc_html( $term->name ) : '';
777 array_push( $tag_links, '<a href="' .$term_link. '">' .$term_name. '</a>');
778 }
779 $tag_links = '<div class="betterdocs-tags">'.join( ', ', $tag_links ).'</div>';
780 }
781
782 return $tag_links;
783 }
784
785 /**
786 * Get the terms that have posts greater than 0 & Count Change Based On Doc Category Page
787 */
788 public static function get_doc_terms( $multiple_kb, $order, $orderby, $tax_page, $current_term_id, $nested_subcategory, $kb_slug = '' ) {
789 $terms_object = array(
790 'hide_empty' => true,
791 'taxonomy' => 'doc_category'
792 );
793
794 $filtered_terms = array();
795
796 if ( $orderby == 'betterdocs_order' ) {
797 $terms_object['meta_key'] = 'doc_category_order';
798 $terms_object['orderby'] = 'meta_value_num';
799 $terms_object['order'] = 'ASC';
800 } else if ($orderby == 1) {
801 $terms_object['orderby'] = 'name';
802 $terms_object['order'] = $order;
803 } else {
804 $terms_object['orderby'] = $orderby;
805 $terms_object['order'] = $order;
806 }
807
808 if ($nested_subcategory == true) {
809 $terms_object['parent'] = 0;
810 }
811
812 $meta_query = '';
813
814 $terms_object['meta_query'] = apply_filters('betterdocs_taxonomy_object_meta_query', $meta_query, $multiple_kb, $kb_slug);
815
816 $terms = get_terms( apply_filters('betterdocs_category_terms_object', $terms_object ) );
817
818 if ( ! is_wp_error( $terms ) ) {
819 foreach( $terms as $term ) {
820 // If inside doc category then change the count of terms based mkb enable/disable || If outside doc category page then change the count of terms based mkb enable/disable
821 if( $tax_page == 'doc_category' ) {
822 $term_count = isset( $term->count ) ? $term->count : '';
823 $term_doc_count = betterdocs_get_postcount( $term_count, $term->term_id, $nested_subcategory );
824 $term_doc_count = apply_filters('betterdocs_postcount', $term_doc_count, $multiple_kb, $term->term_id, $term->slug, $term_count, $nested_subcategory, $kb_slug);
825 } else {
826 $term_count = isset( $term->count ) ? $term->count : '';
827 $kb_slug = $multiple_kb && get_term_meta( $term->term_id,'doc_category_knowledge_base', true ) == true ? get_term_meta( $term->term_id,'doc_category_knowledge_base', true )[0] : '';
828 $term_doc_count = betterdocs_get_postcount( $term_count, $term->term_id, $nested_subcategory );
829 $term_doc_count = apply_filters('betterdocs_postcount', $term_doc_count, $multiple_kb, $term->term_id, $term->slug, $term_count, $nested_subcategory, $kb_slug);
830 }
831 // After fetching the original count of the terms based on mkb enable/disable, include terms that have posts greater than 0
832 if( $term_doc_count > 0 ) {
833 array_push( $filtered_terms, $term );
834 }
835 }
836 }
837
838 // Delete the current category when inside doc category page, this is applicable when mkb enable/disable
839 if( in_array( $current_term_id, array_column( $filtered_terms, 'term_id' ) ) && $tax_page == 'doc_category' ) {
840 $current_term_key = array_search( $current_term_id, array_column( $filtered_terms, 'term_id' ) );
841 unset($filtered_terms[$current_term_key]);
842 $filtered_terms = array_values( $filtered_terms );
843 }
844
845 return $filtered_terms;
846 }
847
848 /**
849 * Formating Number in a Nice way
850 * @since 1.2.1
851 * @param int|string $n
852 * @return string
853 */
854 public static function nice_number($n) {
855 $temp_number = str_replace(",", "", $n);
856 if (!empty($temp_number)) {
857 $n = (0 + $temp_number);
858 } else {
859 $n = $n;
860 }
861 if (!is_numeric($n)) return 0;
862 $is_neg = false;
863 if ($n < 0) {
864 $is_neg = true;
865 $n = abs($n);
866 }
867 $number = 0;
868 $suffix = '';
869 switch (true) {
870 case $n >= 1000000000000:
871 $number = ($n / 1000000000000);
872 $suffix = $n > 1000000000000 ? 'T+' : 'T';
873 break;
874 case $n >= 1000000000:
875 $number = ($n / 1000000000);
876 $suffix = $n > 1000000000 ? 'B+' : 'B';
877 break;
878 case $n >= 1000000:
879 $number = ($n / 1000000);
880 $suffix = $n > 1000000 ? 'M+' : 'M';
881 break;
882 case $n >= 1000:
883 $number = ($n / 1000);
884 $suffix = $n > 1000 ? 'K+' : 'K';
885 break;
886 default:
887 $number = $n;
888 break;
889 }
890 if (strpos($number, '.') !== false && strpos($number, '.') >= 0) {
891 $number = number_format($number, 1);
892 }
893 return ($is_neg ? '-' : '') . $number . $suffix;
894 }
895
896 /* validate html tag
897 * @param $tag
898 * @return mixed|string
899 */
900 public static function validate_html_tag( $tag ){
901 $allowed_tags = [
902 'article',
903 'aside',
904 'div',
905 'footer',
906 'h1',
907 'h2',
908 'h3',
909 'h4',
910 'h5',
911 'h6',
912 'header',
913 'main',
914 'nav',
915 'p',
916 'section',
917 'span',
918 ];
919 return in_array( strtolower( $tag ), $allowed_tags ) ? $tag : 'div';
920 }
921
922
923 public static function faq_term_list() {
924 $args = array(
925 'taxonomy' => 'betterdocs_faq_category',
926 'hide_empty' => true,
927 'orderby' => 'name',
928 'order' => 'ASC',
929 'meta_query' => array(
930 array(
931 'key' => 'status',
932 'value' => 1,
933 'compare' => '=='
934 )
935 )
936 );
937
938 $new_list = array();
939
940 $faq_terms = get_terms( $args );
941
942 if( ! is_wp_error( $faq_terms ) ) {
943 $new_list['all'] = 'Show All';
944 foreach( $faq_terms as $term ) {
945 $new_list[$term->term_id] = $term->name;
946 }
947 }
948
949 return $new_list;
950 }
951
952 public static function faq_widget_term_list() {
953 $args = array(
954 'taxonomy' => 'betterdocs_faq_category',
955 'hide_empty' => true,
956 'orderby' => 'name',
957 'order' => 'ASC',
958 'meta_query' => array(
959 array(
960 'key' => 'status',
961 'value' => 1,
962 'compare' => '=='
963 )
964 )
965 );
966
967 $new_list = array();
968
969 $faq_terms = get_terms( $args );
970
971 if( ! is_wp_error( $faq_terms ) ) {
972 foreach( $faq_terms as $term ) {
973 $new_list[$term->term_id] = $term->name;
974 }
975 }
976
977 return $new_list;
978 }
979 }
980