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 +62 -144 3.1.03.1.4 View file →
@@ -3,9 +3,9 @@
3 3 if (! defined('ABSPATH')) {
4 4 exit; // Exit if accessed directly
5 5 }
6 6
7 -// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- usk_ / BDTUSK_ / ultimate-store-kit- are this plugin's established public prefixes. Ultimate Store Kit Pro calls into these names, as does third-party integration code, so renaming them is a breaking change. Plugin Check only recognises prefixes derived verbatim from the slug and so reports them as unprefixed.
7 +// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- BDTUSK_ / ultimate_store_kit_ / ultimate-store-kit- are this plugin's established public prefixes.
8 8
9 9 use UltimateStoreKit\Ultimate_Store_Kit_Loader;
10 10 use Elementor\Plugin;
11 11
@@ -44,9 +44,9 @@
44 44 if (! defined('BDTUSK_NAME')) {
45 45 define('BDTUSK_NAME', 'Ultimate Store Kit');
46 46 }
47 47
48 -if (_is_usk_pro_activated()) {
48 +if (ultimate_store_kit_is_pro_activated()) {
49 49 if (! defined('BDTUSK_PC')) {
50 50 define('BDTUSK_PC', '');
51 51 } // pro control badge
52 52 define('BDTUSK_IS_PC', '');
@@ -1001,23 +1001,8 @@
1001 1001
1002 1002 return wpautop($output);
1003 1003 }
1004 1004
1005 -function usk_get_order_options() {
1006 - $options = [
1007 - 'title' => __('Title', 'ultimate-store-kit'),
1008 - 'ID' => __('ID', 'ultimate-store-kit'),
1009 - 'date' => __('Date', 'ultimate-store-kit'),
1010 - 'rand' => __('Random', 'ultimate-store-kit'),
1011 - '_price' => __('Product Price', 'ultimate-store-kit'),
1012 - 'total_sales' => __('Top Seller', 'ultimate-store-kit'),
1013 - 'comment_count' => __('Most Reviewed', 'ultimate-store-kit'),
1014 - '_wc_average_rating' => __('Top Rated', 'ultimate-store-kit'),
1015 - ];
1016 -
1017 - return apply_filters('usk_order_options', $options);
1018 -}
1019 -
1020 1005 //wishlist
1021 1006 function ultimate_store_kit_get_wishlist($user_id = 0) {
1022 1007 $_wishlist_key = '_ultimate_store_kit_wishlist';
1023 1008 $_wishlist = [];
@@ -1035,28 +1020,8 @@
1035 1020
1036 1021 return apply_filters('ultimate_store_kit_wishlist', array_unique($_wishlist));
1037 1022 }
1038 1023
1039 -function usk_get_taxonomies() {
1040 - $taxonomy_list = get_object_taxonomies('product');
1041 - $taxonomies = [
1042 - 'search' => 'Search',
1043 - 'price' => 'Price',
1044 - 'orderby' => 'Orderby',
1045 - 'order' => 'Order',
1046 - ];
1047 -
1048 - foreach ($taxonomy_list as $_taxonomy) {
1049 - $taxonomy = get_taxonomy($_taxonomy);
1050 -
1051 - if ($taxonomy->show_ui) {
1052 - $taxonomies[$_taxonomy] = $taxonomy->label;
1053 - }
1054 - }
1055 -
1056 - return $taxonomies;
1057 -}
1058 -
1059 1024 function ultimate_store_kit_hide_on_class($selectors) {
1060 1025 $element_hide_on = '';
1061 1026
1062 1027 if (! empty($selectors)) {
@@ -1085,9 +1050,9 @@
1085 1050 // rather than on a nonce: nothing is written, and only a product the visitor
1086 1051 // could already open on the shop is allowed through. The previous
1087 1052 // wp_verify_nonce() call here had its arguments reversed and its result
1088 1053 // discarded, so it checked nothing.
1089 - if (! usk_is_public_product($product_id)) {
1054 + if (! ultimate_store_kit_is_public_product($product_id)) {
1090 1055 return;
1091 1056 }
1092 1057
1093 1058 global $woocommerce;
@@ -1260,12 +1225,12 @@
1260 1225
1261 1226 /**
1262 1227 * License Validation
1263 1228 */
1264 -if (! function_exists('usk_license_validation')) {
1265 - function usk_license_validation() {
1229 +if (! function_exists('ultimate_store_kit_license_validation')) {
1230 + function ultimate_store_kit_license_validation() {
1266 1231
1267 - 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()) {
1268 1233 return false;
1269 1234 }
1270 1235
1271 1236 $license_key = trim(get_option('ultimate_store_kit_license_key'));
@@ -1280,9 +1245,10 @@
1280 1245 }
1281 1246
1282 1247
1283 1248
1284 -if (! function_exists('usk_is_public_product')) {
1249 +
1250 +if (! function_exists('ultimate_store_kit_is_public_product')) {
1285 1251 /**
1286 1252 * Whether a product id may be read or acted on by the current request.
1287 1253 *
1288 1254 * wc_get_product() resolves an id regardless of post status, so any endpoint
@@ -1291,9 +1257,9 @@
1291 1257 *
1292 1258 * @param mixed $product_id Raw product id, typically straight off $_POST.
1293 1259 * @return bool
1294 1260 */
1295 - function usk_is_public_product($product_id) {
1261 + function ultimate_store_kit_is_public_product($product_id) {
1296 1262 $product_id = absint($product_id);
1297 1263
1298 1264 // Fail closed when WooCommerce is absent — helper.php also loads on EDD-only sites.
1299 1265 if (! $product_id || ! function_exists('wc_get_product')) {
@@ -1326,15 +1292,15 @@
1326 1292 * Both lists are written from unauthenticated endpoints, so they need an upper
1327 1293 * bound — a cookie that outgrows ~4KB is silently dropped by the browser, and an
1328 1294 * unbounded list against a logged-in user means unbounded user meta.
1329 1295 */
1330 -if (! function_exists('usk_get_list_item_limit')) {
1331 - function usk_get_list_item_limit() {
1296 +if (! function_exists('ultimate_store_kit_get_list_item_limit')) {
1297 + function ultimate_store_kit_get_list_item_limit() {
1332 1298 return (int) apply_filters('ultimate_store_kit_list_item_limit', 50);
1333 1299 }
1334 1300 }
1335 1301
1336 -function usk_get_compare_products($user_id = 0) {
1302 +function ultimate_store_kit_get_compare_products($user_id = 0) {
1337 1303 $_compare_products_key = '_ultimate_store_kit_compare_products';
1338 1304 $_compare_products = [];
1339 1305 if ($user_id != 0) {
1340 1306 $_compare_products = get_user_meta($user_id, $_compare_products_key, true) ?: [];
@@ -1354,17 +1320,8 @@
1354 1320
1355 1321 return apply_filters('ultimate_store_kit_compare_products', array_unique($_compare_products));
1356 1322 }
1357 1323
1358 -function usk_get_compare_products_count() {
1359 - $count = 0;
1360 - $user_id = get_current_user_id();
1361 - $products = usk_get_compare_products($user_id);
1362 - if (is_array($products)) {
1363 - $count = count($products);
1364 - }
1365 - return $count;
1366 -}
1367 1324
1368 1325 //if (!function_exists('ultimate_store_kit_get_compare_product_slug')) {
1369 1326 // function ultimate_store_kit_compare_product_slug() {
1370 1327 // return 'compare-products';
@@ -1370,11 +1327,39 @@
1370 1327 // return 'compare-products';
1371 1328 // }
1372 1329 //}
1373 1330
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 +
1374 1359 if (! function_exists('ultimate_store_kit_compare_product_page')) {
1375 1360 function ultimate_store_kit_compare_product_page() {
1376 - if ($postId = intval(get_option('bdt_usk_compare_products_page_id'))) {
1361 + if ($postId = ultimate_store_kit_get_compare_page_option()) {
1377 1362 $post = get_post($postId);
1378 1363 if ($post && $post->post_status == 'publish') {
1379 1364 return $post->ID;
1380 1365 }
@@ -1390,21 +1375,13 @@
1390 1375 }
1391 1376 }
1392 1377 }
1393 1378
1394 -/**
1395 - * Helper function to check if variation swatches Pro is active
1396 - *
1397 - * @return bool
1398 - */
1399 -function usk_has_variation_swatches_support() {
1400 - return class_exists('UltimateStoreKitPro\\VariationSwatches\\Swatches');
1401 -}
1402 1379
1403 1380 /**
1404 1381 * Helper function to load variation swatches scripts and styles
1405 1382 */
1406 -function usk_load_variation_swatches_assets() {
1383 +function ultimate_store_kit_load_variation_swatches_assets() {
1407 1384 // Always load the grid variations script for variation support
1408 1385 wp_register_script('usk-grid-variations', BDTUSK_ASSETS_URL . 'js/modules/grid-variations.js', ['jquery'], BDTUSK_VER, true);
1409 1386 wp_localize_script('usk-grid-variations', 'usk_vars', array(
1410 1387 'ajax_url' => admin_url('admin-ajax.php'),
@@ -1410,91 +1387,28 @@
1410 1387 'ajax_url' => admin_url('admin-ajax.php'),
1411 1388 'nonce' => wp_create_nonce('usk_variations')
1412 1389 ));
1413 1390 }
1414 -add_action('wp_enqueue_scripts', 'usk_load_variation_swatches_assets', 20);
1391 +add_action('wp_enqueue_scripts', 'ultimate_store_kit_load_variation_swatches_assets', 20);
1415 1392
1416 -// Hook into AJAX variation selection to update product image
1417 -function usk_ajax_variation_image_update() {
1418 - // Public read-only endpoint returning a public product image. A nonce cannot
1419 - // survive full-page caching for logged-out visitors, so authorisation is
1420 - // enforced on the product itself further down instead.
1421 - // phpcs:disable WordPress.Security.NonceVerification.Missing
1422 - if (!isset($_POST['variation_id']) || !isset($_POST['product_id'])) {
1423 - wp_send_json_error('Missing required parameters');
1424 - return;
1425 - }
1426 1393
1427 - $variation_id = absint($_POST['variation_id']);
1428 - $product_id = absint($_POST['product_id']);
1429 - // phpcs:enable WordPress.Security.NonceVerification.Missing
1430 -
1431 - $variation = wc_get_product($variation_id);
1432 - if (!$variation) {
1433 - wp_send_json_error('Invalid variation');
1434 - return;
1435 - }
1436 -
1437 - // wc_get_product() ignores post status, so guard the parent product the same way
1438 - // the variations endpoint does before exposing anything about it.
1439 - $parent = wc_get_product($product_id);
1440 - if (!$parent) {
1441 - wp_send_json_error('Invalid product');
1442 - return;
1443 - }
1444 -
1445 - if ('publish' !== $parent->get_status() && !current_user_can('read_post', $product_id)) {
1446 - wp_send_json_error('Product not available', 404);
1447 - return;
1448 - }
1449 -
1450 - if (post_password_required($product_id)) {
1451 - wp_send_json_error('Product not available', 403);
1452 - return;
1453 - }
1454 -
1455 - // The variation must actually belong to the product that passed the check above,
1456 - // otherwise the parent id is just a public decoy for an arbitrary variation.
1457 - if ($variation->get_parent_id() !== $product_id) {
1458 - wp_send_json_error('Invalid variation');
1459 - return;
1460 - }
1461 -
1462 - $image_id = $variation->get_image_id();
1463 - $image_url = '';
1464 -
1465 - if ($image_id) {
1466 - $image_url = wp_get_attachment_image_url($image_id, 'woocommerce_thumbnail');
1467 - } else {
1468 - // If variation has no image, use the parent product image
1469 - $parent_image_id = $parent->get_image_id();
1470 - if ($parent_image_id) {
1471 - $image_url = wp_get_attachment_image_url($parent_image_id, 'woocommerce_thumbnail');
1472 - }
1473 - }
1474 -
1475 - wp_send_json_success(array('image_url' => $image_url));
1476 -}
1477 -add_action('wp_ajax_usk_get_variation_image', 'usk_ajax_variation_image_update');
1478 -add_action('wp_ajax_nopriv_usk_get_variation_image', 'usk_ajax_variation_image_update');
1479 -
1480 1394 // Start: Add to cart quantity buttons conversion
1481 -if (! function_exists('usk_display_quantity_minus')) {
1482 - function usk_display_quantity_minus() {
1395 +if (! function_exists('ultimate_store_kit_display_quantity_minus')) {
1396 + function ultimate_store_kit_display_quantity_minus() {
1483 1397 if (! is_product()) return;
1484 1398 echo '<button type="button" class="bdt-add-to-cart-qty-minus" ><i class="usk-icon-minus3"></i></button>';
1485 1399 }
1486 1400 }
1487 1401
1488 -if (! function_exists('usk_display_quantity_plus')) {
1489 - function usk_display_quantity_plus() {
1402 +if (! function_exists('ultimate_store_kit_display_quantity_plus')) {
1403 + function ultimate_store_kit_display_quantity_plus() {
1490 1404 if (! is_product()) return;
1491 1405 echo '<button type="button" class="bdt-add-to-cart-qty-plus" ><i class="usk-icon-plus3"></i></button>';
1492 1406 }
1493 1407 }
1494 1408
1495 -if (! function_exists('usk_add_cart_quantity_plus_minus')) {
1496 - function usk_add_cart_quantity_plus_minus() {
1409 +if (! function_exists('ultimate_store_kit_add_cart_quantity_plus_minus')) {
1410 + function ultimate_store_kit_add_cart_quantity_plus_minus() {
1497 1411
1498 1412 echo '<style>
1499 1413 input[type="number"]::-webkit-outer-spin-button,
1500 1414 input[type="number"]::-webkit-inner-spin-button {
@@ -1526,20 +1440,24 @@
1526 1440 ");
1527 1441 }
1528 1442 }
1529 1443
1530 -if (! function_exists('usk_setup_quantity_buttons')) {
1531 - function usk_setup_quantity_buttons() {
1444 +if (! function_exists('ultimate_store_kit_setup_quantity_buttons')) {
1445 + function ultimate_store_kit_setup_quantity_buttons() {
1532 1446 if (function_exists('is_product')) {
1533 - // Remove the default version
1534 - remove_all_actions('woocommerce_before_quantity_input_field');
1535 - remove_all_actions('woocommerce_after_quantity_input_field');
1536 - remove_all_actions('woocommerce_before_single_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');
1537 1454
1538 1455 // Add our version
1539 - add_action('woocommerce_before_quantity_input_field', 'usk_display_quantity_minus');
1540 - add_action('woocommerce_after_quantity_input_field', 'usk_display_quantity_plus');
1541 - add_action('woocommerce_after_single_product', 'usk_add_cart_quantity_plus_minus');
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');
1542 1459 }
1543 1460 }
1544 1461 }
1462 +
1545 1463 // End: Add to cart quantity buttons conversion