PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.5
Booking for Appointments and Events Calendar – Amelia v1.2.5
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
343 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 ';
87
88 $statsJoins = '';
89
90 $having = '';
91
92 if ($joinWithBookings) {
93 $params[':bookingPendingStatus'] = BookingStatus::PENDING;
94
95 $statsFields = "
96 MAX(app.bookingStart) as lastAppointment,
97 COUNT(cb.id) as totalAppointments,
98 SUM(case when cb.status = :bookingPendingStatus then 1 else 0 end) as countPendingAppointments,
99 ";
100
101 $statsJoins = "
102 LEFT JOIN {$bookingsTable} cb ON u.id = cb.customerId
103 LEFT JOIN {$appointmentsTable} app ON app.id = cb.appointmentId
104 ";
105
106 if (!empty($criteria['noShow'])) {
107 $having = "HAVING (SUM(case when cb.status = 'no-show' then 1 else 0 end)) " . ($criteria['noShow'] === "3" ? '>=' : '=') . ":noShow";
108
109 $params[':noShow'] = $criteria['noShow'];
110 }
111 }
112
113 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
114
115 $limit = $this->getLimit(
116 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
117 (int)$itemsPerPage
118 );
119
120 $statement = $this->connection->prepare(
121 "SELECT
122 u.id as id,
123 u.status as status,
124 u.firstName as firstName,
125 u.lastName as lastName,
126 u.email as email,
127 u.phone as phone,
128 u.countryPhoneIso AS countryPhoneIso,
129 u.gender as gender,
130 u.externalId as externalId,
131 u.translations as translations,
132 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
133 u.note as note,
134 {$statsFields}
135 IF(wpu.display_name IS NOT NULL, wpu.display_name , '') as wpName
136 FROM {$this->table} as u
137 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
138 {$statsJoins}
139 {$where}
140 GROUP BY u.id
141 {$having}
142 {$order}
143 {$limit}"
144 );
145
146 $statement->execute($params);
147
148 $rows = $statement->fetchAll();
149 } catch (\Exception $e) {
150 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
151 }
152
153 $items = [];
154 foreach ($rows as $row) {
155 $row['id'] = (int)$row['id'];
156 $row['externalId'] = $row['externalId'] === null ? $row['externalId'] : (int)$row['externalId'];
157 $row['lastAppointment'] = $row['lastAppointment'] ?
158 DateTimeService::getCustomDateTimeFromUtc($row['lastAppointment']) : $row['lastAppointment'];
159 $items[(int)$row['id']] = $row;
160 }
161
162 return $items;
163 }
164
165 /**
166 * @param $criteria
167 *
168 * @return mixed
169 * @throws QueryExecutionException
170 */
171 public function getCount($criteria)
172 {
173 $wpUserTable = WPUsersTable::getTableName();
174
175 $params = [
176 ':type_customer' => AbstractUser::USER_ROLE_CUSTOMER,
177 ':type_admin' => AbstractUser::USER_ROLE_ADMIN,
178 ':statusVisible' => Status::VISIBLE,
179 ];
180
181 $where = [
182 'u.type IN (:type_customer, :type_admin)',
183 'u.status = :statusVisible'
184 ];
185
186 if (!empty($criteria['search'])) {
187 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] =
188 "%{$criteria['search']}%";
189
190 $where[] = "((CONCAT(u.firstName, ' ', u.lastName) LIKE :search1
191 OR wpu.display_name LIKE :search2
192 OR u.email LIKE :search3
193 OR u.note LIKE :search4))";
194 }
195
196 if (!empty($criteria['customers'])) {
197 $customersCriteria = [];
198
199 foreach ((array)$criteria['customers'] as $key => $customerId) {
200 $params[":customerId$key"] = $customerId;
201 $customersCriteria[] = ":customerId$key";
202 }
203
204 $where[] = 'u.id IN (' . implode(', ', $customersCriteria) . ')';
205 }
206
207 if (!empty($criteria['noShow'])) {
208 $bookingsTable = CustomerBookingsTable::getTableName();
209
210 $params[':noShow'] = $criteria['noShow'];
211
212 $where[] = "(SELECT COUNT(*) FROM {$bookingsTable} cb WHERE cb.status='no-show' AND cb.customerId=u.id)" . ($criteria['noShow'] === "3" ? '>=' : '=') . " :noShow";
213 }
214
215 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
216
217 try {
218 $statement = $this->connection->prepare(
219 "SELECT COUNT(*) as count
220 FROM {$this->table} as u
221 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
222 $where
223 "
224 );
225
226 $statement->execute($params);
227
228 $rows = $statement->fetch()['count'];
229 } catch (\Exception $e) {
230 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
231 }
232
233 return $rows;
234 }
235
236 /**
237 * @param string $phone
238 *
239 * @return array
240 * @throws QueryExecutionException
241 * @throws \Exception
242 */
243 public function getByPhoneNumber($phone)
244 {
245 try {
246 $params[':phone'] = '+' . $phone;
247
248 $statement = $this->connection->prepare(
249 "SELECT
250 u.id as id,
251 u.status as status,
252 u.firstName as firstName,
253 u.lastName as lastName,
254 u.email as email,
255 u.phone as phone,
256 u.countryPhoneIso AS countryPhoneIso,
257 u.gender as gender,
258 u.externalId as externalId,
259 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
260 u.note as note
261 FROM {$this->table} as u
262 WHERE u.type = 'customer' AND phone = :phone"
263 );
264
265 $statement->execute($params);
266
267 $rows = $statement->fetchAll();
268 } catch (\Exception $e) {
269 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
270 }
271
272 return $rows;
273 }
274
275 /**
276 * @param array $criteria
277 *
278 * @return Collection
279 * @throws QueryExecutionException
280 * @throws InvalidArgumentException
281 * @throws InvalidArgumentException
282 */
283 public function getByCriteria($criteria = [])
284 {
285 $params = [];
286
287 $where = [];
288
289 $fields = '
290 u.id AS id,
291 u.type AS type,
292 u.firstName AS firstName,
293 u.lastName AS lastName,
294 u.email AS email,
295 u.note AS note,
296 u.phone AS phone,
297 u.gender AS gender,
298 u.birthday AS birthday
299 ';
300
301 if (!empty($criteria['ids'])) {
302 $queryIds = [];
303
304 foreach ($criteria['ids'] as $index => $value) {
305 $param = ':id' . $index;
306
307 $queryIds[] = $param;
308
309 $params[$param] = $value;
310 }
311
312 $where[] = 'u.id IN (' . implode(', ', $queryIds) . ')';
313 }
314
315 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
316
317 try {
318 $statement = $this->connection->prepare(
319 "SELECT
320 {$fields}
321 FROM {$this->table} u
322 {$where}"
323 );
324
325 $statement->execute($params);
326
327 $rows = $statement->fetchAll();
328 } catch (\Exception $e) {
329 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
330 }
331
332 $items = new Collection();
333
334 foreach ($rows as $row) {
335 $row['type'] = 'customer';
336
337 $items->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
338 }
339
340 return $items;
341 }
342 }
343