PluginProbe
The Innovative Form Builder – IvyForms / 0.8
The Innovative Form Builder – IvyForms v0.8
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 1.2 1.3
ivyforms / backend / src / Repository / EntryField / EntryFieldRepository.php

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

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