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