PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 1.7.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v1.7.3
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 / elementor / class-betterdocs-elementor.php

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

709 lines 22.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 use Elementor\Controls_Manager;
3 use ElementorPro\Plugin;
4 use ElementorPro\Modules\ThemeBuilder as ThemeBuilder;
5
6 /**
7 * Working with elementor plugin
8 *
9 *
10 * @since 1.3.0
11 * @package BetterDocs
12 * @subpackage BetterDocs/elementor
13 * @author WPDeveloper <support@wpdeveloper.net>
14 */
15 class BetterDocs_Elementor
16 {
17 public static $pro_active;
18
19 /**
20 * Short Description. (use period)
21 *
22 * Long Description.
23 *
24 * @since 1.3.0
25 */
26 public static function init()
27 {
28 self::$pro_active = is_plugin_active('betterdocs-pro/betterdocs-pro.php');
29 add_action('elementor/editor/before_enqueue_scripts', [__CLASS__, 'editor_enqueue_scripts']);
30 if (is_plugin_active('betterdocs/betterdocs.php')) {
31 add_action('elementor/documents/register', [__CLASS__, 'register_singel_documents_page']);
32 add_action('elementor/documents/register', [__CLASS__, 'register_doc_category_archive']);
33 add_filter('elementor/theme/need_override_location', [__CLASS__, 'theme_template_include'], 10, 2);
34 add_action('elementor/widgets/widgets_registered', [__CLASS__, 'register_widgets']);
35 add_action('betterdocs/elementor/widgets/query', [__CLASS__, 'betterdocs_query'], 10, 2);
36 add_filter('elementor/editor/localize_settings', [__CLASS__, 'promote_pro_elements']);
37 add_action('wp_enqueue_scripts', [__CLASS__, 'editor_load_asset']);
38 if (is_plugin_active('elementor-pro/elementor-pro.php')) {
39 add_action('elementor/init', [__CLASS__, 'load_widget_file']);
40 add_action('elementor/theme/register_conditions', [__CLASS__, 'register_conditions']);
41 }
42 }
43
44 add_action('init', [__CLASS__, '__betterdocs_init'], -999);
45 }
46
47 /**
48 *
49 * Mange all widget for single docs
50 *
51 * @return string[]
52 * @since 1.3.0
53 */
54 public static function get_widget_list()
55 {
56 $widget_arr = [
57 'betterdocs-elementor-breadcrumbs' => 'BetterDocs_Elementor_Breadcrumbs',
58 'betterdocs-elementor-title' => 'BetterDocs_Elementor_Title',
59 'betterdocs-elementor-content' => 'BetterDocs_Elementor_Content',
60 'betterdocs-elementor-sidebar' => 'BetterDocs_Elementor_Sidebar',
61 'betterdocs-elementor-navigation' => 'BetterDocs_Elementor_Navigation',
62 'betterdocs-elementor-doc-share' => 'BetterDocs_Elementor_Doc_Share',
63 'betterdocs-elementor-feedback' => 'BetterDocs_Elementor_Feedback',
64 'betterdocs-elementor-doc-date' => 'BetterDocs_Elementor_Doc_Date',
65 'betterdocs-elementor-search-form' => 'BetterDocs_Elementor_Search_Form',
66 'betterdocs-elementor-toc' => 'BetterDocs_Elementor_Toc',
67 'betterdocs-elementor-category-archive-list' => 'BetterDocs_Category_Archive_List',
68 'betterdocs-elementor-category-grid' => 'BetterDocs_Elementor_Category_Grid',
69 'betterdocs-elementor-category-box' => 'BetterDocs_Elementor_Category_Box'
70 ];
71
72 return $widget_arr;
73 }
74
75 /**
76 *
77 * Load asset for elementor icon
78 *
79 * @since 1.3.0
80 */
81 public static function editor_enqueue_scripts()
82 {
83 wp_enqueue_style(
84 'betterdocs-el-icon',
85 BETTERDOCS_ADMIN_URL . 'assets/css/betterdocs-el-icon.css',
86 false,
87 BETTERDOCS_VERSION
88 );
89 }
90
91 public static function editor_load_asset()
92 {
93 wp_enqueue_style(
94 'betterdocs-el-edit',
95 BETTERDOCS_ADMIN_URL . 'assets/css/betterdocs-el-edit.css',
96 false,
97 BETTERDOCS_VERSION
98 );
99
100 wp_enqueue_script(
101 'betterdocs-el-promotion',
102 BETTERDOCS_ADMIN_URL . 'assets/js/promotion.js',
103 ['jquery'],
104 BETTERDOCS_VERSION,
105 true
106 );
107
108 if (!self::$pro_active) {
109 wp_enqueue_script(
110 'betterdocs-el-editor',
111 BETTERDOCS_ADMIN_URL . 'assets/js/betterdocs-el-editor.js',
112 ['jquery'],
113 BETTERDOCS_VERSION,
114 true
115 );
116 }
117 }
118
119 public static function load_widget_file()
120 {
121 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/template-query.php';
122 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/betterdocs-single-docs.php';
123 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/betterdocs-doc-archive.php';
124 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/betterdocs-archive-condition.php';
125 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/docs-page.php';
126 self::__register_tag();
127
128 //load widget file
129 foreach (self::get_widget_list() as $key => $value) {
130 require_once BETTERDOCS_DIR_PATH . "includes/elementor/widgets/$key.php";
131 }
132 }
133
134 public static function register_singel_documents_page($documents_manager)
135 {
136 if (class_exists('BetterDocs_Single_Docs')) {
137 $documents_manager->register_document_type('docs', BetterDocs_Single_Docs::get_class_full_name());
138 }
139 }
140
141 public static function register_doc_category_archive($documents_manager)
142 {
143 if (class_exists('Betterdocs_Doc_Archive')) {
144 $documents_manager->register_document_type('doc-archive', Betterdocs_Doc_Archive::get_class_full_name());
145 }
146 }
147
148 /**
149 * @param Conditions_Manager $conditions_manager
150 */
151 public static function register_conditions($conditions_manager)
152 {
153 $betterdocs_condition = new Betterdocs_Archive_Condition();
154
155 $conditions_manager->get_condition('general')->register_sub_condition($betterdocs_condition);
156 }
157
158 public static function theme_template_include($need_override_location, $location)
159 {
160 if (is_singular(['docs']) && 'single' === $location) {
161 $need_override_location = true;
162 }
163
164 return $need_override_location;
165 }
166
167 public static function register_widgets($widgets_manager)
168 {
169 foreach (self::get_widget_list() as $value) {
170 if (class_exists($value)) {
171 $widgets_manager->register_widget_type(new $value);
172 }
173 }
174 }
175
176 public static function __register_tag()
177 {
178 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/widgets/betterdocs-elementor-title-tag.php';
179
180 $module = Plugin::elementor()->dynamic_tags;
181 $module->register_tag(new BetterDocs_Elementor_Title_Tag());
182 }
183
184 public static function promote_pro_elements($config)
185 {
186 if (is_plugin_active('betterdocs-pro/betterdocs-pro.php')) {
187 return $config;
188 }
189
190 $promotion_widgets = [];
191
192 if (isset($config['promotionWidgets'])) {
193 $promotion_widgets = $config['promotionWidgets'];
194 }
195
196 $combine_array = array_merge($promotion_widgets, [
197 [
198 'name' => 'betterdocs-elementor-reactions',
199 'title' => __('Doc Reactions', 'betterdocs'),
200 'icon' => 'betterdocs-icon-Reactions',
201 'categories' => '["betterdocs-elements"]',
202 ],
203 [
204 'name' => 'betterdocs-multiple-kb',
205 'title' => __('BetterDocs Multiple KB', 'betterdocs'),
206 'icon' => 'betterdocs-icon-category-box',
207 'categories' => '["docs-archive"]',
208 ],
209 ]);
210
211 $config['promotionWidgets'] = $combine_array;
212
213 return $config;
214 }
215
216 public static function __betterdocs_init()
217 {
218 add_action('elementor/init', array(__CLASS__, 'register_bd_template_instance'), 20);
219 if (defined('Elementor\Api::LIBRARY_OPTION_KEY')) {
220 add_filter('option_' . Elementor\Api::LIBRARY_OPTION_KEY, array(__CLASS__, 'prepend_categories'));
221 }
222 add_action('elementor/ajax/register_actions', array(__CLASS__, 'modified_ajax_action'), 20);
223 }
224
225 public static function register_bd_template_instance()
226 {
227 require_once BETTERDOCS_DIR_PATH . 'includes/elementor/betterdocs-template-source.php';
228
229 $elementor = Elementor\Plugin::instance();
230 $elementor->templates_manager->register_source('BetterDocs_Template_Source');
231 }
232
233 public static function modified_ajax_action($ajax)
234 {
235 if (!isset($_REQUEST['actions'])) {
236 return;
237 }
238
239 $actions = json_decode(stripslashes($_REQUEST['actions']), true);
240 $data = false;
241
242 foreach ($actions as $id => $action_data) {
243 if (!isset($action_data['get_template_data'])) {
244 $data = $action_data;
245 }
246 }
247
248
249 if (!$data) {
250 return;
251 }
252
253 if (!isset($data['data'])) {
254 return;
255 }
256
257 $data = $data['data'];
258
259 if (empty($data['template_id'])) {
260 return;
261 }
262
263 if (false === strpos($data['template_id'], 'betterdocs_')) {
264 return;
265 }
266 $ajax->register_ajax_action('get_template_data', array(__CLASS__, 'get_bd_template_data'));
267 }
268
269 public static function prepend_categories($library_data)
270 {
271 $categories = self::get_template_categories();
272 if (!empty($categories)) {
273 $library_data['types_data']['block']['categories'] = array_merge($categories, $library_data['types_data']['block']['categories']);
274 }
275 return $library_data;
276 }
277
278 public static function get_template_categories()
279 {
280 return [
281 'Single Docs', 'Docs Archive'
282 ];
283 }
284
285 public static function get_bd_template_data($args)
286 {
287 $source = Elementor\Plugin::instance()->templates_manager->get_source('betterdocs-templates');
288
289 return $source->get_data($args);
290 }
291
292 /**
293 * Include a file with variables
294 *
295 * @param $file_path
296 * @param $variables
297 *
298 * @return string
299 * @since 4.2.2
300 */
301 public static function include_with_variable( $file_path, $variables = [])
302 {
303 if (file_exists($file_path)) {
304 extract($variables);
305
306 ob_start();
307
308 include $file_path;
309
310 return ob_get_clean();
311 }
312
313 return '';
314 }
315
316 /**
317 * This function is responsible for counting doc post under a category.
318 *
319 * @param int $term_count
320 * @param int $term_id
321 * @return int $term_count;
322 */
323 public static function get_doc_post_count($term_count = 0, $term_id)
324 {
325 $tax_terms = get_terms('doc_category', ['child_of' => $term_id]);
326
327 foreach ($tax_terms as $tax_term) {
328 $term_count += $tax_term->count;
329 }
330
331 return $term_count;
332 }
333
334 public static function get_multiple_kb_terms($prettify = false, $term_id = true)
335 {
336 $args = [
337 'taxonomy' => 'knowledge_base',
338 'hide_empty' => true,
339 'parent' => 0,
340 ];
341
342 $terms = get_terms($args);
343
344 if (is_wp_error($terms)) {
345 return [];
346 }
347
348 if ($prettify) {
349 $pretty_taxonomies = [];
350
351 foreach ($terms as $term) {
352 $pretty_taxonomies[$term_id ? $term->term_id : $term->slug] = $term->name;
353 }
354
355 return $pretty_taxonomies;
356 }
357
358 return $terms;
359 }
360
361 public static function get_betterdocs_multiple_kb_status()
362 {
363 if (\BetterDocs_DB::get_settings('multiple_kb') == 1) {
364 return 'true';
365 }
366
367 return '';
368 }
369
370 /**
371 * POst Orderby Options
372 *
373 * @return array
374 */
375 public static function get_post_orderby_options()
376 {
377 $orderby = array(
378 'ID' => 'Post ID',
379 'author' => 'Post Author',
380 'title' => 'Title',
381 'date' => 'Date',
382 'modified' => 'Last Modified Date',
383 'parent' => 'Parent Id',
384 'rand' => 'Random',
385 'comment_count' => 'Comment Count',
386 'menu_order' => 'Menu Order',
387 'betterdocs_order' => 'BetterDocs Order',
388 );
389
390 return $orderby;
391 }
392
393 /**
394 * Get Post Categories
395 *
396 * @return array
397 */
398 public static function get_terms_list($taxonomy = 'category', $key = 'term_id')
399 {
400 $options = [];
401 $terms = get_terms([
402 'taxonomy' => $taxonomy,
403 'hide_empty' => true,
404 ]);
405
406 if (!empty($terms) && !is_wp_error($terms)) {
407 foreach ($terms as $term) {
408 $options[$term->{$key}] = $term->name;
409 }
410 }
411
412 return $options;
413 }
414
415 /**
416 * Query Controls
417 *
418 */
419 public static function betterdocs_query($wb, $taxonomy)
420 {
421 $wb->start_controls_section(
422 'eael_section_post__filters',
423 [
424 'label' => __('Query', 'betterdocs'),
425 ]
426 );
427
428 $default_multiple_kb = self::get_betterdocs_multiple_kb_status();
429
430 if ($default_multiple_kb && $taxonomy != 'knowledge_base') {
431 $multiple_kb_terms = self::get_multiple_kb_terms(true, false);
432 $default_slug = count($multiple_kb_terms) > 0 ? array_keys($multiple_kb_terms)[0] : '';
433
434 $wb->add_control(
435 'selected_knowledge_base',
436 [
437 'label' => __('Knowledge Bases', 'betterdocs'),
438 'label_block' => true,
439 'type' => Controls_Manager::SELECT2,
440 'options' => $multiple_kb_terms,
441 'multiple' => false,
442 'default' => '',
443 'select2options' => [
444 'placeholder' => __('All Knowledge Base', 'betterdocs'),
445 'allowClear' => true,
446 ],
447 ]
448 );
449 }
450
451 if ($wb->get_name() === 'betterdocs-category-grid') {
452 $wb->add_control(
453 'grid_query_heading',
454 [
455 'label' => __('Category Grid', 'betterdocs'),
456 'type' => Controls_Manager::HEADING,
457 ]
458 );
459 }
460
461 $wb->add_control(
462 'include',
463 [
464 'label' => __('Include', 'betterdocs'),
465 'label_block' => true,
466 'type' => Controls_Manager::SELECT2,
467 'options' => self::get_terms_list($taxonomy, 'term_id'),
468 'multiple' => true,
469 'default' => [],
470 ]
471 );
472
473 $wb->add_control(
474 'exclude',
475 [
476 'label' => __('Exclude', 'betterdocs'),
477 'type' => Controls_Manager::SELECT2,
478 'options' => self::get_terms_list($taxonomy, 'term_id'),
479 'label_block' => true,
480 'post_type' => '',
481 'multiple' => true,
482 ]
483 );
484
485 if ($wb->get_name() === 'betterdocs-category-grid') {
486 $wb->add_control(
487 'grid_per_page',
488 [
489 'label' => __('Grid Per Page', 'betterdocs'),
490 'type' => Controls_Manager::NUMBER,
491 'default' => '8',
492 ]
493 );
494 } else {
495 $wb->add_control(
496 'box_per_page',
497 [
498 'label' => __('Box Per Page', 'betterdocs'),
499 'type' => Controls_Manager::NUMBER,
500 'default' => '8',
501 ]
502 );
503 }
504
505 $wb->add_control(
506 'offset',
507 [
508 'label' => __('Offset', 'betterdocs'),
509 'type' => Controls_Manager::NUMBER,
510 'default' => '0',
511 ]
512 );
513
514 $wb->add_control(
515 'orderby',
516 [
517 'label' => __('Order By', 'betterdocs'),
518 'type' => Controls_Manager::SELECT,
519 'options' => [
520 'name' => __('Name', 'betterdocs'),
521 'slug' => __('Slug', 'betterdocs'),
522 'term_group' => __('Term Group', 'betterdocs'),
523 'term_id' => __('Term ID', 'betterdocs'),
524 'id' => __('ID', 'betterdocs'),
525 'description' => __('Description', 'betterdocs'),
526 'parent' => __('Parent', 'betterdocs'),
527 'betterdocs_order' => __('BetterDocs Order', 'betterdocs'),
528 ],
529 'default' => 'name',
530 ]
531 );
532
533 $wb->add_control(
534 'order',
535 [
536 'label' => __('Order', 'betterdocs'),
537 'type' => Controls_Manager::SELECT,
538 'options' => [
539 'asc' => 'Ascending',
540 'desc' => 'Descending',
541 ],
542 'default' => 'asc',
543
544 ]
545 );
546
547 if ($wb->get_name() === 'betterdocs-category-grid') {
548 $wb->add_control(
549 'grid_posts_query_heading',
550 [
551 'label' => __('Grid List Posts', 'betterdocs'),
552 'type' => Controls_Manager::HEADING,
553 'separator' => 'before',
554 ]
555 );
556
557 $wb->add_control(
558 'post_per_page',
559 [
560 'label' => __('Post Per Page', 'betterdocs'),
561 'type' => Controls_Manager::NUMBER,
562 'default' => '6',
563 ]
564 );
565
566 $wb->add_control(
567 'post_orderby',
568 [
569 'label' => __('Order By', 'betterdocs'),
570 'type' => Controls_Manager::SELECT,
571 'options' => self::get_post_orderby_options(),
572 'default' => 'date',
573 ]
574 );
575
576 $wb->add_control(
577 'post_order',
578 [
579 'label' => __('Order', 'betterdocs'),
580 'type' => Controls_Manager::SELECT,
581 'options' => [
582 'asc' => 'Ascending',
583 'desc' => 'Descending',
584 ],
585 'default' => 'desc',
586 ]
587 );
588
589 $wb->add_control(
590 'nested_subcategory',
591 [
592 'label' => __('Enable Nested Subcategory', 'betterdocs'),
593 'type' => Controls_Manager::SWITCHER,
594 'label_on' => __('Yes', 'betterdocs'),
595 'label_off' => __('No', 'betterdocs'),
596 'return_value' => 'true',
597 'default' => '',
598 ]
599 );
600
601 $wb->add_control(
602 'post_per_subcat',
603 [
604 'label' => __('Post Per Subcategory', 'betterdocs'),
605 'type' => Controls_Manager::NUMBER,
606 'default' => '6',
607 'condition' => [
608 'nested_subcategory' => 'true'
609 ]
610 ]
611 );
612 }
613
614 $wb->end_controls_section();
615 }
616
617 public function nested_subcategory($term_id, $settings, $multiple_kb) {
618 $html='';
619 $sub_categories = BetterDocs_Helper::child_taxonomy_terms($term_id, $multiple_kb, $settings['orderby'], $settings['order']);
620 if ($sub_categories) {
621 foreach ($sub_categories as $sub_category) {
622 $html .= '<span class="el-betterdocs-grid-sub-cat-title">';
623
624 if (isset($settings['nested_list_title_closed_icon']['value']['url']) && !empty($settings['nested_list_title_closed_icon']['value']['url'])) {
625 $html .= '<img class="toggle-arrow arrow-right" src="' . $settings['nested_list_title_closed_icon']['value']['url'] . '" />';
626 } else {
627 $html .= '<i class="' . $settings['nested_list_title_closed_icon']['value'] . ' toggle-arrow arrow-right"></i>';
628 }
629
630 if (isset($settings['nested_list_title_open_icon']['value']['url']) && !empty($settings['nested_list_title_open_icon']['value']['url'])) {
631 $html .= '<img class="toggle-arrow arrow-down" src="' . $settings['nested_list_title_open_icon']['value']['url'] . '" />';
632 } else {
633 $html .= '<i class="' . $settings['nested_list_title_open_icon']['value'] . ' toggle-arrow arrow-down"></i>';
634 }
635
636 $html .= '<a href="#">' . $sub_category->name . '</a></span>';
637 $html .= '<ul class="docs-sub-cat-list">';
638
639 $sub_args = array(
640 'post_type' => 'docs',
641 'post_status' => 'publish'
642 );
643
644 $tax_query = array(
645 array(
646 'taxonomy' => 'doc_category',
647 'field' => 'slug',
648 'terms' => $sub_category->slug,
649 'operator' => 'AND',
650 'include_children' => false
651 ),
652 );
653
654 $sub_args['posts_per_page'] = $settings['post_per_subcat'];
655
656 $sub_args['tax_query'] = apply_filters('betterdocs_list_tax_query_arg', $tax_query, $multiple_kb, $sub_category->slug);
657
658 $sub_post_query = new \WP_Query($sub_args);
659 if ($sub_post_query->have_posts()):
660 while ($sub_post_query->have_posts()): $sub_post_query->the_post();
661 $sub_attr = ['href="' . get_the_permalink() . '"'];
662 $html .= '<li class="sub-list">';
663 if (isset($settings['list_icon']['value']['url']) && !empty($settings['list_icon']['value']['url'])) {
664 $html .= '<img class="el-betterdocs-cg-post-list-icon" src="' . $settings['list_icon']['value']['url'] . '" />';
665 } else {
666 $html .= '<i class="' . $settings['list_icon']['value'] . ' el-betterdocs-cg-post-list-icon"></i>';
667 }
668 $html .= '<a ' . implode(' ', $sub_attr) . '>' . get_the_title() . '</a></li>';
669 endwhile;
670 endif;
671 wp_reset_query();
672 $html .= $this->nested_subcategory($sub_category->term_id, $settings, $multiple_kb);
673 $html .= '</ul>';
674 }
675 }
676 return $html;
677 }
678
679 const ELBD_ALLOWED_HTML_TAGS = [
680 'article',
681 'aside',
682 'div',
683 'footer',
684 'h1',
685 'h2',
686 'h3',
687 'h4',
688 'h5',
689 'h6',
690 'header',
691 'main',
692 'nav',
693 'p',
694 'section',
695 'span',
696 ];
697
698 /**
699 * elbd_validate_html_tag
700 * @param $tag
701 * @return mixed|string
702 */
703 public static function elbd_validate_html_tag( $tag ){
704 return in_array( strtolower( $tag ), self::ELBD_ALLOWED_HTML_TAGS ) ? $tag : 'div';
705 }
706 }
707
708 BetterDocs_Elementor::init();
709