PluginProbe
The Innovative Form Builder – IvyForms / 1.1.1
The Innovative Form Builder – IvyForms v1.1.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
ivyforms / backend / src / Repository / EntryField / EntryFieldRepository.php

EntryFieldRepository.php in The Innovative Form Builder – IvyForms 1.1.1, at backend/src/Repository/EntryField/EntryFieldRepository.php

234 lines 6.8 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\Repository\EntryField;
9
10 use Exception;
11 use IvyForms\Common\Exceptions\InvalidArgumentException;
12 use IvyForms\Common\Exceptions\QueryExecutionException;
13 use IvyForms\Factory\EntryField\EntryFieldFactory;
14 use IvyForms\Repository\AbstractRepository;
15 use IvyForms\Services\InstallActions\DB\Entry\EntriesTable;
16 use IvyForms\Services\InstallActions\DB\EntryField\EntryFieldsTable as EntryFieldsTable;
17 use IvyForms\Services\InstallActions\DB\Field\FieldsTable;
18 use IvyForms\Services\Translations\BackendStrings;
19
20 class EntryFieldRepository extends AbstractRepository implements EntryFieldRepositoryInterface
21 {
22 public const FACTORY = EntryFieldFactory::class;
23
24 /**
25 * Check if an entry field exists in the database.
26 *
27 * @param int $entryFieldId
28 * @return bool
29 * @throws QueryExecutionException
30 */
31 public function exists(int $entryFieldId): bool
32 {
33 $query = $this->wpdb->prepare(
34 "SELECT COUNT(*) FROM {$this->table} WHERE id = %d",
35 $entryFieldId
36 );
37 $count = $this->wpdb->get_var($query);
38 if ($count === false) {
39 throw new QueryExecutionException(
40 BackendStrings::getExceptionStrings()['unable_find_by_id'] . __CLASS__
41 );
42 }
43 return (int)$count > 0;
44 }
45
46 /**
47 * @throws Exception
48 */
49 public function add(object $entity): int
50 {
51 $data = $entity->toArray();
52
53 $result = $this->wpdb->insert(
54 $this->table,
55 [
56 'id' => $data['id'] ?? null,
57 'entryId' => $data['entryId'],
58 'fieldId' => $data['fieldId'],
59 'fieldValue' => $data['fieldValue'],
60 ],
61 [
62 '%d',
63 '%d',
64 '%d',
65 '%s',
66 ],
67 );
68
69 if ($result === false) {
70 throw new QueryExecutionException(
71 BackendStrings::getExceptionStrings()['unable_to_add_data'] . __CLASS__
72 );
73 }
74
75 return $this->wpdb->insert_id;
76 }
77
78 /**
79 * @throws Exception
80 */
81 public function update(int $id, object $entity): bool
82 {
83 $data = $entity->toArray();
84
85 $result = $this->wpdb->update(
86 $this->table,
87 [
88 'fieldId' => $data['fieldId'],
89 'fieldValue' => $data['fieldValue'],
90 ],
91 ['id' => $id],
92 [
93 '%d',
94 '%s',
95 ],
96 ['%d']
97 );
98
99 if ($result === false) {
100 throw new QueryExecutionException(
101 BackendStrings::getExceptionStrings()['unable_update_data'] . __CLASS__
102 );
103 }
104
105 return (bool) $result;
106 }
107
108 /**
109 * Find an entry field by its ID.
110 *
111 * @param array<mixed> $array
112 * @return array<mixed>
113 * @throws QueryExecutionException
114 */
115 public function findBy(array $array): array
116 {
117 $sql = $this->selectQuery() . " {$this->table}";
118 $where = [];
119 $values = [];
120
121 foreach ($array as $field => $value) {
122 $where[] = "{$field} = %s";
123 $values[] = $value;
124 }
125
126 if ($where) {
127 $sql .= ' WHERE ' . implode(' AND ', $where);
128 }
129
130 $query = $this->wpdb->prepare($sql, ...$values);
131 $rows = $this->wpdb->get_results($query, ARRAY_A);
132 if ($rows === false) {
133 throw new QueryExecutionException(
134 BackendStrings::getExceptionStrings()['unable_find_by_id'] . __CLASS__
135 );
136 }
137 $results = [];
138 foreach ($rows as $row) {
139 $results[] = call_user_func([static::FACTORY, 'create'], $row);
140 }
141
142 return $results;
143 }
144
145 /**
146 * Get all entry field IDs for the given entry IDs in a single query.
147 *
148 * @param int[] $entryIds
149 * @return int[]
150 * @throws QueryExecutionException
151 */
152 public function findIdsByEntryIds(array $entryIds): array
153 {
154 if (empty($entryIds)) {
155 return [];
156 }
157 $placeholders = implode(',', array_fill(0, count($entryIds), '%d'));
158 $query = "SELECT id FROM {$this->table} WHERE entryId IN ($placeholders)";
159 $results = $this->wpdb->get_results($this->wpdb->prepare($query, ...$entryIds), ARRAY_A);
160 if ($results === false) {
161 throw new QueryExecutionException(
162 BackendStrings::getExceptionStrings()['unable_find_by_id'] . __CLASS__
163 );
164 }
165 return array_map(fn($row) => (int)$row['id'], $results);
166 }
167
168 /**
169 * Delete entry fields by form IDs using a subquery for fieldId.
170 *
171 * @param int[] $formIds
172 * @return int Number of deleted entry_fields
173 * @throws QueryExecutionException
174 * @throws InvalidArgumentException
175 */
176 public function deleteByFormIds(array $formIds): int
177 {
178 if (empty($formIds)) {
179 return 0;
180 }
181 $formIds = array_map('intval', $formIds);
182 $placeholders = implode(',', array_fill(0, count($formIds), '%d'));
183 $fieldsTable = FieldsTable::getTableName();
184 $query = "DELETE FROM {$this->table} WHERE fieldId IN
185 (SELECT id FROM {$fieldsTable} WHERE formId IN ($placeholders))";
186 $result = $this->wpdb->query($this->wpdb->prepare($query, ...$formIds));
187 if ($result === false) {
188 throw new QueryExecutionException(
189 BackendStrings::getExceptionStrings()['failed_delete_by_foreign_keys']
190 );
191 }
192 return $result;
193 }
194
195 /**
196 * Check if a field value already exists in the database
197 *
198 * @param int $formId
199 * @param int $fieldId
200 * @param string $value
201 * @return bool
202 * @throws QueryExecutionException
203 */
204 public function checkDuplicateValue(int $formId, int $fieldId, string $value): bool
205 {
206 global $wpdb;
207
208 $entriesTable = EntriesTable::getTableName();
209
210 $sql = "SELECT 1
211 FROM {$entriesTable} e
212 INNER JOIN {$this->table} ef ON e.id = ef.entryId
213 WHERE e.formId = %d
214 AND ef.fieldId = %d
215 AND ef.fieldValue = %s
216 LIMIT 1";
217
218 $params = [$formId, $fieldId, $value];
219
220 $exists = $wpdb->get_var($wpdb->prepare($sql, $params));
221
222 if ($exists === false) {
223 throw new QueryExecutionException(
224 sprintf(
225 BackendStrings::getExceptionStrings()['failed_check_duplicates'],
226 $wpdb->last_error ?: BackendStrings::getExceptionStrings()['unknown_error']
227 )
228 );
229 }
230
231 return !empty($exists);
232 }
233 }
234