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

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

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