PluginProbe
Ultimate Store Kit / 3.0.8
Ultimate Store Kit v3.0.8
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 2.0.6 All 92 releases
ultimate-store-kit / includes / builder / builder-integration.php

builder-integration.php in Ultimate Store Kit 3.0.8, at includes/builder/builder-integration.php

543 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 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 } elseif ($template_slug === 'shop' || $template_slug === 'archive') {
109 $template_url = get_permalink(wc_get_page_id('shop'));
110 } elseif ($template_slug === 'single' && $post_type === 'product') {
111 $page_settings_manager = \Elementor\Core\Settings\Manager::get_settings_managers('page');
112 $page_settings_model = $page_settings_manager->get_model($post_id);
113 $sample_product = $page_settings_model->get_settings('usk_builder_sample_post_id');
114
115 $template_url = !empty($sample_product) ?
116 get_permalink($sample_product) :
117 $this->get_default_product_url();
118 } elseif ($template_slug === 'cart') {
119 $template_url = wc_get_cart_url();
120 } elseif ($template_slug === 'checkout') {
121 $template_url = wc_get_checkout_url();
122 } elseif (
123 $template_slug === 'myaccount'
124 || $template_slug === 'login'
125 || strpos($template_slug, 'myaccount-') === 0
126 ) {
127 $template_url = get_permalink(wc_get_page_id('myaccount'));
128 } elseif ($template_slug === 'order-received') {
129 $orders = wc_get_orders(['limit' => 1]);
130 if (!empty($orders)) {
131 $order = $orders[0];
132 $order_id = $order->get_id();
133 $template_url = add_query_arg('order-received', $order_id, wc_get_checkout_url());
134 }
135 }
136
137 if (empty($template_url)) {
138 return $url;
139 }
140
141 $is_demo = apply_filters('ultimate_store_kit/preview/use_demo_bypass', false);
142 $nonce_value = $is_demo ? 'verified' : wp_create_nonce('template_preview_' . $post_id);
143
144 $param = [
145 'usk_template_id' => $post_id,
146 'preview_nonce' => $nonce_value,
147 'preview' => true
148 ];
149
150 // Add parameters two URL
151 $url = add_query_arg($param, $template_url);
152
153 return $url;
154 }
155
156 public function my_custom_fonts() {
157 if (is_admin() && Plugin::instance()->editor->is_edit_mode()) {
158 if (isset($_REQUEST['usk-template'])) {
159 wp_register_style('usk-template-builder-hide-preview-btn-inline', false); // phpcs:ignore
160 wp_enqueue_style('usk-template-builder-hide-preview-btn-inline');
161 wp_add_inline_style(
162 'usk-template-builder-hide-preview-btn-inline',
163 '#elementor-panel-footer-saver-preview {display:none!important}'
164 );
165 }
166 }
167 }
168 function set_sample_post() {
169 if (Builder_Template_Helper::isTemplateEditMode()) {
170 $object = \UltimateStoreKit\Includes\Builder\Builder_Post_Singleton::instance();
171 $object::set_sample_post();
172 }
173 }
174
175 function register_document_controls($document) {
176 if (
177 ! $document instanceof \Elementor\Core\DocumentTypes\PageBase
178 || ! $document::get_property('has_elements')
179 ) {
180 return;
181 }
182
183 if (Plugin::instance()->preview->is_preview_mode())
184 return;
185
186 if (! Builder_Template_Helper::isTemplateEditMode()) {
187 return;
188 }
189
190 global $post;
191
192 if (! isset($post->ID)) {
193 return;
194 }
195 $meta = get_post_meta($post->ID);
196
197 $templateMeta = optional($meta)[Meta::TEMPLATE_TYPE];
198 if (! isset($templateMeta[0])) {
199 return;
200 }
201 $postMeta = $templateMeta[0];
202 $postMeta = explode('|', $postMeta);
203 $postType = $postMeta[0];
204
205 if ($postMeta[1] != 'single') {
206 return;
207 }
208
209 $document->start_controls_section(
210 'usk_page_setting_preview',
211 [
212 'label' => esc_html__('Builder Settings', 'ultimate-store-kit'),
213 'tab' => Controls_Manager::TAB_SETTINGS,
214 ]
215 );
216
217 $document->add_control(
218 'usk_builder_sample_post_id',
219 [
220 'label' => __('Builder Post', 'ultimate-store-kit'),
221 'type' => Dynamic_Select::TYPE,
222 'multiple' => false,
223 'label_block' => true,
224 'query_args' => [
225 'post_type' => $postType
226 ],
227 ]
228 );
229
230 $document->add_control(
231 'usk_builder_sample_apply_preview',
232 [
233 'type' => Controls_Manager::BUTTON,
234 'label' => esc_html__('Apply & Preview', 'ultimate-store-kit'),
235 'label_block' => true,
236 'show_label' => false,
237 'text' => esc_html__('Apply & Preview', 'ultimate-store-kit'),
238 'separator' => 'none',
239 'event' => 'ultimateStoreKitBuilderSetting:applySinglePagePostOnPreview',
240 ]
241 );
242
243 $document->end_controls_section();
244 }
245
246 /**
247 * Rewrite default template
248 *
249 */
250 function set_builder_template($template) {
251 if (Builder_Template_Helper::isTemplateEditMode()) {
252 return $this->setBackendTemplate($template);
253 } else {
254 return $this->setFrontendTemplate($template);
255 }
256 }
257
258
259 protected function setBackendTemplate($template) {
260 return $template;
261 }
262
263
264 protected function setFrontendTemplate($template) {
265
266 if (get_post_type() == 'product') {
267 global $product;
268 $product = wc_get_product();
269 }
270
271 if (defined('ELEMENTOR_PATH')) {
272 $elementorTem = ELEMENTOR_PATH . "modules/page-templates/templates/";
273 $elementorTem = explode($elementorTem, $template);
274 if (count($elementorTem) == 2) {
275 return $template;
276 }
277 }
278
279
280 if (is_post_type_archive('product') || is_page(wc_get_page_id('shop')) || is_product_taxonomy()) {
281 $template_type = 'shop';
282
283 if (is_tax('product_cat')) {
284 $template_type = 'category';
285 } elseif (is_tax('product_tag')) {
286 $template_type = 'tag';
287 }
288
289 if ($custom_template = $this->get_template_id($template_type)) {
290 $this->current_template_id = $custom_template;
291 return $this->getTemplatePath('woocommerce/archive-product', $template);
292 }
293 }
294
295
296 if ( is_cart() ) {
297 $cart_template = $this->resolve_cart_template( $template );
298
299 if ( $cart_template ) {
300 return $cart_template;
301 }
302 }
303
304 if (is_order_received_page()) {
305 if ($custom_template = $this->get_template_id('order-received', 'product')) {
306 $this->current_template_id = $custom_template;
307 return $this->getTemplatePath('woocommerce/order-received', $template);
308 }
309 }
310
311 if (is_checkout()) {
312 if ($custom_template = $this->get_template_id('checkout', 'product')) {
313 $this->current_template_id = $custom_template;
314 return $this->getTemplatePath('woocommerce/checkout', $template);
315 }
316 }
317
318 if (is_single() && get_post_type() == 'product') {
319 if ($custom_template = $this->get_template_id('single', 'product')) {
320 $this->current_template_id = $custom_template;
321 return $this->getTemplatePath('woocommerce/single-product', $template);
322 }
323 }
324
325 if (is_account_page()) {
326 global $wp;
327 $query_vars = WC()->query->get_query_vars();
328
329 /**
330 * Add wishlist endpoint
331 */
332 $query_vars['wishlist'] = 'wishlist';
333
334 $endpoint_match = array_intersect_key($wp->query_vars, $query_vars);
335
336 // Logged-out visitors landing on /my-account/ (no endpoint) see the
337 // single Login & Register template, which is responsible for both
338 // authentication flows. WooCommerce's own form-login.php renders
339 // the login and registration forms on the same URL, so one
340 // template covers both intents.
341 if (! is_user_logged_in() && empty($endpoint_match)) {
342 if ($custom_template = $this->get_template_id('login', 'account')) {
343 $this->current_template_id = $custom_template;
344
345 if ($newTemplate = $this->getTemplatePath('woocommerce/login')) {
346 return $newTemplate;
347 }
348
349 return $this->getTemplatePath('woocommerce/my-account', $template);
350 }
351 }
352
353 if ($endpoint = $endpoint_match) {
354 $endpoint = array_key_first($endpoint);
355
356 if ($endpoint && $custom_template = $this->get_template_id($endpoint, 'account')) {
357 $this->current_template_id = $custom_template;
358
359 if ($newTemplate = $this->getTemplatePath("woocommerce/{$endpoint}")) {
360 return $newTemplate;
361 }
362
363 return $this->getTemplatePath("woocommerce/my-account", '');
364 }
365
366 if ($custom_template = $this->get_template_id('myaccount-orders', 'account')) {
367 $this->current_template_id = $custom_template;
368 return $this->getTemplatePath('woocommerce/my-account', $template);
369 }
370 } else {
371 if ($custom_template = $this->get_template_id('myaccount', 'account')) {
372 $this->current_template_id = $custom_template;
373 return $this->getTemplatePath('woocommerce/my-account', $template);
374 }
375 }
376 }
377
378
379 if (is_single()) {
380 if ($custom_template = $this->get_template_id('single', 'post')) {
381 $this->current_template_id = $custom_template;
382 return $this->getTemplatePath('single-post', $template);
383 }
384 }
385
386 if (is_archive()) {
387 if ($custom_template = $this->get_template_id('archive', 'post')) {
388 $this->current_template_id = $custom_template;
389 return $this->getTemplatePath('archive-post', $template);
390 }
391 }
392
393 if (is_home()) {
394 if ($custom_template = $this->get_template_id('home', 'post')) {
395 $this->current_template_id = $custom_template;
396 return $this->getTemplatePath('home', $template);
397 }
398 }
399
400 if ($page_Id = intval(get_option('bdt_usk_compare_products_page_id'))) {
401 if (is_page($page_Id)) {
402 if ($custom_template = $this->get_template_id('compare-products', 'product')) {
403 $this->current_template_id = $custom_template;
404 return $this->getTemplatePath('home', $template);
405 }
406 }
407 }
408
409 return $template;
410 }
411
412
413 public function getThemeTemplatePath($slug) {
414
415 $fullPath = get_template_directory() . "/ultimate-store-kit/$slug";
416 if (file_exists($fullPath)) {
417 return $fullPath;
418 }
419 }
420
421 public function getPluginTemplatePath($slug) {
422
423 $fullPath = BDTUSK_PATH . "includes/builder/templates/$slug";
424 if (file_exists($fullPath)) {
425 return $fullPath;
426 }
427 }
428
429
430 /**
431 * Get Template Path ID
432 *
433 * @param $slug
434 * @param $postType
435 *
436 * @return mixed|void|null
437 */
438 public function get_template_id($slug, $postType = false) {
439 // If we already have a template ID for this request, return it
440 if (null !== $this->current_template_id) {
441 return $this->current_template_id;
442 }
443
444 // Handle template preview from URL parameters
445 if (!empty($_GET['preview']) && !empty($_GET['usk_template_id']) && !empty($_GET['preview_nonce'])) {
446 $usk_template_id = sanitize_text_field(wp_unslash($_GET['usk_template_id']));
447 $nonce = sanitize_text_field(wp_unslash($_GET['preview_nonce']));
448
449 // Special handling for demo bypass
450 $is_demo_bypass = ($nonce === 'verified');
451 $nonce_verified = $is_demo_bypass ?
452 apply_filters('ultimate_store_kit/preview/verified_bypass', false) :
453 wp_verify_nonce($nonce, 'template_preview_' . $usk_template_id);
454
455 if ($nonce_verified) {
456 // For demo bypass mode, we don't need to check template type
457 if ($is_demo_bypass) {
458 $this->current_template_id = (int)$usk_template_id;
459 return $this->current_template_id;
460 }
461
462 // For normal preview, check template type
463 $template_type = get_post_meta($usk_template_id, Meta::TEMPLATE_TYPE, true);
464 if (!empty($template_type)) {
465 $template_data = explode(Builder_Template_Helper::separator(), $template_type);
466 if (count($template_data) >= 2 && $template_data[1] === $slug && ($postType === false || $template_data[0] === $postType)) {
467 $this->current_template_id = (int)$usk_template_id;
468 return $this->current_template_id;
469 }
470 }
471 }
472 }
473
474 // Regular template retrieval
475 $templateId = Builder_Template_Helper::getTemplate($slug, $postType);
476 $this->current_template_id = apply_filters('ultimate-store-kit-builder/custom-shop-template', $templateId);
477
478 return $this->current_template_id;
479 }
480
481
482 /**
483 * Get Template Path
484 *
485 * @param $slug
486 * @param $default
487 *
488 * @return mixed|string|void
489 */
490 protected function getTemplatePath($slug, $default = '') {
491 $phpSlug = "{$slug}.php";
492
493 if ($template = $this->getThemeTemplatePath($phpSlug)) {
494 return $template;
495 }
496
497 if ($template = $this->getPluginTemplatePath($phpSlug)) {
498 return $template;
499 }
500
501 return $default;
502 }
503
504 /**
505 * Resolve the plugin cart template for WooCommerce cart requests.
506 *
507 * @param string $template Default WordPress template path.
508 * @return string|false
509 */
510 protected function resolve_cart_template( $template ) {
511 if ( ! Cart_Render::is_available() ) {
512 return false;
513 }
514
515 $custom_template = $this->get_template_id( 'cart', 'product' );
516 $this->current_template_id = $custom_template ? absint( $custom_template ) : null;
517
518 return $this->getTemplatePath( 'woocommerce/cart', $template );
519 }
520
521 /**
522 * Get default product URL with proper error checking
523 *
524 * @return string
525 */
526 protected function get_default_product_url() {
527 $products = wc_get_products(['status' => 'publish', 'limit' => 1]);
528
529 if (!empty($products) && isset($products[0]) && is_object($products[0])) {
530 $product = $products[0];
531 if (method_exists($product, 'get_id')) {
532 return get_permalink($product->get_id());
533 }
534 }
535
536 // Fallback to shop page if no products found
537 return get_permalink(wc_get_page_id('shop'));
538 }
539 }
540
541
542 Builder_Integration::instance();
543