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/Services/Entry/EntryService.php +26 -354 0.4 → 1.5.1 View file →
@@ -1,386 +1,58 @@
1 1 <?php
2 2
3 3 namespace IvyForms\Services\Entry;
4 4
5 -// phpcs:disable PSR1.Files.SideEffects
6 -if (!defined('ABSPATH')) {
7 - exit; // Exit if accessed directly
8 -}
5 +use IvyForms\Services\Entry\Managers\EntryManager;
6 +use IvyForms\Services\Entry\Managers\EntryFieldManager;
7 +use IvyForms\Services\Entry\Managers\EntryDeletionManager;
9 8
10 -use IvyForms\Common\Exceptions\NotFoundException;
11 -use IvyForms\Common\Exceptions\InvalidArgumentException;
12 -use IvyForms\Common\Exceptions\QueryExecutionException;
13 -use IvyForms\Common\Exceptions\ValidationException;
14 -use IvyForms\Entity\Entry\Entry;
15 -use IvyForms\Factory\EntryField\EntryFieldFactory;
16 -use IvyForms\Repository\Entry\EntryRepositoryInterface;
17 -use IvyForms\Repository\EntryField\EntryFieldRepositoryInterface;
18 -use IvyForms\Services\Translations\BackendStrings;
19 -
20 9 /**
21 - * @SuppressWarnings("TooManyPublicMethods")
10 + * Main entry service - provides access to entry managers.
11 + * Controllers access managers directly for operations.
22 12 */
23 13 class EntryService
24 14 {
25 - private EntryRepositoryInterface $entryRepository;
26 - private EntryFieldRepositoryInterface $entryFieldRepository;
15 + private EntryManager $entryManager;
16 + private EntryFieldManager $entryFieldManager;
17 + private EntryDeletionManager $deletionManager;
27 18
28 - // Constructor injection for the FormRepository via PHP-DI
29 19 public function __construct(
30 - EntryRepositoryInterface $entryRepository,
31 - EntryFieldRepositoryInterface $entryFieldRepository
20 + EntryManager $entryManager,
21 + EntryFieldManager $entryFieldManager,
22 + EntryDeletionManager $deletionManager
32 23 ) {
33 - $this->entryRepository = $entryRepository;
34 - $this->entryFieldRepository = $entryFieldRepository;
24 + $this->entryManager = $entryManager;
25 + $this->entryFieldManager = $entryFieldManager;
26 + $this->deletionManager = $deletionManager;
35 27 }
36 28
37 29 /**
38 - * Create a new entry and its entry fields.
30 + * Get the EntryManager for entry-related operations.
39 31 *
40 - * @param Entry $entryData
41 - *
42 - * @return int Entry ID
32 + * @return EntryManager
43 33 */
44 - public function createEntry(Entry $entryData): int
34 + public function getEntryManager(): EntryManager
45 35 {
46 - // Insert entry and get ID
47 - return $this->entryRepository->add($entryData);
36 + return $this->entryManager;
48 37 }
49 38
50 39 /**
51 - * Add entry fields to the repository.
40 + * Get the EntryFieldManager for entry field operations.
52 41 *
53 - * @param array<int, object> $formFields
54 - * @param int $entryId
55 - * @param array<mixed> $submissionData
56 - * @throws ValidationException
42 + * @return EntryFieldManager
57 43 */
58 - public function addEntryFields(array $formFields, int $entryId, array $submissionData): void
44 + public function getEntryFieldManager(): EntryFieldManager
59 45 {
60 - $parentChildrenMap = $this->buildParentChildrenMap($formFields);
61 - $parentSubfieldKeys = $this->buildParentSubfieldKeys($parentChildrenMap, $submissionData);
62 -
63 - foreach ($formFields as $field) {
64 - $value = $this->resolveFieldValue($field, $submissionData, $parentChildrenMap, $parentSubfieldKeys);
65 - $entryField = EntryFieldFactory::create([
66 - 'entryId' => $entryId,
67 - 'fieldId' => $field->getId(),
68 - 'fieldValue' => $value,
69 - ]);
70 - $this->entryFieldRepository->add($entryField);
71 - }
46 + return $this->entryFieldManager;
72 47 }
73 48
74 49 /**
75 - * Build parent-children map.
50 + * Get the EntryDeletionManager for deletion operations.
76 51 *
77 - * @param array<int, object> $formFields
78 - * @return array<int, array<int>>
52 + * @return EntryDeletionManager
79 53 */
80 - private function buildParentChildrenMap(array $formFields): array
54 + public function getDeletionManager(): EntryDeletionManager
81 55 {
82 - $parentChildrenMap = [];
83 - foreach ($formFields as $field) {
84 - $parentId = method_exists($field, 'getParentId') ? $field->getParentId() : null;
85 - if ($parentId && $parentId > 0) {
86 - $parentChildrenMap[$parentId][] = $field->getId();
87 - }
88 - }
89 - return $parentChildrenMap;
90 - }
91 -
92 - /**
93 - * Build subfield key map for each parent.
94 - *
95 - * @param array<int, array<int>> $parentChildrenMap
96 - * @param array<mixed> $submissionData
97 - * @return array<int, string|null>
98 - */
99 - private function buildParentSubfieldKeys(array $parentChildrenMap, array $submissionData): array
100 - {
101 - $parentSubfieldKeys = [];
102 - foreach ($parentChildrenMap as $parentId => $childIds) {
103 - $parentValue = $submissionData[$parentId] ?? [];
104 - $keys = array_keys($parentValue);
105 - foreach ($childIds as $i => $childId) {
106 - $parentSubfieldKeys[$childId] = $keys[$i] ?? null;
107 - }
108 - }
109 - return $parentSubfieldKeys;
110 - }
111 -
112 - /**
113 - * Resolve the value for a field based on its type and parent/child relationship.
114 - *
115 - * @param object $field
116 - * @param array<mixed> $submissionData
117 - * @param array<int, array<int>> $parentChildrenMap
118 - * @param array<int, string|null> $parentSubfieldKeys
119 - * @return mixed
120 - */
121 - private function resolveFieldValue(
122 - object $field,
123 - array $submissionData,
124 - array $parentChildrenMap,
125 - array $parentSubfieldKeys
126 - ) {
127 - $fieldId = $field->getId();
128 - $fieldType = $field->getType();
129 - $parentId = method_exists($field, 'getParentId') ? $field->getParentId() : null;
130 -
131 - $parentValue = $this->getParentSubfieldValue($fieldId, $parentId, $submissionData, $parentSubfieldKeys);
132 - if ($parentValue !== null) {
133 - return $parentValue;
134 - }
135 -
136 - if (in_array($fieldType, ['name', 'address'], true) && ($parentId === null || $parentId === 0)) {
137 - return $this->getCompoundFieldValue($fieldId, $parentChildrenMap, $parentSubfieldKeys, $submissionData);
138 - }
139 -
140 - return $this->getDefaultFieldValue($fieldId, $submissionData);
141 - }
142 -
143 - /**
144 - * @param int $fieldId
145 - * @param int|null $parentId
146 - * @param array<int|string, mixed> $submissionData
147 - * @param array<int, string|null> $parentSubfieldKeys
148 - * @return mixed|null
149 - */
150 - private function getParentSubfieldValue(
151 - int $fieldId,
152 - ?int $parentId,
153 - array $submissionData,
154 - array $parentSubfieldKeys
155 - ) {
156 - if ($parentId && isset($parentSubfieldKeys[$fieldId])) {
157 - $subKey = $parentSubfieldKeys[$fieldId];
158 - if (isset($submissionData[$parentId][$subKey])) {
159 - return $submissionData[$parentId][$subKey];
160 - }
161 - }
162 - return null;
163 - }
164 -
165 - /**
166 - * @param int $fieldId
167 - * @param array<int, array<int>> $parentChildrenMap
168 - * @param array<int, string|null> $parentSubfieldKeys
169 - * @param array<int|string, mixed> $submissionData
170 - * @return string
171 - */
172 - private function getCompoundFieldValue(
173 - int $fieldId,
174 - array $parentChildrenMap,
175 - array $parentSubfieldKeys,
176 - array $submissionData
177 - ): string {
178 - $childValues = [];
179 - if (!empty($parentChildrenMap[$fieldId])) {
180 - foreach ($parentChildrenMap[$fieldId] as $childId) {
181 - $subKey = $parentSubfieldKeys[$childId] ?? null;
182 - if ($subKey && isset($submissionData[$fieldId][$subKey])) {
183 - $val = $submissionData[$fieldId][$subKey];
184 - if ($val !== '') {
185 - $childValues[] = $val;
186 - }
187 - }
188 - }
189 - }
190 - return implode(' ', $childValues);
191 - }
192 -
193 - /**
194 - * @param int $fieldId
195 - * @param array<int|string, mixed> $submissionData
196 - * @return mixed|string
197 - */
198 - private function getDefaultFieldValue(int $fieldId, array $submissionData)
199 - {
200 - return $submissionData[$fieldId] ?? '';
201 - }
202 -
203 - /**
204 - * Get a specific entry by its ID.
205 - *
206 - * @param int $entryId
207 - *
208 - * @return object
209 - *
210 - * @throws NotFoundException If the entry is not found
211 - */
212 - public function getEntry(int $entryId): object
213 - {
214 - $entry = $this->entryRepository->getById($entryId);
215 -
216 - if (!$entry) {
217 - throw new NotFoundException(
218 - BackendStrings::getExceptionStrings()['entry_not_found']
219 - );
220 - }
221 -
222 - return $entry;
223 - }
224 -
225 - /**
226 - * Search for entries based on parameters.
227 - *
228 - * @param array<string, mixed> $params
229 - *
230 - * @return array<mixed>
231 - */
232 - public function searchEntries(array $params): array
233 - {
234 - return $this->entryRepository->search($params);
235 - }
236 -
237 - /**
238 - * Get the count of entry filters.
239 - *
240 - * @param array<string, mixed>|null $params
241 - *
242 - * @return array<mixed>
243 - */
244 - public function getFilterCount(?array $params = null): array
245 - {
246 - return $this->entryRepository->getFilterCount($params);
247 - }
248 -
249 - /**
250 - * Delete an entry by its ID.
251 - *
252 - * @param int $id
253 - *
254 - * @return int
255 - */
256 - public function deleteEntry(int $id): int
257 - {
258 - return $this->entryRepository->delete($id);
259 - }
260 -
261 - /**
262 - * Get all entry fields for a specific entry ID.
263 - *
264 - * @param int $entryId
265 - *
266 - * @return array<mixed>
267 - */
268 - public function getFieldsByEntryId(int $entryId): array
269 - {
270 - return $this->entryFieldRepository->findBy(['entryId' => $entryId]);
271 - }
272 -
273 - /**
274 - * Update the starred status of an entry.
275 - *
276 - * @param int $entryId
277 - * @param bool $value
278 - *
279 - * @return void
280 - */
281 - public function updateEntryStarred(int $entryId, bool $value): void
282 - {
283 - $this->entryRepository->updateEntryStarred($entryId, $value);
284 - }
285 -
286 - /**
287 - * Update the status of an entry.
288 - *
289 - * @param int $entryId
290 - * @param string $status
291 - *
292 - * @return void
293 - */
294 - public function updateEntryStatus(int $entryId, string $status): void
295 - {
296 - $this->entryRepository->updateEntryStatus($entryId, $status);
297 - }
298 -
299 - /**
300 - * Fetch entries along with their associated fields.
301 - *
302 - * @param array<int, array<string, mixed>> $entries
303 - * @return array<mixed>
304 - */
305 - public function getEntryFields(array $entries): array
306 - {
307 - return $this->entryRepository->getEntryFields($entries);
308 - }
309 -
310 - /**
311 - * Get the count of entries for multiple form IDs.
312 - *
313 - * @param int[] $formIds
314 - * @return array<int, int> formId => count
315 - */
316 - public function getEntryCountByFormIds(array $formIds): array
317 - {
318 - return $this->entryRepository->getEntryCountByFormIds($formIds);
319 - }
320 -
321 - /**
322 - * Delete all entry fields for multiple entry IDs in bulk.
323 - *
324 - * @param int[] $entryIds
325 - * @return int Number of deleted entry fields
326 - */
327 - public function deleteEntryFieldsByEntryIds(array $entryIds): int
328 - {
329 - if (empty($entryIds)) {
330 - return 0;
331 - }
332 - $allFields = $this->entryFieldRepository->findIdsByEntryIds($entryIds);
333 - if (empty($allFields)) {
334 - return 0;
335 - }
336 - return $this->entryFieldRepository->deleteMany($allFields);
337 - }
338 -
339 - /**
340 - * Delete multiple entries by their IDs in bulk.
341 - *
342 - * @param int[] $ids
343 - * @return int Number of deleted entries
344 - */
345 - public function deleteEntriesByIds(array $ids): int
346 - {
347 - if (empty($ids)) {
348 - return 0;
349 - }
350 - return $this->entryRepository->deleteMany($ids);
351 - }
352 -
353 - /**
354 - * Delete all entries for multiple form IDs in bulk.
355 - *
356 - * @param int[] $formIds
357 - * @return int Number of deleted entries
358 - * @throws InvalidArgumentException
359 - */
360 - public function deleteEntriesByFormIds(array $formIds): int
361 - {
362 - if (empty($formIds)) {
363 - throw new InvalidArgumentException(
364 - BackendStrings::getExceptionStrings()['no_form_ids_provided']
365 - );
366 - }
367 -
368 - // Delete entry fields by form IDs using a subquery
369 - $this->entryFieldRepository->deleteByFormIds($formIds);
370 - // Delete entries by formId
371 - return $this->entryRepository->deleteManyByForeignKeyValues($formIds);
372 - }
373 -
374 - /**
375 - * Check if a value already exists in entry fields for a specific field.
376 - *
377 - * @param int $formId
378 - * @param int $fieldId
379 - * @param string $value
380 - * @return bool
381 - */
382 - public function checkDuplicateValue(int $formId, int $fieldId, string $value): bool
383 - {
384 - return $this->entryFieldRepository->checkDuplicateValue($formId, $fieldId, $value);
56 + return $this->deletionManager;
385 57 }
386 58 }