PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.83
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 / widgets / Facet_Taxonomy / Facet_Taxonomy.php

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

397 lines 12.3 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 'king-addons-icon king-addons-facet-taxonomy';
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 public function get_custom_help_url()
87 {
88 return 'mailto:bug@kingaddons.com?subject=Bug Report - King Addons&body=Please describe the issue';
89 }
90
91 /**
92 * Register controls.
93 *
94 * @return void
95 */
96 public function register_controls(): void
97 {
98 $this->start_controls_section(
99 'kng_facet_section',
100 [
101 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Facet Taxonomy', 'king-addons'),
102 'tab' => Controls_Manager::TAB_CONTENT,
103 ]
104 );
105
106 $this->add_control(
107 'kng_filters_query_id',
108 [
109 'label' => esc_html__('Filter Query ID', 'king-addons'),
110 'type' => Controls_Manager::TEXT,
111 'placeholder' => esc_html__('shop_grid_1', 'king-addons'),
112 ]
113 );
114
115 $this->add_control(
116 'kng_taxonomy',
117 [
118 'label' => esc_html__('Taxonomy', 'king-addons'),
119 'type' => Controls_Manager::SELECT,
120 'options' => $this->get_taxonomy_options(),
121 'default' => 'product_cat',
122 ]
123 );
124
125 $this->add_control(
126 'kng_terms_mode',
127 [
128 'label' => esc_html__('Terms Source', 'king-addons'),
129 'type' => Controls_Manager::SELECT,
130 'options' => [
131 'auto' => esc_html__('Auto (all terms)', 'king-addons'),
132 'manual' => esc_html__('Manual list', 'king-addons'),
133 ],
134 'default' => 'auto',
135 ]
136 );
137
138 $this->add_control(
139 'kng_terms_select',
140 [
141 'label' => esc_html__('Select Terms', 'king-addons'),
142 'type' => Controls_Manager::SELECT2,
143 'multiple' => true,
144 'options' => $this->get_terms_options('product_cat'),
145 'condition' => [
146 'kng_terms_mode' => 'auto',
147 ],
148 ]
149 );
150
151 $this->add_control(
152 'kng_terms',
153 [
154 'label' => esc_html__('Terms (slugs, one per line)', 'king-addons'),
155 'type' => Controls_Manager::TEXTAREA,
156 'placeholder' => "shoes\nboots\nsneakers",
157 'condition' => [
158 'kng_terms_mode' => 'manual',
159 ],
160 ]
161 );
162
163 $this->add_control(
164 'kng_show_counts',
165 [
166 'label' => esc_html__('Show Counts', 'king-addons'),
167 'type' => Controls_Manager::SWITCHER,
168 'return_value' => 'yes',
169 'default' => '',
170 ]
171 );
172
173 $this->add_control(
174 'kng_hide_zero',
175 [
176 'label' => esc_html__('Hide Zero Count', 'king-addons'),
177 'type' => Controls_Manager::SWITCHER,
178 'return_value' => 'yes',
179 'default' => '',
180 'condition' => [
181 'kng_show_counts' => 'yes',
182 ],
183 ]
184 );
185
186 $this->add_control(
187 'kng_display_mode',
188 [
189 'label' => esc_html__('Display Mode', 'king-addons'),
190 'type' => Controls_Manager::SELECT,
191 'options' => [
192 'text' => esc_html__('Text', 'king-addons'),
193 'swatch' => esc_html__('Swatch', 'king-addons'),
194 ],
195 'default' => 'text',
196 ]
197 );
198
199 $this->add_control(
200 'kng_swatch_type',
201 [
202 'label' => esc_html__('Swatch Type', 'king-addons'),
203 'type' => Controls_Manager::SELECT,
204 'options' => [
205 'color' => esc_html__('Color', 'king-addons'),
206 'image' => esc_html__('Image URL', 'king-addons'),
207 'text' => esc_html__('Text (fallback)', 'king-addons'),
208 ],
209 'default' => 'color',
210 'condition' => [
211 'kng_display_mode' => 'swatch',
212 ],
213 ]
214 );
215
216 $this->add_control(
217 'kng_swatch_map',
218 [
219 'label' => esc_html__('Swatch Map', 'king-addons'),
220 'type' => Controls_Manager::TEXTAREA,
221 'placeholder' => "red:#ff0000\nblue:#0000ff\npattern:https://example.com/pattern.jpg",
222 'description' => esc_html__('Key-value per line: slug:value (hex color or image URL).', 'king-addons'),
223 'condition' => [
224 'kng_display_mode' => 'swatch',
225 ],
226 ]
227 );
228
229 $this->end_controls_section();
230 }
231
232 /**
233 * Render widget output.
234 *
235 * @return void
236 */
237 public function render(): void
238 {
239 $settings = $this->get_settings_for_display();
240 $query_id = sanitize_title($settings['kng_filters_query_id'] ?? '');
241 $taxonomy = sanitize_key($settings['kng_taxonomy'] ?? '');
242 $terms = [];
243
244 if (($settings['kng_terms_mode'] ?? 'auto') === 'auto') {
245 $selected = $settings['kng_terms_select'] ?? [];
246 if (!empty($selected) && is_array($selected)) {
247 $terms = array_map('sanitize_title', $selected);
248 } else {
249 $terms = $this->get_term_slugs_for_tax($taxonomy);
250 }
251 } else {
252 $terms_raw = $settings['kng_terms'] ?? '';
253 $terms = array_filter(array_map('trim', preg_split("/\r\n|\n|\r/", (string) $terms_raw)));
254 }
255
256 if (empty($terms)) {
257 return;
258 }
259
260 $swatch_map = $this->parse_swatch_map($settings['kng_swatch_map'] ?? '');
261 $is_swatch = ($settings['kng_display_mode'] ?? 'text') === 'swatch';
262 $swatch_type = $settings['kng_swatch_type'] ?? 'color';
263
264 ?>
265 <div class="king-addons-facet king-addons-facet--taxonomy">
266 <ul class="king-addons-facet__list" data-ka-filters-query-id="<?php echo esc_attr($query_id); ?>">
267 <?php foreach ($terms as $term) : ?>
268 <li class="king-addons-facet__item">
269 <label class="king-addons-facet__label">
270 <input
271 type="checkbox"
272 class="king-addons-facet__input"
273 data-ka-filter-type="taxonomy"
274 data-ka-filters-query-id="<?php echo esc_attr($query_id); ?>"
275 data-ka-taxonomy="<?php echo esc_attr($taxonomy); ?>"
276 data-ka-term="<?php echo esc_attr($term); ?>"
277 data-ka-show-counts="<?php echo esc_attr(($settings['kng_show_counts'] ?? '') === 'yes' ? '1' : '0'); ?>"
278 data-ka-swatch="<?php echo $is_swatch ? '1' : '0'; ?>"
279 data-ka-count-key="<?php echo esc_attr($taxonomy . ':' . $term); ?>"
280 />
281 <?php if ($is_swatch) : ?>
282 <?php
283 $value = $swatch_map[$term] ?? '';
284 $style_attr = '';
285 $class = 'king-addons-facet__swatch';
286 if ('color' === $swatch_type && $value) {
287 $style_attr = ' style="background-color:' . esc_attr($value) . ';"';
288 } elseif ('image' === $swatch_type && $value) {
289 $style_attr = ' style="background-image:url(' . esc_url($value) . ');"';
290 $class .= ' king-addons-facet__swatch--image';
291 }
292 ?>
293 <span class="<?php echo esc_attr($class); ?>"<?php echo $style_attr; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>></span>
294 <span class="king-addons-facet__text"><?php echo esc_html($term); ?></span>
295 <?php else : ?>
296 <span class="king-addons-facet__text"><?php echo esc_html($term); ?></span>
297 <?php endif; ?>
298 <?php if (($settings['kng_show_counts'] ?? '') === 'yes') : ?>
299 <span
300 class="king-addons-facet__count"
301 data-ka-count="<?php echo esc_attr($taxonomy . ':' . $term); ?>"
302 data-ka-hide-zero="<?php echo esc_attr(($settings['kng_hide_zero'] ?? '') === 'yes' ? '1' : '0'); ?>"
303 ></span>
304 <?php endif; ?>
305 </label>
306 </li>
307 <?php endforeach; ?>
308 </ul>
309 </div>
310 <?php
311 }
312
313 /**
314 * Get available taxonomies list.
315 *
316 * @return array<string,string>
317 */
318 private function get_taxonomy_options(): array
319 {
320 $options = [];
321 $taxes = get_taxonomies(['public' => true], 'objects');
322 foreach ($taxes as $tax) {
323 $options[$tax->name] = esc_html($tax->labels->singular_name ?? $tax->label ?? $tax->name);
324 }
325 return $options;
326 }
327
328 /**
329 * Get term options for a taxonomy.
330 *
331 * @param string $taxonomy Taxonomy.
332 *
333 * @return array<string,string>
334 */
335 private function get_terms_options(string $taxonomy): array
336 {
337 $options = [];
338 $terms = get_terms(
339 [
340 'taxonomy' => $taxonomy,
341 'hide_empty' => false,
342 'number' => 50,
343 ]
344 );
345
346 if (is_array($terms)) {
347 foreach ($terms as $term) {
348 $options[$term->slug] = esc_html($term->name);
349 }
350 }
351
352 return $options;
353 }
354
355 /**
356 * Get term slugs for taxonomy (fallback).
357 *
358 * @param string $taxonomy Taxonomy.
359 *
360 * @return array<int,string>
361 */
362 private function get_term_slugs_for_tax(string $taxonomy): array
363 {
364 $options = $this->get_terms_options($taxonomy);
365 return array_keys($options);
366 }
367
368 /**
369 * Parse swatch map textarea (slug:value).
370 *
371 * @param string $raw Raw input.
372 *
373 * @return array<string,string>
374 */
375 private function parse_swatch_map(string $raw): array
376 {
377 $lines = preg_split("/\r\n|\n|\r/", $raw);
378 $map = [];
379 foreach ($lines as $line) {
380 if (strpos($line, ':') === false) {
381 continue;
382 }
383 [$slug, $val] = array_map('trim', explode(':', $line, 2));
384 if ($slug && $val) {
385 $map[sanitize_title($slug)] = $val;
386 }
387 }
388 return $map;
389 }
390 }
391
392
393
394
395
396
397