PluginProbe
The Innovative Form Builder – IvyForms / 0.8
The Innovative Form Builder – IvyForms v0.8
1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 1.2 1.3
ivyforms / backend / src / ValueObjects / Field / Field.php

Field.php in The Innovative Form Builder – IvyForms 0.8, at backend/src/ValueObjects/Field/Field.php

528 lines 12.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @copyright © Melograno Venture Studio. All rights reserved.
5 * @licence See LICENCE.md for license details.
6 */
7
8 namespace IvyForms\ValueObjects\Field;
9
10 // phpcs:disable PSR1.Files.SideEffects
11 if (!defined('ABSPATH')) {
12 exit; // Exit if accessed directly
13 }
14
15 use IvyForms\Common\Exceptions\ValidationException;
16 use IvyForms\Services\Translations\BackendStrings;
17
18 /**
19 * Class Field
20 *
21 * @SuppressWarnings(PHPMD)
22 * @package IvyForms\ValueObjects\Field
23 */
24 final class Field
25 {
26 /**
27 * @var int
28 */
29 public int $id;
30 /**
31 * @var int
32 */
33 public int $formId;
34 /**
35 * @var int
36 */
37 public int $fieldIndex;
38 /**
39 * @var string
40 */
41 public string $type;
42 /**
43 * @var int
44 */
45 public int $position;
46 /**
47 * @var int Row index for grid layout (0-based)
48 */
49 public int $rowIndex;
50 /**
51 * @var int Column index within row (0-based, max 4 for 5 fields per row)
52 */
53 public int $columnIndex;
54 /**
55 * @var int Field width percentage (20, 25, 33, 50, or 100)
56 */
57 public int $width;
58 /**
59 * @var int|null
60 */
61 public ?int $parentId;
62 /**
63 * @var FieldGeneralSettings
64 */
65 public FieldGeneralSettings $generalSettings;
66 /**
67 * @var FieldOptions
68 */
69 public FieldOptions $fieldOptions;
70 /**
71 * @var int Number of rows (for textarea fields)
72 */
73 public int $rows;
74 /** @var bool */
75 public bool $confirmFieldEnabled;
76 /** @var string */
77 public string $confirmFieldLabel;
78 /** @var string */
79 public string $confirmFieldPlaceholder;
80 /** @var bool */
81 public bool $confirmFieldHideLabel;
82 /**
83 * @var FieldAdvancedSettings
84 */
85 public FieldAdvancedSettings $advancedSettings;
86 /**
87 * @var array<string, mixed> Additional properties from Pro plugin
88 */
89 private array $additionalProperties = [];
90
91 /**
92 * Field constructor.
93 * @SuppressWarnings(PHPMD)
94 *
95 * @param int $id
96 * @param int $formId
97 * @param int $fieldIndex
98 * @param string $type
99 * @param int $position
100 * @param int|null $parentId
101 * @param FieldGeneralSettings $generalSettings
102 * @param FieldOptions $fieldOptions
103 * @param FieldAdvancedSettings $advancedSettings
104 * @param int $rows
105 * @param int $rowIndex
106 * @param int $columnIndex
107 * @param int $width
108 *
109 * @throws ValidationException
110 */
111 public function __construct(
112 int $id,
113 int $formId,
114 int $fieldIndex,
115 string $type,
116 int $position,
117 FieldGeneralSettings $generalSettings,
118 FieldOptions $fieldOptions,
119 FieldAdvancedSettings $advancedSettings,
120 ?int $parentId = null,
121 int $rows = 0,
122 int $rowIndex = 0,
123 int $columnIndex = 0,
124 int $width = 100
125 ) {
126 $this->id = $this->validateId($id);
127 $this->formId = $this->validateId($formId);
128 $this->fieldIndex = $this->validateId($fieldIndex);
129 $this->type = $this->validateString($type, 50, 'type');
130 $this->position = $this->validatePosition($position);
131 $this->rowIndex = $this->validateRowIndex($rowIndex);
132 $this->columnIndex = $this->validateColumnIndex($columnIndex);
133 $this->width = $this->validateWidth($width);
134 $this->parentId = $this->validateParentId($parentId);
135 $this->generalSettings = $generalSettings;
136 $this->fieldOptions = $fieldOptions;
137 $this->advancedSettings = $advancedSettings;
138 $this->rows = $this->validateRows($rows);
139
140 /**
141 * Allows initialization of additional properties for the Field value object.
142 * @since 0.1.0
143 *
144 * @param mixed[] $additionalProperties The current list of additional properties.
145 * @param Field $field The Field value object instance.
146 * @return mixed[] The modified list of additional properties.
147 */
148 $this->additionalProperties =
149 apply_filters('ivyforms/field/value_object/init_additional_properties', [], $this);
150 }
151
152 /**
153 * Set an additional property
154 *
155 * @param string $key
156 * @param mixed $value
157 *
158 * @return void
159 */
160 public function setAdditionalProperty(string $key, $value): void
161 {
162 foreach ($this->additionalProperties as &$property) {
163 if (array_key_exists($key, $property)) {
164 $property[$key] = $value; // update existing
165 return;
166 }
167 }
168
169 // if not found, append new key-value pair
170 $this->additionalProperties[] = [$key => $value];
171 }
172
173 /**
174 * Get an additional property
175 *
176 * @param string $key
177 * @return mixed|null The value of the additional property, or null if not found
178 */
179 public function getAdditionalProperty(string $key)
180 {
181 foreach ($this->additionalProperties as $property) {
182 if (array_key_exists($key, $property)) {
183 return $property[$key];
184 }
185 }
186 return null;
187 }
188
189 /**
190 * Get all additional properties
191 *
192 * @return array<string, mixed> The additional properties
193 */
194 public function getAllAdditionalProperties(): array
195 {
196 return $this->additionalProperties;
197 }
198
199 /**
200 * Validates the ID.
201 *
202 * @param int $id
203 *
204 * @return int
205 * @throws ValidationException
206 */
207 public function validateId(int $id): int
208 {
209 if ($id < 0) {
210 throw new ValidationException(BackendStrings::getExceptionStrings()['id_positive_integer']);
211 }
212 return $id;
213 }
214
215 /**
216 * Validates parent id which can be null or non-negative int.
217 *
218 * @param int|null $parentId
219 *
220 * @return int|null
221 * @throws ValidationException
222 */
223 private function validateParentId(?int $parentId): ?int
224 {
225 if ($parentId === null) {
226 return null;
227 }
228 if ($parentId < 0) {
229 throw new ValidationException(BackendStrings::getExceptionStrings()['parentId_positive_integer']);
230 }
231 return $parentId;
232 }
233
234 /**
235 * Validates a string value.
236 *
237 * @param string $value
238 * @param int $maxLength
239 * @param string $fieldName
240 *
241 * @return string
242 *
243 * @throws ValidationException
244 */
245 private function validateString(string $value, int $maxLength, string $fieldName): string
246 {
247 if (strlen($value) > $maxLength) {
248 throw new ValidationException(
249 sprintf(
250 /* translators: 1: String value, 2: String max length. */
251 esc_html__('%1$s must be at most %2$d characters.', 'ivyforms'),
252 esc_html($fieldName),
253 $maxLength
254 )
255 );
256 }
257 return $value;
258 }
259
260 /**
261 * Validates the position.
262 *
263 * @param int $value
264 *
265 * @return int
266 *
267 * @throws ValidationException
268 */
269 private function validatePosition(int $value): int
270 {
271 if ($value < 0) {
272 throw new ValidationException(
273 BackendStrings::getExceptionStrings()['position_non_negative']
274 );
275 }
276 return $value;
277 }
278
279 /**
280 * Validates the row index.
281 *
282 * @param int $value
283 *
284 * @return int
285 *
286 * @throws ValidationException
287 */
288 private function validateRowIndex(int $value): int
289 {
290 if ($value < 0) {
291 throw new ValidationException(
292 BackendStrings::getExceptionStrings()['row_index_non_negative']
293 );
294 }
295 return $value;
296 }
297
298 /**
299 * Validates the column index (0-4 for max 5 fields per row).
300 *
301 * @param int $value
302 *
303 * @return int
304 *
305 * @throws ValidationException
306 */
307 private function validateColumnIndex(int $value): int
308 {
309 if ($value < 0 || $value > 4) {
310 throw new ValidationException(
311 BackendStrings::getExceptionStrings()['column_index_range']
312 );
313 }
314 return $value;
315 }
316
317 /**
318 * Validates the width percentage.
319 *
320 * @param int $value
321 *
322 * @return int
323 *
324 * @throws ValidationException
325 */
326 private function validateWidth(int $value): int
327 {
328 if ($value < 20 || $value > 100) {
329 throw new ValidationException(
330 BackendStrings::getExceptionStrings()['width_range']
331 );
332 }
333 return $value;
334 }
335
336 /**
337 * Validate rows.
338 *
339 * @param int $rows
340 * @return int
341 * @throws ValidationException
342 */
343 private function validateRows(int $rows): int
344 {
345 if ($rows < 0) {
346 throw new ValidationException(
347 BackendStrings::getExceptionStrings()['rows_non_negative']
348 );
349 }
350 return $rows;
351 }
352
353 /**
354 * Get the form ID.
355 *
356 * @return int
357 */
358 public function getFormId(): int
359 {
360 return $this->formId;
361 }
362
363 /**
364 * Get the field ID.
365 *
366 * @return int
367 */
368 public function getId(): int
369 {
370 return $this->id;
371 }
372
373 /**
374 * Get the field index.
375 *
376 * @return int
377 */
378 public function getIndex(): int
379 {
380 return $this->fieldIndex;
381 }
382
383 /**
384 * Get the field type.
385 *
386 * @return string
387 */
388 public function getType(): string
389 {
390 return $this->type;
391 }
392
393 /**
394 * Get the field position.
395 *
396 * @return int
397 */
398 public function getPosition(): int
399 {
400 return $this->position;
401 }
402
403 /**
404 * Get the row index.
405 *
406 * @return int
407 */
408 public function getRowIndex(): int
409 {
410 return $this->rowIndex;
411 }
412
413 /**
414 * Get the column index.
415 *
416 * @return int
417 */
418 public function getColumnIndex(): int
419 {
420 return $this->columnIndex;
421 }
422
423 /**
424 * Get the field width percentage.
425 *
426 * @return int
427 */
428 public function getWidth(): int
429 {
430 return $this->width;
431 }
432
433 /**
434 * Get the parent field id.
435 *
436 * @return int|null
437 */
438 public function getParentId(): ?int
439 {
440 return $this->parentId;
441 }
442
443 /**
444 * Get the general settings object.
445 *
446 * @return FieldGeneralSettings
447 */
448 public function getGeneralSettings(): FieldGeneralSettings
449 {
450 return $this->generalSettings;
451 }
452
453 /**
454 * Get the field options.
455 *
456 * @return FieldOptions
457 */
458 public function getFieldOptions(): FieldOptions
459 {
460 return $this->fieldOptions;
461 }
462
463 /**
464 * Get number of rows.
465 * @return int
466 */
467 public function getRows(): int
468 {
469 return $this->rows;
470 }
471
472 /**
473 * Set number of rows.
474 * @param int $rows
475 */
476 public function setRows(int $rows): void
477 {
478 $this->rows = $rows;
479 }
480
481
482
483 /**
484 * Get the general settings object.
485 *
486 * @return FieldAdvancedSettings
487 */
488 public function getAdvancedSettings(): FieldAdvancedSettings
489 {
490 return $this->advancedSettings;
491 }
492
493 /**
494 * Convert the field to an array.
495 *
496 * @return array<string, mixed>
497 */
498 public function toArray(): array
499 {
500 $data = [
501 'id' => $this->id,
502 'formId' => $this->formId,
503 'fieldIndex' => $this->fieldIndex,
504 'type' => $this->type,
505 'position' => $this->position,
506 'rowIndex' => $this->rowIndex,
507 'columnIndex' => $this->columnIndex,
508 'width' => $this->width,
509 'parentId' => $this->parentId,
510 'generalSettings' => $this->generalSettings->toArray(),
511 'fieldOptions' => $this->fieldOptions->toArray(),
512 'rows' => $this->rows,
513 // Advanced options
514 'advancedSettings' => $this->advancedSettings->toArray()
515 ];
516
517 /**
518 * Allows modification of the array representation of the Field value object.
519 * @since 0.1.0
520 *
521 * @param mixed[] $data The current array representation of the Field value object.
522 * @param Field $field The Field value object instance.
523 * @return mixed[] The modified array representation of the Field value object.
524 */
525 return apply_filters('ivyforms/field/value_object/add_to_array_additional_properties', $data, $this);
526 }
527 }
528