PluginProbe
The Innovative Form Builder – IvyForms / 1.5
The Innovative Form Builder – IvyForms v1.5
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/Services/Entry/Managers/EntryFieldManager.php +52 -11 0.7 → 1.5 View file →
@@ -1,15 +1,12 @@
1 1 <?php
2 2
3 3 namespace IvyForms\Services\Entry\Managers;
4 4
5 -// phpcs:disable PSR1.Files.SideEffects
6 -if (!defined('ABSPATH')) {
7 - exit; // Exit if accessed directly
8 -}
9 -
10 5 use IvyForms\Common\Exceptions\ValidationException;
11 6 use IvyForms\Common\Helpers\EntryHelper;
7 +use IvyForms\Common\Helpers\FieldHelper;
8 +use IvyForms\Entity\EntryField\EntryField;
12 9 use IvyForms\Factory\EntryField\EntryFieldFactory;
13 10 use IvyForms\Repository\Entry\EntryRepositoryInterface;
14 11 use IvyForms\Repository\EntryField\EntryFieldRepositoryInterface;
15 12
@@ -54,16 +51,27 @@
54 51 * @param int $fieldId
55 52 * @param string $value
56 53 * @return bool
57 54 */
58 - public function checkDuplicateValue(int $formId, int $fieldId, string $value): bool
59 - {
60 - return $this->entryFieldRepository->checkDuplicateValue($formId, $fieldId, $value);
55 + public function checkDuplicateValue(
56 + int $formId,
57 + int $fieldId,
58 + string $value,
59 + ?int $excludeEntryId = null
60 + ): bool {
61 + return $this->entryFieldRepository->checkDuplicateValue(
62 + $formId,
63 + $fieldId,
64 + $value,
65 + $excludeEntryId
66 + );
61 67 }
62 68
63 69 /**
64 70 * Add entry fields to the repository.
65 71 *
72 + * Resolves all field values in PHP, then persists with a single multi-row INSERT.
73 + *
66 74 * @param array<int, object> $formFields
67 75 * @param int $entryId
68 76 * @param array<mixed> $submissionData
69 77 * @throws ValidationException
@@ -70,11 +78,30 @@
70 78 */
71 79 public function addEntryFields(array $formFields, int $entryId, array $submissionData): void
72 80 {
73 81 $parentChildrenMap = EntryHelper::buildParentChildrenMap($formFields);
74 - $parentSubfieldKeys = EntryHelper::buildParentSubfieldKeys($parentChildrenMap, $submissionData);
82 + $parentSubfieldKeys = EntryHelper::buildParentSubfieldKeys(
83 + $parentChildrenMap,
84 + $submissionData,
85 + $formFields
86 + );
75 87
88 + /** @var list<array{entryField: EntryField, field: object}> $created */
89 + $created = [];
90 +
76 91 foreach ($formFields as $field) {
92 + // Skip security/CAPTCHA fields - their tokens are only needed for verification, not storage
93 + $fieldType = $field->getType();
94 + if (FieldHelper::isSecurityField($fieldType)) {
95 + continue;
96 + }
97 +
98 + /** @var bool $shouldSkip */
99 + $shouldSkip = apply_filters('ivyforms/entry/field/should_skip', false, $field);
100 + if ($shouldSkip) {
101 + continue;
102 + }
103 +
77 104 $value = $this->valueManager->resolveFieldValue(
78 105 $field,
79 106 $submissionData,
80 107 $parentChildrenMap,
@@ -122,11 +149,25 @@
122 149 $field,
123 150 $submissionData
124 151 );
125 152
126 - $entryField = EntryFieldFactory::create($entryFieldData);
153 + $created[] = [
154 + 'entryField' => EntryFieldFactory::create($entryFieldData),
155 + 'field' => $field,
156 + ];
157 + }
127 158
128 - $this->entryFieldRepository->add($entryField);
159 + if ($created === []) {
160 + return;
161 + }
162 +
163 + $this->entryFieldRepository->batchInsert(
164 + array_column($created, 'entryField')
165 + );
166 +
167 + foreach ($created as $item) {
168 + $entryField = $item['entryField'];
169 + $field = $item['field'];
129 170
130 171 /**
131 172 * Action fired after an entry field has been saved to the database.
132 173 * Allows post-processing or logging of entry field creation.