PluginProbe
The Innovative Form Builder – IvyForms / 1.0
The Innovative Form Builder – IvyForms v1.0
1.5.1 1.5 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 All 27 releases
ivyforms / backend / src / ValueObjects / Field / Field.php

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

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