PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.1.15
ShopBuilder – WooCommerce Builder For Elementor v2.1.15
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 2.3.0 All 62 releases
shopbuilder / app / Controllers / BuilderController.php

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

648 lines 16.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_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 ) {
140 $this->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 $post_type = sanitize_text_field( $_POST['post_type'] );
385 }
386
387 if ( ! empty( $_POST['source_name'] ) ) {
388 $source_name = sanitize_text_field( $_POST['source_name'] );
389 }
390
391 $search = ! empty( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
392 $results = $post_list = [];
393 switch ( $source_name ) {
394 case 'taxonomy':
395 $args = [
396 'hide_empty' => false,
397 'orderby' => 'name',
398 'order' => 'ASC',
399 'search' => $search,
400 'number' => '5',
401 ];
402
403 if ( $post_type !== 'all' ) {
404 $args['taxonomy'] = $post_type;
405 }
406
407 $post_list = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
408 break;
409 case 'user':
410 $users = [];
411
412 foreach ( get_users( [ 'search' => "*{$search}*" ] ) as $user ) {
413 $user_id = $user->ID;
414 $user_name = $user->display_name;
415 $users[ $user_id ] = $user_name;
416 }
417
418 $post_list = $users;
419 break;
420 default:
421 $post_list = $this->get_query_data( $post_type, $query_per_page, $search, $paged );
422 }
423
424 $pagination = true;
425 if ( count( $post_list ) < $query_per_page ) {
426 $pagination = false;
427 }
428 if ( ! empty( $post_list ) ) {
429 foreach ( $post_list as $key => $item ) {
430 $results[] = [
431 'text' => $item,
432 'id' => $key,
433 ];
434 }
435 }
436 wp_send_json(
437 [
438 'results' => $results,
439 'pagination' => [ 'more' => $pagination ],
440 ]
441 );
442 }
443
444
445 /**
446 * Ajax callback for rt-select2
447 *
448 * @return void
449 */
450 public function select2_ajax_get_posts_value_titles() {
451
452 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
453 wp_send_json_error( [] );
454 }
455
456 if ( empty( $_POST['id'] ) ) {
457 wp_send_json_error( [] );
458 }
459
460 if ( empty( array_filter( $_POST['id'] ) ) ) {
461 wp_send_json_error( [] );
462 }
463 $ids = array_map( 'intval', $_POST['id'] );
464 $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : '';
465
466 switch ( $source_name ) {
467 case 'taxonomy':
468 $args = [
469 'hide_empty' => false,
470 'orderby' => 'name',
471 'order' => 'ASC',
472 'include' => implode( ',', $ids ),
473 ];
474
475 if ( $_POST['post_type'] !== 'all' ) {
476 $args['taxonomy'] = sanitize_text_field( $_POST['post_type'] );
477 }
478
479 $response = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
480 break;
481 case 'user':
482 $users = [];
483
484 foreach ( get_users( [ 'include' => $ids ] ) as $user ) {
485 $user_id = $user->ID;
486 $user_name = $user->display_name . '-' . $user->ID;
487 $users[ $user_id ] = $user_name;
488 }
489
490 $response = $users;
491 break;
492 default:
493 $post_info = get_posts(
494 [
495 'post_type' => sanitize_text_field( $_POST['post_type'] ),
496 'include' => implode( ',', $ids ),
497 ]
498 );
499 $response = wp_list_pluck( $post_info, 'post_title', 'ID' );
500 }
501
502 if ( ! empty( $response ) ) {
503 wp_send_json_success( [ 'results' => $response ] );
504 } else {
505 wp_send_json_error( [] );
506 }
507 }
508
509
510 /**
511 * Ajax callback for rt-select2
512 *
513 * @param $post_type
514 * @param $limit
515 * @param $search
516 * @param $paged
517 *
518 * @return array
519 */
520 public function get_query_data( $post_type = 'any', $limit = 10, $search = '', $paged = 1 ) {
521 global $wpdb;
522 $where = '';
523 $data = [];
524
525 if ( - 1 == $limit ) {
526 $limit = '';
527 } elseif ( 0 == $limit ) {
528 $limit = 'limit 0,1';
529 } else {
530 $offset = 0;
531 if ( $paged ) {
532 $offset = ( $paged - 1 ) * $limit;
533 }
534 $limit = $wpdb->prepare( ' limit %d, %d', esc_sql( $offset ), esc_sql( $limit ) );
535 }
536
537 if ( 'any' === $post_type ) {
538 $in_search_post_types = get_post_types( [ 'exclude_from_search' => false ] );
539 if ( empty( $in_search_post_types ) ) {
540 $where .= ' AND 1=0 ';
541 } else {
542 $where .= " AND {$wpdb->posts}.post_type IN ('" . join(
543 "', '",
544 array_map( 'esc_sql', $in_search_post_types )
545 ) . "')";
546 }
547 } elseif ( ! empty( $post_type ) ) {
548 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", esc_sql( $post_type ) );
549 }
550
551 if ( ! empty( $search ) ) {
552 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql( $search ) . '%' );
553 }
554
555 $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' {$where} {$limit}";
556 $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
557
558 if ( ! empty( $results ) ) {
559 foreach ( $results as $row ) {
560 $data[ $row->ID ] = $row->post_title . ' [#' . $row->ID . ']';
561 }
562 }
563
564 return $data;
565 }
566
567 /**
568 * Promotion.
569 *
570 * @param array $config Config.
571 * @return array
572 */
573 public function promotePremiumWidgets( $config ) {
574 if ( rtsb()->has_pro() ) {
575 return $config;
576 }
577
578 if ( ! empty( $config['initial_document']['panel']['elements_categories']['rtsb-shopbuilder']['title'] ) ) {
579 $title = $config['initial_document']['panel']['elements_categories']['rtsb-shopbuilder']['title'];
580
581 if ( 'ShopBuilder - Shop' === $title || 'ShopBuilder - Archive' === $title ) {
582 if ( ! isset( $config['promotionWidgets'] ) || ! is_array( $config['promotionWidgets'] ) ) {
583 $config['promotionWidgets'] = [];
584 }
585
586 $pro_widgets = [
587 [
588 'name' => 'rtsb-ajax-product-filters',
589 'title' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
590 'description' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
591 'icon' => 'rtsb-el-custom rtsb-element icon-rtsb-ajax-product-filters rtsb-promotional-element',
592 'categories' => '[ "rtsb-shopbuilder" ]',
593 ],
594 ];
595
596 $config['promotionWidgets'] = array_merge( $config['promotionWidgets'], $pro_widgets );
597
598 return $config;
599 }
600 }
601
602 return $config;
603 }
604
605 /**
606 * Get Icons.
607 *
608 * @return array
609 */
610 public function get_icons() {
611 return [
612 'heart-empty',
613 'heart',
614 'eye',
615 'exchange',
616 'plus',
617 'minus',
618 'avatar',
619 'pay',
620 'share',
621 'clock',
622 'check-alt',
623 'check',
624 'delete',
625 'marker',
626 'list',
627 'list-2',
628 'power',
629 'cart',
630 'cart-2',
631 'cart-3',
632 'downloads',
633 'zoom',
634 'user-edit',
635 'grid',
636 'filter',
637 'billing',
638 'login',
639 'payment',
640 'search',
641 'edit',
642 'coupon',
643 'arrows-cw',
644 'trash-empty',
645 ];
646 }
647 }
648