PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.32
Booking for Appointments and Events Calendar – Amelia v1.2.32
2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Infrastructure / Repository / User / CustomerRepository.php
ameliabooking / src / Infrastructure / Repository / User Last commit date
CustomerRepository.php 10 months ago ProviderRepository.php 10 months ago UserRepository.php 1 year ago WPUserRepository.php 1 year ago
CustomerRepository.php
357 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\User;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\User\AbstractUser;
8 use AmeliaBooking\Domain\Repository\User\CustomerRepositoryInterface;
9 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
10 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
11 use AmeliaBooking\Domain\ValueObjects\String\Status;
12 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
13 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\AppointmentsTable;
14 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable;
15 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\WPUsersTable;
16
17 /**
18 * Class UserRepository
19 *
20 * @package AmeliaBooking\Infrastructure\Repository
21 */
22 class CustomerRepository extends UserRepository implements CustomerRepositoryInterface
23 {
24 /**
25 * @param $criteria
26 * @param int $itemsPerPage
27 *
28 * @return array
29 * @throws QueryExecutionException
30 * @throws \Exception
31 */
32 public function getFiltered($criteria, $itemsPerPage = null)
33 {
34 try {
35 $wpUserTable = WPUsersTable::getTableName();
36 $bookingsTable = CustomerBookingsTable::getTableName();
37 $appointmentsTable = AppointmentsTable::getTableName();
38
39 $params = [
40 ':type_customer' => AbstractUser::USER_ROLE_CUSTOMER,
41 ':type_admin' => AbstractUser::USER_ROLE_ADMIN,
42 ];
43
44 $joinWithBookings = empty($criteria['ignoredBookings']);
45
46 $where = [
47 'u.type IN (:type_customer, :type_admin)',
48 ];
49
50 $order = '';
51 if (!empty($criteria['sort'])) {
52 $column = $criteria['sort'][0] === '-' ? substr($criteria['sort'], 1) : $criteria['sort'];
53 $orderColumn = $column === 'customer' ? 'CONCAT(u.firstName, " ", u.lastName)' : 'lastAppointment';
54 $orderDirection = $criteria['sort'][0] === '-' ? 'DESC' : 'ASC';
55 $order = "ORDER BY {$orderColumn} {$orderDirection}";
56
57 $joinWithBookings = $column !== 'customer' || $joinWithBookings;
58 }
59
60 if (!empty($criteria['search'])) {
61 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] = $params[':search5'] =
62 "%{$criteria['search']}%";
63
64 $where[] = "((CONCAT(u.firstName, ' ', u.lastName) LIKE :search1
65 OR wpu.display_name LIKE :search2
66 OR u.email LIKE :search3
67 OR u.phone LIKE :search4
68 OR u.note LIKE :search5))";
69 }
70
71 if (!empty($criteria['customers'])) {
72 $customersCriteria = [];
73
74 foreach ((array)$criteria['customers'] as $key => $customerId) {
75 $params[":customerId$key"] = $customerId;
76 $customersCriteria[] = ":customerId$key";
77 }
78
79 $where[] = 'u.id IN (' . implode(', ', $customersCriteria) . ')';
80 }
81
82 $statsFields = '
83 NULL as lastAppointment,
84 0 as totalAppointments,
85 0 as countPendingAppointments,
86 0 as countAppointmentBookings,
87 0 as countEventBookings,
88 ';
89
90 $statsJoins = '';
91
92 $having = '';
93
94 if ($joinWithBookings) {
95 $params[':bookingPendingStatus'] = BookingStatus::PENDING;
96
97 $statsFields = "
98 MAX(app.bookingStart) as lastAppointment,
99 COUNT(cb.id) as totalAppointments,
100 SUM(case when cb.status = :bookingPendingStatus then 1 else 0 end) as countPendingAppointments,
101 COUNT(DISTINCT CASE WHEN cb.appointmentId IS NOT NULL THEN cb.id ELSE NULL END) as countAppointmentBookings,
102 COUNT(DISTINCT CASE WHEN cb.appointmentId IS NULL THEN cb.id ELSE NULL END) as countEventBookings,
103 ";
104
105 $statsJoins = "
106 LEFT JOIN {$bookingsTable} cb ON u.id = cb.customerId
107 LEFT JOIN {$appointmentsTable} app ON app.id = cb.appointmentId
108 ";
109
110 if (!empty($criteria['noShow'])) {
111 $having = "HAVING (SUM(case when cb.status = 'no-show' then 1 else 0 end)) " . ($criteria['noShow'] === "3" ? '>=' : '=') . ":noShow";
112
113 $params[':noShow'] = $criteria['noShow'];
114 }
115 }
116
117 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
118
119 $limit = $this->getLimit(
120 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
121 (int)$itemsPerPage
122 );
123
124 $statement = $this->connection->prepare(
125 "SELECT
126 u.id as id,
127 u.status as status,
128 u.firstName as firstName,
129 u.lastName as lastName,
130 u.email as email,
131 u.phone as phone,
132 u.countryPhoneIso AS countryPhoneIso,
133 u.gender as gender,
134 u.externalId as externalId,
135 u.translations as translations,
136 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
137 u.note as note,
138 u.customFields as customFields,
139 {$statsFields}
140 IF(wpu.display_name IS NOT NULL, wpu.display_name , '') as wpName
141 FROM {$this->table} as u
142 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
143 {$statsJoins}
144 {$where}
145 GROUP BY u.id
146 {$having}
147 {$order}
148 {$limit}"
149 );
150
151 $statement->execute($params);
152
153 $rows = $statement->fetchAll();
154 } catch (\Exception $e) {
155 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
156 }
157
158 $items = [];
159 foreach ($rows as $row) {
160 $row['id'] = (int)$row['id'];
161 $row['externalId'] = $row['externalId'] === null ? $row['externalId'] : (int)$row['externalId'];
162 $row['lastAppointment'] = $row['lastAppointment'] ?
163 DateTimeService::getCustomDateTimeFromUtc($row['lastAppointment']) : $row['lastAppointment'];
164
165 // Fix for customFields being encoded multiple times
166 if ($row['customFields'] && !is_array(json_decode($row['customFields'], true))) {
167 $row['customFields'] = null;
168 }
169
170 $items[(int)$row['id']] = $row;
171 }
172
173 return $items;
174 }
175
176 /**
177 * @param $criteria
178 *
179 * @return mixed
180 * @throws QueryExecutionException
181 */
182 public function getCount($criteria)
183 {
184 $wpUserTable = WPUsersTable::getTableName();
185
186 $params = [
187 ':type_customer' => AbstractUser::USER_ROLE_CUSTOMER,
188 ':type_admin' => AbstractUser::USER_ROLE_ADMIN,
189 ':statusVisible' => Status::VISIBLE,
190 ];
191
192 $where = [
193 'u.type IN (:type_customer, :type_admin)',
194 'u.status = :statusVisible'
195 ];
196
197 if (!empty($criteria['search'])) {
198 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] =
199 "%{$criteria['search']}%";
200
201 $where[] = "((CONCAT(u.firstName, ' ', u.lastName) LIKE :search1
202 OR wpu.display_name LIKE :search2
203 OR u.email LIKE :search3
204 OR u.note LIKE :search4))";
205 }
206
207 if (!empty($criteria['customers'])) {
208 $customersCriteria = [];
209
210 foreach ((array)$criteria['customers'] as $key => $customerId) {
211 $params[":customerId$key"] = $customerId;
212 $customersCriteria[] = ":customerId$key";
213 }
214
215 $where[] = 'u.id IN (' . implode(', ', $customersCriteria) . ')';
216 }
217
218 if (!empty($criteria['noShow'])) {
219 $bookingsTable = CustomerBookingsTable::getTableName();
220
221 $params[':noShow'] = $criteria['noShow'];
222
223 $where[] =
224 "(SELECT COUNT(*) FROM {$bookingsTable} cb WHERE cb.status='no-show' AND cb.customerId=u.id)" .
225 ($criteria['noShow'] === "3" ? '>=' : '=') . " :noShow";
226 }
227
228 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
229
230 try {
231 $statement = $this->connection->prepare(
232 "SELECT COUNT(*) as count
233 FROM {$this->table} as u
234 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
235 $where
236 "
237 );
238
239 $statement->execute($params);
240
241 $rows = $statement->fetch()['count'];
242 } catch (\Exception $e) {
243 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
244 }
245
246 return $rows;
247 }
248
249 /**
250 * @param string $phone
251 *
252 * @return array
253 * @throws QueryExecutionException
254 * @throws \Exception
255 */
256 public function getByPhoneNumber($phone)
257 {
258 try {
259 $params[':phone'] = '+' . $phone;
260
261 $statement = $this->connection->prepare(
262 "SELECT
263 u.id as id,
264 u.status as status,
265 u.firstName as firstName,
266 u.lastName as lastName,
267 u.email as email,
268 u.phone as phone,
269 u.countryPhoneIso AS countryPhoneIso,
270 u.gender as gender,
271 u.externalId as externalId,
272 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
273 u.note as note
274 FROM {$this->table} as u
275 WHERE u.type = 'customer' AND phone = :phone"
276 );
277
278 $statement->execute($params);
279
280 $rows = $statement->fetchAll();
281 } catch (\Exception $e) {
282 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
283 }
284
285 return $rows;
286 }
287
288 /**
289 * @param array $criteria
290 *
291 * @return Collection
292 * @throws QueryExecutionException
293 * @throws InvalidArgumentException
294 * @throws InvalidArgumentException
295 */
296 public function getByCriteria($criteria = [])
297 {
298 $params = [];
299
300 $where = [];
301
302 $fields = '
303 u.id AS id,
304 u.type AS type,
305 u.firstName AS firstName,
306 u.lastName AS lastName,
307 u.email AS email,
308 u.note AS note,
309 u.phone AS phone,
310 u.gender AS gender,
311 u.birthday AS birthday,
312 u.status AS status
313 ';
314
315 if (!empty($criteria['ids'])) {
316 $queryIds = [];
317
318 foreach ($criteria['ids'] as $index => $value) {
319 $param = ':id' . $index;
320
321 $queryIds[] = $param;
322
323 $params[$param] = $value;
324 }
325
326 $where[] = 'u.id IN (' . implode(', ', $queryIds) . ')';
327 }
328
329 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
330
331 try {
332 $statement = $this->connection->prepare(
333 "SELECT
334 {$fields}
335 FROM {$this->table} u
336 {$where}"
337 );
338
339 $statement->execute($params);
340
341 $rows = $statement->fetchAll();
342 } catch (\Exception $e) {
343 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
344 }
345
346 $items = new Collection();
347
348 foreach ($rows as $row) {
349 $row['type'] = 'customer';
350
351 $items->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
352 }
353
354 return $items;
355 }
356 }
357