PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.9
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.9
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Services / FormBuilder / RatingIcon.php

RatingIcon.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.9, at app/Services/FormBuilder/RatingIcon.php

217 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Services\FormBuilder;
4
5 use FluentForm\Framework\Helpers\ArrayHelper;
6
7 class RatingIcon
8 {
9 const DEFAULT_ICON = 'star';
10 const DEFAULT_INACTIVE_COLOR = '#d4d4d4';
11 const DEFAULT_ACTIVE_COLOR = '#ffb100';
12
13 public static function getPresetOptions()
14 {
15 return [
16 [
17 'value' => 'star',
18 'label' => __('Star', 'fluentform'),
19 ],
20 [
21 'value' => 'heart',
22 'label' => __('Heart', 'fluentform'),
23 ],
24 [
25 'value' => 'thumb',
26 'label' => __('Thumb', 'fluentform'),
27 ],
28 [
29 'value' => 'smile',
30 'label' => __('Smile', 'fluentform'),
31 ],
32 [
33 'value' => 'bolt',
34 'label' => __('Bolt', 'fluentform'),
35 ],
36 ];
37 }
38
39 public static function getPresetSvgs()
40 {
41 return [
42 'star' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 62 58"><path fill="currentColor" d="M31 44.237L12.19 57.889l7.172-22.108L.566 22.111l23.241-.01L31 0l7.193 22.1 23.24.011-18.795 13.67 7.171 22.108z"/></svg>',
43 'heart' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 58"><path fill="currentColor" d="M32 55.8 27.36 51.62C11.52 37.4 1 27.92 1 16.28 1 6.8 8.36 0 17.68 0c5.28 0 10.34 2.4 13.66 6.18C34.66 2.4 39.72 0 45 0 54.32 0 61.68 6.8 61.68 16.28c0 11.64-10.52 21.12-26.36 35.34L32 55.8z"/></svg>',
44 'thumb' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="M14 10V4.5a2.5 2.5 0 0 0-5 0V10m0 0H5.8c-.99 0-1.8.81-1.8 1.8V18a2 2 0 0 0 2 2h7.4a3 3 0 0 0 2.93-2.36l1.2-5.4A1.8 1.8 0 0 0 15.77 10H14ZM9 10v10"/></svg>',
45 'smile' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.8"/><path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" d="M9 14c.75 1 1.8 1.5 3 1.5s2.25-.5 3-1.5"/><circle cx="9" cy="10" r="1" fill="currentColor"/><circle cx="15" cy="10" r="1" fill="currentColor"/></svg>',
46 'bolt' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 64"><path fill="currentColor" d="M28.56 0 4 36.22h15.18L12.86 64 44 24.86H28.64L28.56 0z"/></svg>',
47 ];
48 }
49
50 public static function resolveSettings($field)
51 {
52 $settings = ArrayHelper::get($field, 'settings');
53
54 if (!is_array($settings)) {
55 $settings = ArrayHelper::get($field, 'raw.settings', []);
56 }
57
58 if (!is_array($settings)) {
59 $settings = is_array($field) ? $field : [];
60 }
61
62 return [
63 'icon_source' => static::normalizeIconSource(ArrayHelper::get($settings, 'icon_source')),
64 'icon_type' => static::normalizeIconType(ArrayHelper::get($settings, 'icon_type')),
65 'custom_icon_svg' => static::sanitizeCustomSvg(ArrayHelper::get($settings, 'custom_icon_svg')),
66 'inactive_color' => static::sanitizeColor(ArrayHelper::get($settings, 'inactive_color'), static::DEFAULT_INACTIVE_COLOR),
67 'active_color' => static::sanitizeColor(ArrayHelper::get($settings, 'active_color'), static::DEFAULT_ACTIVE_COLOR),
68 ];
69 }
70
71 public static function sanitizeColor($color, $fallback = '')
72 {
73 $sanitized = sanitize_hex_color((string) $color);
74
75 if ($sanitized) {
76 return $sanitized;
77 }
78
79 return $fallback ? sanitize_hex_color($fallback) : '';
80 }
81
82 public static function normalizeIconSource($iconSource)
83 {
84 return sanitize_key($iconSource) === 'custom_svg' ? 'custom_svg' : 'preset';
85 }
86
87 public static function normalizeIconType($iconType)
88 {
89 $iconType = sanitize_key($iconType);
90 $presetSvgs = static::getPresetSvgs();
91
92 return isset($presetSvgs[$iconType]) ? $iconType : static::DEFAULT_ICON;
93 }
94
95 public static function sanitizeCustomSvg($svg)
96 {
97 if (!is_string($svg)) {
98 return '';
99 }
100
101 $svg = trim(preg_replace('/<\?xml.*?\?>/i', '', $svg));
102
103 if (!$svg || stripos($svg, '<svg') !== 0) {
104 return '';
105 }
106
107 $svg = wp_kses($svg, static::getAllowedSvgTags());
108
109 return stripos($svg, '<svg') === 0 ? $svg : '';
110 }
111
112 public static function getResolvedIconSvg($field, $attributes = [])
113 {
114 $settings = static::resolveSettings($field);
115
116 $svg = $settings['custom_icon_svg'];
117 if ($settings['icon_source'] !== 'custom_svg' || !$svg) {
118 $svg = static::getPresetSvgs()[$settings['icon_type']];
119 }
120
121 return static::applySvgAttributes($svg, $attributes);
122 }
123
124 public static function applySvgAttributes($svg, $attributes = [])
125 {
126 if (!$svg || !preg_match('/<svg\b[^>]*>/i', $svg, $match)) {
127 return '';
128 }
129
130 $existingTag = $match[0];
131 $existingClass = '';
132 if (preg_match('/\sclass=("|\')(.*?)\1/i', $existingTag, $classMatch)) {
133 $existingClass = $classMatch[2];
134 }
135
136 if (isset($attributes['class'])) {
137 $attributes['class'] = trim($existingClass . ' ' . $attributes['class']);
138 } elseif ($existingClass) {
139 $attributes['class'] = $existingClass;
140 }
141
142 $attributes = array_merge([
143 'focusable' => 'false',
144 'aria-hidden' => 'true',
145 'preserveAspectRatio' => 'xMidYMid meet',
146 'preserveaspectratio' => 'xMidYMid meet',
147 ], $attributes);
148
149 $attributePairs = [];
150 foreach ($attributes as $key => $value) {
151 if ($value === null || $value === '') {
152 continue;
153 }
154
155 $attributePairs[] = sprintf('%s="%s"', esc_attr($key), esc_attr($value));
156 }
157
158 $tag = preg_replace('/\sclass=("|\')(.*?)\1/i', '', $existingTag);
159 $tag = rtrim(substr($tag, 0, -1)) . ' ' . implode(' ', $attributePairs) . '>';
160
161 return preg_replace('/<svg\b[^>]*>/i', $tag, $svg, 1);
162 }
163
164 protected static function getAllowedSvgTags()
165 {
166 $attributes = [
167 'class' => true,
168 'd' => true,
169 'cx' => true,
170 'cy' => true,
171 'r' => true,
172 'rx' => true,
173 'ry' => true,
174 'x' => true,
175 'y' => true,
176 'x1' => true,
177 'x2' => true,
178 'y1' => true,
179 'y2' => true,
180 'width' => true,
181 'height' => true,
182 'viewbox' => true,
183 'fill' => true,
184 'fill-rule' => true,
185 'clip-rule' => true,
186 'stroke' => true,
187 'stroke-width' => true,
188 'stroke-linecap' => true,
189 'stroke-linejoin' => true,
190 'stroke-miterlimit' => true,
191 'opacity' => true,
192 'points' => true,
193 'transform' => true,
194 'xmlns' => true,
195 'xmlns:xlink' => true,
196 'aria-hidden' => true,
197 'focusable' => true,
198 'role' => true,
199 'preserveaspectratio' => true,
200 ];
201
202 return [
203 'svg' => $attributes,
204 'g' => $attributes,
205 'path' => $attributes,
206 'circle' => $attributes,
207 'rect' => $attributes,
208 'polygon' => $attributes,
209 'polyline' => $attributes,
210 'line' => $attributes,
211 'ellipse' => $attributes,
212 'title' => [],
213 'desc' => [],
214 ];
215 }
216 }
217