taxonomy its value picks from. */ private const TAXONOMY = [ 'product_in_cat' => 'product_cat', 'product_cat_archive' => 'product_cat', 'product_in_tag' => 'product_tag', 'product_tag_archive' => 'product_tag', ]; public static function register(): void { add_filter('zadex/theme/condition_targets', [self::class, 'targets']); add_filter('zadex/theme/condition_score', [self::class, 'score'], 10, 3); add_filter('zadex/theme/condition_context', [self::class, 'context']); add_filter('zadex/theme/condition_labels', [self::class, 'labels']); add_filter('zadex/theme/condition_values', [self::class, 'values'], 10, 4); } public static function targets($targets): array { $targets = is_array($targets) ? $targets : []; return array_values(array_unique(array_merge($targets, self::TARGETS))); } /** Adds the WooCommerce facts to the request context. */ public static function context($c): array { $c = is_array($c) ? $c : []; $c['shop'] = function_exists('is_shop') && is_shop(); $pt = get_query_var('post_type'); $c['product_search'] = is_search() && (is_array($pt) ? in_array('product', $pt, true) : $pt === 'product'); return $c; } /** * @param int $score score so far (0) * @param array $rule sanitized rule * @param array $c request context */ public static function score($score, $rule, $c): int { $rule = is_array($rule) ? $rule : []; $c = (is_array($c) ? $c : []) + ThemeConditions::empty_context() + ['shop' => false, 'product_search' => false]; $value = $rule['value'] ?? ''; $id = is_numeric($value) ? (int) $value : 0; $single = $c['singular'] && $c['post_type'] === 'product'; $archive = $c['archive'] && ($c['archive_post_type'] === 'product' || in_array($c['taxonomy'], ['product_cat', 'product_tag'], true) || str_starts_with((string) $c['taxonomy'], 'pa_')); switch ($rule['target'] ?? '') { case 'product': return $single ? ThemeConditions::SCORE_SINGULAR_TYPE : 0; case 'product_specific': return $single && $id > 0 && (int) $c['post_id'] === $id ? ThemeConditions::SCORE_SPECIFIC : 0; case 'product_in_cat': case 'product_in_tag': if (!$single || $id <= 0) { return 0; } foreach ((array) ($c['terms'][self::TAXONOMY[$rule['target']]] ?? []) as $term) { if (is_array($term) && (int) ($term['id'] ?? 0) === $id) { return ThemeConditions::SCORE_IN_TERM; } } return 0; case 'shop': return $c['shop'] ? self::SCORE_SHOP : 0; case 'product_archive': return $c['shop'] || $archive || $c['product_search'] ? ThemeConditions::SCORE_POST_TYPE_ARCHIVE : 0; case 'product_cat_archive': case 'product_tag_archive': if (!$c['archive'] || $c['taxonomy'] !== self::TAXONOMY[$rule['target']]) { return 0; } if ($id <= 0) { return ThemeConditions::SCORE_TAXONOMY; } return (int) $c['term_id'] === $id ? ThemeConditions::SCORE_TERM_ARCHIVE : 0; } return (int) $score; } public static function labels($labels): array { $labels = is_array($labels) ? $labels : []; return $labels + [ 'product' => __('All products', 'zadex'), 'product_in_cat' => __('Products in category', 'zadex'), 'product_in_tag' => __('Products with tag', 'zadex'), 'product_specific' => __('Specific product', 'zadex'), 'shop' => __('Shop page', 'zadex'), 'product_archive' => __('All product archives', 'zadex'), 'product_cat_archive' => __('Product category archive', 'zadex'), 'product_tag_archive' => __('Product tag archive', 'zadex'), ]; } /** Value options of the conditions dialog (GET /templates/options) for the WooCommerce targets. */ public static function values($out, $target, $sub, $search): array { $out = is_array($out) ? $out : []; $target = (string) $target; $search = (string) $search; if ($target === 'product_specific') { $posts = get_posts([ 'post_type' => 'product', 'post_status' => ['publish', 'private', 'draft', 'future'], 'numberposts' => 20, 's' => $search, 'orderby' => $search !== '' ? 'relevance' : 'date', 'order' => 'DESC', ]); foreach ($posts as $post) { $out[] = ['value' => (int) $post->ID, 'label' => ($post->post_title !== '' ? $post->post_title : __('(no title)', 'zadex')) . ' (#' . (int) $post->ID . ')']; } return $out; } if (isset(self::TAXONOMY[$target]) && taxonomy_exists(self::TAXONOMY[$target])) { $terms = get_terms(['taxonomy' => self::TAXONOMY[$target], 'hide_empty' => false, 'number' => 20, 'search' => $search]); if (is_array($terms)) { foreach ($terms as $term) { $out[] = ['value' => (int) $term->term_id, 'label' => (string) $term->name]; } } } return $out; } }