get_id(); } if (!empty($post->ID) && 'product' === get_post_type($post->ID)) { return (int) $post->ID; } return null; } /** * Match conditions array against current page context. * * @param string $context Page context. * @param array $conditions Conditions array. * * @return bool */ public static function match_conditions(string $context, array $conditions): bool { if (empty($conditions['rules']) || !is_array($conditions['rules'])) { return true; } $product_id = self::get_product_id(); foreach ($conditions['rules'] as $rule) { $type = $rule['type'] ?? ''; $values = is_array($rule['values'] ?? null) ? $rule['values'] : []; if (!self::match_rule($context, $type, $values, $product_id)) { return false; } } return true; } /** * Match a single rule. * * @param string $context Context. * @param string $type Rule type. * @param array $values Rule values. * @param int|null $product_id Product ID. * * @return bool */ private static function match_rule(string $context, string $type, array $values, ?int $product_id): bool { switch ($type) { case 'all_products': return 'single_product' === $context; case 'product_in': case 'products': return ('single_product' === $context && $product_id && in_array($product_id, $values, true)); case 'product_cat_in': case 'product_categories': if ('single_product' !== $context || !$product_id) { return false; } $terms = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'ids']); return !empty(array_intersect($values, $terms)); case 'product_tag_in': case 'product_tags': if ('single_product' !== $context || !$product_id) { return false; } $terms = wp_get_post_terms($product_id, 'product_tag', ['fields' => 'ids']); return !empty(array_intersect($values, $terms)); case 'product_type_in': case 'product_types': if ('single_product' !== $context || !$product_id) { return false; } $types = wp_get_object_terms($product_id, 'product_type', ['fields' => 'slugs']); return !empty(array_intersect($values, $types)); case 'is_shop': case 'shop': return 'product_archive' === $context && is_shop(); case 'product_cat_archive_in': case 'product_cat_archives': if ('product_archive' !== $context) { return false; } if (is_product_category()) { $term = get_queried_object(); if (!empty($term->term_id)) { return in_array((int) $term->term_id, $values, true); } } return false; case 'cart': return 'cart' === $context; case 'checkout': return 'checkout' === $context; case 'my_account': return 'my_account' === $context; case 'always': return true; default: return true; } } /** * Render an editor-only notice if widget is not in the expected Woo context. * * @param string $expected_context Expected context slug. * * @return bool True when context matches or not in edit mode, false when notice rendered. */ public static function maybe_render_context_notice(string $expected_context): bool { if (!class_exists('\Elementor\Plugin') || !\Elementor\Plugin::$instance->editor->is_edit_mode()) { return true; } $current = self::detect_context(); if ($current === $expected_context) { return true; } $labels = [ 'single_product' => esc_html__('This widget works on Single Product pages.', 'king-addons'), 'product_archive' => esc_html__('This widget works on Product Archive pages.', 'king-addons'), 'cart' => esc_html__('This widget works on the Cart page.', 'king-addons'), 'checkout' => esc_html__('This widget works on the Checkout page.', 'king-addons'), 'my_account' => esc_html__('This widget works on My Account pages.', 'king-addons'), ]; $message = $labels[$expected_context] ?? esc_html__('This widget is only available on WooCommerce pages.', 'king-addons'); echo '
' . esc_html($message) . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped return false; } }