PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.27
Booking for Appointments and Events Calendar – Amelia v1.2.27
2.4.9 2.4.8 2.4.7 2.4.6 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 1 year ago ProviderRepository.php 1 year ago UserRepository.php 1 year ago WPUserRepository.php 1 year ago
CustomerRepository.php
351 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 $items[(int)$row['id']] = $row;
165 }
166
167 return $items;
168 }
169
170 /**
171 * @param $criteria
172 *
173 * @return mixed
174 * @throws QueryExecutionException
175 */
176 public function getCount($criteria)
177 {
178 $wpUserTable = WPUsersTable::getTableName();
179
180 $params = [
181 ':type_customer' => AbstractUser::USER_ROLE_CUSTOMER,
182 ':type_admin' => AbstractUser::USER_ROLE_ADMIN,
183 ':statusVisible' => Status::VISIBLE,
184 ];
185
186 $where = [
187 'u.type IN (:type_customer, :type_admin)',
188 'u.status = :statusVisible'
189 ];
190
191 if (!empty($criteria['search'])) {
192 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] =
193 "%{$criteria['search']}%";
194
195 $where[] = "((CONCAT(u.firstName, ' ', u.lastName) LIKE :search1
196 OR wpu.display_name LIKE :search2
197 OR u.email LIKE :search3
198 OR u.note LIKE :search4))";
199 }
200
201 if (!empty($criteria['customers'])) {
202 $customersCriteria = [];
203
204 foreach ((array)$criteria['customers'] as $key => $customerId) {
205 $params[":customerId$key"] = $customerId;
206 $customersCriteria[] = ":customerId$key";
207 }
208
209 $where[] = 'u.id IN (' . implode(', ', $customersCriteria) . ')';
210 }
211
212 if (!empty($criteria['noShow'])) {
213 $bookingsTable = CustomerBookingsTable::getTableName();
214
215 $params[':noShow'] = $criteria['noShow'];
216
217 $where[] =
218 "(SELECT COUNT(*) FROM {$bookingsTable} cb WHERE cb.status='no-show' AND cb.customerId=u.id)" .
219 ($criteria['noShow'] === "3" ? '>=' : '=') . " :noShow";
220 }
221
222 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
223
224 try {
225 $statement = $this->connection->prepare(
226 "SELECT COUNT(*) as count
227 FROM {$this->table} as u
228 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
229 $where
230 "
231 );
232
233 $statement->execute($params);
234
235 $rows = $statement->fetch()['count'];
236 } catch (\Exception $e) {
237 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
238 }
239
240 return $rows;
241 }
242
243 /**
244 * @param string $phone
245 *
246 * @return array
247 * @throws QueryExecutionException
248 * @throws \Exception
249 */
250 public function getByPhoneNumber($phone)
251 {
252 try {
253 $params[':phone'] = '+' . $phone;
254
255 $statement = $this->connection->prepare(
256 "SELECT
257 u.id as id,
258 u.status as status,
259 u.firstName as firstName,
260 u.lastName as lastName,
261 u.email as email,
262 u.phone as phone,
263 u.countryPhoneIso AS countryPhoneIso,
264 u.gender as gender,
265 u.externalId as externalId,
266 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
267 u.note as note
268 FROM {$this->table} as u
269 WHERE u.type = 'customer' AND phone = :phone"
270 );
271
272 $statement->execute($params);
273
274 $rows = $statement->fetchAll();
275 } catch (\Exception $e) {
276 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
277 }
278
279 return $rows;
280 }
281
282 /**
283 * @param array $criteria
284 *
285 * @return Collection
286 * @throws QueryExecutionException
287 * @throws InvalidArgumentException
288 * @throws InvalidArgumentException
289 */
290 public function getByCriteria($criteria = [])
291 {
292 $params = [];
293
294 $where = [];
295
296 $fields = '
297 u.id AS id,
298 u.type AS type,
299 u.firstName AS firstName,
300 u.lastName AS lastName,
301 u.email AS email,
302 u.note AS note,
303 u.phone AS phone,
304 u.gender AS gender,
305 u.birthday AS birthday,
306 u.status AS status
307 ';
308
309 if (!empty($criteria['ids'])) {
310 $queryIds = [];
311
312 foreach ($criteria['ids'] as $index => $value) {
313 $param = ':id' . $index;
314
315 $queryIds[] = $param;
316
317 $params[$param] = $value;
318 }
319
320 $where[] = 'u.id IN (' . implode(', ', $queryIds) . ')';
321 }
322
323 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
324
325 try {
326 $statement = $this->connection->prepare(
327 "SELECT
328 {$fields}
329 FROM {$this->table} u
330 {$where}"
331 );
332
333 $statement->execute($params);
334
335 $rows = $statement->fetchAll();
336 } catch (\Exception $e) {
337 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
338 }
339
340 $items = new Collection();
341
342 foreach ($rows as $row) {
343 $row['type'] = 'customer';
344
345 $items->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
346 }
347
348 return $items;
349 }
350 }
351