PluginProbe
PostNL for WooCommerce / 4.0.1
PostNL for WooCommerce v4.0.1
5.9.12 5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 All 72 releases
woo-postnl / includes / entities / settings-field-arguments.php

settings-field-arguments.php in PostNL for WooCommerce 4.0.1, at includes/entities/settings-field-arguments.php

542 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPO\WC\PostNL\Entity;
4
5 use MyParcelNL\Sdk\src\Support\Arr;
6 use WCPN_Settings_Data;
7
8 defined('ABSPATH') or exit;
9
10 if (class_exists('\\WPO\\WC\\PostNL\\Entity\\SettingsFieldArguments')) {
11 return;
12 }
13
14 class SettingsFieldArguments
15 {
16 private const CONDITION_DEFAULTS = [
17 "type" => "show",
18 "set_value" => null,
19 ];
20
21 public const IGNORED_ARGUMENTS = [
22 "callback",
23 "condition",
24 "default",
25 "id",
26 "label",
27 "loop",
28 "name",
29 "type",
30 ];
31
32 public const ALTERNATIVE_IGNORED_ARGUMENTS = [
33 "callback",
34 "condition",
35 "default",
36 "type",
37 ];
38
39 public const ALLOWED_ARGUMENTS = [
40 "append",
41 "autocomplete",
42 "autofocus",
43 "class",
44 "custom_attributes",
45 "description",
46 "help_text",
47 "id",
48 "input_class",
49 "label",
50 "label_class",
51 "maxlength",
52 "options",
53 "placeholder",
54 "priority",
55 "required",
56 "return",
57 "type",
58 "validate",
59 ];
60
61 /**
62 * @var array
63 */
64 private $input;
65
66 /**
67 * @var string
68 */
69 private $prefix;
70
71 /**
72 * @var string
73 */
74 private $type;
75
76 /**
77 * @var mixed
78 */
79 private $name;
80
81 /**
82 * @var mixed
83 */
84 private $id;
85
86 /**
87 * @var array
88 */
89 private $arguments = [];
90
91 /**
92 * @var array
93 */
94 private $defaults = [
95 "type" => "text",
96 "class" => [],
97 "input_class" => [],
98 "label_class" => [],
99 ];
100
101 /**
102 * @var string|null
103 */
104 private $description;
105
106 /**
107 * @var mixed
108 */
109 private $value;
110
111 /**
112 * @var string
113 */
114 private $default;
115
116 /**
117 * @var string
118 */
119 private $suffix;
120
121 /**
122 * SettingsFieldArguments constructor.
123 *
124 * @param array $args - The setting's arguments.
125 * @param string $prefix - Optional prefix for name and conditions.
126 * @param string $suffix - Optional suffix for name and conditions.
127 *
128 * @throws \Exception
129 */
130 public function __construct(array $args, string $prefix = '' , string $suffix = '')
131 {
132 $this->input = $args;
133 $this->prefix = $prefix;
134 $this->suffix = $suffix;
135 $this->option_id = $args["option_id"] ?? null;
136
137 $this->name = $this->wrap($this->getInputArgument("name"));
138 $this->id = $this->getInputArgument("id") ?? $this->name;
139 $this->description = $this->getInputArgument("description");
140
141 $this->setClass();
142 $this->setType();
143 $this->setDefault();
144 $this->setConditions();
145
146 $this->setArguments($this->input);
147 }
148
149 private function setType(): void
150 {
151 $type = $this->getInputArgument("type");
152
153 switch ($type) {
154 case "number":
155 $this->addArgument("min", 0);
156 $this->addArgument("step", 1);
157 break;
158 case "currency":
159 $type = "number";
160 $this->addArgument("step", 0.01);
161 $this->addArgument("placeholder", "0,00");
162 break;
163 case "toggle":
164 $type = "select";
165
166 $this->addArgument("data-type", "toggle");
167 $this->addArgument(
168 "options",
169 [
170 "1" => __("Enabled", "woocommerce-postnl"),
171 "0" => __("Disabled", "woocommerce-postnl"),
172 ]
173 );
174 break;
175 case "select":
176 $this->addArgument("options", $this->getInputArgument("options") ?? []);
177 break;
178 }
179
180 $this->type = $type;
181 }
182
183 private function setClass(): void
184 {
185 $arr = [
186 "class" => $this->getInputArgument("class"),
187 "input_class" => $this->getInputArgument("input_class"),
188 "label_class" => $this->getInputArgument("label_class"),
189 ];
190
191 foreach ($arr as $class => $value) {
192 if ($value) {
193 $this->addArgument($class, is_array($value) ? $value : [$value]);
194 }
195 }
196 }
197
198 /**
199 * If the setting has conditions set up the attributes so the JS can use them. Supports strings, arrays of
200 * strings and associative arrays.
201 */
202 private function setConditions(): void
203 {
204 $conditionArgument = $this->getInputArgument("condition");
205 $conditions = [];
206
207 if (! $conditionArgument) {
208 return;
209 }
210
211 if (is_array($conditionArgument)) {
212 $conditions = $conditionArgument;
213 } else {
214 $conditions[] = $conditionArgument;
215 }
216
217 $conditionData = array_map([$this, "createCondition"], $conditions);
218 $conditionData = $this->mergeConditions($conditionData);
219
220 $this->addArgument("data-conditions", $conditionData);
221 }
222
223 /**
224 * @param string $name
225 *
226 * @return mixed|null
227 */
228 public function getInputArgument(string $name)
229 {
230 return $this->input[$name] ?? $this->defaults[$name] ?? null;
231 }
232
233 /**
234 * @param string $name
235 *
236 * @return mixed
237 */
238 public function getArgument(string $name)
239 {
240 return $this->arguments[$name] ?? null;
241 }
242
243 /**
244 * Return the arguments formatted for woocommerce_form_field()
245 *
246 * @param bool $ignore
247 *
248 * @return array
249 * @see \woocommerce_form_field
250 */
251 public function getArguments(bool $ignore = true): array
252 {
253 $arguments = [
254 "id" => $this->id,
255 "type" => $this->type,
256 ];
257
258 foreach ($this->arguments as $arg => $value) {
259 $ignoredArguments = $ignore ? self::IGNORED_ARGUMENTS : self::ALTERNATIVE_IGNORED_ARGUMENTS;
260
261 if (in_array($arg, $ignoredArguments)) {
262 continue;
263 }
264
265 if (in_array($arg, self::ALLOWED_ARGUMENTS)) {
266 if (array_key_exists($arg, $arguments)) {
267 $arguments[$arg] = array_replace_recursive(
268 $arguments[$arg],
269 $value
270 );
271 } else {
272 $arguments[$arg] = $value;
273 }
274 } else {
275 if (! isset($arguments["custom_attributes"])) {
276 $arguments["custom_attributes"] = [];
277 }
278
279 if (is_array($value)) {
280 $value = htmlspecialchars(json_encode($value));
281 }
282
283 $arguments["custom_attributes"][$arg] = $value;
284 }
285 }
286
287 return $arguments;
288 }
289
290 /**
291 * Get the custom attributes as a string for use in HTML.
292 *
293 * @return string
294 */
295 public function getCustomAttributesAsString(): string
296 {
297 $attributes = [];
298
299 foreach ($this->getCustomAttributes() ?? [] as $att => $value) {
300 $attributes[] = "$att=\"$value\"";
301 }
302
303 return implode(" ", $attributes);
304 }
305
306 /**
307 * @return array
308 */
309 public function getCustomAttributes(): array
310 {
311 $arguments = $this->getArguments();
312 return $arguments['custom_attributes'] ?? [];
313 }
314
315 /**
316 * Add an argument by key => value.
317 *
318 * @param string $key
319 * @param $value
320 */
321 private function addArgument(string $key, $value): void
322 {
323 $this->setArguments([$key => $value]);
324 }
325
326 /**
327 * @param array $args
328 */
329 private function setArguments(array $args): void
330 {
331 foreach ($args as $arg => $value) {
332 $this->arguments[$arg] = $value;
333 }
334 }
335
336 /**
337 * Set default arguments based on the type.
338 */
339 private function setDefault(): void
340 {
341 if (isset($this->input["default"])) {
342 $this->default = $this->input["default"];
343 return;
344 }
345
346 if (isset($this->input["type"]) && $this->input["type"] === "toggle") {
347 $this->default = "0";
348 return;
349 }
350
351 switch ($this->type) {
352 case "number":
353 $this->default = 0;
354 break;
355 case "text":
356 case "textarea":
357 $this->default = "";
358 break;
359 case "select":
360 // Set first option as default value.
361 if ($this->arguments["options"]) {
362 $this->default = Arr::first($this->arguments["options"]);
363 } else {
364 $this->addArgument("options", []);
365 }
366 break;
367 }
368 }
369
370 /**
371 * @return string|null
372 */
373 public function getOptionId(): ?string
374 {
375 return $this->option_id;
376 }
377
378 /**
379 * @return string
380 */
381 public function getType(): string
382 {
383 return $this->type;
384 }
385
386 /**
387 * @return mixed
388 */
389 public function getName()
390 {
391 return $this->name;
392 }
393
394 /**
395 * @return mixed
396 */
397 public function getId()
398 {
399 return $this->id;
400 }
401
402 /**
403 * @return array
404 */
405 public function getDefaults(): array
406 {
407 return $this->defaults;
408 }
409
410 /**
411 * @return string
412 */
413 public function getDescription(): ?string
414 {
415 return $this->description;
416 }
417
418 /**
419 * @return mixed
420 */
421 public function getValue()
422 {
423 return $this->value;
424 }
425
426 /**
427 * @param string $id
428 */
429 public function setId(string $id): void
430 {
431 $this->id = $id;
432 }
433
434 /**
435 * @return mixed
436 */
437 public function getDefault()
438 {
439 return $this->default;
440 }
441
442 /**
443 * @param mixed $name
444 */
445 public function setName($name): void
446 {
447 $this->name = $name;
448 }
449
450 /**
451 * @param $value
452 */
453 public function setValue($value): void
454 {
455 $this->value = $value;
456 }
457
458 /**
459 * @param string|array $condition
460 *
461 * @return array
462 */
463 private function createCondition($condition): array
464 {
465 if (is_array($condition)) {
466 $parentName = $this->wrap($condition['parent_name']);
467 $parentValue = $condition['parent_value'] ?? WCPN_Settings_Data::ENABLED;
468
469 $condition['parents'] = [
470 $parentName => $parentValue,
471 ];
472
473 unset($condition['parent_name']);
474 unset($condition['parent_value']);
475
476 $newCondition = array_replace_recursive(
477 self::CONDITION_DEFAULTS,
478 $condition
479 );
480 } else {
481 $parentName = $this->wrap($condition);
482 $newCondition = array_merge(
483 self::CONDITION_DEFAULTS,
484 [
485 "parents" => [
486 $parentName => WCPN_Settings_Data::ENABLED,
487 ],
488 ]
489 );
490 }
491
492 return $newCondition;
493 }
494
495 /**
496 * @param string|null $text
497 *
498 * @return string
499 */
500 private function wrap(?string $text): ?string
501 {
502 if (! $text) {
503 return null;
504 }
505
506 return $this->prefix . $text . $this->suffix;
507 }
508
509 /**
510 * Merge multiple matching conditions (if their `type` and `set_value` are the same) into one condition, combining
511 * all `parents` properties.
512 *
513 * @param array $conditionData
514 *
515 * @return array
516 */
517 private function mergeConditions(array $conditionData): array
518 {
519 $mergedConditions = [];
520
521 foreach ($conditionData as $condition) {
522 foreach ($mergedConditions as $key => $mergedCondition) {
523 $typeMatches = $mergedCondition['type'] === $condition['type'];
524
525 if ($typeMatches) {
526 $mergedConditions[$key]['parents'] = array_merge(
527 $mergedCondition['parents'],
528 $condition['parents']
529 );
530
531 // Continue the outer loop as well
532 continue 2;
533 }
534 }
535
536 $mergedConditions[] = $condition;
537 }
538
539 return $mergedConditions;
540 }
541 }
542