PluginProbe
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder / 3.0.4
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder v3.0.4
3.1.4 3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 All 93 releases
ultimate-store-kit / includes / builder / builder-integration.php

builder-integration.php in Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder 3.0.4, at includes/builder/builder-integration.php

535 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimateStoreKit\Builder;
4
5 if (! defined('WPINC')) {
6 die;
7 }
8
9 use Elementor\Controls_Manager;
10 use Elementor\Plugin;
11 use UltimateStoreKit\Includes\Builder\Builder_Template_Helper;
12 use UltimateStoreKit\Base\Singleton;
13 use UltimateStoreKit\Includes\Builder\Meta;
14 use UltimateStoreKit\Includes\Controls\SelectInput\Dynamic_Select;
15
16
17 class Builder_Integration {
18
19 use Singleton;
20
21 private $current_template = null;
22 public $current_template_id = null;
23
24 function __construct() {
25 add_filter('template_include', [$this, 'set_builder_template'], 9999);
26 add_action('elementor/editor/init', [$this, 'set_sample_post'], 999);
27
28 add_action('print_default_editor_scripts', array($this, 'my_custom_fonts'));
29 add_filter("elementor/document/urls/wp_preview", [$this, 'change_preview_editor_url'], 999, 2);
30
31 add_action('elementor/documents/register_controls', [$this, 'register_document_controls']);
32
33 // Add demo bypass filter for template preview
34 add_filter('ultimate_store_kit/preview/verified_bypass', function ($verify) {
35 // Check if we're in a demo environment or development site
36 // For demo sites, you might want to check domain names or other indicators
37 $demo_hosts = apply_filters('ultimate_store_kit/demo_hosts', [
38 'storekit.pro',
39 'demo.storekit.pro',
40 'localhost',
41 '127.0.0.1'
42 ]);
43
44 $current_host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field($_SERVER['HTTP_HOST']) : '';
45
46 foreach ($demo_hosts as $host) {
47 if (strpos($current_host, $host) !== false) {
48 return true;
49 }
50 }
51
52 return $verify;
53 });
54
55 // Add filter to enable demo mode for preview URLs
56 add_filter('ultimate_store_kit/preview/use_demo_bypass', function ($use_demo) {
57 // Enable demo bypass in Elementor editor
58 if (isset($_GET['action']) && $_GET['action'] === 'elementor') {
59 return true;
60 }
61 return $use_demo;
62 });
63 }
64
65 public function change_preview_editor_url($url, $document) {
66 $post_id = $document->get_main_id();
67 $template_type = get_post_meta($post_id, Meta::TEMPLATE_TYPE, true);
68
69 if (empty($template_type) || get_post_type($post_id) !== Meta::POST_TYPE) {
70 return $url;
71 }
72
73 $template_data = explode(Builder_Template_Helper::separator(), $template_type);
74 if (count($template_data) < 2) {
75 return $url;
76 }
77
78 $post_type = $template_data[0];
79 $template_slug = $template_data[1];
80
81 // Get template URL based on template type
82 $template_url = '';
83
84 // Check for product category first
85 if ($template_slug === 'product-category') {
86 $product_cats = get_terms([
87 'taxonomy' => 'product_cat',
88 'hide_empty' => true,
89 'number' => 1,
90 ]);
91
92 if (!empty($product_cats) && !is_wp_error($product_cats)) {
93 $template_url = get_term_link($product_cats[0]);
94 }
95 }
96
97 // Check for product tag
98 elseif ($template_slug === 'product-tag') {
99 $product_tags = get_terms([
100 'taxonomy' => 'product_tag',
101 'hide_empty' => true,
102 'number' => 1,
103 ]);
104
105 if (!empty($product_tags) && !is_wp_error($product_tags)) {
106 $template_url = get_term_link($product_tags[0]);
107 }
108 }
109
110 elseif ($template_slug === 'shop' || $template_slug === 'archive') {
111 $template_url = get_permalink(wc_get_page_id('shop'));
112 }
113
114 elseif ($template_slug === 'single' && $post_type === 'product') {
115 $page_settings_manager = \Elementor\Core\Settings\Manager::get_settings_managers('page');
116 $page_settings_model = $page_settings_manager->get_model($post_id);
117 $sample_product = $page_settings_model->get_settings('usk_builder_sample_post_id');
118
119 $template_url = !empty($sample_product) ?
120 get_permalink($sample_product) :
121 $this->get_default_product_url();
122 }
123
124 elseif ($template_slug === 'cart') {
125 $template_url = wc_get_cart_url();
126 }
127
128 elseif ($template_slug === 'checkout') {
129 $template_url = wc_get_checkout_url();
130 }
131
132 elseif ($template_slug === 'myaccount'
133 || $template_slug === 'login'
134 || strpos($template_slug, 'myaccount-') === 0) {
135 $template_url = get_permalink(wc_get_page_id('myaccount'));
136 }
137
138 elseif ($template_slug === 'order-received') {
139 $orders = wc_get_orders(['limit' => 1]);
140 if (!empty($orders)) {
141 $order = $orders[0];
142 $order_id = $order->get_id();
143 $template_url = add_query_arg('order-received', $order_id, wc_get_checkout_url());
144 }
145 }
146
147 if (empty($template_url)) {
148 return $url;
149 }
150
151 $is_demo = apply_filters('ultimate_store_kit/preview/use_demo_bypass', false);
152 $nonce_value = $is_demo ? 'verified' : wp_create_nonce('template_preview_' . $post_id);
153
154 $param = [
155 'usk_template_id' => $post_id,
156 'preview_nonce' => $nonce_value,
157 'preview' => true
158 ];
159
160 // Add parameters two URL
161 $url = add_query_arg($param, $template_url);
162
163 return $url;
164 }
165
166 public function my_custom_fonts() {
167 if (is_admin() && Plugin::instance()->editor->is_edit_mode()) {
168 if (isset($_REQUEST['usk-template'])) {
169 wp_register_style('usk-template-builder-hide-preview-btn-inline', false); // phpcs:ignore
170 wp_enqueue_style('usk-template-builder-hide-preview-btn-inline');
171 wp_add_inline_style(
172 'usk-template-builder-hide-preview-btn-inline',
173 '#elementor-panel-footer-saver-preview {display:none!important}'
174 );
175 }
176 }
177 }
178 function set_sample_post() {
179 if (Builder_Template_Helper::isTemplateEditMode()) {
180 $object = \UltimateStoreKit\Includes\Builder\Builder_Post_Singleton::instance();
181 $object::set_sample_post();
182 }
183 }
184
185 function register_document_controls($document) {
186 if (
187 ! $document instanceof \Elementor\Core\DocumentTypes\PageBase
188 || ! $document::get_property('has_elements')
189 ) {
190 return;
191 }
192
193 if (Plugin::instance()->preview->is_preview_mode())
194 return;
195
196 if (! Builder_Template_Helper::isTemplateEditMode()) {
197 return;
198 }
199
200 global $post;
201
202 if (! isset($post->ID)) {
203 return;
204 }
205 $meta = get_post_meta($post->ID);
206
207 $templateMeta = optional($meta)[Meta::TEMPLATE_TYPE];
208 if (! isset($templateMeta[0])) {
209 return;
210 }
211 $postMeta = $templateMeta[0];
212 $postMeta = explode('|', $postMeta);
213 $postType = $postMeta[0];
214
215 if ($postMeta[1] != 'single') {
216 return;
217 }
218
219 $document->start_controls_section(
220 'usk_page_setting_preview',
221 [
222 'label' => esc_html__('Builder Settings', 'ultimate-store-kit'),
223 'tab' => Controls_Manager::TAB_SETTINGS,
224 ]
225 );
226
227 $document->add_control(
228 'usk_builder_sample_post_id',
229 [
230 'label' => __('Builder Post', 'ultimate-store-kit'),
231 'type' => Dynamic_Select::TYPE,
232 'multiple' => false,
233 'label_block' => true,
234 'query_args' => [
235 'post_type' => $postType
236 ],
237 ]
238 );
239
240 $document->add_control(
241 'usk_builder_sample_apply_preview',
242 [
243 'type' => Controls_Manager::BUTTON,
244 'label' => esc_html__('Apply & Preview', 'ultimate-store-kit'),
245 'label_block' => true,
246 'show_label' => false,
247 'text' => esc_html__('Apply & Preview', 'ultimate-store-kit'),
248 'separator' => 'none',
249 'event' => 'ultimateStoreKitBuilderSetting:applySinglePagePostOnPreview',
250 ]
251 );
252
253 $document->end_controls_section();
254 }
255
256 /**
257 * Rewrite default template
258 *
259 */
260 function set_builder_template($template) {
261 if (Builder_Template_Helper::isTemplateEditMode()) {
262 return $this->setBackendTemplate($template);
263 } else {
264 return $this->setFrontendTemplate($template);
265 }
266 }
267
268
269 protected function setBackendTemplate($template) {
270 return $template;
271 }
272
273
274 protected function setFrontendTemplate($template) {
275
276 if (get_post_type() == 'product') {
277 global $product;
278 $product = wc_get_product();
279 }
280
281 if (defined('ELEMENTOR_PATH')) {
282 $elementorTem = ELEMENTOR_PATH . "modules/page-templates/templates/";
283 $elementorTem = explode($elementorTem, $template);
284 if (count($elementorTem) == 2) {
285 return $template;
286 }
287 }
288
289
290 if (is_post_type_archive('product') || is_page(wc_get_page_id('shop')) || is_product_taxonomy()) {
291 $template_type = 'shop';
292
293 if (is_tax('product_cat')) {
294 $template_type = 'category';
295 } elseif (is_tax('product_tag')) {
296 $template_type = 'tag';
297 }
298
299 if ($custom_template = $this->get_template_id($template_type)) {
300 $this->current_template_id = $custom_template;
301 return $this->getTemplatePath('woocommerce/archive-product', $template);
302 }
303 }
304
305
306 if (is_cart()) {
307 if ($custom_template = $this->get_template_id('cart', 'product')) {
308 $this->current_template_id = $custom_template;
309 return $this->getTemplatePath('woocommerce/cart', $template);
310 }
311 }
312
313 if (is_order_received_page()) {
314 if ($custom_template = $this->get_template_id('order-received', 'product')) {
315 $this->current_template_id = $custom_template;
316 return $this->getTemplatePath('woocommerce/order-received', $template);
317 }
318 }
319
320 if (is_checkout()) {
321 if ($custom_template = $this->get_template_id('checkout', 'product')) {
322 $this->current_template_id = $custom_template;
323 return $this->getTemplatePath('woocommerce/checkout', $template);
324 }
325 }
326
327 if (is_single() && get_post_type() == 'product') {
328 if ($custom_template = $this->get_template_id('single', 'product')) {
329 $this->current_template_id = $custom_template;
330 return $this->getTemplatePath('woocommerce/single-product', $template);
331 }
332 }
333
334 if (is_account_page()) {
335 global $wp;
336 $query_vars = WC()->query->get_query_vars();
337
338 /**
339 * Add wishlist endpoint
340 */
341 $query_vars['wishlist'] = 'wishlist';
342
343 $endpoint_match = array_intersect_key($wp->query_vars, $query_vars);
344
345 // Logged-out visitors landing on /my-account/ (no endpoint) see the
346 // single Login & Register template, which is responsible for both
347 // authentication flows. WooCommerce's own form-login.php renders
348 // the login and registration forms on the same URL, so one
349 // template covers both intents.
350 if ( ! is_user_logged_in() && empty($endpoint_match) ) {
351 if ( $custom_template = $this->get_template_id('login', 'account') ) {
352 $this->current_template_id = $custom_template;
353
354 if ( $newTemplate = $this->getTemplatePath('woocommerce/login') ) {
355 return $newTemplate;
356 }
357
358 return $this->getTemplatePath('woocommerce/my-account', $template);
359 }
360 }
361
362 if ($endpoint = $endpoint_match) {
363 $endpoint = array_key_first($endpoint);
364
365 if ($endpoint && $custom_template = $this->get_template_id($endpoint, 'account')) {
366 $this->current_template_id = $custom_template;
367
368 if ($newTemplate = $this->getTemplatePath("woocommerce/{$endpoint}")) {
369 return $newTemplate;
370 }
371
372 return $this->getTemplatePath("woocommerce/my-account", '');
373 }
374
375 if ($custom_template = $this->get_template_id('myaccount-orders', 'account')) {
376 $this->current_template_id = $custom_template;
377 return $this->getTemplatePath('woocommerce/my-account', $template);
378 }
379 } else {
380 if ($custom_template = $this->get_template_id('myaccount', 'account')) {
381 $this->current_template_id = $custom_template;
382 return $this->getTemplatePath('woocommerce/my-account', $template);
383 }
384 }
385 }
386
387
388 if (is_single()) {
389 if ($custom_template = $this->get_template_id('single', 'post')) {
390 $this->current_template_id = $custom_template;
391 return $this->getTemplatePath('single-post', $template);
392 }
393 }
394
395 if (is_archive()) {
396 if ($custom_template = $this->get_template_id('archive', 'post')) {
397 $this->current_template_id = $custom_template;
398 return $this->getTemplatePath('archive-post', $template);
399 }
400 }
401
402 if (is_home()) {
403 if ($custom_template = $this->get_template_id('home', 'post')) {
404 $this->current_template_id = $custom_template;
405 return $this->getTemplatePath('home', $template);
406 }
407 }
408
409 if ($page_Id = intval(get_option('bdt_usk_compare_products_page_id'))) {
410 if (is_page($page_Id)) {
411 if ($custom_template = $this->get_template_id('compare-products', 'product')) {
412 $this->current_template_id = $custom_template;
413 return $this->getTemplatePath('home', $template);
414 }
415 }
416 }
417
418 return $template;
419 }
420
421
422 public function getThemeTemplatePath($slug) {
423
424 $fullPath = get_template_directory() . "/ultimate-store-kit/$slug";
425 if (file_exists($fullPath)) {
426 return $fullPath;
427 }
428 }
429
430 public function getPluginTemplatePath($slug) {
431
432 $fullPath = BDTUSK_PATH . "includes/builder/templates/$slug";
433 if (file_exists($fullPath)) {
434 return $fullPath;
435 }
436 }
437
438
439 /**
440 * Get Template Path ID
441 *
442 * @param $slug
443 * @param $postType
444 *
445 * @return mixed|void|null
446 */
447 public function get_template_id($slug, $postType = false) {
448 // If we already have a template ID for this request, return it
449 if (null !== $this->current_template_id) {
450 return $this->current_template_id;
451 }
452
453 // Handle template preview from URL parameters
454 if (!empty($_GET['preview']) && !empty($_GET['usk_template_id']) && !empty($_GET['preview_nonce'])) {
455 $usk_template_id = sanitize_text_field(wp_unslash($_GET['usk_template_id']));
456 $nonce = sanitize_text_field(wp_unslash($_GET['preview_nonce']));
457
458 // Special handling for demo bypass
459 $is_demo_bypass = ($nonce === 'verified');
460 $nonce_verified = $is_demo_bypass ?
461 apply_filters('ultimate_store_kit/preview/verified_bypass', false) :
462 wp_verify_nonce($nonce, 'template_preview_' . $usk_template_id);
463
464 if ($nonce_verified) {
465 // For demo bypass mode, we don't need to check template type
466 if ($is_demo_bypass) {
467 $this->current_template_id = (int)$usk_template_id;
468 return $this->current_template_id;
469 }
470
471 // For normal preview, check template type
472 $template_type = get_post_meta($usk_template_id, Meta::TEMPLATE_TYPE, true);
473 if (!empty($template_type)) {
474 $template_data = explode(Builder_Template_Helper::separator(), $template_type);
475 if (count($template_data) >= 2 && $template_data[1] === $slug && ($postType === false || $template_data[0] === $postType)) {
476 $this->current_template_id = (int)$usk_template_id;
477 return $this->current_template_id;
478 }
479 }
480 }
481 }
482
483 // Regular template retrieval
484 $templateId = Builder_Template_Helper::getTemplate($slug, $postType);
485 $this->current_template_id = apply_filters('ultimate-store-kit-builder/custom-shop-template', $templateId);
486
487 return $this->current_template_id;
488 }
489
490
491 /**
492 * Get Template Path
493 *
494 * @param $slug
495 * @param $default
496 *
497 * @return mixed|string|void
498 */
499 protected function getTemplatePath($slug, $default = '') {
500 $phpSlug = "{$slug}.php";
501
502 if ($template = $this->getThemeTemplatePath($phpSlug)) {
503 return $template;
504 }
505
506 if ($template = $this->getPluginTemplatePath($phpSlug)) {
507 return $template;
508 }
509
510 return $default;
511 }
512
513 /**
514 * Get default product URL with proper error checking
515 *
516 * @return string
517 */
518 protected function get_default_product_url() {
519 $products = wc_get_products(['status' => 'publish', 'limit' => 1]);
520
521 if (!empty($products) && isset($products[0]) && is_object($products[0])) {
522 $product = $products[0];
523 if (method_exists($product, 'get_id')) {
524 return get_permalink($product->get_id());
525 }
526 }
527
528 // Fallback to shop page if no products found
529 return get_permalink(wc_get_page_id('shop'));
530 }
531 }
532
533
534 Builder_Integration::instance();
535