PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
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 3 days ago GetProviderCommand.php 7 years ago GetProviderCommandHandler.php 2 months ago GetProvidersCommand.php 1 year ago GetProvidersCommandHandler.php 4 months ago UpdateProviderCommand.php 1 year ago UpdateProviderCommandHandler.php 3 days ago UpdateProviderStatusCommand.php 1 year ago UpdateProviderStatusCommandHandler.php 6 months ago
UpdateProviderCommandHandler.php
394 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 if (!isset($providerData['stripeConnect'])) {
106 $providerData['stripeConnect'] = null;
107 }
108
109 if (!isset($providerData['zoomUserId'])) {
110 $providerData['zoomUserId'] = null;
111 }
112
113 if (!isset($providerData['appleCalendarId'])) {
114 $providerData['appleCalendarId'] = null;
115 }
116
117 if (!isset($providerData['employeeAppleCalendar'])) {
118 $providerData['employeeAppleCalendar'] = null;
119 } else {
120 /** @var AbstractAppleCalendarService $appleCalendarService */
121 $appleCalendarService = $this->container->get('infrastructure.apple.calendar.service');
122
123 $appleId = $providerData['employeeAppleCalendar']['iCloudId'];
124 $applePassword = $providerData['employeeAppleCalendar']['appSpecificPassword'];
125
126 $credentials = $appleCalendarService->handleAppleCredentials($appleId, $applePassword);
127
128 if (!$credentials) {
129 $providerData['employeeAppleCalendar'] = null;
130 }
131 }
132
133 /** @var EntityApplicationService $entityService */
134 $entityService = $this->container->get('application.entity.service');
135
136 $entityService->removeMissingEntitiesForProvider($providerData);
137
138 if (!!$oldUser->getBadgeId() && !isset($providerData['badgeId'])) {
139 $providerData['badgeId'] = null;
140 }
141
142 if ($oldUser->getTimeZone() && $settingsDS->isFeatureEnabled('timezones') === false) {
143 $providerData['timeZone'] = $oldUser->getTimeZone()->getValue();
144 }
145
146 $newUserData = array_merge($oldUser->toArray(), $providerData);
147
148 $newUserData = apply_filters('amelia_before_provider_updated_filter', $newUserData, $oldUser->toArray());
149
150 /** @var Provider $newUser */
151 $newUser = UserFactory::create($newUserData);
152
153 $oldExternalId = $oldUser->getExternalId() ? $oldUser->getExternalId()->getValue() : null;
154 $newExternalId = $newUser->getExternalId() ? $newUser->getExternalId()->getValue() : null;
155
156 if ($oldExternalId !== $newExternalId && (!$currentUser || $currentUser->getType() !== AbstractUser::USER_ROLE_ADMIN)) {
157 $result->setResult(CommandResult::RESULT_ERROR);
158 $result->setMessage('Could not update user.');
159 return $result;
160 }
161
162 // If the phone is not set and the old phone is set, set the phone and country phone iso to null
163 if (empty($providerData['phone']) && $oldUser->getPhone() && $oldUser->getPhone()->getValue()) {
164 $newUser->setPhone(new Phone(null));
165 $newUser->setCountryPhoneIso(new Name(null));
166 }
167
168 $newUser->setDayOffList(
169 $providerAS->getModifiedDayList(
170 $newUser->getDayOffList(),
171 $oldUser->getDayOffList(),
172 !empty($newUserData['removedDayOffList'])
173 ? UserFactory::createDayOffList($newUserData['removedDayOffList'])
174 : new Collection()
175 )
176 );
177
178 $newUser->setSpecialDayList(
179 $providerAS->getModifiedDayList(
180 $newUser->getSpecialDayList(),
181 $oldUser->getSpecialDayList(),
182 !empty($newUserData['removedSpecialDayList'])
183 ? UserFactory::createSpecialDayList($newUserData['removedSpecialDayList'])
184 : new Collection()
185 )
186 );
187
188 if ($command->getUserApplicationService()->checkProviderPermissions($currentUser, $command->getToken())) {
189 $rolesSettings = $settingsDS->getCategorySettings('roles');
190
191 if (!$rolesSettings['allowConfigureServices']) {
192 $newUser->setServiceList($oldUser->getServiceList());
193 }
194
195 if (!$rolesSettings['allowConfigureSchedule']) {
196 $newUser->setWeekDayList($oldUser->getWeekDayList());
197 }
198
199 if (!$rolesSettings['allowConfigureDaysOff']) {
200 $newUser->setDayOffList($oldUser->getDayOffList());
201 }
202
203 if (!$rolesSettings['allowConfigureSpecialDays']) {
204 $newUser->setSpecialDayList($oldUser->getSpecialDayList());
205 }
206 }
207
208 $providerRepository->beginTransaction();
209
210 if (
211 $providerRepository->getByEmail($newUser->getEmail()->getValue()) &&
212 $oldUser->getEmail()->getValue() !== $newUser->getEmail()->getValue()
213 ) {
214 $result->setResult(CommandResult::RESULT_CONFLICT);
215 $result->setMessage('Email already exist.');
216 $result->setData('This email is already in use.');
217
218 return $result;
219 }
220
221 if ($command->getField('password')) {
222 $newPassword = new Password($command->getField('password'));
223
224 $providerRepository->updateFieldById($command->getArg('id'), $newPassword->getValue(), 'password');
225
226 $isAdmin = $currentUser && $currentUser->getType() === AbstractUser::USER_ROLE_ADMIN;
227 // $currentUser is null in token-only cabinet sessions (get_current_user_id() returns 0).
228 // Fall back to $oldUser which was resolved from the cabinet token and always matches $userId.
229 $callerId = $currentUser && $currentUser->getId() ? $currentUser->getId()->getValue() : null;
230 $isOwnProfile = $callerId === $userId || ($callerId === null && $oldUser->getId()->getValue() === $userId);
231
232 // Propagate to the linked WP user only when the caller is an admin or the provider
233 // updating their own profile. Blocks a Manager from resetting another provider's WP password.
234 if (
235 $newUser->getExternalId() &&
236 $newUser->getExternalId()->getValue() &&
237 ($isAdmin || $isOwnProfile)
238 ) {
239 add_filter('amelia_user_profile_updated', '__return_true');
240 wp_set_password($command->getField('password'), $newUser->getExternalId()->getValue());
241 remove_filter('amelia_user_profile_updated', '__return_true');
242 }
243 }
244
245 do_action('amelia_before_provider_updated', $newUser ? $newUser->toArray() : null, $oldUser ? $oldUser->toArray() : null);
246
247 try {
248 if (!$providerAS->update($oldUser, $newUser, $providerData)) {
249 $providerRepository->rollback();
250 return $result;
251 }
252
253 if (isset($providerData['googleCalendar']['blockedCalendars'])) {
254 $providerAS->updateProviderGoogleCalendarBlockedCalendars(
255 $userId,
256 $providerData['googleCalendar']['blockedCalendars']
257 );
258 }
259
260 $providerData = $this->getGoogleCalendarProviderData($providerData, $providerAS, $userId);
261
262 if (isset($providerData['outlookCalendar']['blockedCalendars'])) {
263 $providerAS->updateProviderOutlookCalendarBlockedCalendars(
264 $userId,
265 $providerData['outlookCalendar']['blockedCalendars']
266 );
267 }
268
269 $providerData = $this->getOutlookCalendarProviderData($providerData, $providerAS, $userId);
270
271 if ($command->getField('externalId') === 0) {
272 /** @var UserApplicationService $userAS */
273 $userAS = $this->getContainer()->get('application.user.service');
274
275 $userAS->setWpUserIdForNewUser($userId, $newUser, Entities::PROVIDER, $command->getField('password'));
276 } elseif ($newUser->getExternalId() && $newUser->getExternalId()->getValue()) {
277 add_filter('amelia_user_profile_updated', '__return_true');
278 wp_update_user(
279 [
280 'ID' => $newUser->getExternalId()->getValue(),
281 'first_name' => $newUser->getFirstName() ? $newUser->getFirstName()->getValue() : '',
282 'last_name' => $newUser->getLastName() ? $newUser->getLastName()->getValue() : '',
283 'user_email' => $newUser->getEmail() ? $newUser->getEmail()->getValue() : ''
284 ]
285 );
286
287 if ($uid = get_current_user_id()) {
288 clean_user_cache($uid);
289 }
290
291 remove_filter('amelia_user_profile_updated', '__return_true');
292 }
293 } catch (QueryExecutionException $e) {
294 $providerRepository->rollback();
295 throw $e;
296 }
297
298 $result = $userAS->getAuthenticatedUserResponse(
299 $newUser,
300 $oldUser->getEmail()->getValue() !== $newUser->getEmail()->getValue(),
301 true,
302 $oldUser->getLoginType(),
303 'provider'
304 );
305
306 $result->setData(
307 array_merge(
308 $result->getData(),
309 [
310 'sendEmployeePanelAccessEmail' =>
311 $command->getField('password') && $command->getField('sendEmployeePanelAccessEmail'),
312 'password' => $command->getField('password')
313 ]
314 )
315 );
316
317 $providerRepository->commit();
318
319 do_action('amelia_after_provider_updated', $newUser ? $newUser->toArray() : null, $oldUser ? $oldUser->toArray() : null);
320
321 return $result;
322 }
323
324 /**
325 * @param array $providerData
326 * @param ProviderApplicationService $providerAS
327 * @param $userId
328 * @return array
329 * @throws QueryExecutionException
330 */
331 public function getGoogleCalendarProviderData(array $providerData, ProviderApplicationService $providerAS, $userId): array
332 {
333 if (isset($providerData['googleCalendar'])) {
334 $googleCalendarSettings = [];
335
336 if (isset($providerData['googleCalendar']['insertPendingAppointments'])) {
337 $googleCalendarSettings['insertPendingAppointments'] = $providerData['googleCalendar']['insertPendingAppointments'];
338 }
339
340 if (isset($providerData['googleCalendar']['includeBufferTime'])) {
341 $googleCalendarSettings['includeBufferTime'] = $providerData['googleCalendar']['includeBufferTime'];
342 }
343
344 if (isset($providerData['googleCalendar']['title'])) {
345 $googleCalendarSettings['title'] = $providerData['googleCalendar']['title'];
346 }
347
348 if (isset($providerData['googleCalendar']['description'])) {
349 $googleCalendarSettings['description'] = $providerData['googleCalendar']['description'];
350 }
351
352 if (!empty($googleCalendarSettings)) {
353 $providerAS->updateProviderGoogleCalendarAccountSettings($userId, $googleCalendarSettings);
354 }
355 }
356 return $providerData;
357 }
358
359 /**
360 * @param array $providerData
361 * @param ProviderApplicationService $providerAS
362 * @param $userId
363 * @return array
364 * @throws QueryExecutionException
365 */
366 public function getOutlookCalendarProviderData(array $providerData, ProviderApplicationService $providerAS, $userId): array
367 {
368 if (isset($providerData['outlookCalendar'])) {
369 $outlookCalendarSettings = [];
370
371 if (isset($providerData['outlookCalendar']['insertPendingAppointments'])) {
372 $outlookCalendarSettings['insertPendingAppointments'] = $providerData['outlookCalendar']['insertPendingAppointments'];
373 }
374
375 if (isset($providerData['outlookCalendar']['includeBufferTime'])) {
376 $outlookCalendarSettings['includeBufferTime'] = $providerData['outlookCalendar']['includeBufferTime'];
377 }
378
379 if (isset($providerData['outlookCalendar']['title'])) {
380 $outlookCalendarSettings['title'] = $providerData['outlookCalendar']['title'];
381 }
382
383 if (isset($providerData['outlookCalendar']['description'])) {
384 $outlookCalendarSettings['description'] = $providerData['outlookCalendar']['description'];
385 }
386
387 if (!empty($outlookCalendarSettings)) {
388 $providerAS->updateProviderOutlookCalendarAccountSettings($userId, $outlookCalendarSettings);
389 }
390 }
391 return $providerData;
392 }
393 }
394