PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.1.8
ShopBuilder – WooCommerce Builder For Elementor v2.1.8
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
shopbuilder / app / Controllers / BuilderController.php

BuilderController.php in ShopBuilder – WooCommerce Builder For Elementor 2.1.8, at app/Controllers/BuilderController.php

644 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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_rt_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
74 add_action( 'wp_ajax_nopriv_rt_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
75 // Select2 ajax save data.
76 add_action( 'wp_ajax_rt_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
77 add_action( 'wp_ajax_nopriv_rt_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 $type = BuilderFns::builder_type( get_the_ID() );
113 if ( $type ) {
114 $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : '';
115 $builder_type = str_replace( 'My Account - ', '', $builder_type );
116 $categories['rtsb-shopbuilder'] = [
117 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
118 'icon' => 'fa fa-plug',
119 ];
120 }
121 if ( 'quick-view' !== $type ) {
122 $categories['rtsb-shopbuilder-general'] = [
123 'title' => esc_html__( 'Shopbuilder - General', 'shopbuilder' ),
124 'icon' => 'fa fa-plug',
125 ];
126 }
127 $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
128 $other_categories = $elements_manager->get_categories();
129 $categories = array_merge(
130 array_slice( $other_categories, 0, 1 ),
131 $categories,
132 array_slice( $other_categories, 1 )
133 );
134
135 $set_categories = function ( $categories ) {
136 $this->categories = $categories;
137 };
138
139 $set_categories->call( $elements_manager, $categories );
140 }
141
142 /**
143 * Init Controls
144 *
145 * Include controls files and register them
146 *
147 * @param object $controls_manager Controls Manager.
148 *
149 * @since 1.0.0
150 */
151 public function init_controls( $controls_manager ) {
152 $controls_manager->register( new ImageSelectorControl() );
153 $controls_manager->register( new Select2AjaxControl() );
154 }
155
156 /**
157 * Init Widgets
158 *
159 * Include widgets files and register them
160 *
161 * @since 1.0.0
162 */
163 public function init_widgets( $widgets_manager ) {
164
165 $get_list = ElementList::instance()->get_list( true, 'active' );
166 foreach ( $get_list as $element ) {
167 if ( isset( $element['active'] ) && 'on' !== $element['active'] ) {
168 continue;
169 }
170
171 if ( ! empty( $element['package'] ) && 'pro-disabled' === $element['package'] ) {
172 continue;
173 }
174
175 if ( empty( $element['base_class'] ) || ! class_exists( $element['base_class'] ) ) {
176 continue;
177 }
178
179 if ( ! empty( $element['category'] ) ) {
180 $widget = false;
181 $import = apply_filters( 'rtsb_import_status', false );
182 switch ( $element['category'] ) {
183 case 'product':
184 if ( BuilderFns::is_product() || $import ) {
185 $widget = new $element['base_class']();
186 }
187 break;
188 case 'shop':
189 if ( BuilderFns::is_archive() || BuilderFns::is_shop() || $import ) {
190 $widget = new $element['base_class']();
191 }
192 break;
193 case 'archive':
194 if ( BuilderFns::is_archive() || $import ) {
195 $widget = new $element['base_class']();
196 }
197 break;
198 case 'cart':
199 if ( BuilderFns::is_cart() || $import ) {
200 $widget = new $element['base_class']();
201 }
202 break;
203 case 'checkout':
204 if ( BuilderFns::is_checkout() || $import ) {
205 $widget = new $element['base_class']();
206 }
207 break;
208 case 'general':
209 $widget = new $element['base_class']();
210 break;
211 default:
212 }
213 $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
214
215 if ( $widget && is_object( $widget ) ) {
216 $widgets_manager->register( $widget );
217 }
218 }
219 }
220 }
221
222 /**
223 * Adding custom icons in Elementor
224 *
225 * @param array $tabs Tabs.
226 *
227 * @return array
228 */
229 public function rtsb_icons( $tabs = [] ) {
230 $custom_icons = $this->get_icons();
231
232 $tabs['shopbuilder-icons'] = [
233 'name' => 'rtsb-fonts',
234 'label' => esc_html__( 'ShopBuilder Icons', 'shopbuilder' ),
235 'labelIcon' => 'fab fa-elementor',
236 'prefix' => 'rtsb-icon-',
237 'displayPrefix' => 'rtsb-icon',
238 'url' => rtsb()->get_assets_uri( 'css/frontend/rtsb-fonts.css' ),
239 'icons' => $custom_icons,
240 'ver' => '1.0',
241 ];
242
243 return $tabs;
244 }
245
246 /**
247 * Editor JS.
248 *
249 * @return void
250 */
251 public function editor_scripts() {
252 $version = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? time() : RTSB_VERSION;
253
254 wp_enqueue_script(
255 'rtsb-editor-script',
256 rtsb()->get_assets_uri( 'js/backend/editor.js' ),
257 [
258 'jquery',
259 'elementor-editor',
260 'jquery-elementor-select2',
261 ],
262 $version,
263 true
264 );
265 $params = [
266 'isEditorForBuilder' => false,
267 ];
268 if ( BuilderFns::is_builder_preview() ) {
269 $params['isEditorForBuilder'] = true;
270 }
271 wp_localize_script( 'rtsb-editor-script', 'rtsbTemplateBuilderEditorScript', $params );
272 wp_enqueue_style( 'rtsb-el-editor-style', rtsb()->get_assets_uri( 'css/backend/elementor-editor.css' ), [], $version );
273 }
274
275 /**
276 * Before Content for Elementor.
277 *
278 * @return void
279 */
280 public function builder_template_before_content() {
281 /**
282 * Before Header-Footer page template content.
283 *
284 * Fires before the content of Elementor Header-Footer page template.
285 *
286 * @since 2.0.0
287 */
288 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
289 do_action( 'elementor/page_templates/header-footer/before_content' );
290 }
291
292 $parent_class = apply_filters( 'rtsb/builder/content/parent_class', [] );
293
294 if ( BuilderFns::is_product() ) {
295 $product_id = Fns::get_prepared_product_id();
296 $parent_class = wc_get_product_class( $parent_class, $product_id );
297 if ( function_exists( 'rtwpvs' ) ) {
298 $_product = Fns::get_product();
299 if ( $_product->is_type( 'variable' ) ) {
300 $parent_class[] = 'rtwpvs-product';
301 $beside_label = function_exists( 'rtwpvsp' ) && rtwpvs()->get_option( 'attribute_on_click_behavior' );
302 if ( $beside_label ) {
303 $parent_class[] = 'rtwpvs-selected-term-beside-label';
304 }
305 }
306 }
307 }
308
309 if ( BuilderFns::is_shop() ) {
310 $parent_class[] = 'shop';
311 }
312
313 if ( BuilderFns::is_archive() ) {
314 $parent_class[] = 'archive';
315 }
316
317 if ( BuilderFns::is_checkout() ) {
318 $parent_class[] = 'checkout-page ';
319 }
320
321 ?>
322 <!-- Before Content start -->
323 <div class="<?php echo esc_attr( implode( ' ', $parent_class ) ); ?>">
324 <?php
325 if ( BuilderFns::is_checkout() ) {
326 if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
327 return;
328 }
329 ?>
330 <form name="checkout" method="post" class="rtsb-woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
331 <?php
332 }
333 }
334
335 /**
336 * After Content for Elementor.
337 *
338 * @return void
339 */
340 public function builder_template_after_content() {
341 /**
342 * After Header-Footer page template content.
343 *
344 * Fires after the content of Elementor Header-Footer page template.
345 *
346 * @since 2.0.0
347 */
348 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
349 do_action( 'elementor/page_templates/header-footer/after_content' );
350 }
351
352 if ( BuilderFns::is_checkout() ) {
353 if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
354 return;
355 }
356 ?>
357 </form>
358 <?php
359 }
360 ?>
361 </div>
362 <!-- After Content end -->
363 <?php
364 }
365
366 /**
367 * Ajax callback for rt-select2
368 *
369 * @return void
370 */
371 public function select2_ajax_posts_filter_autocomplete() {
372 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
373 wp_send_json_error( [] );
374 }
375 $query_per_page = 15;
376 $post_type = 'post';
377 $source_name = 'post_type';
378 $paged = absint( $_POST['page'] ?? 1 );
379 if ( ! empty( $_POST['post_type'] ) ) {
380 $post_type = sanitize_text_field( $_POST['post_type'] );
381 }
382
383 if ( ! empty( $_POST['source_name'] ) ) {
384 $source_name = sanitize_text_field( $_POST['source_name'] );
385 }
386
387 $search = ! empty( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
388 $results = $post_list = [];
389 switch ( $source_name ) {
390 case 'taxonomy':
391 $args = [
392 'hide_empty' => false,
393 'orderby' => 'name',
394 'order' => 'ASC',
395 'search' => $search,
396 'number' => '5',
397 ];
398
399 if ( $post_type !== 'all' ) {
400 $args['taxonomy'] = $post_type;
401 }
402
403 $post_list = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
404 break;
405 case 'user':
406 $users = [];
407
408 foreach ( get_users( [ 'search' => "*{$search}*" ] ) as $user ) {
409 $user_id = $user->ID;
410 $user_name = $user->display_name;
411 $users[ $user_id ] = $user_name;
412 }
413
414 $post_list = $users;
415 break;
416 default:
417 $post_list = $this->get_query_data( $post_type, $query_per_page, $search, $paged );
418 }
419
420 $pagination = true;
421 if ( count( $post_list ) < $query_per_page ) {
422 $pagination = false;
423 }
424 if ( ! empty( $post_list ) ) {
425 foreach ( $post_list as $key => $item ) {
426 $results[] = [
427 'text' => $item,
428 'id' => $key,
429 ];
430 }
431 }
432 wp_send_json(
433 [
434 'results' => $results,
435 'pagination' => [ 'more' => $pagination ],
436 ]
437 );
438 }
439
440
441 /**
442 * Ajax callback for rt-select2
443 *
444 * @return void
445 */
446 public function select2_ajax_get_posts_value_titles() {
447
448 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
449 wp_send_json_error( [] );
450 }
451
452 if ( empty( $_POST['id'] ) ) {
453 wp_send_json_error( [] );
454 }
455
456 if ( empty( array_filter( $_POST['id'] ) ) ) {
457 wp_send_json_error( [] );
458 }
459 $ids = array_map( 'intval', $_POST['id'] );
460 $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : '';
461
462 switch ( $source_name ) {
463 case 'taxonomy':
464 $args = [
465 'hide_empty' => false,
466 'orderby' => 'name',
467 'order' => 'ASC',
468 'include' => implode( ',', $ids ),
469 ];
470
471 if ( $_POST['post_type'] !== 'all' ) {
472 $args['taxonomy'] = sanitize_text_field( $_POST['post_type'] );
473 }
474
475 $response = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
476 break;
477 case 'user':
478 $users = [];
479
480 foreach ( get_users( [ 'include' => $ids ] ) as $user ) {
481 $user_id = $user->ID;
482 $user_name = $user->display_name . '-' . $user->ID;
483 $users[ $user_id ] = $user_name;
484 }
485
486 $response = $users;
487 break;
488 default:
489 $post_info = get_posts(
490 [
491 'post_type' => sanitize_text_field( $_POST['post_type'] ),
492 'include' => implode( ',', $ids ),
493 ]
494 );
495 $response = wp_list_pluck( $post_info, 'post_title', 'ID' );
496 }
497
498 if ( ! empty( $response ) ) {
499 wp_send_json_success( [ 'results' => $response ] );
500 } else {
501 wp_send_json_error( [] );
502 }
503 }
504
505
506 /**
507 * Ajax callback for rt-select2
508 *
509 * @param $post_type
510 * @param $limit
511 * @param $search
512 * @param $paged
513 *
514 * @return array
515 */
516 public function get_query_data( $post_type = 'any', $limit = 10, $search = '', $paged = 1 ) {
517 global $wpdb;
518 $where = '';
519 $data = [];
520
521 if ( - 1 == $limit ) {
522 $limit = '';
523 } elseif ( 0 == $limit ) {
524 $limit = 'limit 0,1';
525 } else {
526 $offset = 0;
527 if ( $paged ) {
528 $offset = ( $paged - 1 ) * $limit;
529 }
530 $limit = $wpdb->prepare( ' limit %d, %d', esc_sql( $offset ), esc_sql( $limit ) );
531 }
532
533 if ( 'any' === $post_type ) {
534 $in_search_post_types = get_post_types( [ 'exclude_from_search' => false ] );
535 if ( empty( $in_search_post_types ) ) {
536 $where .= ' AND 1=0 ';
537 } else {
538 $where .= " AND {$wpdb->posts}.post_type IN ('" . join(
539 "', '",
540 array_map( 'esc_sql', $in_search_post_types )
541 ) . "')";
542 }
543 } elseif ( ! empty( $post_type ) ) {
544 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", esc_sql( $post_type ) );
545 }
546
547 if ( ! empty( $search ) ) {
548 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql( $search ) . '%' );
549 }
550
551 $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' {$where} {$limit}";
552 $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
553
554 if ( ! empty( $results ) ) {
555 foreach ( $results as $row ) {
556 $data[ $row->ID ] = $row->post_title . ' [#' . $row->ID . ']';
557 }
558 }
559
560 return $data;
561 }
562
563 /**
564 * Promotion.
565 *
566 * @param array $config Config.
567 * @return array
568 */
569 public function promotePremiumWidgets( $config ) {
570 if ( rtsb()->has_pro() ) {
571 return $config;
572 }
573
574 if ( ! empty( $config['initial_document']['panel']['elements_categories']['rtsb-shopbuilder']['title'] ) ) {
575 $title = $config['initial_document']['panel']['elements_categories']['rtsb-shopbuilder']['title'];
576
577 if ( 'ShopBuilder - Shop' === $title || 'ShopBuilder - Archive' === $title ) {
578 if ( ! isset( $config['promotionWidgets'] ) || ! is_array( $config['promotionWidgets'] ) ) {
579 $config['promotionWidgets'] = [];
580 }
581
582 $pro_widgets = [
583 [
584 'name' => 'rtsb-ajax-product-filters',
585 'title' => esc_html__( 'Ajax Product Filters', 'testimonial-slider-showcase' ),
586 'description' => esc_html__( 'Ajax Product Filters', 'testimonial-slider-showcase' ),
587 'icon' => 'rtsb-el-custom rtsb-element icon-rtsb-ajax-product-filters rtsb-promotional-element',
588 'categories' => '[ "rtsb-shopbuilder" ]',
589 ],
590 ];
591
592 $config['promotionWidgets'] = array_merge( $config['promotionWidgets'], $pro_widgets );
593
594 return $config;
595 }
596 }
597
598 return $config;
599 }
600
601 /**
602 * Get Icons.
603 *
604 * @return array
605 */
606 public function get_icons() {
607 return [
608 'heart-empty',
609 'heart',
610 'eye',
611 'exchange',
612 'plus',
613 'minus',
614 'avatar',
615 'pay',
616 'share',
617 'clock',
618 'check-alt',
619 'check',
620 'delete',
621 'marker',
622 'list',
623 'list-2',
624 'power',
625 'cart',
626 'cart-2',
627 'cart-3',
628 'downloads',
629 'zoom',
630 'user-edit',
631 'grid',
632 'filter',
633 'billing',
634 'login',
635 'payment',
636 'search',
637 'edit',
638 'coupon',
639 'arrows-cw',
640 'trash-empty',
641 ];
642 }
643 }
644