PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.74
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.74
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / helpers / Theme_Builder / Resolver.php

Resolver.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.74, at includes/helpers/Theme_Builder/Resolver.php

168 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Theme Builder template resolver.
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons\Theme_Builder;
9
10 if (!defined('ABSPATH')) {
11 exit;
12 }
13
14 /**
15 * Resolves which template should render current request.
16 */
17 class Resolver
18 {
19 /**
20 * Repository instance.
21 *
22 * @var Repository
23 */
24 private Repository $repository;
25
26 /**
27 * Constructor.
28 *
29 * @param Repository $repository Template repository.
30 */
31 public function __construct(Repository $repository)
32 {
33 $this->repository = $repository;
34 }
35
36 /**
37 * Find best matching template ID for context.
38 *
39 * @param array<string,mixed> $context Request context.
40 *
41 * @return int|null
42 */
43 public function resolve(array $context): ?int
44 {
45 $candidates = $this->repository->get_location_candidates($context);
46 if (empty($candidates)) {
47 return null;
48 }
49
50 $eligible = [];
51 foreach ($candidates as $candidate) {
52 if (!empty($candidate['is_pro_only']) && !$this->can_use_pro()) {
53 continue;
54 }
55
56 if (!Conditions::evaluate($candidate['conditions'] ?? [], $context)) {
57 continue;
58 }
59
60 $candidate['specificity'] = $this->count_specificity($candidate['conditions'] ?? []);
61 $eligible[] = $candidate;
62 }
63
64 if (empty($eligible)) {
65 return null;
66 }
67
68 usort(
69 $eligible,
70 static function (array $a, array $b): int {
71 if ($a['priority'] !== $b['priority']) {
72 return ($a['priority'] < $b['priority']) ? -1 : 1;
73 }
74
75 if ($a['specificity'] !== $b['specificity']) {
76 return ($a['specificity'] > $b['specificity']) ? -1 : 1;
77 }
78
79 return ($a['id'] < $b['id']) ? -1 : 1;
80 }
81 );
82
83 if (!$this->can_use_pro()) {
84 // Free tier: only one template per primary type.
85 $type = $context['type'] ?? '';
86 foreach ($eligible as $template) {
87 if ($this->matches_primary_type($template, $type)) {
88 return (int) $template['id'];
89 }
90 }
91
92 return null;
93 }
94
95 return (int) $eligible[0]['id'];
96 }
97
98 /**
99 * Count how specific a condition set is.
100 *
101 * @param array<string,mixed> $conditions Conditions data.
102 *
103 * @return int
104 */
105 private function count_specificity(array $conditions): int
106 {
107 $groups = $conditions['groups'] ?? [];
108 $count = 0;
109
110 foreach ($groups as $group) {
111 $rules = $group['rules'] ?? [];
112 $count += count($rules);
113 }
114
115 return $count;
116 }
117
118 /**
119 * Check premium availability.
120 *
121 * @return bool
122 */
123 private function can_use_pro(): bool
124 {
125 return function_exists('king_addons_freemius')
126 && king_addons_freemius()->can_use_premium_code__premium_only();
127 }
128
129 /**
130 * Ensure a template belongs to the requested primary type.
131 *
132 * @param array<string,mixed> $template Template data.
133 * @param string $type Request primary type.
134 *
135 * @return bool
136 */
137 private function matches_primary_type(array $template, string $type): bool
138 {
139 $location = $template['location'] ?? '';
140
141 if ('not_found' === $type) {
142 return 'not_found' === $template['sub_location'] || 'not_found' === $location;
143 }
144
145 if ('search' === $type) {
146 return in_array($template['sub_location'], ['search_results', 'search'], true) || 'search' === $location;
147 }
148
149 if ('author' === $type) {
150 return 'author_all' === ($template['sub_location'] ?? '') || 'author_specific' === ($template['sub_location'] ?? '');
151 }
152
153 if ('single' === $type) {
154 return 'single' === $location;
155 }
156
157 if ('archive' === $type) {
158 return 'archive' === $location;
159 }
160
161 return false;
162 }
163 }
164
165
166
167
168