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