PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.1.0
ShopBuilder – WooCommerce Builder For Elementor v2.1.0
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.0, at app/Controllers/BuilderController.php

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