PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / trunk
ShopBuilder – WooCommerce Builder For Elementor vtrunk
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 / Admin / Ajax / ModalTemplate.php

ModalTemplate.php in ShopBuilder – WooCommerce Builder For Elementor trunk, at app/Controllers/Admin/Ajax/ModalTemplate.php

747 lines 37.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace RadiusTheme\SB\Controllers\Admin\Ajax;
4
5 use Elementor\Plugin;
6 use RadiusTheme\SB\Helpers\BuilderFns;
7 use RadiusTheme\SB\Helpers\Cache;
8 use RadiusTheme\SB\Helpers\Fns;
9 use RadiusTheme\SB\Models\TemplateSettings;
10 use RadiusTheme\SB\Traits\SingletonTrait;
11 use Elementor\Core\Files\Uploads_Manager;
12
13 // Do not allow directly accessing this file.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit( 'This script cannot be accessed directly.' );
16 }
17
18 /**
19 * Template Create Modal.
20 */
21 class ModalTemplate {
22 /**
23 * Singleton Trait.
24 */
25 use SingletonTrait;
26
27 /**
28 * Construct function
29 */
30 private function __construct() {
31 add_action( 'wp_ajax_rtsb_builder_modal_template', [ $this, 'response' ] );
32 add_action( 'wp_ajax_rtsb_modal_product_search', [ $this, 'product_search' ] );
33 add_action( 'wp_ajax_rtsb_modal_term_search', [ $this, 'term_search' ] );
34 }
35
36 /**
37 * Popups For Create Template
38 *
39 * @return void
40 */
41 public function response() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
42 $title = '<h2>' . esc_html__( 'Template Settings', 'shopbuilder' ) . '</h2>';
43 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
44 $return = [
45 'success' => false,
46 'title' => $title,
47 'content' => esc_html__( 'Session Expired...', 'shopbuilder' ),
48 ];
49 wp_send_json( $return );
50 }
51
52 if ( ! current_user_can( 'manage_options' ) ) {
53 $return = [
54 'success' => false,
55 'title' => $title,
56 'content' => esc_html__( 'Permission Denied...', 'shopbuilder' ),
57 ];
58 wp_send_json( $return );
59 }
60 if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
61 $return = [
62 'success' => true,
63 'title' => $title,
64 'content' => '<h2 style="text-align: center;">' . esc_html__( 'Permission Denied. Please Install elementor', 'shopbuilder' ) . '</h2>',
65 ];
66
67 wp_send_json( $return );
68 }
69
70 add_filter( 'option_' . Uploads_Manager::UNFILTERED_FILE_UPLOADS_KEY, '__return_true' );
71 Plugin::$instance->files_manager->clear_cache();
72
73 // user capability check.
74 $user = wp_get_current_user();
75 $allowed_roles = [ 'editor', 'administrator', 'author' ];
76
77 if ( ! array_intersect( $allowed_roles, Fns::get_current_user_roles() ) ) {
78 wp_die( esc_html__( 'You don\'t have permission to perform this action', 'shopbuilder' ) );
79 }
80
81 // Check if the user is not logged in and the provided 'user_id' in the request does not match the currently logged-in user's ID.
82 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.PHP.YodaConditions.NotYoda
83 if ( ! is_user_logged_in() && $user->ID !== sanitize_text_field( $_REQUEST['user_id'] ) ) {
84 wp_die( esc_html__( 'You don\'t have proper authorization to perform this action', 'shopbuilder' ) );
85 }
86
87 $post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : null;
88 $layout_id = isset( $_REQUEST['layout_id'] ) ? absint( $_REQUEST['layout_id'] ) : null;
89
90 $template_type = null;
91 $product_page_for = 'all_products';
92 $template_default = null;
93 $url = '';
94 $tmp_title = '';
95 $_rtsb_import_id = '';
96 $edit_by = did_action( 'elementor/loaded' ) ? 'elementor' : 'elementor';
97 if ( $post_id ) {
98 $tmp_title = get_the_title( $post_id );
99 $template_type = get_post_meta( $post_id, BuilderFns::template_type_meta_key(), true );
100 $options = BuilderFns::option_name( $template_type );
101 $template_default = TemplateSettings::instance()->get_option( $options );
102 $edit_by = Fns::page_edit_with( $post_id );
103 $action = 'edit';
104 if ( rtsb()->has_pro() ) {
105 $product_page_for = get_post_meta( $post_id, '_is_product_page_template_for', true );
106 }
107
108 /* This Condition Will remove after release Gutenberg Addons. */
109 if ( 'gutenberg' == $edit_by ) {
110 $action = 'elementor';
111 $edit_by = 'elementor';
112 }
113
114 if ( 'elementor' == $edit_by ) {
115 $action = 'elementor';
116 }
117
118 $url = add_query_arg(
119 [
120 'post' => $post_id,
121 'action' => $action,
122 ],
123 admin_url( 'post.php' )
124 );
125
126 $_rtsb_import_id = get_post_meta( $post_id, '_rtsb_import_id', true );
127 }
128 ob_start();
129
130 ?>
131 <form action="<?php echo esc_url( admin_url( 'edit.php?post_type=rtsb_builder' ) ); ?>" autocomplete="off" data-imported-id="<?php echo esc_attr( $_rtsb_import_id ); ?>">
132 <div class="rtsb-tb-modal-wrapper">
133 <div class="rtsb-template-name rtsb-tb-field-wraper">
134 <label for="rtsb_tb_template_name"> <?php esc_html_e( 'Template Name', 'shopbuilder' ); ?></label>
135 <input
136 required
137 class="rtsb-field"
138 type="text"
139 id="rtsb_tb_template_name"
140 name="rtsb_tb_template_name"
141 placeholder="<?php esc_attr_e( 'Enter Template Name', 'shopbuilder' ); ?>"
142 value="<?php echo esc_attr( $tmp_title ); ?>"
143 autocomplete="off"
144 >
145 <span class="message" style="display: none; color:red"><?php esc_html_e( 'This field is required', 'shopbuilder' ); ?></span>
146 </div>
147 <div class="rtsb-template-type rtsb-tb-field-wraper">
148 <label for="rtsb_tb_template_type"><?php esc_html_e( 'Select Template Type', 'shopbuilder' ); ?></label>
149 <select class="rtsb-field" id="rtsb_tb_template_type" name="rtsb_tb_template_type">
150 <?php
151 $builder_page_types = BuilderFns::builder_page_types();
152 foreach ( $builder_page_types as $key => $value ) {
153 ?>
154 <option <?php echo esc_attr( $key === $template_type ? 'selected="selected"' : '' ); ?> value="<?php echo esc_attr( $key ); ?>"> <?php echo esc_html( $value ); ?> </option>
155 <?php } ?>
156 </select>
157 </div>
158
159 <div class="rtsb-product-page-for rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;" >
160 <label for="product_page_for">
161 <?php esc_html_e( 'Product Template For', 'shopbuilder' ); ?>
162 <?php if ( ! rtsb()->has_pro() ) { ?>
163 <div class="card-label">
164 <span class="rtsb-btn-import pro-btn">
165 <?php echo esc_html( 'PRO' ); ?>
166 </span>
167 </div>
168 <?php } ?>
169 </label>
170
171 <select class="rtsb-field" id="product_page_for" name="product_page_for">
172 <?php
173 $builder_page_types = [
174 'all_products' => esc_html__( 'All Products', 'shopbuilder' ),
175 'product_cats' => esc_html__( 'Product Categories', 'shopbuilder' ),
176 'product_brands' => esc_html__( 'Product Brands', 'shopbuilder' ),
177 'product_tags' => esc_html__( 'Product Tags', 'shopbuilder' ),
178 'specific_products' => esc_html__( 'Selected Products', 'shopbuilder' ),
179 ];
180 // Only expose the brand option when the `product_brand` taxonomy is
181 // registered (WC 9.4+ native, or a brand plugin). Hides gracefully
182 // on sites without brand support.
183 if ( ! taxonomy_exists( 'product_brand' ) ) {
184 unset( $builder_page_types['product_brands'] );
185 }
186 foreach ( $builder_page_types as $key => $value ) {
187 ?>
188 <option <?php echo esc_attr( $key === $product_page_for ? 'selected="selected"' : '' ); ?> value="<?php echo esc_attr( $key ); ?>"> <?php echo esc_html( $value ); ?> </option>
189 <?php } ?>
190 </select>
191 </div>
192
193 <?php if ( ! rtsb()->has_pro() ) { ?>
194 <div class="rtsb-product-page-for rtsb-tb-field-wraper" style="display:none;" >
195 <label for="product_page_for"> </label>
196 <span class="elementor-pro-notice"><a target="_blank" href="<?php echo esc_url( rtsb()->pro_version_link() ); ?>">Upgrade to PRO</a> to unlock Product Categories, Product Tags, Selected Products</span>
197 </div>
198 <?php } ?>
199
200 <!-- Product Page For Categories -->
201 <div class="rtsb-categories-page-field rtsb-product-page-for-the-categories rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
202 <?php
203 $default_items_link = '';
204 $default_items = '';
205 $categories_name = apply_filters( 'rtsb/template/builder/selected/categories', [], $post_id, $template_type );
206 if ( ! empty( $categories_name ) && is_array( $categories_name ) ) {
207 foreach ( $categories_name as $c_name ) {
208 $cat = get_term_by( 'slug', $c_name, 'product_cat' );
209 $title_cat = $cat->name;
210 $link = get_term_link( $cat );
211 if ( ! is_wp_error( $link ) ) {
212 $default_items_link .= '<a target="_blank" href="' . get_term_link( $cat ) . '">' . $title_cat . '</a>';
213 }
214 $default_items .= '<option selected="selected" value="' . $c_name . '">' . $title_cat . '</option>';
215 }
216 }
217 ?>
218 <label for="rtsb_page_for_the_products">
219 <?php esc_html_e( 'Select Product Categories', 'shopbuilder' ); ?>
220 <?php if ( ! rtsb()->has_pro() ) { ?>
221 <div class="card-label">
222 <span class="rtsb-btn-import pro-btn">
223 <?php echo esc_html( 'PRO' ); ?>
224 </span>
225 </div>
226 <?php } ?>
227 </label>
228 <select class="rtsb-field" id="rtsb_page_for_the_categories" name="rtsb_page_for_the_categories" multiple="multiple">
229 <?php Fns::print_html( $default_items, true ); ?>
230 </select>
231 <p style="margin:0;">Select a Product Category to apply this template. You can select multiple Categories. Keep it blank to apply to all Categories.
232 <?php
233 if ( ! empty( $default_items_link ) ) {
234 ?>
235 <span style="display: flex; gap: 3px 7px; flex-wrap: wrap; margin-top: 10px;"> <?php Fns::print_html( 'View Category Archive Pages: ' . $default_items_link ); ?> </span>
236 <?php
237 }
238 ?>
239 </p>
240 </div>
241
242 <?php if ( ! rtsb()->has_pro() ) { ?>
243 <div class="rtsb-categories-page-field rtsb-product-page-for-the-categories rtsb-tb-field-wraper" style="display:none;">
244 <label for="product_page_for"> </label>
245 <span class="elementor-pro-notice"><a target="_blank" href="<?php echo esc_url( rtsb()->pro_version_link() ); ?>">Upgrade to PRO</a> to unlock Categories Base Prodcut Page.</span>
246 </div>
247 <?php } ?>
248
249 <!-- Product Page for Selected Product Tags-->
250 <div class="rtsb-product-tags-page-field rtsb-product-page-for-the-tags rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
251 <?php
252 $default_items_link = '';
253 $default_items = '';
254 $tags_name = apply_filters( 'rtsb/template/builder/selected/tags', [], $post_id, $template_type );
255 if ( ! empty( $tags_name ) && is_array( $tags_name ) ) {
256 foreach ( $tags_name as $tg_name ) {
257 $tag = get_term_by( 'slug', $tg_name, 'product_tag' );
258 $title_tag = $tag->name;
259 $link = get_term_link( $tag );
260 if ( ! is_wp_error( $link ) ) {
261 $default_items_link .= '<a target="_blank" href="' . get_term_link( $tag ) . '">' . $title_tag . '</a>';
262 }
263 $default_items .= '<option selected="selected" value="' . $tg_name . '">' . $title_tag . '</option>';
264 }
265 }
266 ?>
267 <label for="rtsb_page_for_the_products_tags">
268 <?php esc_html_e( 'Select Product Tags', 'shopbuilder' ); ?>
269 <?php if ( ! rtsb()->has_pro() ) { ?>
270 <div class="card-label">
271 <span class="rtsb-btn-import pro-btn">
272 <?php echo esc_html( 'PRO' ); ?>
273 </span>
274 </div>
275 <?php } ?>
276 </label>
277 <select class="rtsb-field" id="rtsb_page_for_the_products_tags" name="rtsb_page_for_the_products_tags" multiple="multiple">
278 <?php Fns::print_html( $default_items, true ); ?>
279 </select>
280 <p style="margin:0;">Select a Product Tags to apply this template. You can select multiple Tags. Keep it blank to apply to All.
281 <?php
282 if ( ! empty( $default_items_link ) ) {
283 ?>
284 <span style="display: flex; gap: 3px 7px; flex-wrap: wrap; margin-top: 10px;"> <?php Fns::print_html( 'View Tags Archive Pages: ' . $default_items_link ); ?> </span>
285 <?php
286 }
287 ?>
288 </p>
289 </div>
290
291
292 <!-- Product Page for Selected Product Brands -->
293 <?php if ( taxonomy_exists( 'product_brand' ) ) : ?>
294 <div class="rtsb-product-brands-page-field rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
295 <?php
296 $default_items_link = '';
297 $default_items = '';
298 $brands_name = apply_filters( 'rtsb/template/builder/selected/brands', [], $post_id, $template_type );
299 if ( ! empty( $brands_name ) && is_array( $brands_name ) ) {
300 foreach ( $brands_name as $b_name ) {
301 $brand = get_term_by( 'slug', $b_name, 'product_brand' );
302 if ( empty( $brand ) || is_wp_error( $brand ) ) {
303 continue;
304 }
305 $title_brand = $brand->name;
306 $link = get_term_link( $brand );
307 if ( ! is_wp_error( $link ) ) {
308 $default_items_link .= '<a target="_blank" href="' . esc_url( $link ) . '">' . esc_html( $title_brand ) . '</a>';
309 }
310 $default_items .= '<option selected="selected" value="' . esc_attr( $b_name ) . '">' . esc_html( $title_brand ) . '</option>';
311 }
312 }
313 ?>
314 <label for="rtsb_page_for_the_product_brands">
315 <?php esc_html_e( 'Select Product Brands', 'shopbuilder' ); ?>
316 <?php if ( ! rtsb()->has_pro() ) { ?>
317 <div class="card-label">
318 <span class="rtsb-btn-import pro-btn">
319 <?php echo esc_html( 'PRO' ); ?>
320 </span>
321 </div>
322 <?php } ?>
323 </label>
324 <select class="rtsb-field" id="rtsb_page_for_the_product_brands" name="rtsb_page_for_the_product_brands" multiple="multiple">
325 <?php Fns::print_html( $default_items, true ); ?>
326 </select>
327 <p style="margin:0;">Select a Product Brand to apply this template. You can select multiple Brands. Keep it blank to apply to all.
328 <?php
329 if ( ! empty( $default_items_link ) ) {
330 ?>
331 <span style="display: flex; gap: 3px 7px; flex-wrap: wrap; margin-top: 10px;"> <?php Fns::print_html( 'View Brand Archive Pages: ' . $default_items_link ); ?> </span>
332 <?php
333 }
334 ?>
335 </p>
336 </div>
337
338 <?php if ( ! rtsb()->has_pro() ) { ?>
339 <div class="rtsb-product-brands-page-field rtsb-tb-field-wraper" style="display:none;">
340 <label for="product_page_for"> </label>
341 <span class="elementor-pro-notice"><a target="_blank" href="<?php echo esc_url( rtsb()->pro_version_link() ); ?>">Upgrade to PRO</a> to unlock Brand Base Product Page.</span>
342 </div>
343 <?php } ?>
344 <?php endif; ?>
345
346 <?php do_action( 'rtsb/builder/modal/extra_fields', $post_id, $template_type, $product_page_for ); ?>
347
348 <!-- Product Page for Selected Product -->
349 <div class="rtsb-page-for-the-products rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
350 <?php
351 $default_items_link = '';
352 $default_items = '';
353 $product_ids = apply_filters( 'rtsb/product/page/builder/selected/products', [], $post_id );
354 if ( ! empty( $product_ids ) && is_array( $product_ids ) ) {
355 foreach ( $product_ids as $p_id ) {
356 $p_title = get_the_title( $p_id );
357 $default_items_link .= '<a target="_blank" href="' . get_the_permalink( $p_id ) . '">' . $p_title . '</a>';
358 $default_items .= '<option selected="selected" value="' . $p_id . '">' . $p_title . ' - ( ID ' . $p_id . ' )</option>';
359 }
360 }
361 ?>
362 <label for="rtsb_page_for_the_products "><?php esc_html_e( 'Select Products ', 'shopbuilder' ); ?>
363 <?php if ( ! rtsb()->has_pro() ) { ?>
364 <div class="card-label">
365 <span class="rtsb-btn-import pro-btn">
366 <?php echo esc_html( 'PRO' ); ?>
367 </span>
368 </div>
369 <?php } ?>
370 </label>
371 <select class="rtsb-field" id="rtsb_page_for_the_products" name="rtsb_page_for_the_products" multiple="multiple">
372 <?php Fns::print_html( $default_items, true ); ?>
373 </select>
374 <p style="margin:0;">Select a Product to apply this template. You can select multiple Products. Keep it blank to apply to all Products.
375 <?php
376 if ( ! empty( $default_items_link ) ) {
377 ?>
378 <span style="display: flex; gap: 3px 7px; flex-wrap: wrap; margin-top: 10px;"> <?php Fns::print_html( 'View Product Pages: ' . $default_items_link ); ?> </span>
379 <?php
380 }
381 ?>
382 </p>
383 </div>
384
385 <div class="rtsb-product-page-preview-field rtsb-tb-field-wraper" style="display:none;">
386 <?php
387 $default_items = '';
388 $product_id = get_post_meta( $post_id, BuilderFns::$product_template_meta, true );
389 if ( $product_id && get_post_status( $product_id ) ) {
390 $default_items = '<option selected="selected" value="' . $product_id . '">' . get_the_title( $product_id ) . ' - ( ID ' . $product_id . ' )</option>';
391 }
392 if ( $product_id && ! get_post_status( $product_id ) ) {
393 delete_post_meta( $post_id, BuilderFns::$product_template_meta );
394 }
395 ?>
396 <label for="rtsb_product_page_preview"><?php esc_html_e( 'Select Preview Product', 'shopbuilder' ); ?></label>
397 <select class="rtsb-field" id="rtsb_product_page_preview" name="rtsb_product_page_preview">
398 <?php Fns::print_html( $default_items, true ); ?>
399 </select>
400 <p style="margin:0;">Select a Product for preview and Elementor editing purposes only.</p>
401 </div>
402
403
404 <div class="rtsb-template-edit-with rtsb-tb-field-wraper">
405 <label for="rtsb_tb_template_edit_with"><?php esc_html_e( 'Select Editor Type', 'shopbuilder' ); ?></label>
406 <select class="rtsb-field" id="rtsb_tb_template_edit_with" name="rtsb_tb_template_edit_with"
407 required>
408 <option value="elementor" <?php echo 'elementor' === $edit_by ? 'selected="selected"' : ''; ?> ><?php esc_html_e( 'Elementor', 'shopbuilder' ); ?></option>
409 <!-- disabled-->
410 <option disabled value="gutenberg" <?php echo 'gutenberg' === $edit_by ? 'selected="selected"' : ''; ?> ><?php esc_html_e( 'Gutenberg (Coming Soon)', 'shopbuilder' ); ?></option>
411 </select>
412 </div>
413 <div class="rtsb-template-setdefaults rtsb-tb-field-wraper">
414 <label for="default_template"> <?php esc_html_e( 'Set as Active Template', 'shopbuilder' ); ?></label>
415 <?php
416 $singleton_types = apply_filters(
417 'rtsb/builder/singleton_types',
418 array_keys( BuilderFns::builder_page_types() )
419 );
420 $is_pool_type = $template_type && ! in_array( $template_type, $singleton_types, true );
421 if ( $post_id && $is_pool_type ) {
422 $template_default = 'on' === get_post_meta( $post_id, '_rtsb_tb_enabled_in_pool', true ) ? $post_id : 0;
423 }
424 if ( $post_id && 'product' === $template_type ) {
425 if ( 'specific_products' === $product_page_for ) {
426 $set_default = BuilderFns::get_specific_product_as_default( $post_id );
427 if ( $set_default ) {
428 $template_default = $post_id;
429 }
430 if ( ! $set_default && $template_default === $post_id ) {
431 $template_default = '';
432 }
433 } else {
434 $set_default_option_name = '';
435 if ( 'product_cats' === $product_page_for ) {
436 $set_default_option_name = BuilderFns::option_name_product_page_specific_cat_set_default( $post_id );
437 } elseif ( 'product_tags' === $product_page_for ) {
438 $set_default_option_name = BuilderFns::option_name_product_page_specific_tag_set_default( $post_id );
439 } elseif ( 'product_brands' === $product_page_for ) {
440 $set_default_option_name = BuilderFns::option_name_product_page_specific_brand_set_default( $post_id );
441 }
442 $default_id = ! empty( $set_default_option_name ) && TemplateSettings::instance()->get_option( $set_default_option_name );
443 if ( $default_id ) {
444 $template_default = $post_id;
445 }
446 }
447 } elseif ( $post_id && 'archive' === $template_type ) {
448 $categories_name = apply_filters( 'rtsb/template/builder/selected/categories', [], $post_id, $template_type );
449 $set_default = BuilderFns::get_specific_category_as_default( $post_id );
450 if ( ! empty( $categories_name ) && $set_default ) {
451 $template_default = $post_id;
452 } else {
453 $option_name = BuilderFns::option_name( $template_type );
454 $is_set_default = TemplateSettings::instance()->get_option( $option_name );
455 $set_default = $is_set_default;
456 }
457 if ( ! $set_default && $template_default === $post_id ) {
458 $template_default = '';
459 }
460 }
461
462 $template_default = apply_filters( 'rtsb/builder/modal/template_default', $template_default, $post_id, $template_type );
463 ?>
464 <span class="rtsb-switch-wrapper"
465 title="<?php esc_html_e( 'Switch on to set as active template', 'shopbuilder' ); ?>">
466 <label class="rtsb-switch">
467 <input class="rtsb_set_default rtsb-field"
468 type="checkbox"
469 id="default_template"
470 name="default_template"
471 value="default_template"
472 <?php echo esc_attr( ( $post_id && ( absint( $post_id ) === absint( $template_default ) ) ) ? 'checked' : '' ); ?>
473 >
474 <span class="rtsb-slider rtsb-round ">
475 <span class="rtsb-loader"></span>
476 </span>
477 </label>
478 </span>
479 </div>
480 <!-- TODO: Moday Layout -->
481 <?php
482 if ( ! $post_id ) {
483 if ( defined( 'ELEMENTOR_PATH' ) && class_exists( '\Elementor\Utils' ) ) {
484 $placeholderImageSrc = \Elementor\Utils::get_placeholder_image_src();
485 } else {
486 $placeholderImageSrc = '#';
487 }
488 ?>
489 <div class="set-default-layout-wrapper rtsb-tb-field-wraper" style="opacity: 0" >
490 <div style="display: flex; justify-content: space-between;">
491 <label>
492 <?php esc_html_e( 'Pre-built Templates ', 'shopbuilder' ); ?>
493 <span id="modallabelPrefix"></span>
494 </label>
495 <div class="rtsb-tb-button-wrapper">
496 <a class="btn" href="https://shopbuilderwp.com/themes/" target="_blank" style="opacity: 1; visibility: visible;">View Out Themes</a>
497 </div>
498 </div>
499 <div class="set-default-layout" data-has-pro="<?php echo esc_attr( rtsb()->has_pro() ); ?>" data-rest-url="<?php echo esc_url( rtsb()->BASE_API ); ?>" data-placeholder-image-src="<?php echo esc_url( $placeholderImageSrc ); ?>">
500 <!-- Layout Will Add Via Ajax-->
501 </div>
502 </div>
503 <?php } ?>
504 <input type="hidden" id="page_id" name="page_id" value="<?php echo esc_attr( $post_id ); ?>">
505 </div>
506 </form>
507 <?php
508 $content = ob_get_clean();
509 ob_start();
510 ?>
511 <div class="rtsb-template-footer">
512 <div class="rtsb-tb-button-wrapper save-button">
513 <button class="rtsb-import-layout" <?php echo esc_attr( $post_id ? 'disabled' : '' ); ?> type="submit" id="rtsb_tb_button">
514 <?php esc_html_e( 'Save', 'shopbuilder' ); ?>
515 </button>
516 </div>
517 <div class="rtsb-tb-button-wrapper rtsb-tb-edit-button-wrapper">
518 <a href="<?php echo esc_url( $url ); ?>" class="btn">
519 <?php
520 printf(
521 /* translators: %s: Edit */
522 esc_html__( 'Edit with %s', 'shopbuilder' ),
523 esc_html( $edit_by )
524 );
525 ?>
526 </a>
527 </div>
528 </div>
529 <?php
530 $footer = ob_get_clean();
531 $return = [
532 'success' => true,
533 'title' => $title,
534 'content' => $content,
535 'footer' => $footer,
536 ];
537 wp_send_json( $return );
538 wp_die();
539 }
540
541 /**
542 * Get Modal Card Markup.
543 *
544 * @param array $item Item.
545 *
546 * @return void
547 */
548 public function get_modal_card_html( $item ) {
549 ?>
550 <div class="layout-container rtsb-template-item type-<?php echo esc_attr( $item['template_type'] ); ?>"
551 data-layout-type='<?php echo esc_attr( $item['template_type'] ); ?>'>
552 <input class="rtsb-field" type="hidden" value="<?php echo esc_attr( $item['id'] ?? '' ); ?>" name="import_default_layout"/>
553 <div class="image-wrapper">
554 <?php if ( $item['image_url'] ) : ?>
555 <img src="<?php echo esc_url( $item['image_url'] ); ?>" alt="<?php echo esc_attr( $item['title'] ); ?>">
556 <?php endif; ?>
557
558 <?php if ( 'default' != $item['template_type'] && ( ! rtsb()->has_pro() ) ) : ?>
559 <div class="card-label lllllll">
560 label
561 <span class="rtsb-btn-import <?php echo esc_attr( $item['status'] ?? 'free' ); ?>-btn">
562 <?php echo esc_html( $item['status'] ?? 'Free' ); ?>
563 </span>
564 </div>
565 <?php endif; ?>
566
567 <div class="import-btn-wrap">
568 <?php if ( $item['preview_link'] ) : ?>
569 <a class="rtsb-btn-import preview-btn" target="_blank" href="<?php echo esc_url( $item['preview_link'] ); ?>">
570 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
571 <path d="M19 0H13C12.7348 0 12.4804 0.105357 12.2929 0.292893C12.1054 0.48043 12 0.734783 12 1C12 1.26522 12.1054 1.51957 12.2929 1.70711C12.4804 1.89464 12.7348 2 13 2H16.586L8.293 10.293C8.19749 10.3852 8.12131 10.4956 8.0689 10.6176C8.01649 10.7396 7.9889 10.8708 7.98775 11.0036C7.9866 11.1364 8.0119 11.2681 8.06218 11.391C8.11246 11.5138 8.18671 11.6255 8.28061 11.7194C8.3745 11.8133 8.48615 11.8875 8.60905 11.9378C8.73194 11.9881 8.86362 12.0134 8.9964 12.0122C9.12918 12.0111 9.2604 11.9835 9.38241 11.9311C9.50441 11.8787 9.61475 11.8025 9.707 11.707L18 3.414V7C18 7.26522 18.1054 7.51957 18.2929 7.70711C18.4804 7.89464 18.7348 8 19 8C19.2652 8 19.5196 7.89464 19.7071 7.70711C19.8946 7.51957 20 7.26522 20 7V1C20 0.734783 19.8946 0.48043 19.7071 0.292893C19.5196 0.105357 19.2652 0 19 0Z"
572 fill="black"></path>
573 <path d="M17 8.588C16.7348 8.588 16.4804 8.69336 16.2929 8.88089C16.1054 9.06843 16 9.32278 16 9.588V16.751C15.9997 17.0822 15.8681 17.3997 15.6339 17.6339C15.3997 17.8681 15.0822 17.9997 14.751 18H3.249C2.91783 17.9997 2.60029 17.8681 2.36612 17.6339C2.13194 17.3997 2.00026 17.0822 2 16.751V5.249C2.00026 4.91783 2.13194 4.60029 2.36612 4.36612C2.60029 4.13194 2.91783 4.00026 3.249 4H9.471C9.73621 4 9.99057 3.89464 10.1781 3.70711C10.3656 3.51957 10.471 3.26522 10.471 3C10.471 2.73478 10.3656 2.48043 10.1781 2.29289C9.99057 2.10536 9.73621 2 9.471 2H3.249C2.38764 2.00106 1.56186 2.3437 0.952779 2.95278C0.343703 3.56186 0.00105851 4.38764 0 5.249V16.749C0.000529143 17.6107 0.34294 18.437 0.952073 19.0465C1.56121 19.656 2.38729 19.9989 3.249 20H14.749C15.6107 19.9995 16.437 19.6571 17.0465 19.0479C17.656 18.4388 17.9989 17.6127 18 16.751V9.588C18 9.32278 17.8946 9.06843 17.7071 8.88089C17.5196 8.69336 17.2652 8.588 17 8.588Z"
574 fill="black"></path>
575 </svg>
576 <?php echo esc_html__( 'Preview', 'shopbuilder' ); ?>
577 </a>
578
579
580 <?php
581 // phpcs:ignore WordPress.PHP.YodaConditions.NotYoda
582 if ( rtsb()->has_pro() || $item['status'] == 'free' ) :
583 ?>
584 <a class="rtsb-btn-import import-btn rtsb-import-layout">
585 <svg width="22" height="20" viewBox="0 0 22 20" fill="none" xmlns="http://www.w3.org/2000/svg">
586 <path d="M11 12.2295C10.9048 12.2296 10.8106 12.2113 10.7226 12.1757C10.6347 12.14 10.5547 12.0878 10.4874 12.0219C10.4201 11.956 10.3668 11.8778 10.3304 11.7917C10.294 11.7056 10.2753 11.6134 10.2754 11.5202L10.2754 0.912773C10.2754 0.72466 10.3517 0.544251 10.4876 0.411235C10.6235 0.278219 10.8078 0.203491 11 0.203491C11.1922 0.203491 11.3765 0.278219 11.5124 0.411235C11.6483 0.544251 11.7246 0.72466 11.7246 0.912773L11.7246 11.5202C11.7246 11.7083 11.6483 11.8887 11.5124 12.0218C11.3765 12.1548 11.1922 12.2295 11 12.2295Z"
587 fill="white"></path>
588 <path fill-rule="evenodd" clip-rule="evenodd"
589 d="M11.0002 12.4295C10.8793 12.4296 10.7595 12.4064 10.6475 12.361C10.5356 12.3157 10.4336 12.2491 10.3475 12.1648C10.2614 12.0806 10.1929 11.9803 10.1461 11.8696C10.0994 11.7589 10.0753 11.6402 10.0754 11.5201C10.0754 11.5201 10.0754 11.5201 10.0754 11.52L10.2748 11.5202H10.0754L10.0754 11.5201L10.0754 0.91276C10.0754 0.670205 10.1738 0.438473 10.3477 0.268295C10.5214 0.0982601 10.7561 0.003479 11 0.003479C11.2439 0.003479 11.4786 0.0982601 11.6523 0.268295C11.8262 0.438473 11.9246 0.670205 11.9246 0.91276L11.9246 11.5202C11.9246 11.7628 11.8262 11.9945 11.6523 12.1647C11.4786 12.3347 11.244 12.4294 11.0002 12.4295ZM10.7226 12.1756C10.8106 12.2113 10.9048 12.2296 11 12.2295C11.1922 12.2295 11.3765 12.1548 11.5124 12.0217C11.6483 11.8887 11.7246 11.7083 11.7246 11.5202L11.7246 0.91276C11.7246 0.724647 11.6483 0.544239 11.5124 0.411223C11.3765 0.278207 11.1922 0.203479 11 0.203479C10.8078 0.203479 10.6235 0.278207 10.4876 0.411223C10.3517 0.544239 10.2754 0.724647 10.2754 0.91276L10.2754 11.5202C10.2753 11.6134 10.294 11.7056 10.3304 11.7917C10.3668 11.8778 10.4201 11.956 10.4874 12.0219C10.5547 12.0878 10.6347 12.14 10.7226 12.1756Z"
590 fill="white"></path>
591 <path d="M11 12.5484C10.7565 12.5488 10.5152 12.5021 10.2902 12.4109C10.0652 12.3198 9.86076 12.186 9.6887 12.0173L5.77508 8.18661C5.63924 8.05365 5.56293 7.87332 5.56293 7.68529C5.56293 7.49726 5.63924 7.31693 5.77508 7.18397C5.91091 7.05101 6.09515 6.97632 6.28725 6.97632C6.47935 6.97632 6.66359 7.05101 6.79942 7.18397L10.713 11.0147C10.7507 11.0515 10.7955 11.0808 10.8447 11.1008C10.8939 11.1207 10.9467 11.131 11 11.131C11.0533 11.131 11.1061 11.1207 11.1553 11.1008C11.2045 11.0808 11.2493 11.0515 11.287 11.0147L15.2006 7.18397C15.3372 7.05473 15.5202 6.98319 15.7102 6.98475C15.9002 6.98632 16.082 7.06086 16.2164 7.19233C16.3508 7.3238 16.427 7.50168 16.4288 7.68765C16.4305 7.87362 16.3575 8.0528 16.2255 8.18661L12.3113 12.0173C12.1392 12.186 11.9348 12.3197 11.7098 12.4108C11.4847 12.502 11.2435 12.5487 11 12.5484Z"
592 fill="white"></path>
593 <path fill-rule="evenodd" clip-rule="evenodd"
594 d="M11.287 11.0146L15.2006 7.18396C15.3372 7.05472 15.5202 6.98318 15.7102 6.98474C15.9002 6.9863 16.082 7.06085 16.2164 7.19232C16.3508 7.32379 16.4271 7.50166 16.4288 7.68763C16.4305 7.87361 16.3575 8.05279 16.2255 8.1866L12.3113 12.0173C12.1392 12.1859 11.9348 12.3197 11.7098 12.4108C11.4847 12.502 11.2435 12.5487 11 12.5484C10.7565 12.5488 10.5153 12.5021 10.2902 12.4109C10.0652 12.3198 9.86076 12.186 9.6887 12.0173L5.77508 8.1866C5.63924 8.05364 5.56293 7.87331 5.56293 7.68528C5.56293 7.49725 5.63924 7.31692 5.77508 7.18396C5.91092 7.051 6.09515 6.97631 6.28725 6.97631C6.47936 6.97631 6.66359 7.051 6.79943 7.18396L10.713 11.0146C10.7507 11.0515 10.7955 11.0808 10.8447 11.1008C10.8939 11.1207 10.9467 11.131 11 11.131C11.0533 11.131 11.1061 11.1207 11.1553 11.1008C11.2045 11.0808 11.2493 11.0515 11.287 11.0146ZM12.4513 12.1601L16.3654 8.32954L16.3679 8.32703C16.5368 8.1558 16.6309 7.92559 16.6287 7.6858C16.6266 7.44602 16.5282 7.21755 16.3563 7.04935C16.1845 6.88129 15.953 6.78673 15.7119 6.78475C15.4708 6.78276 15.2378 6.8735 15.0631 7.03866L11.1471 10.8717C11.1281 10.8902 11.1054 10.9052 11.0802 10.9154C11.0549 10.9257 11.0276 10.931 11 10.931C10.9724 10.931 10.9451 10.9257 10.9199 10.9154C10.8946 10.9052 10.8719 10.8902 10.853 10.8717L6.93933 7.04103C6.76567 6.87106 6.53103 6.77631 6.28725 6.77631C6.04347 6.77631 5.80884 6.87106 5.63518 7.04103C5.46138 7.21115 5.36293 7.44281 5.36293 7.68528C5.36293 7.92775 5.46138 8.15941 5.63518 8.32953L9.54868 12.1601C9.73954 12.3472 9.96607 12.4954 10.2151 12.5963C10.4641 12.6971 10.7308 12.7488 11 12.7484"
595 fill="white"></path>
596 <path d="M19.0788 19H2.92116C2.41182 18.9994 1.92353 18.8011 1.56337 18.4486C1.20322 18.0961 1.00061 17.6181 1 17.1196V12.1614C1 11.9733 1.07635 11.7929 1.21224 11.6599C1.34814 11.5269 1.53245 11.4521 1.72464 11.4521C1.91682 11.4521 2.10114 11.5269 2.23703 11.6599C2.37293 11.7929 2.44928 11.9733 2.44928 12.1614V17.1196C2.44943 17.242 2.49919 17.3594 2.58766 17.446C2.67612 17.5326 2.79605 17.5813 2.92116 17.5815H19.0788C19.2039 17.5813 19.3239 17.5326 19.4123 17.446C19.5008 17.3594 19.5506 17.242 19.5507 17.1196V12.1614C19.5507 11.9733 19.6271 11.7929 19.763 11.6599C19.8989 11.5269 20.0832 11.4521 20.2754 11.4521C20.4675 11.4521 20.6519 11.5269 20.7878 11.6599C20.9237 11.7929 21 11.9733 21 12.1614V17.1196C20.9994 17.6181 20.7968 18.0961 20.4366 18.4486C20.0765 18.8011 19.5882 18.9994 19.0788 19Z"
597 fill="white"></path>
598 <path fill-rule="evenodd" clip-rule="evenodd"
599 d="M19.0788 19.2H2.92116C2.36023 19.1994 1.82139 18.981 1.42348 18.5915C1.02542 18.2019 0.800684 17.6727 0.800003 17.1198L0.800003 12.1614C0.800003 11.9189 0.898484 11.6871 1.07235 11.517C1.24606 11.3469 1.48078 11.2521 1.72464 11.2521C1.9685 11.2521 2.20322 11.3469 2.37694 11.517C2.5508 11.6871 2.64928 11.9189 2.64928 12.1614L2.64928 17.1193C2.64928 17.1194 2.64928 17.1193 2.64928 17.1193C2.64939 17.1874 2.67702 17.2536 2.72756 17.3031C2.77826 17.3527 2.84789 17.3814 2.9214 17.3815H19.0786C19.1521 17.3814 19.2217 17.3527 19.2724 17.3031C19.323 17.2536 19.3506 17.1874 19.3507 17.1193V12.1614C19.3507 11.9189 19.4492 11.6871 19.6231 11.517C19.7968 11.3469 20.0315 11.2521 20.2754 11.2521C20.5192 11.2521 20.7539 11.3469 20.9277 11.517C21.1015 11.6871 21.2 11.9189 21.2 12.1614V17.1196C21.1993 17.6725 20.9746 18.2019 20.5765 18.5915C20.1786 18.981 19.6398 19.1994 19.0788 19.2ZM19.0788 17.5815H2.92116C2.79606 17.5813 2.67612 17.5326 2.58766 17.446C2.4992 17.3594 2.44943 17.242 2.44928 17.1196V12.1614C2.44928 11.9733 2.37293 11.7929 2.23704 11.6599C2.10114 11.5269 1.91683 11.4521 1.72464 11.4521C1.53245 11.4521 1.34814 11.5269 1.21224 11.6599C1.07635 11.7929 1 11.9733 1 12.1614V17.1196C1.00062 17.6181 1.20322 18.0961 1.56338 18.4486C1.92353 18.8011 2.41183 18.9994 2.92116 19H19.0788C19.5882 18.9994 20.0765 18.8011 20.4366 18.4486C20.7968 18.0961 20.9994 17.6181 21 17.1196V12.1614C21 11.9733 20.9237 11.7929 20.7878 11.6599C20.6519 11.5269 20.4676 11.4521 20.2754 11.4521C20.0832 11.4521 19.8989 11.5269 19.763 11.6599C19.6271 11.7929 19.5507 11.9733 19.5507 12.1614V17.1196C19.5506 17.242 19.5008 17.3594 19.4123 17.446C19.3239 17.5326 19.2039 17.5813 19.0788 17.5815Z"
600 fill="white"></path>
601 </svg>
602 <span class="import-label" data-label="<?php echo esc_html__( 'Importing...', 'shopbuilder' ); ?>"><?php echo esc_html__( 'Import', 'shopbuilder' ); ?></span>
603 </a>
604
605 <?php else : ?>
606 <a class="rtsb-btn-import import-btn" target="_blank" href="https://shopbuilderwp.com/">
607 <i class="dashicons dashicons-migrate"></i>
608 <span class="import-label"><?php echo esc_html__( 'Upgrade', 'shopbuilder' ); ?></span>
609 </a>
610 <?php endif; ?>
611
612 <?php else : ?>
613 <a class="rtsb-btn-import import-btn rtsb-import-layout">
614 <i class="dashicons dashicons-plus"></i>
615 <span class="import-label" data-label="<?php echo esc_html__( 'Creating Template...', 'shopbuilder' ); ?>"><?php echo esc_html__( 'Create Blank Template', 'shopbuilder' ); ?></span>
616 </a>
617 <?php endif; ?>
618 </div>
619
620 </div>
621
622 <?php if ( $item['title'] ) : ?>
623 <div class="image-label">
624 <span class="label-text"><?php echo esc_html( $item['title'] ); ?></span>
625 </div>
626 <?php endif; ?>
627 </div>
628 <?php
629 }
630
631 /**
632 * Popups For Create Template
633 *
634 * @return void
635 */
636 public function product_search() {
637 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
638 $return = [
639 'success' => false,
640 'content' => esc_html__( 'Session Expired...', 'shopbuilder' ),
641 ];
642 wp_send_json( $return );
643 }
644 if ( ! current_user_can( 'manage_options' ) ) {
645 $return = [
646 'success' => false,
647 'content' => esc_html__( 'Permission Denied...', 'shopbuilder' ),
648 ];
649 wp_send_json( $return );
650 }
651 global $wpdb;
652 $search = isset( $_REQUEST['search'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['search'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
653 if ( empty( $search ) ) {
654 $return = [
655 'success' => false,
656 'content' => esc_html__( 'Empty string Not allowed...', 'shopbuilder' ),
657 ];
658 wp_send_json( $return );
659 }
660 /** @noinspection SqlNoDataSourceInspection */
661 /** @noinspection SqlResolve */
662 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
663 $query = $wpdb->prepare(
664 "SELECT ID, post_title
665 FROM $wpdb->posts
666 WHERE post_type = 'product'
667 AND post_status = 'publish'
668 AND post_title LIKE %s
669 LIMIT %d",
670 '%' . $search . '%',
671 10
672 );
673 $cache_key = md5( $query );
674 $_product = wp_cache_get( $cache_key, 'shopbuilder' );
675 if ( false === $_product ) {
676 $_product = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
677 wp_cache_set( $cache_key, $_product, 'shopbuilder' );
678 Cache::set_data_cache_key( $cache_key );
679 }
680 $product_list = [];
681 foreach ( $_product as $product ) {
682 $product_list['items'][] = [
683 'id' => $product->ID,
684 'text' => html_entity_decode( $product->post_title, ENT_QUOTES | ENT_HTML5 ) . ' - (ID#' . $product->ID . ')',
685 ];
686 }
687
688 wp_send_json_success( $product_list );
689 wp_die();
690 }
691
692 /**
693 * Popups For Create Template
694 *
695 * @return void
696 */
697 public function term_search() {
698
699 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
700 $return = [
701 'success' => false,
702 'content' => esc_html__( 'Session Expired...', 'shopbuilder' ),
703 ];
704 wp_send_json( $return );
705 }
706
707 if ( ! current_user_can( 'manage_options' ) ) {
708 $return = [
709 'success' => false,
710 'content' => esc_html__( 'Permission Denied...', 'shopbuilder' ),
711 ];
712 wp_send_json( $return );
713 }
714
715 $search = isset( $_REQUEST['search'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['search'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
716 $taxonomy = isset( $_REQUEST['taxonomy'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['taxonomy'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
717 if ( ! $taxonomy ) {
718 $return = [
719 'success' => false,
720 'content' => esc_html__( 'Invalid taxonomy', 'shopbuilder' ),
721 ];
722 wp_send_json( $return );
723 }
724 $args = [
725 'taxonomy' => [ $taxonomy ], // taxonomy name.
726 'orderby' => 'name',
727 'order' => 'ASC',
728 'hide_empty' => false,
729 'name__like' => $search,
730 ];
731 $terms = get_terms( $args );
732 $count = count( $terms );
733 $term_list = [];
734 if ( $count > 0 ) {
735 foreach ( $terms as $term ) {
736 $term_list['items'][] = [
737 'id' => $term->slug,
738 'text' => html_entity_decode( $term->name, ENT_QUOTES | ENT_HTML5 ),
739 ];
740 }
741 }
742 wp_send_json_success( $term_list );
743
744 wp_die();
745 }
746 }
747