PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.6
Booking for Appointments and Events Calendar – Amelia v2.4.6
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 / Application / Commands / User / Provider / UpdateProviderCommandHandler.php
ameliabooking / src / Application / Commands / User / Provider Last commit date
AddProviderCommand.php 1 year ago AddProviderCommandHandler.php 1 month ago GetProviderCommand.php 7 years ago GetProviderCommandHandler.php 3 months ago GetProvidersCommand.php 1 year ago GetProvidersCommandHandler.php 6 months ago UpdateProviderCommand.php 1 year ago UpdateProviderCommandHandler.php 1 week ago UpdateProviderStatusCommand.php 1 year ago UpdateProviderStatusCommandHandler.php 1 week ago
UpdateProviderCommandHandler.php
397 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands\User\Provider;
4
5 use AmeliaBooking\Application\Commands\CommandHandler;
6 use AmeliaBooking\Application\Commands\CommandResult;
7 use AmeliaBooking\Application\Common\Exceptions\AccessDeniedException;
8 use AmeliaBooking\Application\Services\Entity\EntityApplicationService;
9 use AmeliaBooking\Application\Services\User\ProviderApplicationService;
10 use AmeliaBooking\Application\Services\User\UserApplicationService;
11 use AmeliaBooking\Domain\Collection\Collection;
12 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
13 use AmeliaBooking\Domain\Entity\Entities;
14 use AmeliaBooking\Domain\Entity\User\AbstractUser;
15 use AmeliaBooking\Domain\Entity\User\Provider;
16 use AmeliaBooking\Domain\Factory\User\UserFactory;
17 use AmeliaBooking\Domain\Services\Settings\SettingsService;
18 use AmeliaBooking\Domain\ValueObjects\String\Password;
19 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
20 use AmeliaBooking\Infrastructure\Repository\User\ProviderRepository;
21 use AmeliaBooking\Infrastructure\Services\Apple\AbstractAppleCalendarService;
22 use Exception;
23 use AmeliaBooking\Domain\ValueObjects\String\Name;
24 use AmeliaBooking\Domain\ValueObjects\String\Phone;
25
26 /**
27 * Class UpdateProviderCommandHandler
28 *
29 * @package AmeliaBooking\Application\Commands\User\Provider
30 */
31 class UpdateProviderCommandHandler extends CommandHandler
32 {
33 /**
34 * @param UpdateProviderCommand $command
35 *
36 * @return CommandResult
37 * @throws AccessDeniedException
38 * @throws InvalidArgumentException
39 * @throws QueryExecutionException
40 * @throws Exception
41 */
42 public function handle(UpdateProviderCommand $command)
43 {
44 /** @var AbstractUser $currentUser */
45 $currentUser = $command->authorizeProviderWritePermission((int)$command->getArg('id'));
46
47 $result = new CommandResult();
48
49 $this->checkMandatoryFields($command);
50
51 /** @var ProviderRepository $providerRepository */
52 $providerRepository = $this->container->get('domain.users.providers.repository');
53
54 /** @var ProviderApplicationService $providerAS */
55 $providerAS = $this->container->get('application.user.provider.service');
56
57 /** @var SettingsService $settingsDS */
58 $settingsDS = $this->container->get('domain.settings.service');
59
60 $userId = (int)$command->getArg('id');
61
62 /** @var UserApplicationService $userAS */
63 $userAS = $this->getContainer()->get('application.user.service');
64
65 /** @var Provider $oldUser */
66 $oldUser = $providerAS->getProviderWithServicesAndSchedule($userId);
67
68 // If the current user is a provider and does not have write others permission, and the externalId is changed, throw an access denied exception
69 if (
70 $userAS->isProvider($currentUser) &&
71 !$command->getPermissionService()->currentUserCanWriteOthers(Entities::EMPLOYEES) &&
72 (int)$command->getField('externalId') &&
73 (!$oldUser->getExternalId() || $oldUser->getExternalId()->getValue() !== $command->getField('externalId'))
74 ) {
75 throw new AccessDeniedException('You are not allowed');
76 }
77
78 $command->setField('id', $userId);
79
80 $providerData = $command->getFields();
81
82 $providerData['type'] = Entities::PROVIDER;
83
84 if (!isset($providerData['stripeConnect'])) {
85 $providerData['stripeConnect'] = null;
86 }
87
88 if (!isset($providerData['zoomUserId'])) {
89 $providerData['zoomUserId'] = null;
90 }
91
92 if (!isset($providerData['appleCalendarId'])) {
93 $providerData['appleCalendarId'] = null;
94 }
95
96 if (!isset($providerData['employeeAppleCalendar'])) {
97 $providerData['employeeAppleCalendar'] = null;
98 } else {
99 /** @var AbstractAppleCalendarService $appleCalendarService */
100 $appleCalendarService = $this->container->get('infrastructure.apple.calendar.service');
101
102 $appleId = $providerData['employeeAppleCalendar']['iCloudId'];
103 $applePassword = $providerData['employeeAppleCalendar']['appSpecificPassword'];
104
105 $credentials = $appleCalendarService->handleAppleCredentials($appleId, $applePassword);
106
107 if (!$credentials) {
108 $providerData['employeeAppleCalendar'] = null;
109 }
110 }
111
112 /** @var EntityApplicationService $entityService */
113 $entityService = $this->container->get('application.entity.service');
114
115 $entityService->removeMissingEntitiesForProvider($providerData);
116
117 if (!!$oldUser->getBadgeId() && !isset($providerData['badgeId'])) {
118 $providerData['badgeId'] = null;
119 }
120
121 if ($oldUser->getTimeZone() && $settingsDS->isFeatureEnabled('timezones') === false) {
122 $providerData['timeZone'] = $oldUser->getTimeZone()->getValue();
123 }
124
125 $newUserData = array_merge($oldUser->toArray(), $providerData);
126
127 $newUserData = apply_filters('amelia_before_provider_updated_filter', $newUserData, $oldUser->toArray());
128
129 /** @var Provider $newUser */
130 $newUser = UserFactory::create($newUserData);
131
132 $oldExternalId = $oldUser->getExternalId() ? $oldUser->getExternalId()->getValue() : null;
133 $newExternalId = $newUser->getExternalId() ? $newUser->getExternalId()->getValue() : null;
134
135 if (
136 $oldExternalId !== $newExternalId &&
137 (
138 !$currentUser ||
139 !(
140 $currentUser->getType() === AbstractUser::USER_ROLE_ADMIN ||
141 $currentUser->getType() === AbstractUser::USER_ROLE_MANAGER
142 )
143 )
144 ) {
145 // Non-admin/manager cannot change externalId at all
146
147 $result->setResult(CommandResult::RESULT_ERROR);
148 $result->setMessage('Could not update user.');
149
150 return $result;
151 }
152
153 if (
154 $newExternalId &&
155 !$userAS->isRoleForExternalIdAllowed($newExternalId, Entities::PROVIDER)
156 ) {
157 // Linking to existing WP user must pass role check
158
159 $result->setResult(CommandResult::RESULT_ERROR);
160 $result->setMessage('Could not update user.');
161
162 return $result;
163 }
164
165 // If the phone is not set and the old phone is set, set the phone and country phone iso to null
166 if (empty($providerData['phone']) && $oldUser->getPhone() && $oldUser->getPhone()->getValue()) {
167 $newUser->setPhone(new Phone(null));
168 $newUser->setCountryPhoneIso(new Name(null));
169 }
170
171 $newUser->setDayOffList(
172 $providerAS->getModifiedDayList(
173 $newUser->getDayOffList(),
174 $oldUser->getDayOffList(),
175 !empty($newUserData['removedDayOffList'])
176 ? UserFactory::createDayOffList($newUserData['removedDayOffList'])
177 : new Collection()
178 )
179 );
180
181 $newUser->setSpecialDayList(
182 $providerAS->getModifiedDayList(
183 $newUser->getSpecialDayList(),
184 $oldUser->getSpecialDayList(),
185 !empty($newUserData['removedSpecialDayList'])
186 ? UserFactory::createSpecialDayList($newUserData['removedSpecialDayList'])
187 : new Collection()
188 )
189 );
190
191 if ($command->getUserApplicationService()->checkProviderPermissions($currentUser, $command->getToken())) {
192 $rolesSettings = $settingsDS->getCategorySettings('roles');
193
194 if (!$rolesSettings['allowConfigureServices']) {
195 $newUser->setServiceList($oldUser->getServiceList());
196 }
197
198 if (!$rolesSettings['allowConfigureSchedule']) {
199 $newUser->setWeekDayList($oldUser->getWeekDayList());
200 }
201
202 if (!$rolesSettings['allowConfigureDaysOff']) {
203 $newUser->setDayOffList($oldUser->getDayOffList());
204 }
205
206 if (!$rolesSettings['allowConfigureSpecialDays']) {
207 $newUser->setSpecialDayList($oldUser->getSpecialDayList());
208 }
209 }
210
211 $providerRepository->beginTransaction();
212
213 if (
214 $providerRepository->getByEmail($newUser->getEmail()->getValue()) &&
215 $oldUser->getEmail()->getValue() !== $newUser->getEmail()->getValue()
216 ) {
217 $result->setResult(CommandResult::RESULT_CONFLICT);
218 $result->setMessage('Email already exist.');
219 $result->setData('This email is already in use.');
220
221 return $result;
222 }
223
224 if ($command->getField('password')) {
225 $newPassword = new Password($command->getField('password'));
226
227 $providerRepository->updateFieldById($command->getArg('id'), $newPassword->getValue(), 'password');
228
229 $isAdmin = $currentUser && $currentUser->getType() === AbstractUser::USER_ROLE_ADMIN;
230 // $currentUser is null in token-only cabinet sessions (get_current_user_id() returns 0).
231 // Fall back to $oldUser which was resolved from the cabinet token and always matches $userId.
232 $callerId = $currentUser && $currentUser->getId() ? $currentUser->getId()->getValue() : null;
233 $isOwnProfile = $callerId === $userId || ($callerId === null && $oldUser->getId()->getValue() === $userId);
234
235 // Propagate to the linked WP user only when the caller is an admin or the provider
236 // updating their own profile. Blocks a Manager from resetting another provider's WP password.
237 if (
238 $newUser->getExternalId() &&
239 $newUser->getExternalId()->getValue() &&
240 ($isAdmin || $isOwnProfile)
241 ) {
242 add_filter('amelia_user_profile_updated', '__return_true');
243 wp_set_password($command->getField('password'), $newUser->getExternalId()->getValue());
244 remove_filter('amelia_user_profile_updated', '__return_true');
245 }
246 }
247
248 do_action('amelia_before_provider_updated', $newUser ? $newUser->toArray() : null, $oldUser ? $oldUser->toArray() : null);
249
250 try {
251 if (!$providerAS->update($oldUser, $newUser, $providerData)) {
252 $providerRepository->rollback();
253 return $result;
254 }
255
256 if (isset($providerData['googleCalendar']['blockedCalendars'])) {
257 $providerAS->updateProviderGoogleCalendarBlockedCalendars(
258 $userId,
259 $providerData['googleCalendar']['blockedCalendars']
260 );
261 }
262
263 $providerData = $this->getGoogleCalendarProviderData($providerData, $providerAS, $userId);
264
265 if (isset($providerData['outlookCalendar']['blockedCalendars'])) {
266 $providerAS->updateProviderOutlookCalendarBlockedCalendars(
267 $userId,
268 $providerData['outlookCalendar']['blockedCalendars']
269 );
270 }
271
272 $providerData = $this->getOutlookCalendarProviderData($providerData, $providerAS, $userId);
273
274 if ($command->getField('externalId') === 0) {
275 /** @var UserApplicationService $userAS */
276 $userAS = $this->getContainer()->get('application.user.service');
277
278 $userAS->setWpUserIdForNewUser($userId, $newUser, Entities::PROVIDER, $command->getField('password'));
279 } elseif ($newUser->getExternalId() && $newUser->getExternalId()->getValue()) {
280 add_filter('amelia_user_profile_updated', '__return_true');
281 wp_update_user(
282 [
283 'ID' => $newUser->getExternalId()->getValue(),
284 'first_name' => $newUser->getFirstName() ? $newUser->getFirstName()->getValue() : '',
285 'last_name' => $newUser->getLastName() ? $newUser->getLastName()->getValue() : '',
286 'user_email' => $newUser->getEmail() ? $newUser->getEmail()->getValue() : ''
287 ]
288 );
289
290 if ($uid = get_current_user_id()) {
291 clean_user_cache($uid);
292 }
293
294 remove_filter('amelia_user_profile_updated', '__return_true');
295 }
296 } catch (QueryExecutionException $e) {
297 $providerRepository->rollback();
298 throw $e;
299 }
300
301 $result = $userAS->getAuthenticatedUserResponse(
302 $newUser,
303 $oldUser->getEmail()->getValue() !== $newUser->getEmail()->getValue(),
304 true,
305 $oldUser->getLoginType(),
306 'provider'
307 );
308
309 $result->setData(
310 array_merge(
311 $result->getData(),
312 [
313 'sendEmployeePanelAccessEmail' =>
314 $command->getField('password') && $command->getField('sendEmployeePanelAccessEmail'),
315 'password' => $command->getField('password')
316 ]
317 )
318 );
319
320 $providerRepository->commit();
321
322 do_action('amelia_after_provider_updated', $newUser ? $newUser->toArray() : null, $oldUser ? $oldUser->toArray() : null);
323
324 return $result;
325 }
326
327 /**
328 * @param array $providerData
329 * @param ProviderApplicationService $providerAS
330 * @param $userId
331 * @return array
332 * @throws QueryExecutionException
333 */
334 public function getGoogleCalendarProviderData(array $providerData, ProviderApplicationService $providerAS, $userId): array
335 {
336 if (isset($providerData['googleCalendar'])) {
337 $googleCalendarSettings = [];
338
339 if (isset($providerData['googleCalendar']['insertPendingAppointments'])) {
340 $googleCalendarSettings['insertPendingAppointments'] = $providerData['googleCalendar']['insertPendingAppointments'];
341 }
342
343 if (isset($providerData['googleCalendar']['includeBufferTime'])) {
344 $googleCalendarSettings['includeBufferTime'] = $providerData['googleCalendar']['includeBufferTime'];
345 }
346
347 if (isset($providerData['googleCalendar']['title'])) {
348 $googleCalendarSettings['title'] = $providerData['googleCalendar']['title'];
349 }
350
351 if (isset($providerData['googleCalendar']['description'])) {
352 $googleCalendarSettings['description'] = $providerData['googleCalendar']['description'];
353 }
354
355 if (!empty($googleCalendarSettings)) {
356 $providerAS->updateProviderGoogleCalendarAccountSettings($userId, $googleCalendarSettings);
357 }
358 }
359 return $providerData;
360 }
361
362 /**
363 * @param array $providerData
364 * @param ProviderApplicationService $providerAS
365 * @param $userId
366 * @return array
367 * @throws QueryExecutionException
368 */
369 public function getOutlookCalendarProviderData(array $providerData, ProviderApplicationService $providerAS, $userId): array
370 {
371 if (isset($providerData['outlookCalendar'])) {
372 $outlookCalendarSettings = [];
373
374 if (isset($providerData['outlookCalendar']['insertPendingAppointments'])) {
375 $outlookCalendarSettings['insertPendingAppointments'] = $providerData['outlookCalendar']['insertPendingAppointments'];
376 }
377
378 if (isset($providerData['outlookCalendar']['includeBufferTime'])) {
379 $outlookCalendarSettings['includeBufferTime'] = $providerData['outlookCalendar']['includeBufferTime'];
380 }
381
382 if (isset($providerData['outlookCalendar']['title'])) {
383 $outlookCalendarSettings['title'] = $providerData['outlookCalendar']['title'];
384 }
385
386 if (isset($providerData['outlookCalendar']['description'])) {
387 $outlookCalendarSettings['description'] = $providerData['outlookCalendar']['description'];
388 }
389
390 if (!empty($outlookCalendarSettings)) {
391 $providerAS->updateProviderOutlookCalendarAccountSettings($userId, $outlookCalendarSettings);
392 }
393 }
394 return $providerData;
395 }
396 }
397