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/helper.php +688 -505 2.0.03.1.4 View file →
@@ -1,6 +1,12 @@
1 1 <?php
2 2
3 +if (! defined('ABSPATH')) {
4 + exit; // Exit if accessed directly
5 +}
6 +
7 +// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- BDTUSK_ / ultimate_store_kit_ / ultimate-store-kit- are this plugin's established public prefixes.
8 +
3 9 use UltimateStoreKit\Ultimate_Store_Kit_Loader;
4 10 use Elementor\Plugin;
5 11
6 12 /**
@@ -8,38 +14,50 @@
8 14 * Don't try for regular license otherwise your license will be invalid.
9 15 * return white label
10 16 */
11 17
12 -if ( ! defined( 'BDTUSK' ) ) {
13 - define( 'BDTUSK', '' );
18 +if (! defined('BDTUSK')) {
19 + define('BDTUSK', '');
14 20 }
15 21
16 22 //Add prefix for all widgets <span class="usk-widget-badge"></span>
17 -if ( ! defined( 'BDTUSK_CP' ) ) {
18 - define( 'BDTUSK_CP', '<span class="usk-widget-badge"></span>' );
23 +if (! defined('BDTUSK_CP')) {
24 + define('BDTUSK_CP', '<span class="usk-widget-badge"></span>');
19 25 }
20 26
21 27 //Add prefix for all widgets <span class="usk-widget-badge"></span>
22 -if ( ! defined( 'BDTUSK_NC' ) ) {
23 - define( 'BDTUSK_NC', '<span class="usk-new-control"></span>' );
28 +if (! defined('BDTUSK_NC')) {
29 + define('BDTUSK_NC', '<span class="usk-new-control"></span>');
24 30 }
25 31
26 32 // if you have any custom style
27 -if ( ! defined( 'BDTUSK_SLUG' ) ) {
28 - define( 'BDTUSK_SLUG', 'ultimate-store-kit' );
33 +if (! defined('BDTUSK_SLUG')) {
34 + define('BDTUSK_SLUG', 'ultimate-store-kit');
29 35 }
30 36
31 37 // set your own alias
32 -if ( ! defined( 'BDTUSK_VER' ) ) {
33 - define( 'BDTUSK_VER', 'Ultimate Store Kit' );
38 +if (! defined('BDTUSK_VER')) {
39 + define('BDTUSK_VER', 'Ultimate Store Kit');
34 40 }
35 41
36 42 // Set your own name for plugin
37 43
38 -if ( ! defined( 'BDTUSK_NAME' ) ) {
39 - define( 'BDTUSK_NAME', 'Ultimate Store Kit' );
44 +if (! defined('BDTUSK_NAME')) {
45 + define('BDTUSK_NAME', 'Ultimate Store Kit');
40 46 }
41 47
48 +if (ultimate_store_kit_is_pro_activated()) {
49 + if (! defined('BDTUSK_PC')) {
50 + define('BDTUSK_PC', '');
51 + } // pro control badge
52 + define('BDTUSK_IS_PC', '');
53 +} else {
54 + if (! defined('BDTUSK_PC')) {
55 + define('BDTUSK_PC', '<span class="usk-pro-control"></span>');
56 + } // pro control badge
57 + define('BDTUSK_IS_PC', 'usk-disabled-control');
58 +}
59 +
42 60 /**
43 61 * Show any alert by this function
44 62 *
45 63 * @param mixed $message [description]
@@ -57,26 +75,26 @@
57 75 function ultimate_store_kit_is_preview() {
58 76 return Plugin::$instance->preview->is_preview_mode();
59 77 }
60 78
61 -function ultimate_store_kit_alert( $message, $type = 'warning', $close = true ) {
62 - ?>
63 - <div class="usk-alert-<?php echo esc_attr( '$type' ); ?>" usk-alert>
64 - <?php if ( $close ) : ?>
79 +function ultimate_store_kit_alert($message, $type = 'warning', $close = true) {
80 +?>
81 + <div class="usk-alert-<?php echo esc_attr('$type'); ?>" usk-alert>
82 + <?php if ($close) : ?>
65 83 <a class="usk-alert-close" usk-close></a>
66 84 <?php endif; ?>
67 - <?php echo wp_kses_post( $message ); ?>
85 + <?php echo wp_kses_post($message); ?>
68 86 </div>
69 87 <?php
70 88 }
71 89
72 -function ultimate_store_kit_get_alert( $message, $type = 'warning', $close = true ) {
90 +function ultimate_store_kit_get_alert($message, $type = 'warning', $close = true) {
73 91
74 92 $output = '<div class="usk-alert-' . $type . '" usk-alert>';
75 - if ( $close ) :
93 + if ($close) :
76 94 $output .= '<a class="usk-alert-close" usk-close></a>';
77 95 endif;
78 - $output .= wp_kses_post( $message );
96 + $output .= wp_kses_post($message);
79 97 $output .= '</div>';
80 98
81 99 return $output;
82 100 }
@@ -88,24 +106,24 @@
88 106 *
89 107 * @return proper string
90 108 */
91 109
92 -function ultimate_store_kit_get_post_types( $args = [] ) {
110 +function ultimate_store_kit_get_post_types($args = []) {
93 111
94 - $post_type_args = [
112 + $post_type_args = [
95 113 'show_in_nav_menus' => true,
96 114 ];
97 115
98 - if ( ! empty( $args['post_type'] ) ) {
116 + if (! empty($args['post_type'])) {
99 117 $post_type_args['name'] = $args['post_type'];
100 118 }
101 119
102 - $_post_types = get_post_types( $post_type_args, 'objects' );
120 + $_post_types = get_post_types($post_type_args, 'objects');
103 121
104 - $post_types = [ '0' => esc_html__( 'Select Type', 'ultimate-store-kit' ) ];
122 + $post_types = ['0' => esc_html__('Select Type', 'ultimate-store-kit')];
105 123
106 - foreach ( $_post_types as $post_type => $object ) {
107 - $post_types[ $post_type ] = $object->label;
124 + foreach ($_post_types as $post_type => $object) {
125 + $post_types[$post_type] = $object->label;
108 126 }
109 127
110 128 return $post_types;
111 129 }
@@ -139,12 +157,12 @@
139 157 // }
140 158
141 159 // add_action( 'init', 'bdt_custom_post_type_rest_support', 25 );
142 160
143 -function ultimate_store_kit_allow_tags( $tag = null ) {
144 - $tag_allowed = wp_kses_allowed_html( 'post' );
161 +function ultimate_store_kit_allow_tags($tag = null) {
162 + $tag_allowed = wp_kses_allowed_html('post');
145 163
146 - $tag_allowed['input'] = [
164 + $tag_allowed['input'] = [
147 165 'class' => [],
148 166 'id' => [],
149 167 'name' => [],
150 168 'value' => [],
@@ -150,9 +168,9 @@
150 168 'value' => [],
151 169 'checked' => [],
152 170 'type' => [],
153 171 ];
154 - $tag_allowed['select'] = [
172 + $tag_allowed['select'] = [
155 173 'class' => [],
156 174 'id' => [],
157 175 'name' => [],
158 176 'value' => [],
@@ -158,15 +176,15 @@
158 176 'value' => [],
159 177 'multiple' => [],
160 178 'type' => [],
161 179 ];
162 - $tag_allowed['option'] = [
180 + $tag_allowed['option'] = [
163 181 'value' => [],
164 182 'selected' => [],
165 183 ];
166 184
167 - $tag_allowed['title'] = [
168 - 'a' => [
185 + $tag_allowed['title'] = [
186 + 'a' => [
169 187 'href' => [],
170 188 'title' => [],
171 189 'class' => [],
172 190 ],
@@ -175,10 +193,10 @@
175 193 'strong' => [],
176 194 'hr' => [],
177 195 ];
178 196
179 - $tag_allowed['text'] = [
180 - 'a' => [
197 + $tag_allowed['text'] = [
198 + 'a' => [
181 199 'href' => [],
182 200 'title' => [],
183 201 'class' => [],
184 202 ],
@@ -185,18 +203,18 @@
185 203 'br' => [],
186 204 'em' => [],
187 205 'strong' => [],
188 206 'hr' => [],
189 - 'i' => [
207 + 'i' => [
190 208 'class' => [],
191 209 ],
192 - 'span' => [
210 + 'span' => [
193 211 'class' => [],
194 212 ],
195 213 ];
196 214
197 - $tag_allowed['svg'] = [
198 - 'svg' => [
215 + $tag_allowed['svg'] = [
216 + 'svg' => [
199 217 'version' => [],
200 218 'xmlns' => [],
201 219 'viewbox' => [],
202 220 'xml:space' => [],
@@ -205,13 +223,13 @@
205 223 'y' => [],
206 224 'style' => [],
207 225 ],
208 226 'g' => [],
209 - 'path' => [
227 + 'path' => [
210 228 'class' => [],
211 229 'd' => [],
212 230 ],
213 - 'ellipse' => [
231 + 'ellipse' => [
214 232 'class' => [],
215 233 'cx' => [],
216 234 'cy' => [],
217 235 'rx' => [],
@@ -216,15 +234,15 @@
216 234 'cy' => [],
217 235 'rx' => [],
218 236 'ry' => [],
219 237 ],
220 - 'circle' => [
238 + 'circle' => [
221 239 'class' => [],
222 240 'cx' => [],
223 241 'cy' => [],
224 242 'r' => [],
225 243 ],
226 - 'rect' => [
244 + 'rect' => [
227 245 'x' => [],
228 246 'y' => [],
229 247 'transform' => [],
230 248 'height' => [],
@@ -230,9 +248,9 @@
230 248 'height' => [],
231 249 'width' => [],
232 250 'class' => [],
233 251 ],
234 - 'line' => [
252 + 'line' => [
235 253 'class' => [],
236 254 'x1' => [],
237 255 'x2' => [],
238 256 'y1' => [],
@@ -241,221 +259,209 @@
241 259 'style' => [],
242 260
243 261 ];
244 262
245 - if ( $tag == null ) {
263 + if ($tag == null) {
246 264 return $tag_allowed;
247 - } elseif ( is_array( $tag ) ) {
265 + } elseif (is_array($tag)) {
248 266 $new_tag_allow = [];
249 267
250 - foreach ( $tag as $_tag ) {
251 - $new_tag_allow[ $_tag ] = $tag_allowed[ $_tag ];
268 + foreach ($tag as $_tag) {
269 + $new_tag_allow[$_tag] = $tag_allowed[$_tag];
252 270 }
253 271
254 272 return $new_tag_allow;
255 273 } else {
256 - return isset( $tag_allowed[ $tag ] ) ? $tag_allowed[ $tag ] : [];
274 + return isset($tag_allowed[$tag]) ? $tag_allowed[$tag] : [];
257 275 }
258 276 }
259 277
260 278 /**
261 - * post pagination
279 + * Build a pagination link for widget grids or standard WordPress queries.
280 + *
281 + * @param int $page Page number.
282 + * @param string $query_arg Optional custom query arg (e.g. product-page).
283 + * @param string $current_url Base URL when using a custom query arg.
284 + * @return string
262 285 */
263 -function ultimate_store_kit_post_pagination( $wp_query ) {
286 +function ultimate_store_kit_get_pagination_link($page, $query_arg = '', $current_url = '') {
287 + $page = absint($page);
264 288
265 - /** Stop execution if there's only 1 page */
289 + if (! empty($query_arg)) {
290 + if ($page <= 1) {
291 + return remove_query_arg($query_arg, $current_url);
292 + }
266 293
267 - if ( $wp_query->max_num_pages <= 1 ) {
268 - return;
294 + return add_query_arg($query_arg, $page, $current_url);
269 295 }
270 296
271 - if ( is_front_page() ) {
272 - $paged = ( get_query_var( 'page' ) ) ? get_query_var( 'page' ) : 1;
273 - } else {
274 - $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
275 - }
297 + return get_pagenum_link($page);
298 +}
276 299
277 - $max = intval( $wp_query->max_num_pages );
278 -
279 - /** Add current page to the array */
280 -
281 - if ( $paged >= 1 ) {
282 - $links[] = $paged;
300 +/**
301 + * Whether pagination should use the product-page query arg.
302 + *
303 + * WooCommerce product grids read the page from ?product-page= so widget
304 + * pagination does not conflict with WordPress paged/page on embedded pages.
305 + *
306 + * @param WP_Query|object $wp_query Query object.
307 + * @return bool
308 + */
309 +function ultimate_store_kit_pagination_uses_product_page($wp_query) {
310 + if (! $wp_query instanceof \WP_Query) {
311 + return false;
283 312 }
284 313
285 - /** Add the pages around the current page to the array */
314 + $post_type = $wp_query->get('post_type');
286 315
287 - if ( $paged >= 3 ) {
288 - $links[] = $paged - 1;
289 - $links[] = $paged - 2;
316 + if (empty($post_type) && isset($wp_query->query_vars['post_type'])) {
317 + $post_type = $wp_query->query_vars['post_type'];
290 318 }
291 319
292 - if ( ( $paged + 2 ) <= $max ) {
293 - $links[] = $paged + 2;
294 - $links[] = $paged + 1;
320 + if (is_array($post_type)) {
321 + return in_array('product', $post_type, true);
295 322 }
296 323
297 - echo '<ul class="usk-pagination">' . "\n";
324 + return 'product' === $post_type;
325 +}
298 326
299 - /** Previous Post Link */
327 +/**
328 + * Post pagination.
329 + *
330 + * Auto-detects WooCommerce product grids and uses the product-page query arg.
331 + * EDD grids, product reviews, and other queries use standard WordPress pagination.
332 + *
333 + * @param WP_Query|object $wp_query Query object with max_num_pages.
334 + * @param array $args Optional. 'query_arg' => 'product-page' to force custom arg mode.
335 + */
336 +function ultimate_store_kit_post_pagination($wp_query, $args = []) {
337 + $args = wp_parse_args($args, [
338 + 'query_arg' => '',
339 + ]);
300 340
301 - if ( get_previous_posts_link() ) {
302 - printf( '<li>%s</li>' . "\n", wp_kses_post( get_previous_posts_link( '<span class="usk-icon-arrow-left-5"></span>' ) ) );
341 + if ($wp_query->max_num_pages <= 1) {
342 + return;
303 343 }
304 344
305 - /** Link to first page, plus ellipses if necessary */
345 + $query_arg = sanitize_key($args['query_arg']);
306 346
307 - if ( ! in_array( 1, $links ) ) {
308 - $class = 1 == $paged ? ' class="current"' : '';
309 -
310 - printf( '<li%s><a href="%s" target="_self">%s</a></li>' . "\n", wp_kses_post( $class ), esc_url( get_pagenum_link( 1 ) ), '1' );
311 -
312 - if ( ! in_array( 2, $links ) ) {
313 - echo '<li class="usk-pagination-dot-dot"><span>...</span></li>';
314 - }
347 + if ('' === $query_arg && ultimate_store_kit_pagination_uses_product_page($wp_query)) {
348 + $query_arg = 'product-page';
315 349 }
316 350
317 - /** Link to current page, plus 2 pages in either direction if necessary */
318 - sort( $links );
351 + $use_custom_arg = ! empty($query_arg);
319 352
320 - foreach ( (array) $links as $link ) {
321 - $class = $paged == $link ? ' class="usk-active"' : '';
322 - printf( '<li%s><a href="%s" target="_self">%s</a></li>' . "\n", wp_kses_post( $class ), esc_url( get_pagenum_link( $link ) ), esc_html( $link ) );
323 - }
353 + if ($use_custom_arg) {
354 + $page = max(1, absint(get_query_var('paged')), absint(get_query_var('page')));
355 + $custom_page = filter_input(INPUT_GET, $query_arg, FILTER_VALIDATE_INT);
324 356
325 - /** Link to last page, plus ellipses if necessary */
326 -
327 - if ( ! in_array( $max, $links ) ) {
328 -
329 - if ( ! in_array( $max - 1, $links ) ) {
330 - echo '<li class="usk-pagination-dot-dot"><span>...</span></li>' . "\n";
357 + if ($custom_page && $custom_page >= 1) {
358 + $page = absint($custom_page);
331 359 }
332 360
333 - $class = $paged == $max ? ' class="usk-active"' : '';
334 - printf( '<li%s><a href="%s" target="_self">%s</a></li>' . "\n", wp_kses_post( $class ), esc_url( get_pagenum_link( $max ) ), esc_html( $max ) );
361 + $paged = absint($page);
362 + } elseif (is_front_page()) {
363 + $paged = absint(get_query_var('page')) ?: 1;
364 + } else {
365 + $paged = absint(get_query_var('paged')) ?: 1;
335 366 }
336 367
337 - /** Next Post Link */
368 + $max = absint($wp_query->max_num_pages);
369 + $links = [];
338 370
339 - if ( get_next_posts_link() ) {
340 - printf( '<li>%s</li>' . "\n", wp_kses_post( get_next_posts_link( '<span class="usk-icon-arrow-right-1"></span>' ) ) );
341 - }
342 -
343 - echo '</ul>' . "\n";
344 -}
345 -function ultimate_store_kit_post_pagination__new( $wp_query ) {
346 -
347 - $page = max( 1, get_query_var( 'paged' ), get_query_var( 'page' ) );
348 - $page = absint( empty( $_GET['product-page'] ) ? $page : $_GET['product-page'] );
349 - $paged = absint( $page );
350 -
351 - $current_page_url = strtok( get_pagenum_link( 1 ), '?' );
352 -
353 - /** Stop execution if there's only 1 page */
354 -
355 - if ( $wp_query->max_num_pages <= 1 ) {
356 - return;
357 - }
358 -
359 - $max = intval( $wp_query->max_num_pages );
360 -
361 - /** Add current page to the array */
362 -
363 - if ( $paged >= 1 ) {
371 + if ($paged >= 1) {
364 372 $links[] = $paged;
365 373 }
366 374
367 - /** Add the pages around the current page to the array */
368 -
369 - if ( $paged >= 3 ) {
375 + if ($paged >= 3) {
370 376 $links[] = $paged - 1;
371 377 $links[] = $paged - 2;
372 378 }
373 379
374 - if ( ( $paged + 2 ) <= $max ) {
380 + if (($paged + 2) <= $max) {
375 381 $links[] = $paged + 2;
376 382 $links[] = $paged + 1;
377 383 }
378 384
379 - echo '<ul class="usk-pagination">' . "\n";
385 + $current_url = '';
380 386
381 - /** Previous Post Link */
387 + if ($use_custom_arg) {
388 + $current_url = remove_query_arg(['paged', 'page', $query_arg]);
382 389
383 - if ( get_previous_posts_link() ) {
384 - $prev_page = $paged - 1;
385 -
386 - if( $prev_page < 1 ) {
387 - return;
390 + if (is_post_type_archive() || is_tax()) {
391 + $current_url = remove_query_arg(
392 + ['paged', 'page', $query_arg],
393 + get_pagenum_link(1, false)
394 + );
388 395 }
396 + }
389 397
390 - $class = $paged == $prev_page ? ' class="current"' : '';
398 + echo '<ul class="usk-pagination" aria-label="' . esc_attr__('Pagination', 'ultimate-store-kit') . '">' . "\n";
391 399
400 + if ($paged > 1) {
392 401 printf(
393 - '<li%s><a href="%s" target="_self">%s</a></li>' . "\n",
394 - wp_kses_post( $class ),
395 - esc_url( add_query_arg( 'product-page', $prev_page, $current_page_url ) ),
396 - '<span class="usk-icon-arrow-left-5"></span>'
402 + '<li class="usk-pagination-previous">
403 + <a href="%s" aria-label="%s">
404 + <span class="usk-icon-arrow-left-5" aria-hidden="true"></span>
405 + </a>
406 + </li>' . "\n",
407 + esc_url(ultimate_store_kit_get_pagination_link($paged - 1, $query_arg, $current_url)),
408 + esc_attr__('Previous Page', 'ultimate-store-kit')
397 409 );
398 410 }
399 411
400 - /** Link to first page, plus ellipses if necessary */
412 + if (! in_array(1, $links, true)) {
413 + $class = (1 === $paged) ? 'usk-active' : '';
401 414
402 - if ( ! in_array( 1, $links ) ) {
403 - $class = 1 == $paged ? ' class="current"' : '';
404 -
405 - printf(
406 - '<li%s><a href="%s" target="_self">%s</a></li>' . "\n",
407 - wp_kses_post( $class ),
408 - esc_url( add_query_arg( 'product-page', '1', $current_page_url ) ),
409 - '1'
415 + printf(
416 + '<li class="%s"><a href="%s" target="_self">%s</a></li>' . "\n",
417 + esc_attr($class),
418 + esc_url(ultimate_store_kit_get_pagination_link(1, $query_arg, $current_url)),
419 + esc_html('1')
410 420 );
411 421
412 - if ( ! in_array( 2, $links ) ) {
413 - echo '<li class="usk-pagination-dot-dot"><span>...</span></li>';
422 + if (! in_array(2, $links, true)) {
423 + echo '<li class="usk-pagination-dot-dot"><span>...</span></li>' . "\n";
414 424 }
415 425 }
416 426
417 - /** Link to current page, plus 2 pages in either direction if necessary */
418 - sort( $links );
427 + sort($links);
419 428
420 - foreach ( (array) $links as $link ) {
421 - $class = $paged == $link ? ' class="usk-active"' : '';
422 - printf( '<li%s><a href="%s" target="_self">%s</a></li>' . "\n",
423 - wp_kses_post( $class ),
424 - esc_url( add_query_arg( 'product-page', $link, $current_page_url ) ),
425 - esc_html( $link ) );
429 + foreach ($links as $link) {
430 + $class = ($paged === (int) $link) ? 'usk-active' : '';
431 +
432 + printf(
433 + '<li class="%s"><a href="%s" target="_self">%s</a></li>' . "\n",
434 + esc_attr($class),
435 + esc_url(ultimate_store_kit_get_pagination_link($link, $query_arg, $current_url)),
436 + esc_html($link)
437 + );
426 438 }
427 439
428 - /** Link to last page, plus ellipses if necessary */
429 -
430 - if ( ! in_array( $max, $links ) ) {
431 -
432 - if ( ! in_array( $max - 1, $links ) ) {
440 + if (! in_array($max, $links, true)) {
441 + if (! in_array($max - 1, $links, true)) {
433 442 echo '<li class="usk-pagination-dot-dot"><span>...</span></li>' . "\n";
434 443 }
435 444
436 - $class = $paged == $max ? ' class="usk-active"' : '';
437 - printf(
438 - '<li%s><a href="%s" target="_self">%s</a></li>' . "\n",
439 - wp_kses_post( $class ),
440 - esc_url( add_query_arg( 'product-page', $max, $current_page_url ) ),
441 - esc_html( $max ) );
445 + $class = ($paged === $max) ? 'usk-active' : '';
446 +
447 + printf(
448 + '<li class="%s"><a href="%s" target="_self">%s</a></li>' . "\n",
449 + esc_attr($class),
450 + esc_url(ultimate_store_kit_get_pagination_link($max, $query_arg, $current_url)),
451 + esc_html($max)
452 + );
442 453 }
443 454
444 - /** Next Post Link */
445 -
446 - if ( get_next_posts_link() ) {
447 - $next_page = $paged + 1;
448 -
449 - if( $next_page > $max ) {
450 - return;
451 - }
452 -
455 + if ($paged < $max) {
453 456 printf(
454 - '<li%s><a href="%s" target="_self">%s</a></li>' . "\n",
455 - wp_kses_post( $class ),
456 - esc_url( add_query_arg( 'product-page', $next_page, $current_page_url ) ),
457 - '<span class="usk-icon-arrow-right-1"></span>'
457 + '<li class="usk-pagination-next">
458 + <a href="%s" aria-label="%s">
459 + <span class="usk-icon-arrow-right-5" aria-hidden="true"></span>
460 + </a>
461 + </li>' . "\n",
462 + esc_url(ultimate_store_kit_get_pagination_link($paged + 1, $query_arg, $current_url)),
463 + esc_attr__('Next Page', 'ultimate-store-kit')
458 464 );
459 465 }
460 466
461 467 echo '</ul>' . "\n";
@@ -460,30 +466,30 @@
460 466
461 467 echo '</ul>' . "\n";
462 468 }
463 469
464 -function ultimate_store_kit_template_edit_link( $template_id ) {
470 +function ultimate_store_kit_template_edit_link($template_id) {
465 471
466 - if ( Ultimate_Store_Kit_Loader::elementor()->editor->is_edit_mode() ) {
472 + if (Ultimate_Store_Kit_Loader::elementor()->editor->is_edit_mode()) {
467 473
468 - $final_url = add_query_arg( [ 'elementor' => '' ], get_permalink( $template_id ) );
474 + $final_url = add_query_arg(['elementor' => ''], get_permalink($template_id));
469 475
470 - $output = sprintf( '<a class="usk-elementor-template-edit-link" href="%s" title="%s" target="_blank"><i class="usk-icon-edit"></i></a>', esc_url( $final_url ), esc_html__( 'Edit Template', 'ultimate-store-kit' ) );
476 + $output = sprintf('<a class="usk-elementor-template-edit-link" href="%s" title="%s" target="_blank"><i class="usk-icon-edit"></i></a>', esc_url($final_url), esc_html__('Edit Template', 'ultimate-store-kit'));
471 477
472 478 return $output;
473 479 }
474 480 }
475 481
476 -function ultimate_store_kit_iso_time( $time ) {
477 - $current_offset = (float) get_option( 'gmt_offset' );
478 - $timezone_string = get_option( 'timezone_string' );
482 +function ultimate_store_kit_iso_time($time) {
483 + $current_offset = (float) get_option('gmt_offset');
484 + $timezone_string = get_option('timezone_string');
479 485
480 486 // Create a UTC+- zone if no timezone string exists.
481 487
482 488 //if ( empty( $timezone_string ) ) {
483 - if ( 0 === $current_offset ) {
489 + if (0 === $current_offset) {
484 490 $timezone_string = '+00:00';
485 - } elseif ( $current_offset < 0 ) {
491 + } elseif ($current_offset < 0) {
486 492 $timezone_string = $current_offset . ':00';
487 493 } else {
488 494 $timezone_string = '+0' . $current_offset . ':00';
489 495 }
@@ -490,9 +496,9 @@
490 496
491 497 //}
492 498
493 499 $sub_time = [];
494 - $sub_time = explode( " ", $time );
500 + $sub_time = explode(" ", $time);
495 501 $final_time = $sub_time[0] . 'T' . $sub_time[1] . ':00' . $timezone_string;
496 502
497 503 return $final_time;
498 504 }
@@ -502,46 +508,46 @@
502 508 * @param int $precision
503 509 *
504 510 * @return false|string
505 511 */
506 -function ultimate_store_kit_currency_format( $currency, $precision = 1 ) {
512 +function ultimate_store_kit_currency_format($currency, $precision = 1) {
507 513
508 - if ( $currency > 0 ) {
514 + if ($currency > 0) {
509 515
510 - if ( $currency < 900 ) {
516 + if ($currency < 900) {
511 517 // 0 - 900
512 - $currency_format = number_format( $currency, $precision );
518 + $currency_format = number_format($currency, $precision);
513 519 $suffix = '';
514 520 } else
515 521
516 - if ( $currency < 900000 ) {
517 - // 0.9k-850k
518 - $currency_format = number_format( $currency / 1000, $precision );
519 - $suffix = 'K';
520 - } else
522 + if ($currency < 900000) {
523 + // 0.9k-850k
524 + $currency_format = number_format($currency / 1000, $precision);
525 + $suffix = 'K';
526 + } else
521 527
522 - if ( $currency < 900000000 ) {
523 - // 0.9m-850m
524 - $currency_format = number_format( $currency / 1000000, $precision );
525 - $suffix = 'M';
526 - } else
528 + if ($currency < 900000000) {
529 + // 0.9m-850m
530 + $currency_format = number_format($currency / 1000000, $precision);
531 + $suffix = 'M';
532 + } else
527 533
528 - if ( $currency < 900000000000 ) {
529 - // 0.9b-850b
530 - $currency_format = number_format( $currency / 1000000000, $precision );
531 - $suffix = 'B';
532 - } else {
533 - // 0.9t+
534 - $currency_format = number_format( $currency / 1000000000000, $precision );
535 - $suffix = 'T';
536 - }
534 + if ($currency < 900000000000) {
535 + // 0.9b-850b
536 + $currency_format = number_format($currency / 1000000000, $precision);
537 + $suffix = 'B';
538 + } else {
539 + // 0.9t+
540 + $currency_format = number_format($currency / 1000000000000, $precision);
541 + $suffix = 'T';
542 + }
537 543
538 544 // Remove unecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1"
539 545
540 546 // Intentionally does not affect partials, eg "1.50" -> "1.50"
541 - if ( $precision > 0 ) {
542 - $dotzero = '.' . str_repeat( '0', $precision );
543 - $currency_format = str_replace( $dotzero, '', $currency_format );
547 + if ($precision > 0) {
548 + $dotzero = '.' . str_repeat('0', $precision);
549 + $currency_format = str_replace($dotzero, '', $currency_format);
544 550 }
545 551
546 552 return $currency_format . $suffix;
547 553 }
@@ -554,11 +560,11 @@
554 560 */
555 561 function ultimate_store_kit_get_menu() {
556 562
557 563 $menus = wp_get_nav_menus();
558 - $items = [ 0 => esc_html__( 'Select Menu', 'ultimate-store-kit' ) ];
559 - foreach ( $menus as $menu ) {
560 - $items[ $menu->slug ] = $menu->name;
564 + $items = [0 => esc_html__('Select Menu', 'ultimate-store-kit')];
565 + foreach ($menus as $menu) {
566 + $items[$menu->slug] = $menu->name;
561 567 }
562 568
563 569 return $items;
564 570 }
@@ -571,14 +577,14 @@
571 577 * @param string $default default text if it's not found
572 578 *
573 579 * @return mixed
574 580 */
575 -function ultimate_store_kit_option( $option, $section, $default = '' ) {
581 +function ultimate_store_kit_option($option, $section, $default = '') {
576 582
577 - $options = get_option( $section );
583 + $options = get_option($section);
578 584
579 - if ( isset( $options[ $option ] ) ) {
580 - return $options[ $option ];
585 + if (isset($options[$option])) {
586 + return $options[$option];
581 587 }
582 588
583 589 return $default;
584 590 }
@@ -587,19 +593,19 @@
587 593 * @return array of elementor template
588 594 */
589 595 function ultimate_store_kit_et_options() {
590 596
591 - $templates = Ultimate_Store_Kit_Loader::elementor()->templates_manager->get_source( 'local' )->get_items();
597 + $templates = Ultimate_Store_Kit_Loader::elementor()->templates_manager->get_source('local')->get_items();
592 598 $types = [];
593 599
594 - if ( empty( $templates ) ) {
595 - $template_options = [ '0' => __( 'Template Not Found!', 'ultimate-store-kit' ) ];
600 + if (empty($templates)) {
601 + $template_options = ['0' => __('Template Not Found!', 'ultimate-store-kit')];
596 602 } else {
597 - $template_options = [ '0' => __( 'Select Template', 'ultimate-store-kit' ) ];
603 + $template_options = ['0' => __('Select Template', 'ultimate-store-kit')];
598 604
599 - foreach ( $templates as $template ) {
600 - $template_options[ $template['template_id'] ] = $template['title'] . ' (' . $template['type'] . ')';
601 - $types[ $template['template_id'] ] = $template['type'];
605 + foreach ($templates as $template) {
606 + $template_options[$template['template_id']] = $template['title'] . ' (' . $template['type'] . ')';
607 + $types[$template['template_id']] = $template['type'];
602 608 }
603 609 }
604 610
605 611 return $template_options;
@@ -612,15 +618,15 @@
612 618
613 619 global $wp_registered_sidebars;
614 620 $sidebar_options = [];
615 621
616 - if ( ! $wp_registered_sidebars ) {
617 - $sidebar_options[0] = esc_html__( 'No sidebars were found', 'ultimate-store-kit' );
622 + if (! $wp_registered_sidebars) {
623 + $sidebar_options[0] = esc_html__('No sidebars were found', 'ultimate-store-kit');
618 624 } else {
619 - $sidebar_options[0] = esc_html__( 'Select Sidebar', 'ultimate-store-kit' );
625 + $sidebar_options[0] = esc_html__('Select Sidebar', 'ultimate-store-kit');
620 626
621 - foreach ( $wp_registered_sidebars as $sidebar_id => $sidebar ) {
622 - $sidebar_options[ $sidebar_id ] = $sidebar['name'];
627 + foreach ($wp_registered_sidebars as $sidebar_id => $sidebar) {
628 + $sidebar_options[$sidebar_id] = $sidebar['name'];
623 629 }
624 630 }
625 631
626 632 return $sidebar_options;
@@ -630,24 +636,27 @@
630 636 * @param string category name
631 637 *
632 638 * @return array of category
633 639 */
634 -function ultimate_store_kit_get_category( $taxonomy = 'product_cat' ) {
640 +function ultimate_store_kit_get_category($taxonomy = 'product_cat') {
635 641
636 642 $post_options = [];
637 643
638 - $post_categories = get_terms( [
644 + $post_categories = get_terms([
639 645 'taxonomy' => $taxonomy,
640 646 'hide_empty' => false,
641 - ] );
647 + ]);
642 648
643 - if ( is_wp_error( $post_categories ) ) {
649 + if (is_wp_error($post_categories)) {
644 650 return $post_options;
645 651 }
646 652
647 - if ( false !== $post_categories and is_array( $post_categories ) ) {
648 - foreach ( $post_categories as $category ) {
649 - $post_options[ $category->term_id ] = $category->name;
653 + if (false !== $post_categories and is_array($post_categories)) {
654 + foreach ($post_categories as $category) {
655 + // Ensure $category is an object, not an array
656 + if (is_object($category) && isset($category->term_id, $category->name)) {
657 + $post_options[$category->term_id] = $category->name;
658 + }
650 659 }
651 660 }
652 661
653 662 return $post_options;
@@ -656,16 +665,19 @@
656 665 /**
657 666 * @param string parent category name
658 667 * @return array of parent category
659 668 */
660 -function ultimate_store_kit_get_only_parent_cats( $taxonomy = 'category' ) {
669 +function ultimate_store_kit_get_only_parent_cats($taxonomy = 'category') {
661 670
662 - $parent_categories = [ 'none' => __( 'None', 'ultimate-store-kit' ) ];
663 - $args = [ 'parent' => 0 ];
664 - $parent_cats = get_terms( $taxonomy, $args );
671 + $parent_categories = ['none' => __('None', 'ultimate-store-kit')];
672 + $args = ['taxonomy' => $taxonomy, 'parent' => 0];
673 + $parent_cats = get_terms($args);
665 674
666 - foreach ( $parent_cats as $parent_cat ) {
667 - $parent_categories[ $parent_cat->term_id ] = ucfirst( $parent_cat->name );
675 + foreach ($parent_cats as $parent_cat) {
676 + // Ensure $parent_cat is an object, not an array
677 + if (is_object($parent_cat) && isset($parent_cat->term_id, $parent_cat->name)) {
678 + $parent_categories[$parent_cat->term_id] = ucfirst($parent_cat->name);
679 + }
668 680 }
669 681
670 682 return $parent_categories;
671 683 }
@@ -674,11 +686,11 @@
674 686 * @param array all ajax posted array there
675 687 *
676 688 * @return array return all setting as array
677 689 */
678 -function ultimate_store_kit_ajax_settings( $settings ) {
690 +function ultimate_store_kit_ajax_settings($settings) {
679 691
680 - $required_settings = [
692 + $required_settings = [
681 693 'show_date' => true,
682 694 'show_comment' => true,
683 695 'show_link' => true,
684 696 'show_meta' => true,
@@ -689,11 +701,11 @@
689 701 'show_category' => false,
690 702 'show_tags' => false,
691 703 ];
692 704
693 - foreach ( $settings as $key => $value ) {
694 - if ( in_array( $key, $required_settings ) ) {
695 - $required_settings[ $key ] = $value;
705 + foreach ($settings as $key => $value) {
706 + if (in_array($key, $required_settings)) {
707 + $required_settings[$key] = $value;
696 708 }
697 709 }
698 710
699 711 return $required_settings;
@@ -703,25 +715,25 @@
703 715 * @return array of all transition names
704 716 */
705 717 function ultimate_store_kit_transition_options() {
706 718
707 - $transition_options = [
708 - '' => esc_html__( 'None', 'ultimate-store-kit' ),
709 - 'fade' => esc_html__( 'Fade', 'ultimate-store-kit' ),
710 - 'scale-up' => esc_html__( 'Scale Up', 'ultimate-store-kit' ),
711 - 'scale-down' => esc_html__( 'Scale Down', 'ultimate-store-kit' ),
712 - 'slide-top' => esc_html__( 'Slide Top', 'ultimate-store-kit' ),
713 - 'slide-bottom' => esc_html__( 'Slide Bottom', 'ultimate-store-kit' ),
714 - 'slide-left' => esc_html__( 'Slide Left', 'ultimate-store-kit' ),
715 - 'slide-right' => esc_html__( 'Slide Right', 'ultimate-store-kit' ),
716 - 'slide-top-small' => esc_html__( 'Slide Top Small', 'ultimate-store-kit' ),
717 - 'slide-bottom-small' => esc_html__( 'Slide Bottom Small', 'ultimate-store-kit' ),
718 - 'slide-left-small' => esc_html__( 'Slide Left Small', 'ultimate-store-kit' ),
719 - 'slide-right-small' => esc_html__( 'Slide Right Small', 'ultimate-store-kit' ),
720 - 'slide-top-medium' => esc_html__( 'Slide Top Medium', 'ultimate-store-kit' ),
721 - 'slide-bottom-medium' => esc_html__( 'Slide Bottom Medium', 'ultimate-store-kit' ),
722 - 'slide-left-medium' => esc_html__( 'Slide Left Medium', 'ultimate-store-kit' ),
723 - 'slide-right-medium' => esc_html__( 'Slide Right Medium', 'ultimate-store-kit' ),
719 + $transition_options = [
720 + '' => esc_html__('None', 'ultimate-store-kit'),
721 + 'fade' => esc_html__('Fade', 'ultimate-store-kit'),
722 + 'scale-up' => esc_html__('Scale Up', 'ultimate-store-kit'),
723 + 'scale-down' => esc_html__('Scale Down', 'ultimate-store-kit'),
724 + 'slide-top' => esc_html__('Slide Top', 'ultimate-store-kit'),
725 + 'slide-bottom' => esc_html__('Slide Bottom', 'ultimate-store-kit'),
726 + 'slide-left' => esc_html__('Slide Left', 'ultimate-store-kit'),
727 + 'slide-right' => esc_html__('Slide Right', 'ultimate-store-kit'),
728 + 'slide-top-small' => esc_html__('Slide Top Small', 'ultimate-store-kit'),
729 + 'slide-bottom-small' => esc_html__('Slide Bottom Small', 'ultimate-store-kit'),
730 + 'slide-left-small' => esc_html__('Slide Left Small', 'ultimate-store-kit'),
731 + 'slide-right-small' => esc_html__('Slide Right Small', 'ultimate-store-kit'),
732 + 'slide-top-medium' => esc_html__('Slide Top Medium', 'ultimate-store-kit'),
733 + 'slide-bottom-medium' => esc_html__('Slide Bottom Medium', 'ultimate-store-kit'),
734 + 'slide-left-medium' => esc_html__('Slide Left Medium', 'ultimate-store-kit'),
735 + 'slide-right-medium' => esc_html__('Slide Right Medium', 'ultimate-store-kit'),
724 736 ];
725 737
726 738 return $transition_options;
727 739 }
@@ -727,24 +739,24 @@
727 739 }
728 740
729 741 // BDT Blend Type
730 742 function ultimate_store_kit_blend_options() {
731 - $blend_options = [
732 - 'multiply' => esc_html__( 'Multiply', 'ultimate-store-kit' ),
733 - 'screen' => esc_html__( 'Screen', 'ultimate-store-kit' ),
734 - 'overlay' => esc_html__( 'Overlay', 'ultimate-store-kit' ),
735 - 'darken' => esc_html__( 'Darken', 'ultimate-store-kit' ),
736 - 'lighten' => esc_html__( 'Lighten', 'ultimate-store-kit' ),
737 - 'color-dodge' => esc_html__( 'Color-Dodge', 'ultimate-store-kit' ),
738 - 'color-burn' => esc_html__( 'Color-Burn', 'ultimate-store-kit' ),
739 - 'hard-light' => esc_html__( 'Hard-Light', 'ultimate-store-kit' ),
740 - 'soft-light' => esc_html__( 'Soft-Light', 'ultimate-store-kit' ),
741 - 'difference' => esc_html__( 'Difference', 'ultimate-store-kit' ),
742 - 'exclusion' => esc_html__( 'Exclusion', 'ultimate-store-kit' ),
743 - 'hue' => esc_html__( 'Hue', 'ultimate-store-kit' ),
744 - 'saturation' => esc_html__( 'Saturation', 'ultimate-store-kit' ),
745 - 'color' => esc_html__( 'Color', 'ultimate-store-kit' ),
746 - 'luminosity' => esc_html__( 'Luminosity', 'ultimate-store-kit' ),
743 + $blend_options = [
744 + 'multiply' => esc_html__('Multiply', 'ultimate-store-kit'),
745 + 'screen' => esc_html__('Screen', 'ultimate-store-kit'),
746 + 'overlay' => esc_html__('Overlay', 'ultimate-store-kit'),
747 + 'darken' => esc_html__('Darken', 'ultimate-store-kit'),
748 + 'lighten' => esc_html__('Lighten', 'ultimate-store-kit'),
749 + 'color-dodge' => esc_html__('Color-Dodge', 'ultimate-store-kit'),
750 + 'color-burn' => esc_html__('Color-Burn', 'ultimate-store-kit'),
751 + 'hard-light' => esc_html__('Hard-Light', 'ultimate-store-kit'),
752 + 'soft-light' => esc_html__('Soft-Light', 'ultimate-store-kit'),
753 + 'difference' => esc_html__('Difference', 'ultimate-store-kit'),
754 + 'exclusion' => esc_html__('Exclusion', 'ultimate-store-kit'),
755 + 'hue' => esc_html__('Hue', 'ultimate-store-kit'),
756 + 'saturation' => esc_html__('Saturation', 'ultimate-store-kit'),
757 + 'color' => esc_html__('Color', 'ultimate-store-kit'),
758 + 'luminosity' => esc_html__('Luminosity', 'ultimate-store-kit'),
747 759 ];
748 760
749 761 return $blend_options;
750 762 }
@@ -750,19 +762,19 @@
750 762 }
751 763
752 764 // BDT Position
753 765 function ultimate_store_kit_position() {
754 - $position_options = [
755 - '' => esc_html__( 'Default', 'ultimate-store-kit' ),
756 - 'top-left' => esc_html__( 'Top Left', 'ultimate-store-kit' ),
757 - 'top-center' => esc_html__( 'Top Center', 'ultimate-store-kit' ),
758 - 'top-right' => esc_html__( 'Top Right', 'ultimate-store-kit' ),
759 - 'center' => esc_html__( 'Center', 'ultimate-store-kit' ),
760 - 'center-left' => esc_html__( 'Center Left', 'ultimate-store-kit' ),
761 - 'center-right' => esc_html__( 'Center Right', 'ultimate-store-kit' ),
762 - 'bottom-left' => esc_html__( 'Bottom Left', 'ultimate-store-kit' ),
763 - 'bottom-center' => esc_html__( 'Bottom Center', 'ultimate-store-kit' ),
764 - 'bottom-right' => esc_html__( 'Bottom Right', 'ultimate-store-kit' ),
766 + $position_options = [
767 + '' => esc_html__('Default', 'ultimate-store-kit'),
768 + 'top-left' => esc_html__('Top Left', 'ultimate-store-kit'),
769 + 'top-center' => esc_html__('Top Center', 'ultimate-store-kit'),
770 + 'top-right' => esc_html__('Top Right', 'ultimate-store-kit'),
771 + 'center' => esc_html__('Center', 'ultimate-store-kit'),
772 + 'center-left' => esc_html__('Center Left', 'ultimate-store-kit'),
773 + 'center-right' => esc_html__('Center Right', 'ultimate-store-kit'),
774 + 'bottom-left' => esc_html__('Bottom Left', 'ultimate-store-kit'),
775 + 'bottom-center' => esc_html__('Bottom Center', 'ultimate-store-kit'),
776 + 'bottom-right' => esc_html__('Bottom Right', 'ultimate-store-kit'),
765 777 ];
766 778
767 779 return $position_options;
768 780 }
@@ -768,17 +780,17 @@
768 780 }
769 781
770 782 // BDT Thumbnavs Position
771 783 function ultimate_store_kit_thumbnavs_position() {
772 - $position_options = [
773 - 'top-left' => esc_html__( 'Top Left', 'ultimate-store-kit' ),
774 - 'top-center' => esc_html__( 'Top Center', 'ultimate-store-kit' ),
775 - 'top-right' => esc_html__( 'Top Right', 'ultimate-store-kit' ),
776 - 'center-left' => esc_html__( 'Center Left', 'ultimate-store-kit' ),
777 - 'center-right' => esc_html__( 'Center Right', 'ultimate-store-kit' ),
778 - 'bottom-left' => esc_html__( 'Bottom Left', 'ultimate-store-kit' ),
779 - 'bottom-center' => esc_html__( 'Bottom Center', 'ultimate-store-kit' ),
780 - 'bottom-right' => esc_html__( 'Bottom Right', 'ultimate-store-kit' ),
784 + $position_options = [
785 + 'top-left' => esc_html__('Top Left', 'ultimate-store-kit'),
786 + 'top-center' => esc_html__('Top Center', 'ultimate-store-kit'),
787 + 'top-right' => esc_html__('Top Right', 'ultimate-store-kit'),
788 + 'center-left' => esc_html__('Center Left', 'ultimate-store-kit'),
789 + 'center-right' => esc_html__('Center Right', 'ultimate-store-kit'),
790 + 'bottom-left' => esc_html__('Bottom Left', 'ultimate-store-kit'),
791 + 'bottom-center' => esc_html__('Bottom Center', 'ultimate-store-kit'),
792 + 'bottom-right' => esc_html__('Bottom Right', 'ultimate-store-kit'),
781 793 ];
782 794
783 795 return $position_options;
784 796 }
@@ -783,16 +795,16 @@
783 795 return $position_options;
784 796 }
785 797
786 798 function ultimate_store_kit_navigation_position() {
787 - $position_options = [
788 - 'top-left' => esc_html__( 'Top Left', 'ultimate-store-kit' ),
789 - 'top-center' => esc_html__( 'Top Center', 'ultimate-store-kit' ),
790 - 'top-right' => esc_html__( 'Top Right', 'ultimate-store-kit' ),
791 - 'center' => esc_html__( 'Center', 'ultimate-store-kit' ),
792 - 'bottom-left' => esc_html__( 'Bottom Left', 'ultimate-store-kit' ),
793 - 'bottom-center' => esc_html__( 'Bottom Center', 'ultimate-store-kit' ),
794 - 'bottom-right' => esc_html__( 'Bottom Right', 'ultimate-store-kit' ),
799 + $position_options = [
800 + 'top-left' => esc_html__('Top Left', 'ultimate-store-kit'),
801 + 'top-center' => esc_html__('Top Center', 'ultimate-store-kit'),
802 + 'top-right' => esc_html__('Top Right', 'ultimate-store-kit'),
803 + 'center' => esc_html__('Center', 'ultimate-store-kit'),
804 + 'bottom-left' => esc_html__('Bottom Left', 'ultimate-store-kit'),
805 + 'bottom-center' => esc_html__('Bottom Center', 'ultimate-store-kit'),
806 + 'bottom-right' => esc_html__('Bottom Right', 'ultimate-store-kit'),
795 807 ];
796 808
797 809 return $position_options;
798 810 }
@@ -797,15 +809,15 @@
797 809 return $position_options;
798 810 }
799 811
800 812 function ultimate_store_kit_pagination_position() {
801 - $position_options = [
802 - 'top-left' => esc_html__( 'Top Left', 'ultimate-store-kit' ),
803 - 'top-center' => esc_html__( 'Top Center', 'ultimate-store-kit' ),
804 - 'top-right' => esc_html__( 'Top Right', 'ultimate-store-kit' ),
805 - 'bottom-left' => esc_html__( 'Bottom Left', 'ultimate-store-kit' ),
806 - 'bottom-center' => esc_html__( 'Bottom Center', 'ultimate-store-kit' ),
807 - 'bottom-right' => esc_html__( 'Bottom Right', 'ultimate-store-kit' ),
813 + $position_options = [
814 + 'top-left' => esc_html__('Top Left', 'ultimate-store-kit'),
815 + 'top-center' => esc_html__('Top Center', 'ultimate-store-kit'),
816 + 'top-right' => esc_html__('Top Right', 'ultimate-store-kit'),
817 + 'bottom-left' => esc_html__('Bottom Left', 'ultimate-store-kit'),
818 + 'bottom-center' => esc_html__('Bottom Center', 'ultimate-store-kit'),
819 + 'bottom-right' => esc_html__('Bottom Right', 'ultimate-store-kit'),
808 820 ];
809 821
810 822 return $position_options;
811 823 }
@@ -811,23 +823,23 @@
811 823 }
812 824
813 825 // BDT Drop Position
814 826 function ultimate_store_kit_drop_position() {
815 - $drop_position_options = [
816 - 'bottom-left' => esc_html__( 'Bottom Left', 'ultimate-store-kit' ),
817 - 'bottom-center' => esc_html__( 'Bottom Center', 'ultimate-store-kit' ),
818 - 'bottom-right' => esc_html__( 'Bottom Right', 'ultimate-store-kit' ),
819 - 'bottom-justify' => esc_html__( 'Bottom Justify', 'ultimate-store-kit' ),
820 - 'top-left' => esc_html__( 'Top Left', 'ultimate-store-kit' ),
821 - 'top-center' => esc_html__( 'Top Center', 'ultimate-store-kit' ),
822 - 'top-right' => esc_html__( 'Top Right', 'ultimate-store-kit' ),
823 - 'top-justify' => esc_html__( 'Top Justify', 'ultimate-store-kit' ),
824 - 'left-top' => esc_html__( 'Left Top', 'ultimate-store-kit' ),
825 - 'left-center' => esc_html__( 'Left Center', 'ultimate-store-kit' ),
826 - 'left-bottom' => esc_html__( 'Left Bottom', 'ultimate-store-kit' ),
827 - 'right-top' => esc_html__( 'Right Top', 'ultimate-store-kit' ),
828 - 'right-center' => esc_html__( 'Right Center', 'ultimate-store-kit' ),
829 - 'right-bottom' => esc_html__( 'Right Bottom', 'ultimate-store-kit' ),
827 + $drop_position_options = [
828 + 'bottom-left' => esc_html__('Bottom Left', 'ultimate-store-kit'),
829 + 'bottom-center' => esc_html__('Bottom Center', 'ultimate-store-kit'),
830 + 'bottom-right' => esc_html__('Bottom Right', 'ultimate-store-kit'),
831 + 'bottom-justify' => esc_html__('Bottom Justify', 'ultimate-store-kit'),
832 + 'top-left' => esc_html__('Top Left', 'ultimate-store-kit'),
833 + 'top-center' => esc_html__('Top Center', 'ultimate-store-kit'),
834 + 'top-right' => esc_html__('Top Right', 'ultimate-store-kit'),
835 + 'top-justify' => esc_html__('Top Justify', 'ultimate-store-kit'),
836 + 'left-top' => esc_html__('Left Top', 'ultimate-store-kit'),
837 + 'left-center' => esc_html__('Left Center', 'ultimate-store-kit'),
838 + 'left-bottom' => esc_html__('Left Bottom', 'ultimate-store-kit'),
839 + 'right-top' => esc_html__('Right Top', 'ultimate-store-kit'),
840 + 'right-center' => esc_html__('Right Center', 'ultimate-store-kit'),
841 + 'right-bottom' => esc_html__('Right Bottom', 'ultimate-store-kit'),
830 842 ];
831 843
832 844 return $drop_position_options;
833 845 }
@@ -833,14 +845,14 @@
833 845 }
834 846
835 847 // Button Size
836 848 function ultimate_store_kit_button_sizes() {
837 - $button_sizes = [
838 - 'xs' => esc_html__( 'Extra Small', 'ultimate-store-kit' ),
839 - 'sm' => esc_html__( 'Small', 'ultimate-store-kit' ),
840 - 'md' => esc_html__( 'Medium', 'ultimate-store-kit' ),
841 - 'lg' => esc_html__( 'Large', 'ultimate-store-kit' ),
842 - 'xl' => esc_html__( 'Extra Large', 'ultimate-store-kit' ),
849 + $button_sizes = [
850 + 'xs' => esc_html__('Extra Small', 'ultimate-store-kit'),
851 + 'sm' => esc_html__('Small', 'ultimate-store-kit'),
852 + 'md' => esc_html__('Medium', 'ultimate-store-kit'),
853 + 'lg' => esc_html__('Large', 'ultimate-store-kit'),
854 + 'xl' => esc_html__('Extra Large', 'ultimate-store-kit'),
843 855 ];
844 856
845 857 return $button_sizes;
846 858 }
@@ -846,9 +858,9 @@
846 858 }
847 859
848 860 // Button Size
849 861 function ultimate_store_kit_heading_size() {
850 - $heading_sizes = [
862 + $heading_sizes = [
851 863 'h1' => 'H1',
852 864 'h2' => 'H2',
853 865 'h3' => 'H3',
854 866 'h4' => 'H4',
@@ -860,9 +872,9 @@
860 872 }
861 873
862 874 // Title Tags
863 875 function ultimate_store_kit_title_tags() {
864 - $title_tags = [
876 + $title_tags = [
865 877 'h1' => 'H1',
866 878 'h2' => 'H2',
867 879 'h3' => 'H3',
868 880 'h4' => 'H4',
@@ -879,12 +891,12 @@
879 891 function ultimate_store_kit_mask_shapes() {
880 892 $path = BDTUSK_ASSETS_URL . 'images/mask/';
881 893 $shape_name = 'shape';
882 894 $extension = '.svg';
883 - $list = [ 0 => esc_html__( 'Select Mask', 'ultimate-store-kit' ) ];
895 + $list = [0 => esc_html__('Select Mask', 'ultimate-store-kit')];
884 896
885 - for ( $i = 1; $i <= 20; $i++ ) {
886 - $list[ $path . $shape_name . '-' . $i . $extension ] = ucwords( $shape_name . ' ' . $i );
897 + for ($i = 1; $i <= 20; $i++) {
898 + $list[$path . $shape_name . '-' . $i . $extension] = ucwords($shape_name . ' ' . $i);
887 899 }
888 900
889 901 return $list;
890 902 }
@@ -895,13 +907,13 @@
895 907 * @param svg file
896 908 *
897 909 * @return svg content
898 910 */
899 -function ultimate_store_kit_svg_icon( $icon ) {
911 +function ultimate_store_kit_svg_icon($icon) {
900 912
901 913 $icon_path = BDTUSK_ASSETS_PATH . "images/svg/{$icon}.svg";
902 914
903 - if ( ! file_exists( $icon_path ) ) {
915 + if (! file_exists($icon_path)) {
904 916 return false;
905 917 }
906 918
907 919 ob_start();
@@ -919,33 +931,33 @@
919 931 * @param false $header
920 932 *
921 933 * @return string
922 934 */
923 -function ultimate_store_kit_parse_csv( $csv, $delimiter = ';', $header = true ) {
935 +function ultimate_store_kit_parse_csv($csv, $delimiter = ';', $header = true) {
924 936
925 - if ( ! is_string( $csv ) ) {
937 + if (! is_string($csv)) {
926 938 return '';
927 939 }
928 940
929 - if ( ! function_exists( 'str_getcsv' ) ) {
941 + if (! function_exists('str_getcsv')) {
930 942 return $csv;
931 943 }
932 944
933 945 $html = '';
934 - $rows = explode( PHP_EOL, $csv );
946 + $rows = explode(PHP_EOL, $csv);
935 947 $headRow = 1;
936 948
937 - foreach ( $rows as $row ) {
949 + foreach ($rows as $row) {
938 950
939 - if ( $headRow == 1 and $header ) {
951 + if ($headRow == 1 and $header) {
940 952 $html .= '<thead><tr>';
941 953 } else {
942 954 $html .= '<tr>';
943 955 }
944 956
945 - foreach ( str_getcsv( $row, $delimiter ) as $cell ) {
957 + foreach (str_getcsv($row, $delimiter) as $cell) {
946 958
947 - $cell = trim( $cell );
959 + $cell = trim($cell);
948 960
949 961 $html .= $header
950 962 ? '<th>' . $cell . '</th>'
951 963 : '<td>' . $cell . '</td>';
@@ -950,9 +962,9 @@
950 962 ? '<th>' . $cell . '</th>'
951 963 : '<td>' . $cell . '</td>';
952 964 }
953 965
954 - if ( $headRow == 1 and $header ) {
966 + if ($headRow == 1 and $header) {
955 967 $html .= '</tr></thead><tbody>';
956 968 } else {
957 969 $html .= '</tr>';
958 970 }
@@ -963,10 +975,10 @@
963 975
964 976 return '<table>' . $html . '</tbody></table>';
965 977 }
966 978
967 -function ultimate_store_kit_dashboard_link( $suffix = '#welcome' ) {
968 - return add_query_arg( [ 'page' => 'ultimate_store_kit_options' . $suffix ], admin_url( 'admin.php' ) );
979 +function ultimate_store_kit_dashboard_link($suffix = '') {
980 + return add_query_arg(['page' => 'ultimate-store-kit' . $suffix], admin_url('admin.php'));
969 981 }
970 982
971 983 /**
972 984 * @param int $limit default limit is 25 word
@@ -974,94 +986,58 @@
974 986 * @param string $trail trail string default is ...
975 987 *
976 988 * @return string return custom limited excerpt text
977 989 */
978 -function ultimate_store_kit_custom_excerpt( $limit = 25, $strip_shortcode = false, $trail = '' ) {
990 +function ultimate_store_kit_custom_excerpt($limit = 25, $strip_shortcode = false, $trail = '') {
979 991
980 992 $output = get_the_content();
981 993
982 - if ( $limit ) {
983 - $output = wp_trim_words( $output, $limit, $trail );
994 + if ($limit) {
995 + $output = wp_trim_words($output, $limit, $trail);
984 996 }
985 997
986 - if ( $strip_shortcode ) {
987 - $output = strip_shortcodes( $output );
998 + if ($strip_shortcode) {
999 + $output = strip_shortcodes($output);
988 1000 }
989 1001
990 - return wpautop( $output );
1002 + return wpautop($output);
991 1003 }
992 1004
993 -function usk_get_order_options() {
994 - $options = [
995 - 'title' => __( 'Title', 'ultimate-store-kit' ),
996 - 'ID' => __( 'ID', 'ultimate-store-kit' ),
997 - 'date' => __( 'Date', 'ultimate-store-kit' ),
998 - 'rand' => __( 'Random', 'ultimate-store-kit' ),
999 - '_price' => __( 'Product Price', 'ultimate-store-kit' ),
1000 - 'total_sales' => __( 'Top Seller', 'ultimate-store-kit' ),
1001 - 'comment_count' => __( 'Most Reviewed', 'ultimate-store-kit' ),
1002 - '_wc_average_rating' => __( 'Top Rated', 'ultimate-store-kit' ),
1003 - ];
1004 -
1005 - return apply_filters( 'usk_order_options', $options );
1006 -}
1007 -
1008 1005 //wishlist
1009 -function ultimate_store_kit_get_wishlist( $user_id = 0 ) {
1006 +function ultimate_store_kit_get_wishlist($user_id = 0) {
1010 1007 $_wishlist_key = '_ultimate_store_kit_wishlist';
1011 1008 $_wishlist = [];
1012 1009
1013 - if ( isset( $_COOKIE[ $_wishlist_key ] ) ) {
1014 - $cookie_data = stripslashes( $_COOKIE[ $_wishlist_key ] );
1015 - $decoded_data = unserialize( $cookie_data );
1010 + if (isset($_COOKIE[$_wishlist_key])) {
1011 + // The cookie is visitor-controlled, so it is sanitized before decoding and
1012 + // every decoded entry is forced to a product id — nothing else is kept.
1013 + $cookie_data = sanitize_text_field(wp_unslash($_COOKIE[$_wishlist_key]));
1014 + $decoded_data = json_decode($cookie_data, true);
1016 1015
1017 - if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded_data ) ) {
1018 - $_wishlist = $decoded_data;
1019 - } else {
1020 - // Handle JSON decoding error if necessary
1021 - $_wishlist = [];
1016 + if (json_last_error() === JSON_ERROR_NONE && is_array($decoded_data)) {
1017 + $_wishlist = array_values(array_filter(array_map('absint', array_filter($decoded_data, 'is_scalar'))));
1022 1018 }
1023 1019 }
1024 1020
1025 - return apply_filters( 'ultimate_store_kit_wishlist', array_unique( $_wishlist ) );
1021 + return apply_filters('ultimate_store_kit_wishlist', array_unique($_wishlist));
1026 1022 }
1027 1023
1028 -function usk_get_taxonomies() {
1029 - $taxonomy_list = get_object_taxonomies( 'product' );
1030 - $taxonomies = [
1031 - 'search' => 'Search',
1032 - 'price' => 'Price',
1033 - 'orderby' => 'Orderby',
1034 - 'order' => 'Order',
1035 - ];
1036 -
1037 - foreach ( $taxonomy_list as $_taxonomy ) {
1038 - $taxonomy = get_taxonomy( $_taxonomy );
1039 -
1040 - if ( $taxonomy->show_ui ) {
1041 - $taxonomies[ $_taxonomy ] = $taxonomy->label;
1042 - }
1043 - }
1044 -
1045 - return $taxonomies;
1046 -}
1047 -
1048 -function ultimate_store_kit_hide_on_class( $selectors ) {
1024 +function ultimate_store_kit_hide_on_class($selectors) {
1049 1025 $element_hide_on = '';
1050 1026
1051 - if ( ! empty( $selectors ) ) {
1027 + if (! empty($selectors)) {
1052 1028
1053 - foreach ( $selectors as $element ) {
1029 + foreach ($selectors as $element) {
1054 1030
1055 - if ( $element == 'desktop' ) {
1031 + if ($element == 'desktop') {
1056 1032 $element_hide_on .= ' usk-hide-desktop';
1057 1033 }
1058 1034
1059 - if ( $element == 'tablet' ) {
1035 + if ($element == 'tablet') {
1060 1036 $element_hide_on .= ' usk-hide-tablet';
1061 1037 }
1062 1038
1063 - if ( $element == 'mobile' ) {
1039 + if ($element == 'mobile') {
1064 1040 $element_hide_on .= ' usk-hide-mobile';
1065 1041 }
1066 1042 }
1067 1043 }
@@ -1068,64 +1044,62 @@
1068 1044
1069 1045 return $element_hide_on;
1070 1046 }
1071 1047
1072 -function ultimate_store_kit_wc_product_quick_view_content( $product_id ) {
1073 - wp_verify_nonce( 'ajax-usk-quick-view-nonce', 'usk-quick-view-modal-sc' );
1048 +function ultimate_store_kit_wc_product_quick_view_content($product_id) {
1049 + // This renders on an unauthenticated endpoint, so the gate is on the product
1050 + // rather than on a nonce: nothing is written, and only a product the visitor
1051 + // could already open on the shop is allowed through. The previous
1052 + // wp_verify_nonce() call here had its arguments reversed and its result
1053 + // discarded, so it checked nothing.
1054 + if (! ultimate_store_kit_is_public_product($product_id)) {
1055 + return;
1056 + }
1057 +
1074 1058 global $woocommerce;
1075 1059 global $post;
1076 1060
1077 - if ( intval( $product_id ) ) {
1078 - $post = get_post( $product_id );
1061 + if (intval($product_id)) {
1062 + $post = get_post($product_id);
1079 1063 $next_post = get_next_post();
1080 1064 $prev_post = get_previous_post();
1081 1065
1082 - wp( 'p=' . $product_id . '&post_type=product' );
1066 + wp('p=' . $product_id . '&post_type=product');
1083 1067 ob_start();
1084 - ?>
1068 + ?>
1085 1069 <div class="usk-modal-page">
1086 1070 <?php
1087 -
1088 - while ( have_posts() ) :
1071 + while (have_posts()) :
1089 1072 the_post(); ?>
1090 -
1091 - <script>
1092 - var url = '<?php echo esc_url( plugins_url( 'assets/js/prettyPhoto/jquery.prettyPhoto.init.js', WC_PLUGIN_FILE ) ); ?>';
1093 - jQuery.getScript(url);
1094 - var wc_add_to_cart_variation_params = {
1095 - "ajax_url": "\/wp-admin\/admin-ajax.php"
1096 - };
1097 - jQuery.getScript("<?php echo esc_url( $woocommerce->plugin_url() ); ?> '/assets/js/frontend/add-to-cart-variation.min.js'");
1098 - </script>
1099 1073 <div class="usk-modal-product">
1100 - <div id="product-<?php the_ID(); ?>" <?php post_class( 'product' ); ?>>
1074 + <div id="product-<?php the_ID(); ?>" <?php post_class('product'); ?>>
1101 1075 <div class="usk-modal-image-wrapper">
1102 - <?php do_action( 'ultimate_store_kit_quick_florence_grid_view_product_images' ); ?>
1076 + <?php do_action('ultimate_store_kit_quick_florence_grid_view_product_images'); ?>
1103 1077 <div class="usk-onsale">
1104 - <?php do_action( 'ultimate_store_kit_wc_product_quick_view_product_sale_flash' ); ?>
1078 + <?php do_action('ultimate_store_kit_wc_product_quick_view_product_sale_flash'); ?>
1105 1079 </div>
1106 1080 </div>
1107 1081 <div class="usk-modal-content-box">
1108 - <a href="<?php echo esc_url( get_permalink() ); ?>" class="usk-product-title">
1109 - <?php do_action( 'ultimate_store_kit_quick_view_product_title' ); ?>
1082 + <a href="<?php echo esc_url(get_permalink()); ?>" class="usk-product-title">
1083 + <?php do_action('ultimate_store_kit_quick_view_product_title'); ?>
1110 1084 </a>
1111 1085 <div class="usk-rating">
1112 - <?php do_action( 'ultimate_store_kit_quick_view_product_single_rating' ); ?>
1086 + <?php do_action('ultimate_store_kit_quick_view_product_single_rating'); ?>
1113 1087 </div>
1114 1088 <div class="usk-product-price">
1115 - <?php do_action( 'ultimate_store_kit_quick_view_product_single_price' ); ?>
1089 + <?php do_action('ultimate_store_kit_quick_view_product_single_price'); ?>
1116 1090 </div>
1117 1091 <div class="usk-product-meta">
1118 1092 <div class="usk-sku-wrapper">
1119 - <?php do_action( 'ultimate_store_kit_quick_view_product_single_meta' ); ?>
1093 + <?php do_action('ultimate_store_kit_quick_view_product_single_meta'); ?>
1120 1094 </div>
1121 1095 </div>
1122 1096 <div class="usk-product-desc">
1123 - <?php do_action( 'ultimate_store_kit_quick_view_product_single_excerpt' ); ?>
1097 + <?php do_action('ultimate_store_kit_quick_view_product_single_excerpt'); ?>
1124 1098 </div>
1125 1099
1126 1100 <div class="usk-quick-action-wrap">
1127 - <?php do_action( 'ultimate_store_kit_quick_view_product_single_add_to_cart' ); ?>
1101 + <?php do_action('ultimate_store_kit_quick_view_product_single_add_to_cart'); ?>
1128 1102 </div>
1129 1103 </div>
1130 1104 </div>
1131 1105 </div>
@@ -1131,9 +1105,58 @@
1131 1105 </div>
1132 1106 <?php endwhile; ?>
1133 1107 </div>
1134 1108
1135 - <?php echo ob_get_clean();
1109 + <?php
1110 + $content = ob_get_clean();
1111 + echo wp_kses_post($content);
1112 + ?>
1113 + <script type="text/javascript">
1114 + jQuery(document).ready(function($) {
1115 + // Load required WooCommerce scripts
1116 + var scripts = [
1117 + '<?php echo esc_url(plugins_url('assets/js/prettyPhoto/jquery.prettyPhoto.init.js', WC_PLUGIN_FILE)); ?>',
1118 + '<?php echo esc_url(plugins_url('assets/js/frontend/add-to-cart-variation.min.js', WC_PLUGIN_FILE)); ?>',
1119 + '<?php echo esc_url(plugins_url('assets/js/frontend/add-to-cart.min.js', WC_PLUGIN_FILE)); ?>',
1120 + '<?php echo esc_url(plugins_url('assets/js/frontend/single-product.min.js', WC_PLUGIN_FILE)); ?>'
1121 + ];
1122 +
1123 + // Load scripts sequentially
1124 + function loadScript(index) {
1125 + if (index >= scripts.length) {
1126 + initializeWooCommerce();
1127 + return;
1128 + }
1129 +
1130 + $.getScript(scripts[index], function() {
1131 + loadScript(index + 1);
1132 + });
1133 + }
1134 +
1135 + function initializeWooCommerce() {
1136 + // Initialize WooCommerce add to cart functionality
1137 + var wc_add_to_cart_variation_params = {
1138 + "ajax_url": "<?php echo esc_url(admin_url('admin-ajax.php')); ?>",
1139 + "i18n_view_cart": "<?php echo esc_js(__('View cart', 'ultimate-store-kit')); ?>",
1140 + "cart_url": "<?php echo esc_url(wc_get_cart_url()); ?>",
1141 + "is_cart": "<?php echo is_cart() ? '1' : '0'; ?>",
1142 + "cart_redirect_after_add": "<?php echo get_option('woocommerce_cart_redirect_after_add') ? '1' : '0'; ?>"
1143 + };
1144 +
1145 + // Initialize variation forms
1146 + $(document.body).trigger('wc_variation_form');
1147 +
1148 + // Initialize add to cart buttons
1149 + $(document.body).trigger('wc_fragments_refreshed');
1150 + $(document.body).trigger('wc_fragments_loaded');
1151 + $(document.body).trigger('added_to_cart');
1152 + }
1153 +
1154 + // Start loading scripts
1155 + // loadScript(0);
1156 + });
1157 + </script>
1158 + <?php
1136 1159 exit();
1137 1160 }
1138 1161 }
1139 1162
@@ -1141,55 +1164,55 @@
1141 1164 global $post, $product; ?>
1142 1165 <div class="images">
1143 1166 <?php
1144 1167
1145 - if ( has_post_thumbnail() ) {
1146 - $attachment_count = count( $product->get_gallery_image_ids() );
1168 + if (has_post_thumbnail()) {
1169 + $attachment_count = count($product->get_gallery_image_ids());
1147 1170 $gallery = $attachment_count > 0 ? '[product-gallery]' : '';
1148 - $props = wc_get_product_attachment_props( get_post_thumbnail_id(), $post );
1149 - $image = get_the_post_thumbnail( $post->ID, apply_filters( 'single_product_large_thumbnail_size', 'shop_single' ), [
1171 + $props = wc_get_product_attachment_props(get_post_thumbnail_id(), $post);
1172 + $image = get_the_post_thumbnail($post->ID, apply_filters('single_product_large_thumbnail_size', 'shop_single'), [
1150 1173 'title' => $props['title'],
1151 1174 'alt' => $props['alt'],
1152 - ] );
1153 - echo wp_kses_post( apply_filters( 'woocommerce_single_product_image_html', sprintf( '<a href="%s" itemprop="image" class="usk-product woocommerce-main-image zoom" title="%s" data-rel="prettyPhoto' . $gallery . '">%s</a>', $props['url'], $props['caption'], $image ), $post->ID ) );
1175 + ]);
1176 + echo wp_kses_post(apply_filters('woocommerce_single_product_image_html', sprintf('<a href="%s" itemprop="image" class="usk-product woocommerce-main-image zoom" title="%s" data-rel="prettyPhoto' . $gallery . '">%s</a>', $props['url'], $props['caption'], $image), $post->ID));
1154 1177 } else {
1155 - echo wp_kses_post( apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="%s" />', wc_placeholder_img_src(), esc_html__( 'Placeholder', 'ultimate-store-kit' ) ), $post->ID ) );
1178 + echo wp_kses_post(apply_filters('woocommerce_single_product_image_html', sprintf('<img src="%s" alt="%s" />', wc_placeholder_img_src(), esc_html__('Placeholder', 'ultimate-store-kit')), $post->ID));
1156 1179 }
1157 1180
1158 1181 $attachment_ids = $product->get_gallery_image_ids();
1159 1182
1160 - if ( $attachment_ids ) :
1183 + if ($attachment_ids) :
1161 1184 $loop = 0;
1162 - $columns = apply_filters( 'woocommerce_product_thumbnails_columns', 3 );
1163 - ?>
1164 - <div class="thumbnails columns-<?php echo esc_attr( $columns ); ?>">
1185 + $columns = apply_filters('woocommerce_product_thumbnails_columns', 3);
1186 + ?>
1187 + <div class="thumbnails columns-<?php echo esc_attr($columns); ?>">
1165 1188 <?php
1166 1189
1167 - foreach ( $attachment_ids as $attachment_id ) {
1168 - $classes = [ 'thumbnail' ];
1190 + foreach ($attachment_ids as $attachment_id) {
1191 + $classes = ['thumbnail'];
1169 1192
1170 - if ( $loop === 0 || $loop % $columns === 0 ) {
1193 + if ($loop === 0 || $loop % $columns === 0) {
1171 1194 $classes[] = 'first';
1172 1195 }
1173 1196
1174 - if ( ( $loop + 1 ) % $columns === 0 ) {
1197 + if (($loop + 1) % $columns === 0) {
1175 1198 $classes[] = 'last';
1176 1199 }
1177 1200
1178 - $image_link = wp_get_attachment_url( $attachment_id );
1201 + $image_link = wp_get_attachment_url($attachment_id);
1179 1202
1180 - if ( ! $image_link ) {
1203 + if (! $image_link) {
1181 1204 continue;
1182 1205 }
1183 1206
1184 - $image_title = esc_attr( get_the_title( $attachment_id ) );
1185 - $image_caption = esc_attr( get_post_field( 'post_excerpt', $attachment_id ) );
1186 - $image = wp_get_attachment_image( $attachment_id, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ), 0, $attr = [
1207 + $image_title = esc_attr(get_the_title($attachment_id));
1208 + $image_caption = esc_attr(get_post_field('post_excerpt', $attachment_id));
1209 + $image = wp_get_attachment_image($attachment_id, apply_filters('single_product_small_thumbnail_size', 'shop_thumbnail'), 0, $attr = [
1187 1210 'title' => $image_title,
1188 1211 'alt' => $image_title,
1189 - ] );
1190 - $image_class = esc_attr( implode( ' ', $classes ) );
1191 - echo wp_kses_post( apply_filters( 'woocommerce_single_product_image_thumbnail_html', sprintf( '<a href="%s" class="%s" title="%s" >%s</a>', $image_link, $image_class, $image_caption, $image ), $attachment_id, $post->ID, $image_class ) );
1212 + ]);
1213 + $image_class = esc_attr(implode(' ', $classes));
1214 + echo wp_kses_post(apply_filters('woocommerce_single_product_image_thumbnail_html', sprintf('<a href="%s" class="%s" title="%s" >%s</a>', $image_link, $image_class, $image_caption, $image), $attachment_id, $post->ID, $image_class));
1192 1215 $loop++;
1193 1216 }
1194 1217
1195 1218 ?>
@@ -1195,9 +1218,9 @@
1195 1218 ?>
1196 1219 </div>
1197 1220 <?php endif; ?>
1198 1221 </div>
1199 - <?php
1222 +<?php
1200 1223 }
1201 1224
1202 1225
1203 1226 /**
@@ -1202,18 +1225,18 @@
1202 1225
1203 1226 /**
1204 1227 * License Validation
1205 1228 */
1206 -if ( ! function_exists( 'usk_license_validation' ) ) {
1207 - function usk_license_validation() {
1229 +if (! function_exists('ultimate_store_kit_license_validation')) {
1230 + function ultimate_store_kit_license_validation() {
1208 1231
1209 - if ( function_exists( '_is_usk_pro_activated' ) && false === _is_usk_pro_activated() ) {
1232 + if (function_exists('ultimate_store_kit_is_pro_activated') && false === ultimate_store_kit_is_pro_activated()) {
1210 1233 return false;
1211 1234 }
1212 1235
1213 - $license_key = trim( get_option( 'ultimate_post_kit_license_key' ) );
1236 + $license_key = trim(get_option('ultimate_store_kit_license_key'));
1214 1237
1215 - if ( isset( $license_key ) && ! empty( $license_key ) ) {
1238 + if (isset($license_key) && ! empty($license_key)) {
1216 1239 return true;
1217 1240 } else {
1218 1241 return false;
1219 1242 }
@@ -1222,37 +1245,83 @@
1222 1245 }
1223 1246
1224 1247
1225 1248
1226 -function usk_get_compare_products( $user_id = 0 ) {
1249 +
1250 +if (! function_exists('ultimate_store_kit_is_public_product')) {
1251 + /**
1252 + * Whether a product id may be read or acted on by the current request.
1253 + *
1254 + * wc_get_product() resolves an id regardless of post status, so any endpoint
1255 + * reachable by untrusted users must run the id through here before it reads
1256 + * product data or stores the id against the visitor.
1257 + *
1258 + * @param mixed $product_id Raw product id, typically straight off $_POST.
1259 + * @return bool
1260 + */
1261 + function ultimate_store_kit_is_public_product($product_id) {
1262 + $product_id = absint($product_id);
1263 +
1264 + // Fail closed when WooCommerce is absent — helper.php also loads on EDD-only sites.
1265 + if (! $product_id || ! function_exists('wc_get_product')) {
1266 + return false;
1267 + }
1268 +
1269 + $product = wc_get_product($product_id);
1270 +
1271 + if (! $product) {
1272 + return false;
1273 + }
1274 +
1275 + // Private, draft, pending and trashed products stay invisible unless the
1276 + // current user could read the post anyway (shop managers, the editor).
1277 + if ('publish' !== $product->get_status() && ! current_user_can('read_post', $product_id)) {
1278 + return false;
1279 + }
1280 +
1281 + if (post_password_required($product_id)) {
1282 + return false;
1283 + }
1284 +
1285 + return true;
1286 + }
1287 +}
1288 +
1289 +/**
1290 + * Maximum number of items kept in a wishlist or compare list.
1291 + *
1292 + * Both lists are written from unauthenticated endpoints, so they need an upper
1293 + * bound — a cookie that outgrows ~4KB is silently dropped by the browser, and an
1294 + * unbounded list against a logged-in user means unbounded user meta.
1295 + */
1296 +if (! function_exists('ultimate_store_kit_get_list_item_limit')) {
1297 + function ultimate_store_kit_get_list_item_limit() {
1298 + return (int) apply_filters('ultimate_store_kit_list_item_limit', 50);
1299 + }
1300 +}
1301 +
1302 +function ultimate_store_kit_get_compare_products($user_id = 0) {
1227 1303 $_compare_products_key = '_ultimate_store_kit_compare_products';
1228 1304 $_compare_products = [];
1229 - if ( $user_id != 0 ) {
1230 - $_compare_products = get_user_meta( $user_id, $_compare_products_key, true ) ?: [];
1231 - } elseif ( isset( $_COOKIE[ $_compare_products_key ] ) ) {
1232 - //$_compare_products = unserialize(stripslashes($_COOKIE[sanitize_text_field($_compare_products_key)]));
1305 + if ($user_id != 0) {
1306 + $_compare_products = get_user_meta($user_id, $_compare_products_key, true) ?: [];
1307 + } elseif (isset($_COOKIE[$_compare_products_key])) {
1308 + // Same treatment as the wishlist cookie: sanitize the visitor-supplied value
1309 + // before decoding, then keep nothing but product ids.
1310 + $cookie_value = sanitize_text_field(wp_unslash($_COOKIE[$_compare_products_key]));
1311 + $_compare_products = json_decode($cookie_value, true);
1233 1312
1234 - $cookie_value = sanitize_text_field( $_COOKIE[ $_compare_products_key ] );
1235 - $_compare_products = json_decode( stripslashes( $cookie_value ), true );
1236 -
1237 1313 // Check if JSON decoding failed
1238 - if ( ! is_array( $_compare_products ) ) {
1314 + if (! is_array($_compare_products)) {
1239 1315 $_compare_products = [];
1316 + } else {
1317 + $_compare_products = array_values(array_filter(array_map('absint', array_filter($_compare_products, 'is_scalar'))));
1240 1318 }
1241 1319 }
1242 1320
1243 - return apply_filters( 'ultimate_store_kit_compare_products', array_unique( $_compare_products ) );
1321 + return apply_filters('ultimate_store_kit_compare_products', array_unique($_compare_products));
1244 1322 }
1245 1323
1246 -function usk_get_compare_products_count() {
1247 - $count = 0;
1248 - $user_id = get_current_user_id();
1249 - $products = usk_get_compare_products( $user_id );
1250 - if ( is_array( $products ) ) {
1251 - $count = count( $products );
1252 - }
1253 - return $count;
1254 -}
1255 1324
1256 1325 //if (!function_exists('ultimate_store_kit_get_compare_product_slug')) {
1257 1326 // function ultimate_store_kit_compare_product_slug() {
1258 1327 // return 'compare-products';
@@ -1258,13 +1327,41 @@
1258 1327 // return 'compare-products';
1259 1328 // }
1260 1329 //}
1261 1330
1262 -if ( ! function_exists( 'ultimate_store_kit_compare_product_page' ) ) {
1331 +if (! function_exists('ultimate_store_kit_get_compare_page_option')) {
1332 + /**
1333 + * Read the compare-products page id, migrating it off the old "bdt_"-prefixed
1334 + * option key the first time it is seen.
1335 + *
1336 + * The option is written by Ultimate Store Kit Pro on activation and read by
1337 + * both plugins, so it is stored user data: a bare rename would detach an
1338 + * existing site's compare page.
1339 + *
1340 + * @return int Page id, or 0 when unset.
1341 + */
1342 + function ultimate_store_kit_get_compare_page_option() {
1343 + $value = get_option('ultimate_store_kit_compare_products_page_id', null);
1344 +
1345 + if (null === $value) {
1346 + $legacy = get_option('bdt_usk_compare_products_page_id', null);
1347 +
1348 + if (null !== $legacy) {
1349 + update_option('ultimate_store_kit_compare_products_page_id', $legacy, true);
1350 + delete_option('bdt_usk_compare_products_page_id');
1351 + $value = $legacy;
1352 + }
1353 + }
1354 +
1355 + return intval($value);
1356 + }
1357 +}
1358 +
1359 +if (! function_exists('ultimate_store_kit_compare_product_page')) {
1263 1360 function ultimate_store_kit_compare_product_page() {
1264 - if ( $postId = intval( get_option( 'bdt_usk_compare_products_page_id' ) ) ) {
1265 - $post = get_post( $postId );
1266 - if ( $post->post_status == 'publish' ) {
1361 + if ($postId = ultimate_store_kit_get_compare_page_option()) {
1362 + $post = get_post($postId);
1363 + if ($post && $post->post_status == 'publish') {
1267 1364 return $post->ID;
1268 1365 }
1269 1366 }
1270 1367 }
@@ -1269,12 +1366,98 @@
1269 1366 }
1270 1367 }
1271 1368 }
1272 1369
1273 -if ( ! function_exists( 'ultimate_store_kit_is_compare_product_page' ) ) {
1370 +if (! function_exists('ultimate_store_kit_is_compare_product_page')) {
1274 1371 function ultimate_store_kit_is_compare_product_page() {
1275 - if ( $page = ultimate_store_kit_compare_product_page() ) {
1372 + if ($page = ultimate_store_kit_compare_product_page()) {
1276 1373 // return is_page( $page->ID );
1277 - return is_page( $page );
1374 + return is_page($page);
1278 1375 }
1279 1376 }
1280 1377 }
1378 +
1379 +
1380 +/**
1381 + * Helper function to load variation swatches scripts and styles
1382 + */
1383 +function ultimate_store_kit_load_variation_swatches_assets() {
1384 + // Always load the grid variations script for variation support
1385 + wp_register_script('usk-grid-variations', BDTUSK_ASSETS_URL . 'js/modules/grid-variations.js', ['jquery'], BDTUSK_VER, true);
1386 + wp_localize_script('usk-grid-variations', 'usk_vars', array(
1387 + 'ajax_url' => admin_url('admin-ajax.php'),
1388 + 'nonce' => wp_create_nonce('usk_variations')
1389 + ));
1390 +}
1391 +add_action('wp_enqueue_scripts', 'ultimate_store_kit_load_variation_swatches_assets', 20);
1392 +
1393 +
1394 +// Start: Add to cart quantity buttons conversion
1395 +if (! function_exists('ultimate_store_kit_display_quantity_minus')) {
1396 + function ultimate_store_kit_display_quantity_minus() {
1397 + if (! is_product()) return;
1398 + echo '<button type="button" class="bdt-add-to-cart-qty-minus" ><i class="usk-icon-minus3"></i></button>';
1399 + }
1400 +}
1401 +
1402 +if (! function_exists('ultimate_store_kit_display_quantity_plus')) {
1403 + function ultimate_store_kit_display_quantity_plus() {
1404 + if (! is_product()) return;
1405 + echo '<button type="button" class="bdt-add-to-cart-qty-plus" ><i class="usk-icon-plus3"></i></button>';
1406 + }
1407 +}
1408 +
1409 +if (! function_exists('ultimate_store_kit_add_cart_quantity_plus_minus')) {
1410 + function ultimate_store_kit_add_cart_quantity_plus_minus() {
1411 +
1412 + echo '<style>
1413 + input[type="number"]::-webkit-outer-spin-button,
1414 + input[type="number"]::-webkit-inner-spin-button {
1415 + -webkit-appearance: none;
1416 + margin: 0;
1417 + }
1418 +
1419 + input[type="number"] {
1420 + -moz-appearance: textfield; /* Firefox */
1421 + }
1422 + </style>';
1423 +
1424 + wc_enqueue_js("
1425 + $(document).off('click.bdtQtyHandler'); // Remove previous handler
1426 + $(document).on('click.bdtQtyHandler', 'button.bdt-add-to-cart-qty-plus, button.bdt-add-to-cart-qty-minus', function(e) {
1427 + e.preventDefault();
1428 + var qty = $(this).closest('form.cart').find('.qty');
1429 + var val = parseFloat(qty.val()) || 0;
1430 + var max = parseFloat(qty.attr('max')) || Infinity;
1431 + var min = parseFloat(qty.attr('min')) || 0;
1432 + var step = parseFloat(qty.attr( 'step' ));
1433 +
1434 + if ($(this).is('.bdt-add-to-cart-qty-plus')) {
1435 + qty.val(Math.min(val + step, max)).trigger('change');
1436 + } else {
1437 + qty.val(Math.max(val - step, min)).trigger('change');
1438 + }
1439 + });
1440 + ");
1441 + }
1442 +}
1443 +
1444 +if (! function_exists('ultimate_store_kit_setup_quantity_buttons')) {
1445 + function ultimate_store_kit_setup_quantity_buttons() {
1446 + if (function_exists('is_product')) {
1447 + // Element Pack renders its own quantity buttons on these hooks. Remove
1448 + // only those callbacks: the previous remove_all_actions() also stripped
1449 + // WooCommerce core's own handlers on woocommerce_before_single_product
1450 + // (notably woocommerce_output_all_notices), suppressing store notices.
1451 + remove_action('woocommerce_before_quantity_input_field', 'ep_display_quantity_minus');
1452 + remove_action('woocommerce_after_quantity_input_field', 'ep_display_quantity_plus');
1453 + remove_action('woocommerce_before_single_product', 'ep_add_cart_quantity_plus_minus');
1454 +
1455 + // Add our version
1456 + add_action('woocommerce_before_quantity_input_field', 'ultimate_store_kit_display_quantity_minus');
1457 + add_action('woocommerce_after_quantity_input_field', 'ultimate_store_kit_display_quantity_plus');
1458 + add_action('woocommerce_after_single_product', 'ultimate_store_kit_add_cart_quantity_plus_minus');
1459 + }
1460 + }
1461 +}
1462 +
1463 +// End: Add to cart quantity buttons conversion