PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.3
4.9.2 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 All 200 releases
← All changes | includes/Editors/Elementor.php +60 -255 4.9.23.5.3 View file →
@@ -2,9 +2,9 @@
2 2
3 3 namespace WPDeveloper\BetterDocs\Editors;
4 4
5 5 if ( ! defined( 'ABSPATH' ) ) {
6 - exit; // Exit if accessed directly
6 + exit; // Exit if accessed directly
7 7 }
8 8
9 9 use Elementor\Controls_Manager;
10 10 use Elementor\Api as ElementorAPI;
@@ -13,9 +13,8 @@
13 13 use WPDeveloper\BetterDocs\Utils\Enqueue;
14 14 use WPDeveloper\BetterDocs\Editors\Elementor\Helper;
15 15 use WPDeveloper\BetterDocs\Editors\Elementor\SingleDocs;
16 16 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\ToC;
17 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\DocAuthor;
18 17 use WPDeveloper\BetterDocs\Editors\Elementor\DocsArchive;
19 18 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Title;
20 19 use WPDeveloper\BetterDocs\Editors\Elementor\Tags\TitleTag;
21 20 use WPDeveloper\BetterDocs\Editors\Elementor\TemplateSource;
@@ -26,22 +25,15 @@
26 25 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Feedback;
27 26 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Basic\FAQ;
28 27 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Reactions;
29 28 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Navigation;
30 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\CodeSnippet;
31 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\CodeSnippetTab;
32 29 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\ArchiveList;
33 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\PrintButton;
34 30 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Breadcrumbs;
35 31 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\ReadingTime;
36 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\ArticleSummary;
37 32 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Basic\SearchForm;
38 33 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Basic\CategoryBox;
39 34 use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Basic\CategoryGrid;
40 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Basic\CategorySlateLayout;
41 35 use WPDeveloper\BetterDocs\Editors\Elementor\Conditions\ArchiveCondition;
42 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\Tags;
43 -use WPDeveloper\BetterDocs\Editors\Elementor\Widget\CategoryArchiveHeader;
44 36
45 37 class Elementor extends BaseEditor {
46 38 protected $is_elementor_active = false;
47 39 protected $is_elementor_pro_active = false;
@@ -87,9 +79,8 @@
87 79 add_filter( 'elementor/editor/localize_settings', [$this, 'promote_pro_elements'] );
88 80
89 81 add_filter( 'elementor/theme/need_override_location', [$this, 'override_location'], 10, 2 );
90 82 add_action( 'betterdocs/elementor/widgets/query', [$this, 'betterdocs_query'], 10, 2 );
91 - add_filter( 'betterdocs_base_terms_args', [$this, 'handle_editor_mode_terms_args'], 10, 1 );
92 83
93 84 if ( $this->is_elementor_pro_active ) {
94 85 add_action( 'elementor/dynamic_tags/register', [$this, 'register_basic_tags'] );
95 86 add_action( 'elementor/widgets/register', [$this, 'register_theme_builder_widgets'] );
@@ -205,11 +196,9 @@
205 196 } else if ( $wb->get_name() !== 'betterdocs-sidebar' ) {
206 197 $wb->add_control(
207 198 'box_per_page',
208 199 [
209 - 'label' => $wb->get_name() == 'betterdocs-tab-view-list'
210 - ? __( 'Tabs Per Page', 'betterdocs' )
211 - : __( 'Box Per Page', 'betterdocs' ),
200 + 'label' => __( 'Box Per Page', 'betterdocs' ),
212 201 'type' => Controls_Manager::NUMBER,
213 202 'default' => '8'
214 203 ]
215 204 );
@@ -228,9 +217,9 @@
228 217 if ( $wb->get_name() === 'betterdocs-sidebar' ) {
229 218 $wb->add_control(
230 219 'orderby',
231 220 [
232 - 'label' => __( 'Terms Order By', 'betterdocs' ),
221 + 'label' => __( 'Order By', 'betterdocs' ),
233 222 'type' => Controls_Manager::SELECT,
234 223 'options' => [
235 224 'none' => __( 'No order', 'betterdocs' ),
236 225 'name' => __( 'Name', 'betterdocs' ),
@@ -248,9 +237,9 @@
248 237
249 238 $wb->add_control(
250 239 'order',
251 240 [
252 - 'label' => __( 'Terms Order', 'betterdocs' ),
241 + 'label' => __( 'Order', 'betterdocs' ),
253 242 'type' => Controls_Manager::SELECT,
254 243 'options' => [
255 244 'ASC' => 'Ascending',
256 245 'DESC' => 'Descending'
@@ -261,34 +250,8 @@
261 250 ]
262 251
263 252 ]
264 253 );
265 -
266 - $wb->add_control(
267 - 'post_orderby',
268 - [
269 - 'label' => __( 'Docs Order By', 'betterdocs' ),
270 - 'type' => Controls_Manager::SELECT,
271 - 'options' => $this->helper->orderby_options(),
272 - 'default' => 'date'
273 - ]
274 - );
275 -
276 - $wb->add_control(
277 - 'post_order',
278 - [
279 - 'label' => __( 'Docs Order', 'betterdocs' ),
280 - 'type' => Controls_Manager::SELECT,
281 - 'options' => [
282 - 'asc' => 'Ascending',
283 - 'desc' => 'Descending'
284 - ],
285 - 'default' => 'asc',
286 - 'condition' => [
287 - 'post_orderby!' => 'betterdocs_order'
288 - ]
289 - ]
290 - );
291 254 } else {
292 255 $wb->add_control(
293 256 'orderby',
294 257 [
@@ -317,9 +280,9 @@
317 280 'options' => [
318 281 'ASC' => 'Ascending',
319 282 'DESC' => 'Descending'
320 283 ],
321 - 'default' => 'ASC',
284 + 'default' => 'asc',
322 285 'condition' => [
323 286 'orderby!' => 'betterdocs_order'
324 287 ]
325 288
@@ -326,9 +289,9 @@
326 289 ]
327 290 );
328 291 }
329 292
330 - if ( $wb->get_name() === 'betterdocs-category-grid' || $wb->get_name() === 'betterdocs-category-slate-layout' ) {
293 + if ( $wb->get_name() === 'betterdocs-category-grid' ) {
331 294 $wb->add_control(
332 295 'grid_posts_query_heading',
333 296 [
334 297 'label' => __( 'Grid List Posts', 'betterdocs' ),
@@ -351,9 +314,9 @@
351 314 [
352 315 'label' => __( 'Order By', 'betterdocs' ),
353 316 'type' => Controls_Manager::SELECT,
354 317 'options' => $this->helper->orderby_options(),
355 - 'default' => 'betterdocs_order'
318 + 'default' => 'date'
356 319 ]
357 320 );
358 321
359 322 $wb->add_control(
@@ -364,103 +327,38 @@
364 327 'options' => [
365 328 'asc' => 'Ascending',
366 329 'desc' => 'Descending'
367 330 ],
368 - 'default' => 'asc',
369 - 'condition' => [
370 - 'post_orderby!' => 'betterdocs_order'
371 - ]
331 + 'default' => 'desc'
372 332 ]
373 333 );
374 - }
375 334
376 - if ( $wb->get_name() === 'betterdocs-category-grid' ) {
377 - $wb->add_control(
378 - 'nested_subcategory',
379 - [
380 - 'label' => __( 'Enable Nested Subcategory', 'betterdocs' ),
381 - 'type' => Controls_Manager::SWITCHER,
382 - 'label_on' => __( 'Yes', 'betterdocs' ),
383 - 'label_off' => __( 'No', 'betterdocs' ),
384 - 'return_value' => 'true',
385 - 'default' => false
386 - ]
387 - );
388 -
389 - $wb->add_control(
390 - 'subcategory_per_grid',
391 - [
392 - 'label' => __( 'Subcategory Per Grid', 'betterdocs' ),
393 - 'type' => Controls_Manager::NUMBER,
394 - 'default' => '2',
395 - 'condition' => [
396 - 'nested_subcategory' => 'true'
397 - ]
398 - ]
399 - );
400 -
401 - $wb->add_control(
402 - 'post_per_subcat',
403 - [
404 - 'label' => __( 'Post Per Subcategory', 'betterdocs' ),
405 - 'type' => Controls_Manager::NUMBER,
406 - 'default' => '6',
407 - 'condition' => [
408 - 'nested_subcategory' => 'true'
409 - ]
410 - ]
411 - );
412 -
413 - $wb->add_control(
414 - 'lazy_load',
415 - [
416 - 'label' => __( 'Lazy Load Docs & Subcategories', 'betterdocs' ),
417 - 'description' => __( 'Render only the active category upfront; fetch the rest on click. Recommended for large knowledge bases when this widget is used as a sidebar.', 'betterdocs' ),
418 - 'type' => Controls_Manager::SWITCHER,
419 - 'label_on' => __( 'Yes', 'betterdocs' ),
420 - 'label_off' => __( 'No', 'betterdocs' ),
421 - 'return_value' => 'true',
422 - 'default' => ''
423 - ]
424 - );
425 - }
426 -
427 - if ( $wb->get_name() === 'betterdocs-category-box' ) {
428 335 $wb->add_control(
429 336 'nested_subcategory',
430 337 [
431 - 'label' => __( 'Nested Subcategory', 'betterdocs' ),
338 + 'label' => __( 'Enable Nested Subcategory', 'betterdocs' ),
432 339 'type' => Controls_Manager::SWITCHER,
433 340 'label_on' => __( 'Yes', 'betterdocs' ),
434 341 'label_off' => __( 'No', 'betterdocs' ),
435 342 'return_value' => 'true',
436 - 'default' => 'true',
343 + 'default' => false
437 344 ]
438 345 );
439 346
440 - $wb->add_control(
441 - 'show_dynamic_categories_in_doc_category_template',
347 + $wb->add_control(
348 + 'post_per_subcat',
442 349 [
443 - 'label' => __( 'Show Categories Dynamically', 'betterdocs' ),
444 - 'type' => Controls_Manager::SWITCHER,
445 - 'label_on' => __( 'Yes', 'betterdocs' ),
446 - 'label_off' => __( 'No', 'betterdocs' ),
447 - 'return_value' => 'true',
448 - 'default' => 'true',
350 + 'label' => __( 'Post Per Subcategory', 'betterdocs' ),
351 + 'type' => Controls_Manager::NUMBER,
352 + 'default' => '6',
353 + 'condition' => [
354 + 'nested_subcategory' => 'true'
355 + ]
449 356 ]
450 357 );
451 -
452 - $wb->add_control(
453 - 'show_dynamic_categories_in_doc_category_template_description',
454 - [
455 - 'type' => Controls_Manager::RAW_HTML,
456 - 'raw' => __( "Note: This option is only applicable for BetterDocs Category Archive page. If enabled, this will show the Categories dynamically in your BetterDocs Category Archive page.", 'betterdocs' ),
457 - 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info'
458 - ]
459 - );
460 358 }
461 359
462 - if ( $wb->get_name() === 'betterdocs-sidebar' ) {
360 + if ( $wb->get_name() === 'betterdocs-category-box' ) {
463 361 $wb->add_control(
464 362 'nested_subcategory',
465 363 [
466 364 'label' => __( 'Nested Subcategory', 'betterdocs' ),
@@ -467,22 +365,23 @@
467 365 'type' => Controls_Manager::SWITCHER,
468 366 'label_on' => __( 'Yes', 'betterdocs' ),
469 367 'label_off' => __( 'No', 'betterdocs' ),
470 368 'return_value' => 'true',
471 - 'default' => ( $this->settings->get( 'archive_nested_subcategory' ) == 1 ) ? 'true' : ''
369 + 'default' => false
472 370 ]
473 371 );
372 + }
474 373
374 + if ( $wb->get_name() === 'betterdocs-sidebar' ) {
475 375 $wb->add_control(
476 - 'lazy_load',
376 + 'nested_subcategory',
477 377 [
478 - 'label' => __( 'Lazy Load Docs & Subcategories', 'betterdocs' ),
479 - 'description' => __( 'Render only the active category upfront; fetch the rest on click (or on scroll for the Memphis sidebar layout).', 'betterdocs' ),
378 + 'label' => __( 'Nested Subcategory', 'betterdocs' ),
480 379 'type' => Controls_Manager::SWITCHER,
481 380 'label_on' => __( 'Yes', 'betterdocs' ),
482 381 'label_off' => __( 'No', 'betterdocs' ),
483 382 'return_value' => 'true',
484 - 'default' => ( $this->settings->get( 'archive_lazy_load_descendants' ) == 1 ) ? 'true' : ''
383 + 'default' => ( $this->settings->get( 'archive_nested_subcategory' ) == 1 ) ? 'true' : ''
485 384 ]
486 385 );
487 386 }
488 387
@@ -496,17 +395,8 @@
496 395 ]
497 396 );
498 397
499 398 $wb->add_control(
500 - 'tab_box_per_tabs',
501 - [
502 - 'label' => __( 'Box Per Tabs', 'betterdocs' ),
503 - 'type' => Controls_Manager::NUMBER,
504 - 'default' => '10'
505 - ]
506 - );
507 -
508 - $wb->add_control(
509 399 'post_per_tab',
510 400 [
511 401 'label' => __( 'Posts Per Tab', 'betterdocs' ),
512 402 'type' => Controls_Manager::NUMBER,
@@ -622,25 +512,16 @@
622 512 return '';
623 513 }
624 514
625 515 public function get_kb_terms( $prettify = false, $term_id = true ) {
626 - // This list populates the widget "Knowledge Bases" selector — an admin-side
627 - // config picker, not a front-end listing. It must show EVERY KB regardless of
628 - // whether it currently has content or is access-restricted for the editing
629 - // user's role. Previously it ran through terms_query()/get_terms(), so on a
630 - // regular page the Pro access-control terms_clauses filter + hide_empty pruned
631 - // the list to a subset, while the theme-builder context showed them all.
632 - // hide_empty:false keeps empty KBs; suppress_filters:true signals AccessControl
633 - // (get_terms_args) to skip its role-based terms_clauses filter, so the picker is
634 - // consistent everywhere.
635 - $terms = get_terms( [
636 - 'taxonomy' => 'knowledge_base',
637 - 'hide_empty' => false,
638 - 'parent' => 0,
639 - 'orderby' => 'name',
640 - 'suppress_filters' => true,
641 - ] );
516 + $args = [
517 + 'taxonomy' => 'knowledge_base',
518 + 'hide_empty' => true,
519 + 'parent' => 0
520 + ];
642 521
522 + $terms = get_terms( $args );
523 +
643 524 if ( is_wp_error( $terms ) ) {
644 525 return [];
645 526 }
646 527
@@ -647,11 +528,9 @@
647 528 if ( $prettify ) {
648 529 $pretty_taxonomies = [];
649 530
650 531 foreach ( $terms as $term ) {
651 - // Decode HTML entities (e.g. "&" → "&") so the select2 control
652 - // shows the real KB name instead of the escaped entity.
653 - $pretty_taxonomies[$term_id ? $term->term_id : $term->slug] = wp_specialchars_decode( $term->name, ENT_QUOTES );
532 + $pretty_taxonomies[$term_id ? $term->term_id : $term->slug] = $term->name;
654 533 }
655 534
656 535 return $pretty_taxonomies;
657 536 }
@@ -662,24 +541,8 @@
662 541 public function register_basic_tags( $module ) {
663 542 $module->register( new TitleTag );
664 543 }
665 544
666 - /**
667 - * Handle editor mode for terms query args
668 - *
669 - * @param array $args Terms query arguments
670 - * @return array Modified arguments
671 - */
672 - public function handle_editor_mode_terms_args( $args ) {
673 - // Only modify if we're in Elementor editor mode
674 - if ( $this->elementor && $this->elementor->editor->is_edit_mode() ) {
675 - // Show empty categories in editor mode for better preview
676 - $args['hide_empty'] = false;
677 - }
678 -
679 - return $args;
680 - }
681 -
682 545 public function register_basic_widgets( $widgets_manager ) {
683 546 foreach ( $this->basic_widget_lists() as $value ) {
684 547 $widgets_manager->register( new $value );
685 548 }
@@ -693,15 +556,12 @@
693 556 * @since 1.3.0
694 557 */
695 558 private function basic_widget_lists() {
696 559 $widget_arr = [
697 - 'betterdocs-elementor-search-form' => SearchForm::class,
698 - 'betterdocs-elementor-category-grid' => CategoryGrid::class,
699 - 'betterdocs-elementor-category-box' => CategoryBox::class,
700 - 'betterdocs-elementor-category-slate' => CategorySlateLayout::class,
701 - 'betterdocs-faq-widget' => FAQ::class,
702 - 'betterdocs-code-snippet' => CodeSnippet::class,
703 - 'betterdocs-code-snippet-tab' => CodeSnippetTab::class
560 + 'betterdocs-elementor-search-form' => SearchForm::class,
561 + 'betterdocs-elementor-category-grid' => CategoryGrid::class,
562 + 'betterdocs-elementor-category-box' => CategoryBox::class,
563 + 'betterdocs-faq-widget' => FAQ::class
704 564 ];
705 565
706 566 return $widget_arr;
707 567 }
@@ -761,32 +621,14 @@
761 621 $assets->register( 'betterdocs-el-category-grid', 'elementor/css/category-grid.css' );
762 622 $assets->register( 'betterdocs-el-category-box', 'elementor/css/category-box.css' );
763 623 $assets->register( 'betterdocs-el-articles-list', 'elementor/css/articles-list.css' );
764 624 $assets->register( 'betterdocs-el-navigation', 'elementor/css/navigation.css' );
765 - $assets->register( 'betterdocs-code-snippet', 'public/css/code-snippet.css' );
766 - $assets->register( 'betterdocs-code-snippet-tab', 'public/css/code-snippet-tab.css' );
767 625
768 626 /**
769 627 * Widget's JS
770 628 */
771 629 $assets->register( 'betterdocs-el-category-grid', 'elementor/js/category-grid.js', ['jquery', 'betterdocs-category-toggler'] );
772 - $assets->register( 'betterdocs-code-snippet', 'public/js/code-snippet.js', ['jquery'] );
773 - $assets->register( 'betterdocs-code-snippet-tab', 'public/js/code-snippet-tab.js', ['jquery'] );
774 630
775 - /**
776 - * Localize This In Order To Know If This Block Is Arriving From Betterdocs Templates Or Not
777 - */
778 - betterdocs()->assets->localize( 'betterdocs-el-category-grid', 'betterdocsCategoryGridConfig', [
779 - 'is_betterdocs_templates' => betterdocs()->helper->is_templates() ? true : false,
780 - // Must also carry the lazy-load endpoint. wp_localize_script concatenates
781 - // every `var betterdocsCategoryGridConfig = …` for this object name and the
782 - // last assignment wins; shipping only is_betterdocs_templates here clobbered
783 - // Scripts.php's full config on Elementor pages, leaving ajax_url undefined so
784 - // loadLazyBody() bailed and sidebar lazy-load never fired.
785 - 'ajax_url' => admin_url( 'admin-ajax.php' ),
786 - 'lazy_load_action' => 'betterdocs_lazy_category_body',
787 - ] );
788 -
789 631 if ( betterdocs()->helper->is_el_templates() == true ) {
790 632 $assets->enqueue( 'betterdocs-elementor-editor', 'elementor/css/betterdocs-el-edit.css' );
791 633
792 634 if ( ! $this->is_pro_active ) {
@@ -812,25 +654,20 @@
812 654 * @since 1.3.0
813 655 */
814 656 public function builder_widget_list() {
815 657 return apply_filters( 'betterdocs_elementor_pro_widgets', [
816 - 'betterdocs-elementor-toc' => ToC::class,
817 - 'betterdocs-elementor-title' => Title::class,
818 - 'betterdocs-elementor-sidebar' => Sidebar::class,
819 - 'betterdocs-elementor-content' => Content::class,
820 - 'betterdocs-elementor-doc-date' => DocDate::class,
821 - 'betterdocs-elementor-doc-share' => DocShare::class,
822 - 'betterdocs-elementor-feedback' => Feedback::class,
823 - 'betterdocs-elementor-reactions' => Reactions::class,
824 - 'betterdocs-article-summary' => ArticleSummary::class,
825 - 'betterdocs-elementor-navigation' => Navigation::class,
826 - 'betterdocs-elementor-breadcrumbs' => Breadcrumbs::class,
827 - 'betterdocs-elementor-category-archive-list' => ArchiveList::class,
828 - 'betteredocs-elementor-reading-time' => ReadingTime::class,
829 - 'betterdocs-print-button' => PrintButton::class,
830 - 'betterdocs-elementor-doc-author' => DocAuthor::class,
831 - 'betteredocs-elementor-doc-category-archive-header' => CategoryArchiveHeader::class,
832 - 'betterdocs-elementor-tags' => Tags::class
658 + 'betterdocs-elementor-toc' => ToC::class,
659 + 'betterdocs-elementor-title' => Title::class,
660 + 'betterdocs-elementor-sidebar' => Sidebar::class,
661 + 'betterdocs-elementor-content' => Content::class,
662 + 'betterdocs-elementor-doc-date' => DocDate::class,
663 + 'betterdocs-elementor-doc-share' => DocShare::class,
664 + 'betterdocs-elementor-feedback' => Feedback::class,
665 + 'betterdocs-elementor-reactions' => Reactions::class,
666 + 'betterdocs-elementor-navigation' => Navigation::class,
667 + 'betterdocs-elementor-breadcrumbs' => Breadcrumbs::class,
668 + 'betterdocs-elementor-category-archive-list' => ArchiveList::class,
669 + 'betteredocs-elementor-reading-time' => ReadingTime::class
833 670 ] );
834 671 }
835 672
836 673 /**
@@ -894,9 +731,9 @@
894 731 $categories = $this->template_categories();
895 732 if ( ! empty( $categories ) ) {
896 733 $library_data['types_data']['block']['categories'] = array_merge(
897 734 $categories,
898 - isset( $library_data['types_data']['block']['categories'] ) ? $library_data['types_data']['block']['categories'] : []
735 + $library_data['types_data']['block']['categories']
899 736 );
900 737 }
901 738 return $library_data;
902 739 }
@@ -937,22 +774,17 @@
937 774 * @return array|mixed
938 775 * @since 2.0.0
939 776 */
940 777 public function get_templates() {
941 - $_cache_key = 'betterdocs_template_library_' . betterdocs()->version;
942 - $source = new TemplateSource;
943 - $local_ids = array_column( $source->get_local_templates(), 'template_id' );
944 - $templates = get_transient( $_cache_key );
778 + $_cache_key = 'betterdocs_template_library_' . betterdocs()->version;
779 + $templates = get_transient( $_cache_key );
945 780
946 781 if ( ! $templates ) {
947 - // Only cache remote templates — local templates are always appended fresh below
948 - $all_templates = $source->get_items();
949 - $remote_only = array_values( array_filter( $all_templates, function ( $t ) use ( $local_ids ) {
950 - return ! in_array( $t['template_id'], $local_ids, true );
951 - } ) );
782 + $source = new TemplateSource;
783 + $templates = $source->get_items();
952 784
953 - if ( ! empty( $remote_only ) ) {
954 - $remote_only = array_map( function ( $template ) {
785 + if ( ! empty( $templates ) ) {
786 + $templates = array_map( function ( $template ) {
955 787 $template['id'] = $template['template_id'];
956 788 $template['tmpl_created'] = $template['date'];
957 789 $template['tags'] = json_encode( $template['tags'] );
958 790 $template['is_pro'] = $template['isPro'];
@@ -961,52 +793,25 @@
961 793 $template['trend_index'] = $template['trendIndex'];
962 794 $template['has_page_settings'] = $template['hasPageSettings'];
963 795
964 796 return $template;
965 - }, $remote_only );
797 + }, $templates );
966 798
967 - set_transient( $_cache_key, $remote_only, WEEK_IN_SECONDS );
968 - $templates = $remote_only;
799 + set_transient( $_cache_key, $templates, WEEK_IN_SECONDS );
969 800 } else {
970 801 $templates = [];
971 802 }
972 - } else {
973 - // Strip any local templates that may have been cached in a previous version
974 - $templates = array_values( array_filter( $templates, function ( $t ) use ( $local_ids ) {
975 - $id = isset( $t['template_id'] ) ? $t['template_id'] : ( isset( $t['id'] ) ? $t['id'] : '' );
976 - return ! in_array( $id, $local_ids, true );
977 - } ) );
978 803 }
979 804
980 - // Always append local templates fresh so they are never stale-cached
981 - $local_templates = array_map( function ( $template ) {
982 - $template['id'] = $template['template_id'];
983 - $template['tmpl_created'] = $template['date'];
984 - $template['tags'] = json_encode( $template['tags'] );
985 - $template['is_pro'] = $template['isPro'];
986 - $template['access_level'] = $template['accessLevel'];
987 - $template['popularity_index'] = $template['popularityIndex'];
988 - $template['trend_index'] = $template['trendIndex'];
989 - $template['has_page_settings'] = $template['hasPageSettings'];
990 -
991 - return $template;
992 - }, $source->get_local_templates() );
993 -
994 - return array_merge( $templates, $local_templates );
805 + return $templates;
995 806 }
996 807
997 808 public function modified_ajax_action( $ajax ) {
998 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Elementor's own ajax handler verifies nonce upstream.
999 809 if ( ! isset( $_REQUEST['actions'] ) ) {
1000 810 return;
1001 811 }
1002 812
1003 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Elementor's ajax handler verifies nonce; raw JSON is structure-validated below.
1004 - $raw_actions = wp_unslash( $_REQUEST['actions'] );
1005 - $actions = json_decode( $raw_actions, true );
1006 - if ( ! is_array( $actions ) ) {
1007 - return;
1008 - }
813 + $actions = json_decode( stripslashes( $_REQUEST['actions'] ), true );
1009 814 $data = false;
1010 815
1011 816 foreach ( $actions as $id => $action_data ) {
1012 817 if ( ! isset( $action_data['get_template_data'] ) ) {