PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.25
Booking for Appointments and Events Calendar – Amelia v1.2.25
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 4 years ago
CustomerRepository.php
349 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[] = "(SELECT COUNT(*) FROM {$bookingsTable} cb WHERE cb.status='no-show' AND cb.customerId=u.id)" . ($criteria['noShow'] === "3" ? '>=' : '=') . " :noShow";
218 }
219
220 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
221
222 try {
223 $statement = $this->connection->prepare(
224 "SELECT COUNT(*) as count
225 FROM {$this->table} as u
226 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
227 $where
228 "
229 );
230
231 $statement->execute($params);
232
233 $rows = $statement->fetch()['count'];
234 } catch (\Exception $e) {
235 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
236 }
237
238 return $rows;
239 }
240
241 /**
242 * @param string $phone
243 *
244 * @return array
245 * @throws QueryExecutionException
246 * @throws \Exception
247 */
248 public function getByPhoneNumber($phone)
249 {
250 try {
251 $params[':phone'] = '+' . $phone;
252
253 $statement = $this->connection->prepare(
254 "SELECT
255 u.id as id,
256 u.status as status,
257 u.firstName as firstName,
258 u.lastName as lastName,
259 u.email as email,
260 u.phone as phone,
261 u.countryPhoneIso AS countryPhoneIso,
262 u.gender as gender,
263 u.externalId as externalId,
264 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
265 u.note as note
266 FROM {$this->table} as u
267 WHERE u.type = 'customer' AND phone = :phone"
268 );
269
270 $statement->execute($params);
271
272 $rows = $statement->fetchAll();
273 } catch (\Exception $e) {
274 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
275 }
276
277 return $rows;
278 }
279
280 /**
281 * @param array $criteria
282 *
283 * @return Collection
284 * @throws QueryExecutionException
285 * @throws InvalidArgumentException
286 * @throws InvalidArgumentException
287 */
288 public function getByCriteria($criteria = [])
289 {
290 $params = [];
291
292 $where = [];
293
294 $fields = '
295 u.id AS id,
296 u.type AS type,
297 u.firstName AS firstName,
298 u.lastName AS lastName,
299 u.email AS email,
300 u.note AS note,
301 u.phone AS phone,
302 u.gender AS gender,
303 u.birthday AS birthday,
304 u.status AS status
305 ';
306
307 if (!empty($criteria['ids'])) {
308 $queryIds = [];
309
310 foreach ($criteria['ids'] as $index => $value) {
311 $param = ':id' . $index;
312
313 $queryIds[] = $param;
314
315 $params[$param] = $value;
316 }
317
318 $where[] = 'u.id IN (' . implode(', ', $queryIds) . ')';
319 }
320
321 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
322
323 try {
324 $statement = $this->connection->prepare(
325 "SELECT
326 {$fields}
327 FROM {$this->table} u
328 {$where}"
329 );
330
331 $statement->execute($params);
332
333 $rows = $statement->fetchAll();
334 } catch (\Exception $e) {
335 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
336 }
337
338 $items = new Collection();
339
340 foreach ($rows as $row) {
341 $row['type'] = 'customer';
342
343 $items->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
344 }
345
346 return $items;
347 }
348 }
349