PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 1.1.2
ShopBuilder – WooCommerce Builder For Elementor v1.1.2
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
← All changes | app/Controllers/BuilderController.php +297 -653 2.2.21.1.2 View file →
@@ -1,653 +1,297 @@
1 -<?php
2 -/**
3 - * Main BuilderController class.
4 - *
5 - * @package RadiusTheme\SB
6 - */
7 -
8 -namespace RadiusTheme\SB\Controllers;
9 -
10 -use RadiusTheme\SB\Helpers\Fns;
11 -use RadiusTheme\SB\Helpers\BuilderFns;
12 -use RadiusTheme\SB\Traits\SingletonTrait;
13 -use RadiusTheme\SB\Controllers\Builder\BuilderCpt;
14 -use RadiusTheme\SB\Controllers\Hooks\BuilderHooks;
15 -use RadiusTheme\SB\Elementor\Controls\ImageSelectorControl;
16 -use RadiusTheme\SB\Elementor\Controls\Select2AjaxControl;
17 -use RadiusTheme\SB\Models\ElementList;
18 -
19 -// Do not allow directly accessing this file.
20 -if ( ! defined( 'ABSPATH' ) ) {
21 - exit( 'This script cannot be accessed directly.' );
22 -}
23 -
24 -/**
25 - * Builder Controller
26 - */
27 -class BuilderController {
28 - /**
29 - * @var array
30 - */
31 - private static $cache = [];
32 -
33 - /**
34 - * Builder page id.
35 - *
36 - * @var integer
37 - */
38 - private $builder_page_id = 0;
39 -
40 - /**
41 - * Page Edit By.
42 - *
43 - * @var string
44 - */
45 - private $page_edit_with = '';
46 -
47 - /**
48 - * Singleton Trait
49 - */
50 - use SingletonTrait;
51 -
52 - /**
53 - * Construct function
54 - */
55 - private function __construct() {
56 - $this->builder_page_id = BuilderFns::builder_page_id_by_page();
57 - $this->page_edit_with = Fns::page_edit_with( $this->builder_page_id );
58 -
59 - if ( ! is_admin() ) {
60 - BuilderHooks::instance();
61 - }
62 -
63 - BuilderCpt::instance();
64 -
65 - $this->elementor_init();
66 - $this->both_builder_frontend();
67 -
68 - // add_action( 'elementor/init', [ $this, 'elementor_init' ] );
69 - add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'editor_scripts' ] );
70 - // add_action( 'template_redirect', [ $this, 'both_builder_frontend' ], 99 );
71 -
72 - // RT Select2 Ajax.
73 - add_action( 'wp_ajax_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
74 - add_action( 'wp_ajax_nopriv_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
75 - // Select2 ajax save data.
76 - add_action( 'wp_ajax_rtsb_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
77 - add_action( 'wp_ajax_nopriv_rtsb_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
78 - }
79 -
80 - /**
81 - * Apply for frontend.
82 - *
83 - * @return void
84 - */
85 - public function both_builder_frontend() {
86 - add_action( 'rtsb/builder/template/before/content', [ $this, 'builder_template_before_content' ] );
87 - add_action( 'rtsb/builder/template/after/content', [ $this, 'builder_template_after_content' ] );
88 - }
89 -
90 - /**
91 - * Register Category
92 - *
93 - * @return void
94 - */
95 - public function elementor_init() {
96 - add_action( 'elementor/elements/categories_registered', [ $this, 'add_elementor_widget_categories' ] );
97 - add_action( 'elementor/widgets/register', [ $this, 'init_widgets' ] );
98 - add_action( 'elementor/controls/register', [ $this, 'init_controls' ] );
99 - add_filter( 'elementor/editor/localize_settings', [ $this, 'promotePremiumWidgets' ] );
100 - add_action( 'elementor/icons_manager/additional_tabs', [ $this, 'rtsb_icons' ] );
101 - }
102 -
103 - /**
104 - * Register Category
105 - *
106 - * @param object $elements_manager Category hooks.
107 - *
108 - * @return void
109 - */
110 - public function add_elementor_widget_categories( $elements_manager ) {
111 - $categories = [];
112 - $builder_id = get_queried_object_id();
113 - $id = Fns::wpml_object_id( $builder_id, BuilderFns::$post_type_tb, 'default' );
114 - $type = BuilderFns::builder_type( $id );
115 -
116 - if ( $type ) {
117 - $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : '';
118 - $builder_type = str_replace( [ 'My Account - ', 'Endpoint: ' ], '', $builder_type );
119 - $categories['rtsb-shopbuilder'] = [
120 - 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
121 - 'icon' => 'fa fa-plug',
122 - ];
123 - }
124 - if ( 'quick-view' !== $type ) {
125 - $categories['rtsb-shopbuilder-general'] = [
126 - 'title' => esc_html__( 'Shopbuilder - General', 'shopbuilder' ),
127 - 'icon' => 'fa fa-plug',
128 - ];
129 - }
130 - $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
131 -
132 - $other_categories = $elements_manager->get_categories();
133 - $categories = array_merge(
134 - array_slice( $other_categories, 0, 1 ),
135 - $categories,
136 - array_slice( $other_categories, 1 )
137 - );
138 -
139 - $set_categories = function ( $categories ) use ( $elements_manager ) {
140 - $elements_manager->categories = $categories;
141 - };
142 -
143 - $set_categories->call( $elements_manager, $categories );
144 - }
145 -
146 - /**
147 - * Init Controls
148 - *
149 - * Include controls files and register them
150 - *
151 - * @param object $controls_manager Controls Manager.
152 - *
153 - * @since 1.0.0
154 - */
155 - public function init_controls( $controls_manager ) {
156 - $controls_manager->register( new ImageSelectorControl() );
157 - $controls_manager->register( new Select2AjaxControl() );
158 - }
159 -
160 - /**
161 - * Init Widgets
162 - *
163 - * Include widgets files and register them
164 - *
165 - * @since 1.0.0
166 - */
167 - public function init_widgets( $widgets_manager ) {
168 -
169 - $get_list = ElementList::instance()->get_list( true, 'active' );
170 - foreach ( $get_list as $element ) {
171 - if ( isset( $element['active'] ) && 'on' !== $element['active'] ) {
172 - continue;
173 - }
174 -
175 - if ( ! empty( $element['package'] ) && 'pro-disabled' === $element['package'] ) {
176 - continue;
177 - }
178 -
179 - if ( empty( $element['base_class'] ) || ! class_exists( $element['base_class'] ) ) {
180 - continue;
181 - }
182 -
183 - if ( ! empty( $element['category'] ) ) {
184 - $widget = false;
185 - $import = apply_filters( 'rtsb_import_status', false );
186 - switch ( $element['category'] ) {
187 - case 'product':
188 - if ( BuilderFns::is_product() || $import ) {
189 - $widget = new $element['base_class']();
190 - }
191 - break;
192 - case 'shop':
193 - if ( BuilderFns::is_archive() || BuilderFns::is_shop() || $import ) {
194 - $widget = new $element['base_class']();
195 - }
196 - break;
197 - case 'archive':
198 - if ( BuilderFns::is_archive() || $import ) {
199 - $widget = new $element['base_class']();
200 - }
201 - break;
202 - case 'cart':
203 - if ( BuilderFns::is_cart() || $import ) {
204 - $widget = new $element['base_class']();
205 - }
206 - break;
207 - case 'checkout':
208 - if ( BuilderFns::is_checkout() || $import ) {
209 - $widget = new $element['base_class']();
210 - }
211 - break;
212 - case 'general':
213 - $widget = new $element['base_class']();
214 - break;
215 - default:
216 - }
217 - $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
218 -
219 - if ( $widget && is_object( $widget ) ) {
220 - $widgets_manager->register( $widget );
221 - }
222 - }
223 - }
224 - }
225 -
226 - /**
227 - * Adding custom icons in Elementor
228 - *
229 - * @param array $tabs Tabs.
230 - *
231 - * @return array
232 - */
233 - public function rtsb_icons( $tabs = [] ) {
234 - $custom_icons = Fns::get_custom_icon_names();
235 -
236 - $tabs['shopbuilder-icons'] = [
237 - 'name' => 'rtsb-fonts',
238 - 'label' => esc_html__( 'ShopBuilder Icons', 'shopbuilder' ),
239 - 'labelIcon' => 'fab fa-elementor',
240 - 'prefix' => 'rtsb-icon-',
241 - 'displayPrefix' => 'rtsb-icon',
242 - 'url' => rtsb()->get_assets_uri( 'css/frontend/rtsb-fonts.css' ),
243 - 'icons' => $custom_icons,
244 - 'ver' => '1.0',
245 - ];
246 -
247 - return $tabs;
248 - }
249 -
250 - /**
251 - * Editor JS.
252 - *
253 - * @return void
254 - */
255 - public function editor_scripts() {
256 - $version = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? time() : RTSB_VERSION;
257 -
258 - wp_enqueue_script(
259 - 'rtsb-editor-script',
260 - rtsb()->get_assets_uri( 'js/backend/editor.js' ),
261 - [
262 - 'jquery',
263 - 'elementor-editor',
264 - 'jquery-elementor-select2',
265 - ],
266 - $version,
267 - true
268 - );
269 - $params = [
270 - 'isEditorForBuilder' => false,
271 - ];
272 - if ( BuilderFns::is_builder_preview() ) {
273 - $params['isEditorForBuilder'] = true;
274 - }
275 - wp_localize_script( 'rtsb-editor-script', 'rtsbTemplateBuilderEditorScript', $params );
276 - wp_enqueue_style( 'rtsb-el-editor-style', rtsb()->get_assets_uri( 'css/backend/elementor-editor.css' ), [], $version );
277 - }
278 -
279 - /**
280 - * Before Content for Elementor.
281 - *
282 - * @return void
283 - */
284 - public function builder_template_before_content() {
285 - /**
286 - * Before Header-Footer page template content.
287 - *
288 - * Fires before the content of Elementor Header-Footer page template.
289 - *
290 - * @since 2.0.0
291 - */
292 - if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
293 - do_action( 'elementor/page_templates/header-footer/before_content' );
294 - }
295 -
296 - $parent_class = apply_filters( 'rtsb/builder/content/parent_class', [] );
297 -
298 - if ( BuilderFns::is_product() ) {
299 - $product_id = Fns::get_prepared_product_id();
300 - $parent_class = wc_get_product_class( $parent_class, $product_id );
301 - if ( function_exists( 'rtwpvs' ) ) {
302 - $_product = Fns::get_product();
303 - if ( $_product->is_type( 'variable' ) ) {
304 - $parent_class[] = 'rtwpvs-product';
305 - $beside_label = function_exists( 'rtwpvsp' ) && rtwpvs()->get_option( 'attribute_on_click_behavior' );
306 - if ( $beside_label ) {
307 - $parent_class[] = 'rtwpvs-selected-term-beside-label';
308 - }
309 - }
310 - }
311 - }
312 -
313 - if ( BuilderFns::is_shop() ) {
314 - $parent_class[] = 'shop';
315 - }
316 -
317 - if ( BuilderFns::is_archive() ) {
318 - $parent_class[] = 'archive';
319 - }
320 -
321 - if ( BuilderFns::is_checkout() ) {
322 - $parent_class[] = 'checkout-page ';
323 - }
324 -
325 - ?>
326 - <!-- Before Content start -->
327 - <div class="<?php echo esc_attr( implode( ' ', $parent_class ) ); ?>">
328 - <?php
329 - if ( BuilderFns::is_checkout() ) {
330 - if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
331 - return;
332 - }
333 - ?>
334 - <form name="checkout" method="post" class="rtsb-woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
335 - <?php
336 - }
337 - }
338 -
339 - /**
340 - * After Content for Elementor.
341 - *
342 - * @return void
343 - */
344 - public function builder_template_after_content() {
345 - /**
346 - * After Header-Footer page template content.
347 - *
348 - * Fires after the content of Elementor Header-Footer page template.
349 - *
350 - * @since 2.0.0
351 - */
352 - if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
353 - do_action( 'elementor/page_templates/header-footer/after_content' );
354 - }
355 -
356 - if ( BuilderFns::is_checkout() ) {
357 - if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
358 - return;
359 - }
360 - ?>
361 - </form>
362 - <?php
363 - }
364 - ?>
365 - </div>
366 - <!-- After Content end -->
367 - <?php
368 - }
369 -
370 - /**
371 - * Ajax callback for rt-select2
372 - *
373 - * @return void
374 - */
375 - public function select2_ajax_posts_filter_autocomplete() {
376 - if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
377 - wp_send_json_error( [] );
378 - }
379 - $query_per_page = 15;
380 - $post_type = 'post';
381 - $source_name = 'post_type';
382 - $paged = absint( $_POST['page'] ?? 1 );
383 - if ( ! empty( $_POST['post_type'] ) ) {
384 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
385 - $post_type = sanitize_text_field( $_POST['post_type'] );
386 - }
387 -
388 - if ( ! empty( $_POST['source_name'] ) ) {
389 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
390 - $source_name = sanitize_text_field( $_POST['source_name'] );
391 - }
392 -
393 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
394 - $search = ! empty( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
395 - $results = $post_list = [];
396 - switch ( $source_name ) {
397 - case 'taxonomy':
398 - $args = [
399 - 'hide_empty' => false,
400 - 'orderby' => 'name',
401 - 'order' => 'ASC',
402 - 'search' => $search,
403 - 'number' => '5',
404 - ];
405 -
406 - if ( $post_type !== 'all' ) {
407 - $args['taxonomy'] = $post_type;
408 - }
409 -
410 - $post_list = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
411 - break;
412 - case 'user':
413 - $users = [];
414 -
415 - foreach ( get_users( [ 'search' => "*{$search}*" ] ) as $user ) {
416 - $user_id = $user->ID;
417 - $user_name = $user->display_name;
418 - $users[ $user_id ] = $user_name;
419 - }
420 -
421 - $post_list = $users;
422 - break;
423 - default:
424 - $post_list = $this->get_query_data( $post_type, $query_per_page, $search, $paged );
425 - }
426 -
427 - $pagination = true;
428 - if ( count( $post_list ) < $query_per_page ) {
429 - $pagination = false;
430 - }
431 - if ( ! empty( $post_list ) ) {
432 - foreach ( $post_list as $key => $item ) {
433 - $results[] = [
434 - 'text' => $item,
435 - 'id' => $key,
436 - ];
437 - }
438 - }
439 - wp_send_json(
440 - [
441 - 'results' => $results,
442 - 'pagination' => [ 'more' => $pagination ],
443 - ]
444 - );
445 - }
446 -
447 -
448 - /**
449 - * Ajax callback for rt-select2
450 - *
451 - * @return void
452 - */
453 - public function select2_ajax_get_posts_value_titles() {
454 -
455 - if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
456 - wp_send_json_error( [] );
457 - }
458 -
459 - if ( empty( $_POST['id'] ) ) {
460 - wp_send_json_error( [] );
461 - }
462 -
463 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
464 - if ( empty( array_filter( $_POST['id'] ) ) ) {
465 - wp_send_json_error( [] );
466 - }
467 - $ids = array_map( 'intval', $_POST['id'] );
468 - $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
469 -
470 - switch ( $source_name ) {
471 - case 'taxonomy':
472 - $args = [
473 - 'hide_empty' => false,
474 - 'orderby' => 'name',
475 - 'order' => 'ASC',
476 - 'include' => implode( ',', $ids ),
477 - ];
478 -
479 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
480 - if ( $_POST['post_type'] !== 'all' ) {
481 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
482 - $args['taxonomy'] = sanitize_text_field( $_POST['post_type'] );
483 - }
484 -
485 - $response = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
486 - break;
487 - case 'user':
488 - $users = [];
489 -
490 - foreach ( get_users( [ 'include' => $ids ] ) as $user ) {
491 - $user_id = $user->ID;
492 - $user_name = $user->display_name . '-' . $user->ID;
493 - $users[ $user_id ] = $user_name;
494 - }
495 -
496 - $response = $users;
497 - break;
498 - default:
499 - $post_info = get_posts(
500 - [
501 - 'post_type' => sanitize_text_field( $_POST['post_type'] ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
502 - 'include' => implode( ',', $ids ),
503 - ]
504 - );
505 - $response = wp_list_pluck( $post_info, 'post_title', 'ID' );
506 - }
507 -
508 - if ( ! empty( $response ) ) {
509 - wp_send_json_success( [ 'results' => $response ] );
510 - } else {
511 - wp_send_json_error( [] );
512 - }
513 - }
514 -
515 -
516 - /**
517 - * Ajax callback for rt-select2
518 - *
519 - * @param $post_type
520 - * @param $limit
521 - * @param $search
522 - * @param $paged
523 - *
524 - * @return array
525 - */
526 - public function get_query_data( $post_type = 'any', $limit = 10, $search = '', $paged = 1 ) {
527 - global $wpdb;
528 - $where = '';
529 - $data = [];
530 -
531 - if ( - 1 == $limit ) {
532 - $limit = '';
533 - } elseif ( 0 == $limit ) {
534 - $limit = 'limit 0,1';
535 - } else {
536 - $offset = 0;
537 - if ( $paged ) {
538 - $offset = ( $paged - 1 ) * $limit;
539 - }
540 - $limit = $wpdb->prepare( ' limit %d, %d', esc_sql( $offset ), esc_sql( $limit ) );
541 - }
542 -
543 - if ( 'any' === $post_type ) {
544 - $in_search_post_types = get_post_types( [ 'exclude_from_search' => false ] );
545 - if ( empty( $in_search_post_types ) ) {
546 - $where .= ' AND 1=0 ';
547 - } else {
548 - $where .= " AND {$wpdb->posts}.post_type IN ('" . join(
549 - "', '",
550 - array_map( 'esc_sql', $in_search_post_types )
551 - ) . "')";
552 - }
553 - } elseif ( ! empty( $post_type ) ) {
554 - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", esc_sql( $post_type ) );
555 - }
556 -
557 - if ( ! empty( $search ) ) {
558 - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql( $search ) . '%' );
559 - }
560 -
561 - $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' {$where} {$limit}";
562 - $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
563 -
564 - if ( ! empty( $results ) ) {
565 - foreach ( $results as $row ) {
566 - $data[ $row->ID ] = $row->post_title . ' [#' . $row->ID . ']';
567 - }
568 - }
569 -
570 - return $data;
571 - }
572 -
573 - /**
574 - * Promotion.
575 - *
576 - * @param array $config Config.
577 - * @return array
578 - */
579 - public function promotePremiumWidgets( $config ) {
580 - if ( rtsb()->has_pro() ) {
581 - return $config;
582 - }
583 -
584 - if ( ! empty( $config['initial_document']['panel']['elements_categories']['rtsb-shopbuilder']['title'] ) ) {
585 - $title = $config['initial_document']['panel']['elements_categories']['rtsb-shopbuilder']['title'];
586 -
587 - if ( 'ShopBuilder - Shop' === $title || 'ShopBuilder - Archive' === $title ) {
588 - if ( ! isset( $config['promotionWidgets'] ) || ! is_array( $config['promotionWidgets'] ) ) {
589 - $config['promotionWidgets'] = [];
590 - }
591 -
592 - $pro_widgets = [
593 - [
594 - 'name' => 'rtsb-ajax-product-filters',
595 - 'title' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
596 - 'description' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
597 - 'icon' => 'rtsb-el-custom rtsb-element icon-rtsb-ajax-product-filters rtsb-promotional-element',
598 - 'categories' => '[ "rtsb-shopbuilder" ]',
599 - ],
600 - ];
601 -
602 - $config['promotionWidgets'] = array_merge( $config['promotionWidgets'], $pro_widgets );
603 -
604 - return $config;
605 - }
606 - }
607 -
608 - return $config;
609 - }
610 -
611 - /**
612 - * Get Icons.
613 - *
614 - * @return array
615 - */
616 - public function get_icons() {
617 - return [
618 - 'heart-empty',
619 - 'heart',
620 - 'eye',
621 - 'exchange',
622 - 'plus',
623 - 'minus',
624 - 'avatar',
625 - 'pay',
626 - 'share',
627 - 'clock',
628 - 'check-alt',
629 - 'check',
630 - 'delete',
631 - 'marker',
632 - 'list',
633 - 'list-2',
634 - 'power',
635 - 'cart',
636 - 'cart-2',
637 - 'cart-3',
638 - 'downloads',
639 - 'zoom',
640 - 'user-edit',
641 - 'grid',
642 - 'filter',
643 - 'billing',
644 - 'login',
645 - 'payment',
646 - 'search',
647 - 'edit',
648 - 'coupon',
649 - 'arrows-cw',
650 - 'trash-empty',
651 - ];
652 - }
653 -}
1 +<?php
2 +/**
3 + * Main BuilderController class.
4 + *
5 + * @package RadiusTheme\SB
6 + */
7 +
8 +namespace RadiusTheme\SB\Controllers;
9 +
10 +use Elementor\Plugin;
11 +use RadiusTheme\SB\Helpers\Fns;
12 +use RadiusTheme\SB\Helpers\BuilderFns;
13 +use RadiusTheme\SB\Traits\SingletonTrait;
14 +use RadiusTheme\SB\Controllers\Builder\BuilderCpt;
15 +use RadiusTheme\SB\Controllers\Hooks\BuilderHooks;
16 +use RadiusTheme\SB\Elementor\Controls\ImageSelectorControl;
17 +use RadiusTheme\SB\Models\ElementList;
18 +
19 +// Do not allow directly accessing this file.
20 +if ( ! defined( 'ABSPATH' ) ) {
21 + exit( 'This script cannot be accessed directly.' );
22 +}
23 +
24 +/**
25 + * Builder Controller
26 + */
27 +class BuilderController {
28 + /**
29 + * Builder page id.
30 + *
31 + * @var integer
32 + */
33 + private $builder_page_id = 0;
34 +
35 + /**
36 + * Page Edit By.
37 + *
38 + * @var string
39 + */
40 + private $page_edit_with = '';
41 +
42 + /**
43 + * Singleton Trait
44 + */
45 + use SingletonTrait;
46 +
47 + /**
48 + * Construct function
49 + */
50 + private function __construct() {
51 + $this->builder_page_id = BuilderFns::builder_page_id_by_page();
52 + $this->page_edit_with = Fns::page_edit_with( $this->builder_page_id );
53 +
54 + if ( ! is_admin() ) {
55 + BuilderHooks::instance();
56 + }
57 +
58 + BuilderCpt::instance();
59 +
60 + add_action( 'elementor/init', [ $this, 'elementor_init' ] );
61 + add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'editor_scripts' ] );
62 + add_action( 'template_redirect', [ $this, 'both_builder_frontend' ], 99 );
63 + }
64 +
65 + /**
66 + * Apply for frontend.
67 + *
68 + * @return void
69 + */
70 + public function both_builder_frontend() {
71 + add_action( 'rtsb/builder/template/before/content', [ $this, 'builder_template_before_content' ] );
72 + add_action( 'rtsb/builder/template/after/content', [ $this, 'builder_template_after_content' ] );
73 + }
74 +
75 + /**
76 + * Register Category
77 + *
78 + * @return void
79 + */
80 + public function elementor_init() {
81 + add_action( 'elementor/elements/categories_registered', [ $this, 'add_elementor_widget_categories' ] );
82 + add_action( 'elementor/widgets/register', [ $this, 'init_widgets' ] );
83 + add_action( 'elementor/controls/register', [ $this, 'init_controls' ] );
84 + }
85 +
86 + /**
87 + * Register Category
88 + *
89 + * @param object $elements_manager Category hooks.
90 + *
91 + * @return void
92 + */
93 + public function add_elementor_widget_categories( $elements_manager ) {
94 + $type = BuilderFns::builder_type( get_the_ID() );
95 + $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : null;
96 + $categories['rtsb-shopbuilder'] = [
97 + 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
98 + 'icon' => 'fa fa-plug',
99 + ];
100 + $categories['rtsb-shopbuilder-general'] = [
101 + 'title' => esc_html__( 'Shopbuilder - General', 'shopbuilder' ),
102 + 'icon' => 'fa fa-plug',
103 + ];
104 +
105 + $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
106 + $other_categories = $elements_manager->get_categories();
107 + $categories = array_merge(
108 + array_slice( $other_categories, 0, 1 ),
109 + $categories,
110 + array_slice( $other_categories, 1 )
111 + );
112 +
113 + $set_categories = function ( $categories ) {
114 + $this->categories = $categories;
115 + };
116 +
117 + $set_categories->call( $elements_manager, $categories );
118 + }
119 +
120 + /**
121 + * Init Controls
122 + *
123 + * Include controls files and register them
124 + *
125 + * @param object $controls_manager Controls Manager.
126 + *
127 + * @since 1.0.0
128 + */
129 + public function init_controls( $controls_manager ) {
130 + $controls_manager->register( new ImageSelectorControl() );
131 + }
132 +
133 + /**
134 + * Init Widgets
135 + *
136 + * Include widgets files and register them
137 + *
138 + * @since 1.0.0
139 + */
140 + public function init_widgets( $widgets_manager ) {
141 + foreach ( ElementList::instance()->get_list( true, 'active' ) as $element ) {
142 + if ( isset( $element['active'] ) && $element['active'] !== 'on' ) {
143 + continue;
144 + }
145 +
146 + if ( ! empty( $element['package'] ) && $element['package'] === 'pro-disabled' ) {
147 + continue;
148 + }
149 +
150 + if ( isset( $element['base_class'] ) && ! class_exists( $element['base_class'] ) ) {
151 + continue;
152 + }
153 +
154 + if ( ! empty( $element['category'] ) ) {
155 + $widget = false;
156 + switch ( $element['category'] ) {
157 + case 'product':
158 + if ( BuilderFns::is_product() ) {
159 + $widget = new $element['base_class']();
160 + }
161 + break;
162 + case 'shop':
163 + if ( BuilderFns::is_archive() || BuilderFns::is_shop() ) {
164 + $widget = new $element['base_class']();
165 + }
166 + break;
167 + case 'archive':
168 + if ( BuilderFns::is_archive() ) {
169 + $widget = new $element['base_class']();
170 + }
171 + break;
172 + case 'cart':
173 + if ( BuilderFns::is_cart() ) {
174 + $widget = new $element['base_class']();
175 + }
176 + break;
177 + case 'checkout':
178 + if ( BuilderFns::is_checkout() ) {
179 + $widget = new $element['base_class']();
180 + }
181 + break;
182 + case 'general':
183 + $widget = new $element['base_class']();
184 + break;
185 + default:
186 + }
187 + $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
188 +
189 + if ( $widget && is_object( $widget ) ) {
190 + $widgets_manager->register( $widget );
191 + }
192 + }
193 + }
194 + }
195 +
196 + /**
197 + * Editor JS.
198 + *
199 + * @return void
200 + */
201 + public function editor_scripts() {
202 + $version = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? time() : RTSB_VERSION;
203 +
204 + wp_enqueue_script(
205 + 'rtsb-editor-script',
206 + rtsb()->get_assets_uri( 'js/backend/editor.js' ),
207 + [
208 + 'jquery',
209 + 'elementor-editor',
210 + ],
211 + $version,
212 + true
213 + );
214 + $params = [
215 + 'isEditorForBuilder' => false,
216 + ];
217 + if ( BuilderFns::is_builder_preview() ) {
218 + $params['isEditorForBuilder'] = true;
219 + }
220 + wp_localize_script( 'rtsb-editor-script', 'rtsbTemplateBuilderEditorScript', $params );
221 + wp_enqueue_style( 'rtsb-el-editor-style', rtsb()->get_assets_uri( 'css/backend/elementor-editor.css' ), [], $version );
222 + }
223 +
224 + /**
225 + * Before Content for Elementor.
226 + *
227 + * @return void
228 + */
229 + public function builder_template_before_content() {
230 + /**
231 + * Before Header-Footer page template content.
232 + *
233 + * Fires before the content of Elementor Header-Footer page template.
234 + *
235 + * @since 2.0.0
236 + */
237 + if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
238 + do_action( 'elementor/page_templates/header-footer/before_content' );
239 + }
240 +
241 + $parent_class = apply_filters( 'rtsb/builder/content/parent_class', [] );
242 +
243 + if ( BuilderFns::is_product() ) {
244 + $product_id = Fns::get_prepared_product_id();
245 + $parent_class = wc_get_product_class( $parent_class, $product_id );
246 + }
247 +
248 + if ( BuilderFns::is_shop() ) {
249 + $parent_class[] = 'shop';
250 + }
251 +
252 + if ( BuilderFns::is_archive() ) {
253 + $parent_class[] = 'archive';
254 + }
255 +
256 + if ( BuilderFns::is_checkout() ) {
257 + $parent_class[] = 'checkout-page ';
258 + }
259 +
260 + ?>
261 + <!-- Before Content start -->
262 + <div class="<?php echo esc_attr( implode( ' ', $parent_class ) ); ?>">
263 + <?php if ( BuilderFns::is_checkout() ) { ?>
264 + <form name="checkout" method="post" class="rtsb-woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
265 + <?php
266 + }
267 +
268 + }
269 +
270 + /**
271 + * After Content for Elementor.
272 + *
273 + * @return void
274 + */
275 + public function builder_template_after_content() {
276 + /**
277 + * After Header-Footer page template content.
278 + *
279 + * Fires after the content of Elementor Header-Footer page template.
280 + *
281 + * @since 2.0.0
282 + */
283 + if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
284 + do_action( 'elementor/page_templates/header-footer/after_content' );
285 + }
286 +
287 + if ( BuilderFns::is_checkout() ) {
288 + ?>
289 + </form>
290 + <?php
291 + }
292 + ?>
293 + </div>
294 + <!-- After Content end -->
295 + <?php
296 + }
297 +}