PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.44
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.44
51.1.87 51.1.86 51.1.84 51.1.85 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 All 41 releases
king-addons / includes / widgets / Facet_Taxonomy / Facet_Taxonomy.php

Facet_Taxonomy.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.44, at includes/widgets/Facet_Taxonomy/Facet_Taxonomy.php

392 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Facet Taxonomy widget.
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Widget_Base;
12
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 /**
18 * Checkbox taxonomy filter widget.
19 */
20 class Facet_Taxonomy extends Widget_Base
21 {
22 /**
23 * Widget slug.
24 *
25 * @return string
26 */
27 public function get_name(): string
28 {
29 return 'king-addons-facet-taxonomy';
30 }
31
32 /**
33 * Widget title.
34 *
35 * @return string
36 */
37 public function get_title(): string
38 {
39 return esc_html__('Facet Taxonomy', 'king-addons');
40 }
41
42 /**
43 * Widget icon.
44 *
45 * @return string
46 */
47 public function get_icon(): string
48 {
49 return 'eicon-checkbox';
50 }
51
52 /**
53 * Categories.
54 *
55 * @return array<int, string>
56 */
57 public function get_categories(): array
58 {
59 return ['king-addons'];
60 }
61
62 /**
63 * Style dependencies.
64 *
65 * @return array<int, string>
66 */
67 public function get_style_depends(): array
68 {
69 return [
70 KING_ADDONS_ASSETS_UNIQUE_KEY . '-facet-taxonomy-style',
71 ];
72 }
73
74 /**
75 * Script dependencies.
76 *
77 * @return array<int, string>
78 */
79 public function get_script_depends(): array
80 {
81 return [
82 KING_ADDONS_ASSETS_UNIQUE_KEY . '-facet-taxonomy-script',
83 ];
84 }
85
86 /**
87 * Register controls.
88 *
89 * @return void
90 */
91 public function register_controls(): void
92 {
93 $this->start_controls_section(
94 'kng_facet_section',
95 [
96 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Facet Taxonomy', 'king-addons'),
97 'tab' => Controls_Manager::TAB_CONTENT,
98 ]
99 );
100
101 $this->add_control(
102 'kng_filters_query_id',
103 [
104 'label' => esc_html__('Filter Query ID', 'king-addons'),
105 'type' => Controls_Manager::TEXT,
106 'placeholder' => esc_html__('shop_grid_1', 'king-addons'),
107 ]
108 );
109
110 $this->add_control(
111 'kng_taxonomy',
112 [
113 'label' => esc_html__('Taxonomy', 'king-addons'),
114 'type' => Controls_Manager::SELECT,
115 'options' => $this->get_taxonomy_options(),
116 'default' => 'product_cat',
117 ]
118 );
119
120 $this->add_control(
121 'kng_terms_mode',
122 [
123 'label' => esc_html__('Terms Source', 'king-addons'),
124 'type' => Controls_Manager::SELECT,
125 'options' => [
126 'auto' => esc_html__('Auto (all terms)', 'king-addons'),
127 'manual' => esc_html__('Manual list', 'king-addons'),
128 ],
129 'default' => 'auto',
130 ]
131 );
132
133 $this->add_control(
134 'kng_terms_select',
135 [
136 'label' => esc_html__('Select Terms', 'king-addons'),
137 'type' => Controls_Manager::SELECT2,
138 'multiple' => true,
139 'options' => $this->get_terms_options('product_cat'),
140 'condition' => [
141 'kng_terms_mode' => 'auto',
142 ],
143 ]
144 );
145
146 $this->add_control(
147 'kng_terms',
148 [
149 'label' => esc_html__('Terms (slugs, one per line)', 'king-addons'),
150 'type' => Controls_Manager::TEXTAREA,
151 'placeholder' => "shoes\nboots\nsneakers",
152 'condition' => [
153 'kng_terms_mode' => 'manual',
154 ],
155 ]
156 );
157
158 $this->add_control(
159 'kng_show_counts',
160 [
161 'label' => esc_html__('Show Counts', 'king-addons'),
162 'type' => Controls_Manager::SWITCHER,
163 'return_value' => 'yes',
164 'default' => '',
165 ]
166 );
167
168 $this->add_control(
169 'kng_hide_zero',
170 [
171 'label' => esc_html__('Hide Zero Count', 'king-addons'),
172 'type' => Controls_Manager::SWITCHER,
173 'return_value' => 'yes',
174 'default' => '',
175 'condition' => [
176 'kng_show_counts' => 'yes',
177 ],
178 ]
179 );
180
181 $this->add_control(
182 'kng_display_mode',
183 [
184 'label' => esc_html__('Display Mode', 'king-addons'),
185 'type' => Controls_Manager::SELECT,
186 'options' => [
187 'text' => esc_html__('Text', 'king-addons'),
188 'swatch' => esc_html__('Swatch', 'king-addons'),
189 ],
190 'default' => 'text',
191 ]
192 );
193
194 $this->add_control(
195 'kng_swatch_type',
196 [
197 'label' => esc_html__('Swatch Type', 'king-addons'),
198 'type' => Controls_Manager::SELECT,
199 'options' => [
200 'color' => esc_html__('Color', 'king-addons'),
201 'image' => esc_html__('Image URL', 'king-addons'),
202 'text' => esc_html__('Text (fallback)', 'king-addons'),
203 ],
204 'default' => 'color',
205 'condition' => [
206 'kng_display_mode' => 'swatch',
207 ],
208 ]
209 );
210
211 $this->add_control(
212 'kng_swatch_map',
213 [
214 'label' => esc_html__('Swatch Map', 'king-addons'),
215 'type' => Controls_Manager::TEXTAREA,
216 'placeholder' => "red:#ff0000\nblue:#0000ff\npattern:https://example.com/pattern.jpg",
217 'description' => esc_html__('Key-value per line: slug:value (hex color or image URL).', 'king-addons'),
218 'condition' => [
219 'kng_display_mode' => 'swatch',
220 ],
221 ]
222 );
223
224 $this->end_controls_section();
225 }
226
227 /**
228 * Render widget output.
229 *
230 * @return void
231 */
232 public function render(): void
233 {
234 $settings = $this->get_settings_for_display();
235 $query_id = sanitize_title($settings['kng_filters_query_id'] ?? '');
236 $taxonomy = sanitize_key($settings['kng_taxonomy'] ?? '');
237 $terms = [];
238
239 if (($settings['kng_terms_mode'] ?? 'auto') === 'auto') {
240 $selected = $settings['kng_terms_select'] ?? [];
241 if (!empty($selected) && is_array($selected)) {
242 $terms = array_map('sanitize_title', $selected);
243 } else {
244 $terms = $this->get_term_slugs_for_tax($taxonomy);
245 }
246 } else {
247 $terms_raw = $settings['kng_terms'] ?? '';
248 $terms = array_filter(array_map('trim', preg_split("/\r\n|\n|\r/", (string) $terms_raw)));
249 }
250
251 if (empty($terms)) {
252 return;
253 }
254
255 $swatch_map = $this->parse_swatch_map($settings['kng_swatch_map'] ?? '');
256 $is_swatch = ($settings['kng_display_mode'] ?? 'text') === 'swatch';
257 $swatch_type = $settings['kng_swatch_type'] ?? 'color';
258
259 ?>
260 <div class="king-addons-facet king-addons-facet--taxonomy">
261 <ul class="king-addons-facet__list" data-ka-filters-query-id="<?php echo esc_attr($query_id); ?>">
262 <?php foreach ($terms as $term) : ?>
263 <li class="king-addons-facet__item">
264 <label class="king-addons-facet__label">
265 <input
266 type="checkbox"
267 class="king-addons-facet__input"
268 data-ka-filter-type="taxonomy"
269 data-ka-filters-query-id="<?php echo esc_attr($query_id); ?>"
270 data-ka-taxonomy="<?php echo esc_attr($taxonomy); ?>"
271 data-ka-term="<?php echo esc_attr($term); ?>"
272 data-ka-show-counts="<?php echo esc_attr(($settings['kng_show_counts'] ?? '') === 'yes' ? '1' : '0'); ?>"
273 data-ka-swatch="<?php echo $is_swatch ? '1' : '0'; ?>"
274 data-ka-count-key="<?php echo esc_attr($taxonomy . ':' . $term); ?>"
275 />
276 <?php if ($is_swatch) : ?>
277 <?php
278 $value = $swatch_map[$term] ?? '';
279 $style_attr = '';
280 $class = 'king-addons-facet__swatch';
281 if ('color' === $swatch_type && $value) {
282 $style_attr = ' style="background-color:' . esc_attr($value) . ';"';
283 } elseif ('image' === $swatch_type && $value) {
284 $style_attr = ' style="background-image:url(' . esc_url($value) . ');"';
285 $class .= ' king-addons-facet__swatch--image';
286 }
287 ?>
288 <span class="<?php echo esc_attr($class); ?>"<?php echo $style_attr; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>></span>
289 <span class="king-addons-facet__text"><?php echo esc_html($term); ?></span>
290 <?php else : ?>
291 <span class="king-addons-facet__text"><?php echo esc_html($term); ?></span>
292 <?php endif; ?>
293 <?php if (($settings['kng_show_counts'] ?? '') === 'yes') : ?>
294 <span
295 class="king-addons-facet__count"
296 data-ka-count="<?php echo esc_attr($taxonomy . ':' . $term); ?>"
297 data-ka-hide-zero="<?php echo esc_attr(($settings['kng_hide_zero'] ?? '') === 'yes' ? '1' : '0'); ?>"
298 ></span>
299 <?php endif; ?>
300 </label>
301 </li>
302 <?php endforeach; ?>
303 </ul>
304 </div>
305 <?php
306 }
307
308 /**
309 * Get available taxonomies list.
310 *
311 * @return array<string,string>
312 */
313 private function get_taxonomy_options(): array
314 {
315 $options = [];
316 $taxes = get_taxonomies(['public' => true], 'objects');
317 foreach ($taxes as $tax) {
318 $options[$tax->name] = esc_html($tax->labels->singular_name ?? $tax->label ?? $tax->name);
319 }
320 return $options;
321 }
322
323 /**
324 * Get term options for a taxonomy.
325 *
326 * @param string $taxonomy Taxonomy.
327 *
328 * @return array<string,string>
329 */
330 private function get_terms_options(string $taxonomy): array
331 {
332 $options = [];
333 $terms = get_terms(
334 [
335 'taxonomy' => $taxonomy,
336 'hide_empty' => false,
337 'number' => 50,
338 ]
339 );
340
341 if (is_array($terms)) {
342 foreach ($terms as $term) {
343 $options[$term->slug] = esc_html($term->name);
344 }
345 }
346
347 return $options;
348 }
349
350 /**
351 * Get term slugs for taxonomy (fallback).
352 *
353 * @param string $taxonomy Taxonomy.
354 *
355 * @return array<int,string>
356 */
357 private function get_term_slugs_for_tax(string $taxonomy): array
358 {
359 $options = $this->get_terms_options($taxonomy);
360 return array_keys($options);
361 }
362
363 /**
364 * Parse swatch map textarea (slug:value).
365 *
366 * @param string $raw Raw input.
367 *
368 * @return array<string,string>
369 */
370 private function parse_swatch_map(string $raw): array
371 {
372 $lines = preg_split("/\r\n|\n|\r/", $raw);
373 $map = [];
374 foreach ($lines as $line) {
375 if (strpos($line, ':') === false) {
376 continue;
377 }
378 [$slug, $val] = array_map('trim', explode(':', $line, 2));
379 if ($slug && $val) {
380 $map[sanitize_title($slug)] = $val;
381 }
382 }
383 return $map;
384 }
385 }
386
387
388
389
390
391
392