PluginProbe
The Innovative Form Builder – IvyForms / 1.5.1
The Innovative Form Builder – IvyForms v1.5.1
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
← All changes | backend/src/ValueObjects/Field/Field.php +527 -0 0.6.1 → 1.5.1 View file →
@@ -1,0 +1,527 @@
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 string|null Page ID for multi-page forms
59 + */
60 + public ?string $pageId;
61 + /**
62 + * @var FieldGeneralSettings
63 + */
64 + public FieldGeneralSettings $generalSettings;
65 + /**
66 + * @var FieldOptions
67 + */
68 + public FieldOptions $fieldOptions;
69 + /**
70 + * @var int Number of rows (for textarea fields)
71 + */
72 + public int $rows;
73 + /** @var bool */
74 + public bool $confirmFieldEnabled;
75 + /** @var string */
76 + public string $confirmFieldLabel;
77 + /** @var string */
78 + public string $confirmFieldPlaceholder;
79 + /** @var bool */
80 + public bool $confirmFieldHideLabel;
81 + /**
82 + * @var FieldAdvancedSettings
83 + */
84 + public FieldAdvancedSettings $advancedSettings;
85 + /**
86 + * @var array<string, mixed> Additional properties from Pro plugin
87 + */
88 + private array $additionalProperties = [];
89 +
90 + /**
91 + * Field constructor.
92 + * @SuppressWarnings(PHPMD)
93 + *
94 + * @param int $id
95 + * @param int $formId
96 + * @param int $fieldIndex
97 + * @param string $type
98 + * @param int $position
99 + * @param int|null $parentId
100 + * @param FieldGeneralSettings $generalSettings
101 + * @param FieldOptions $fieldOptions
102 + * @param FieldAdvancedSettings $advancedSettings
103 + * @param int $rows
104 + * @param int $rowIndex
105 + * @param int $columnIndex
106 + * @param int $width
107 + * @param string|null $pageId
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 + ?string $pageId = null
126 + ) {
127 + $this->id = $this->validateId($id);
128 + $this->formId = $this->validateId($formId);
129 + $this->fieldIndex = $this->validateId($fieldIndex);
130 + $this->type = $this->validateString($type, 50, 'type');
131 + $this->position = $this->validatePosition($position);
132 + $this->rowIndex = $this->validateRowIndex($rowIndex);
133 + $this->columnIndex = $this->validateColumnIndex($columnIndex);
134 + $this->width = $this->validateWidth($width);
135 + $this->parentId = $this->validateParentId($parentId);
136 + $this->pageId = $pageId;
137 + $this->generalSettings = $generalSettings;
138 + $this->fieldOptions = $fieldOptions;
139 + $this->advancedSettings = $advancedSettings;
140 + $this->rows = $this->validateRows($rows);
141 +
142 + /**
143 + * Allows initialization of additional properties for the Field value object.
144 + * @since 0.1.0
145 + *
146 + * @param mixed[] $additionalProperties The current list of additional properties.
147 + * @param Field $field The Field value object instance.
148 + * @return mixed[] The modified list of additional properties.
149 + */
150 + $this->additionalProperties =
151 + apply_filters('ivyforms/field/value_object/init_additional_properties', [], $this);
152 + }
153 +
154 + /**
155 + * Set an additional property
156 + *
157 + * @param string $key
158 + * @param mixed $value
159 + *
160 + * @return void
161 + */
162 + public function setAdditionalProperty(string $key, $value): void
163 + {
164 + foreach ($this->additionalProperties as &$property) {
165 + if (array_key_exists($key, $property)) {
166 + $property[$key] = $value; // update existing
167 + return;
168 + }
169 + }
170 +
171 + // if not found, append new key-value pair
172 + $this->additionalProperties[] = [$key => $value];
173 + }
174 +
175 + /**
176 + * Get an additional property
177 + *
178 + * @param string $key
179 + * @return mixed|null The value of the additional property, or null if not found
180 + */
181 + public function getAdditionalProperty(string $key)
182 + {
183 + foreach ($this->additionalProperties as $property) {
184 + if (array_key_exists($key, $property)) {
185 + return $property[$key];
186 + }
187 + }
188 + return null;
189 + }
190 +
191 + /**
192 + * Get all additional properties
193 + *
194 + * @return array<string, mixed> The additional properties
195 + */
196 + public function getAllAdditionalProperties(): array
197 + {
198 + return $this->additionalProperties;
199 + }
200 +
201 + /**
202 + * Validates the ID.
203 + *
204 + * @param int $id
205 + *
206 + * @return int
207 + * @throws ValidationException
208 + */
209 + public function validateId(int $id): int
210 + {
211 + if ($id < 0) {
212 + throw new ValidationException(BackendStrings::getExceptionStrings()['id_positive_integer']);
213 + }
214 + return $id;
215 + }
216 +
217 + /**
218 + * Validates parent id which can be null or non-negative int.
219 + *
220 + * @param int|null $parentId
221 + *
222 + * @return int|null
223 + * @throws ValidationException
224 + */
225 + private function validateParentId(?int $parentId): ?int
226 + {
227 + if ($parentId === null) {
228 + return null;
229 + }
230 + if ($parentId < 0) {
231 + throw new ValidationException(BackendStrings::getExceptionStrings()['parentId_positive_integer']);
232 + }
233 + return $parentId;
234 + }
235 +
236 + /**
237 + * Validates a string value.
238 + *
239 + * @param string $value
240 + * @param int $maxLength
241 + * @param string $fieldName
242 + *
243 + * @return string
244 + *
245 + * @throws ValidationException
246 + */
247 + private function validateString(string $value, int $maxLength, string $fieldName): string
248 + {
249 + if (strlen($value) > $maxLength) {
250 + throw new ValidationException(
251 + sprintf(
252 + /* translators: 1: String value, 2: String max length. */
253 + esc_html__('%1$s must be at most %2$d characters.', 'ivyforms'),
254 + esc_html($fieldName),
255 + $maxLength
256 + )
257 + );
258 + }
259 + return $value;
260 + }
261 +
262 + /**
263 + * Validates the position.
264 + *
265 + * @param int $value
266 + *
267 + * @return int
268 + *
269 + * @throws ValidationException
270 + */
271 + private function validatePosition(int $value): int
272 + {
273 + if ($value < 0) {
274 + throw new ValidationException(
275 + BackendStrings::getExceptionStrings()['position_non_negative']
276 + );
277 + }
278 + return $value;
279 + }
280 +
281 + /**
282 + * Validates the row index.
283 + *
284 + * @param int $value
285 + *
286 + * @return int
287 + *
288 + * @throws ValidationException
289 + */
290 + private function validateRowIndex(int $value): int
291 + {
292 + if ($value < 0) {
293 + throw new ValidationException(
294 + BackendStrings::getExceptionStrings()['row_index_non_negative']
295 + );
296 + }
297 + return $value;
298 + }
299 +
300 + /**
301 + * Validates the column index (0-4 for max 5 fields per row).
302 + *
303 + * @param int $value
304 + *
305 + * @return int
306 + *
307 + * @throws ValidationException
308 + */
309 + private function validateColumnIndex(int $value): int
310 + {
311 + if ($value < 0 || $value > 4) {
312 + throw new ValidationException(
313 + BackendStrings::getExceptionStrings()['column_index_range']
314 + );
315 + }
316 + return $value;
317 + }
318 +
319 + /**
320 + * Validates the width percentage.
321 + *
322 + * @param int $value
323 + *
324 + * @return int
325 + *
326 + * @throws ValidationException
327 + */
328 + private function validateWidth(int $value): int
329 + {
330 + if ($value < 20 || $value > 100) {
331 + throw new ValidationException(
332 + BackendStrings::getExceptionStrings()['width_range']
333 + );
334 + }
335 + return $value;
336 + }
337 +
338 + /**
339 + * Validate rows.
340 + *
341 + * @param int $rows
342 + * @return int
343 + * @throws ValidationException
344 + */
345 + private function validateRows(int $rows): int
346 + {
347 + if ($rows < 0) {
348 + throw new ValidationException(
349 + BackendStrings::getExceptionStrings()['rows_non_negative']
350 + );
351 + }
352 + return $rows;
353 + }
354 +
355 + /**
356 + * Get the form ID.
357 + *
358 + * @return int
359 + */
360 + public function getFormId(): int
361 + {
362 + return $this->formId;
363 + }
364 +
365 + /**
366 + * Get the field ID.
367 + *
368 + * @return int
369 + */
370 + public function getId(): int
371 + {
372 + return $this->id;
373 + }
374 +
375 + /**
376 + * Get the field index.
377 + *
378 + * @return int
379 + */
380 + public function getIndex(): int
381 + {
382 + return $this->fieldIndex;
383 + }
384 +
385 + /**
386 + * Get the field type.
387 + *
388 + * @return string
389 + */
390 + public function getType(): string
391 + {
392 + return $this->type;
393 + }
394 +
395 + /**
396 + * Get the field position.
397 + *
398 + * @return int
399 + */
400 + public function getPosition(): int
401 + {
402 + return $this->position;
403 + }
404 +
405 + /**
406 + * Get the row index.
407 + *
408 + * @return int
409 + */
410 + public function getRowIndex(): int
411 + {
412 + return $this->rowIndex;
413 + }
414 +
415 + /**
416 + * Get the column index.
417 + *
418 + * @return int
419 + */
420 + public function getColumnIndex(): int
421 + {
422 + return $this->columnIndex;
423 + }
424 +
425 + /**
426 + * Get the field width percentage.
427 + *
428 + * @return int
429 + */
430 + public function getWidth(): int
431 + {
432 + return $this->width;
433 + }
434 +
435 + /**
436 + * Get the parent field id.
437 + *
438 + * @return int|null
439 + */
440 + public function getParentId(): ?int
441 + {
442 + return $this->parentId;
443 + }
444 +
445 + /**
446 + * Get the general settings object.
447 + *
448 + * @return FieldGeneralSettings
449 + */
450 + public function getGeneralSettings(): FieldGeneralSettings
451 + {
452 + return $this->generalSettings;
453 + }
454 +
455 + /**
456 + * Get the field options.
457 + *
458 + * @return FieldOptions
459 + */
460 + public function getFieldOptions(): FieldOptions
461 + {
462 + return $this->fieldOptions;
463 + }
464 +
465 + /**
466 + * Get number of rows.
467 + * @return int
468 + */
469 + public function getRows(): int
470 + {
471 + return $this->rows;
472 + }
473 +
474 + /**
475 + * Set number of rows.
476 + * @param int $rows
477 + */
478 + public function setRows(int $rows): void
479 + {
480 + $this->rows = $rows;
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 +}