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 / Infrastructure / WP / InstallActions / ActivationSettingsHook.php
ameliabooking / src / Infrastructure / WP / InstallActions Last commit date
DB 1 month ago ActivationDatabaseHook.php 7 months ago ActivationMultisite.php 1 year ago ActivationNewSiteMultisite.php 2 months ago ActivationRolesHook.php 1 year ago ActivationSettingsHook.php 4 weeks ago AutoUpdateHook.php 4 weeks ago DeleteDatabaseHook.php 1 year ago DeletionMultisite.php 1 year ago
ActivationSettingsHook.php
2715 lines
1 <?php
2
3 /**
4 * Settings hook for activation
5 */
6
7 namespace AmeliaBooking\Infrastructure\WP\InstallActions;
8
9 use AmeliaBooking\Domain\Entity\Entities;
10 use AmeliaBooking\Domain\Services\Settings\SettingsService;
11 use AmeliaBooking\Domain\ValueObjects\String\Token;
12 use AmeliaBooking\Infrastructure\Licence\Licence;
13 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTagsTable;
14 use AmeliaBooking\Infrastructure\WP\SettingsService\SettingsStorage;
15 use AmeliaBooking\Infrastructure\WP\PermissionsService\PermissionsChecker;
16 use Exception;
17
18 /**
19 * Class ActivationSettingsHook
20 *
21 * @package AmeliaBooking\Infrastructure\WP\InstallActions
22 */
23 class ActivationSettingsHook
24 {
25 /**
26 * Initialize the plugin
27 *
28 * @throws Exception
29 */
30 public static function init()
31 {
32 self::initDBSettings();
33
34 self::initGeneralSettings();
35
36 self::initCompanySettings();
37
38 self::initNotificationsSettings();
39
40 self::initDaysOffSettings();
41
42 self::initWeekScheduleSettings();
43
44 self::initGoogleCalendarSettings();
45
46 self::initOutlookCalendarSettings();
47
48 self::initPaymentsSettings();
49
50 self::initActivationSettings();
51
52 self::initLabelsSettings();
53
54 self::initRolesSettings();
55
56 self::initAppointmentsSettings();
57
58 self::initWebHooksSettings();
59
60 self::initZoomSettings();
61
62 self::initApiKeySettings();
63
64 self::initLessonSpaceSettings();
65
66 self::initIcsSettings();
67
68 self::initFacebookPixelSettings();
69
70 self::initGoogleAnalyticsSettings();
71
72 self::initGoogleTagSettings();
73
74 self::initMailchimpSettings();
75
76 self::initIvySettings();
77
78 self::initAppleCalendarSettings();
79
80 self::initPageColumnSettings();
81
82 self::initSocialLoginSettings();
83
84 self::initFeaturesIntegrationsSettings();
85 }
86
87 /**
88 * @param string $category
89 * @param array $settings
90 * @param bool $replace
91 */
92 public static function initSettings($category, $settings, $replace = false)
93 {
94 $settingsService = new SettingsService(new SettingsStorage());
95
96 if (!$settingsService->getCategorySettings($category)) {
97 $settingsService->setCategorySettings(
98 $category,
99 []
100 );
101 }
102
103 foreach ($settings as $key => $value) {
104 if ($replace || null === $settingsService->getSetting($category, $key)) {
105 $settingsService->setSetting(
106 $category,
107 $key,
108 $value
109 );
110 }
111 }
112 }
113
114 /**
115 * Init General Settings
116 *
117 * @param array $savedSettings
118 *
119 * @return array
120 */
121 public static function getDefaultGeneralSettings($savedSettings)
122 {
123 return [
124 'timeSlotLength' => 1800,
125 'serviceDurationAsSlot' => false,
126 'bufferTimeInSlot' => true,
127 'defaultAppointmentStatus' => 'approved',
128 'defaultEventStatus' => 'approved',
129 'minimumTimeRequirementPriorToBooking' => 0,
130 'minimumTimeRequirementPriorToCanceling' => 0,
131 'minimumTimeRequirementPriorToRescheduling' =>
132 isset($savedSettings['minimumTimeRequirementPriorToCanceling']) &&
133 !isset($savedSettings['minimumTimeRequirementPriorToRescheduling']) ?
134 $savedSettings['minimumTimeRequirementPriorToCanceling'] : 0,
135 'numberOfDaysAvailableForBooking' => SettingsService::NUMBER_OF_DAYS_AVAILABLE_FOR_BOOKING,
136 'backendSlotsDaysInFuture' => SettingsService::NUMBER_OF_DAYS_AVAILABLE_FOR_BOOKING,
137 'backendSlotsDaysInPast' => SettingsService::NUMBER_OF_DAYS_AVAILABLE_FOR_BOOKING,
138 'phoneDefaultCountryCode' => 'auto',
139 'ipLocateApiKey' => '',
140 'requiredPhoneNumberField' => false,
141 'requiredEmailField' => true,
142 'itemsPerPage' => 12,
143 'appointmentsPerPage' => 100,
144 'eventsPerPage' => 100,
145 'servicesPerPage' => 100,
146 'customersFilterLimit' => 100,
147 'eventsFilterLimit' => 1000,
148 'calendarEmployeesPreselected' => 0,
149 'gMapApiKey' => '',
150 'addToCalendar' => true,
151 'defaultPageOnBackend' => 'Dashboard',
152 'showClientTimeZone' => false,
153 'redirectUrlAfterAppointment' => '',
154 'customFieldsUploadsPath' => '',
155 'customFieldsAllowedExtensions' => [
156 '.jpg' => 'image/jpeg',
157 '.jpeg' => 'image/jpeg',
158 '.png' => 'image/png',
159 '.mp3' => 'audio/mpeg',
160 '.mpeg' => 'video/mpeg',
161 '.mp4' => 'video/mp4',
162 '.txt' => 'text/plain',
163 '.csv' => 'text/plain',
164 '.xls' => 'application/vnd.ms-excel',
165 '.pdf' => 'application/pdf',
166 '.doc' => 'application/msword',
167 '.docx' => 'application/msword'
168 ],
169 'customFieldsBackendValidation' => false,
170 'runInstantPostBookingActions' => false,
171 'sortingPackages' => 'nameAsc',
172 'sortingServices' => 'nameAsc',
173 'calendarLocaleSubstitutes' => [],
174 'googleRecaptcha' => [
175 'invisible' => true,
176 'siteKey' => '',
177 'secret' => '',
178 ],
179 'usedLanguages' => [],
180 ];
181 }
182
183 /**
184 * Get General Settings
185 */
186 private static function initGeneralSettings()
187 {
188 $settingsService = new SettingsService(new SettingsStorage());
189
190 $savedSettings = $settingsService->getCategorySettings('general');
191
192 $settings = self::getDefaultGeneralSettings($savedSettings);
193
194 $settings['backLink'] = self::getBackLinkSetting();
195
196 self::initSettings('general', $settings);
197
198 self::setNewSettingsToExistingSettings(
199 'general',
200 [
201 ['backLink', 'url'],
202 ],
203 $settings
204 );
205 }
206
207 /**
208 * Init DB Settings
209 */
210 private static function initDBSettings()
211 {
212 self::initSettings('db', [
213 'wpTablesPrefix' => '',
214 ]);
215 }
216
217 /**
218 * Init Company Settings
219 */
220 private static function initCompanySettings()
221 {
222
223 $settings = [
224 'pictureFullPath' => '',
225 'pictureThumbPath' => '',
226 'name' => '',
227 'address' => '',
228 'addressComponents' => [],
229 'countryCode' => '',
230 'phone' => '',
231 'vat' => '',
232 'countryPhoneIso' => '',
233 'website' => '',
234 'translations' => '',
235 ];
236
237 self::initSettings('company', $settings);
238 }
239
240 /**
241 * Get Notification Settings
242 *
243 * @return array
244 */
245 public static function getDefaultNotificationsSettings()
246 {
247 return [
248 'mailService' => '',
249 'smtpHost' => '',
250 'smtpPort' => '',
251 'smtpSecure' => 'ssl',
252 'smtpUsername' => '',
253 'smtpPassword' => '',
254 'mailgunApiKey' => '',
255 'mailgunDomain' => '',
256 'mailgunEndpoint' => '',
257 'senderName' => '',
258 'replyTo' => '',
259 'senderEmail' => '',
260 'sendAllCF' => true,
261 'smsAlphaSenderId' => 'Amelia',
262 'smsSignedIn' => false,
263 'smsApiToken' => '',
264 'bccEmail' => '',
265 'bccSms' => '',
266 'emptyPackageEmployees' => '',
267 'smsBalanceEmail' => ['enabled' => false, 'minimum' => 0, 'email' => ''],
268 'cancelSuccessUrl' => '',
269 'cancelErrorUrl' => '',
270 'approveSuccessUrl' => '',
271 'approveErrorUrl' => '',
272 'rejectSuccessUrl' => '',
273 'rejectErrorUrl' => '',
274 'breakReplacement' => '<br>',
275 'pendingReminder' => false,
276 'sendInvoice' => false,
277 'invoiceFormat' => 'pdf',
278 'whatsAppPhoneID' => '',
279 'whatsAppAccessToken' => '',
280 'whatsAppBusinessID' => '',
281 'whatsAppLanguage' => '',
282 'whatsAppReplyEnabled' => false,
283 'whatsAppReplyMsg' => 'Dear %customer_full_name%,
284 This message does not have an option for responding. If you need additional information about your booking, please contact us at %company_phone%',
285 'whatsAppReplyToken' => (new Token(null, 20))->getValue(),
286 ];
287 }
288
289 /**
290 * Init Notification Settings
291 */
292 private static function initNotificationsSettings()
293 {
294 $settings = self::getDefaultNotificationsSettings();
295
296 self::initSettings('notifications', $settings);
297 }
298
299 /**
300 * Init Days Off Settings
301 */
302 private static function initDaysOffSettings()
303 {
304 self::initSettings('daysOff', []);
305 }
306
307 /**
308 * Init Work Schedule Settings
309 */
310 private static function initWeekScheduleSettings()
311 {
312 self::initSettings(
313 'weekSchedule',
314 [
315 [
316 'day' => 'Monday',
317 'time' => ['09:00', '17:00'],
318 'breaks' => [],
319 'periods' => []
320 ],
321 [
322 'day' => 'Tuesday',
323 'time' => ['09:00', '17:00'],
324 'breaks' => [],
325 'periods' => []
326 ],
327 [
328 'day' => 'Wednesday',
329 'time' => ['09:00', '17:00'],
330 'breaks' => [],
331 'periods' => []
332 ],
333 [
334 'day' => 'Thursday',
335 'time' => ['09:00', '17:00'],
336 'breaks' => [],
337 'periods' => []
338 ],
339 [
340 'day' => 'Friday',
341 'time' => ['09:00', '17:00'],
342 'breaks' => [],
343 'periods' => []
344 ],
345 [
346 'day' => 'Saturday',
347 'time' => [],
348 'breaks' => [],
349 'periods' => []
350 ],
351 [
352 'day' => 'Sunday',
353 'time' => [],
354 'breaks' => [],
355 'periods' => []
356 ]
357 ]
358 );
359 }
360
361 /**
362 * Init Google Calendar Settings
363 */
364 private static function initGoogleCalendarSettings()
365 {
366 $settingsService = new SettingsService(new SettingsStorage());
367
368 $savedSettings = $settingsService->getCategorySettings('googleCalendar');
369
370 $settings = [
371 'clientID' => '',
372 'clientSecret' => '',
373 'redirectURI' => AMELIA_SITE_URL . '/wp-admin/admin.php?page=wpamelia-employees',
374 'showAttendees' => false,
375 'insertPendingAppointments' => false,
376 'addAttendees' => false,
377 'sendEventInvitationEmail' => false,
378 'removeGoogleCalendarBusySlots' => false,
379 'maximumNumberOfEventsReturned' => 50,
380 'eventTitle' => '%service_name%',
381 'eventDescription' => '',
382 'includeBufferTimeGoogleCalendar' => false,
383 'status' => 'tentative',
384 'enableGoogleMeet' => false,
385 'title' => [
386 'appointment' => $savedSettings && !empty($savedSettings['eventTitle']) ?
387 $savedSettings['eventTitle'] : '%service_name%',
388 'event' => '%event_name%'
389 ],
390 'description' => [
391 'appointment' => $savedSettings && !empty($savedSettings['eventDescription']) ?
392 $savedSettings['eventDescription'] : '',
393 'event' => ''
394 ],
395 'accessToken' => '',
396 'googleAccountData' => null
397 ];
398
399 self::initSettings('googleCalendar', $settings);
400 }
401
402 /**
403 * Init Outlook Calendar Settings
404 */
405 private static function initOutlookCalendarSettings()
406 {
407 $settingsService = new SettingsService(new SettingsStorage());
408
409 $savedSettings = $settingsService->getCategorySettings('outlookCalendar');
410
411 $settings = [
412 'clientID' => '',
413 'clientSecret' => '',
414 'redirectURI' => AMELIA_SITE_URL . '/wp-admin/',
415 'insertPendingAppointments' => false,
416 'addAttendees' => false,
417 'sendEventInvitationEmail' => false,
418 'removeOutlookCalendarBusySlots' => false,
419 'maximumNumberOfEventsReturned' => 50,
420 'ignoreAmeliaEvents' => false,
421 'eventTitle' => '%service_name%',
422 'eventDescription' => '',
423 'includeBufferTimeOutlookCalendar' => false,
424 'enableMicrosoftTeams' => false,
425 'title' => [
426 'appointment' => $savedSettings && !empty($savedSettings['eventTitle']) ?
427 $savedSettings['eventTitle'] : '%service_name%',
428 'event' => '%event_name%'
429 ],
430 'description' => [
431 'appointment' => $savedSettings && !empty($savedSettings['eventDescription']) ?
432 $savedSettings['eventDescription'] : '',
433 'event' => ''
434 ],
435 'mailEnabled' => false,
436 'token' => null,
437 'accessToken' => '',
438 'outlookAccountData' => null
439 ];
440
441 self::initSettings('outlookCalendar', $settings);
442 }
443
444 /**
445 * Init Apple Calendar Settings
446 */
447 private static function initAppleCalendarSettings()
448 {
449 $settings = [
450 'clientID' => '',
451 'clientSecret' => '',
452 'redirectURI' => AMELIA_SITE_URL . '/wp-admin/admin.php?page=wpamelia-employees',
453 'insertPendingAppointments' => false,
454 'addAttendees' => false,
455 'removeAppleCalendarBusySlots' => false,
456 'eventTitle' => '%service_name%',
457 'eventDescription' => '',
458 'includeBufferTimeAppleCalendar' => false,
459 'title' => [
460 'appointment' => '%service_name%',
461 'event' => '%event_name%'
462 ],
463 'description' => [
464 'appointment' => '',
465 'event' => ''
466 ],
467 ];
468
469 self::initSettings('appleCalendar', $settings);
470 }
471
472 /**
473 * Init Zoom Settings
474 */
475 private static function initZoomSettings()
476 {
477 $settings = [
478 'enabled' => true,
479 'apiKey' => '',
480 'apiSecret' => '',
481 'meetingTitle' => '%reservation_name%',
482 'meetingAgenda' => '%reservation_description%',
483 'pendingAppointmentsMeetings' => false,
484 's2sEnabled' => true,
485 'accountId' => '',
486 'clientId' => '',
487 'clientSecret' => '',
488 'accessToken' => '',
489 ];
490
491 self::initSettings('zoom', $settings);
492 }
493
494
495 /**
496 * Init Api Key Settings
497 */
498 private static function initApiKeySettings()
499 {
500 $settings = [
501 'apiKeys' => []
502 ];
503
504 self::initSettings('apiKeys', $settings);
505 }
506
507 /**
508 * Init Lesson Space Settings
509 */
510 private static function initLessonSpaceSettings()
511 {
512 $settings = [
513 'apiKey' => '',
514 'spaceNameAppointments' => '%reservation_name%',
515 'spaceNameEvents' => '%reservation_name%',
516 'pendingAppointments' => false,
517 'companyId' => ''
518 ];
519
520 self::initSettings('lessonSpace', $settings);
521 }
522
523 /**
524 * Init FacebookPixel Settings
525 */
526 private static function initFacebookPixelSettings()
527 {
528 $settings = [
529 'id' => '',
530 'tracking' => [
531 'appointment' => [],
532 'event' => [],
533 'package' => [],
534 ],
535 ];
536
537 self::initSettings('facebookPixel', $settings);
538 }
539
540 /**
541 * Init Google Analytics Settings
542 */
543 private static function initGoogleAnalyticsSettings()
544 {
545 $settings = [
546 'id' => '',
547 'tracking' => [
548 'appointment' => [],
549 'event' => [],
550 'package' => [],
551 ],
552 ];
553
554 self::initSettings('googleAnalytics', $settings);
555 }
556
557 /**
558 * Init GoogleTag Settings
559 */
560 private static function initGoogleTagSettings()
561 {
562 $settings = [
563 'id' => '',
564 'tracking' => [
565 'appointment' => [],
566 'event' => [],
567 'package' => [],
568 ],
569 ];
570
571 self::initSettings('googleTag', $settings);
572 }
573
574
575 /**
576 * Init Mailchimp Settings
577 */
578 private static function initMailchimpSettings()
579 {
580 $settings = [
581 'accessToken' => null,
582 'server' => null,
583 'list' => null,
584 'checkedByDefault' => false
585 ];
586
587 self::initSettings('mailchimp', $settings);
588 }
589
590 /**
591 * Init Ivy Settings
592 */
593 private static function initIvySettings()
594 {
595 $settings = [];
596
597 self::initSettings('ivy', $settings);
598 }
599
600 /**
601 * Init Page Column Settings
602 */
603 private static function initPageColumnSettings()
604 {
605 $settings = self::getDefaultPageColumnSettings();
606
607 self::initSettings('pageColumnSettings', $settings);
608
609 // Handle updates to existing page column settings
610 self::updatePageColumnSettings($settings);
611 }
612
613 /**
614 * Get Default Page Column Settings
615 *
616 * @return array
617 */
618 public static function getDefaultPageColumnSettings()
619 {
620 return [
621 "customersPage" => [
622 [
623 "prop" => "id",
624 "visible" => true,
625 "width" => 80,
626 "label" => "id",
627 "sortable" => false
628 ],
629 [
630 "prop" => "name",
631 "visible" => true,
632 "width" => 320,
633 "label" => "name",
634 "sortable" => true,
635 "required" => true
636 ],
637 [
638 "prop" => "phone",
639 "visible" => true,
640 "width" => 160,
641 "label" => "phone",
642 "sortable" => false
643 ],
644 [
645 "prop" => "email",
646 "visible" => true,
647 "width" => 240,
648 "label" => "email",
649 "sortable" => false
650 ],
651 [
652 "prop" => "note",
653 "visible" => true,
654 "width" => 80,
655 "label" => "note",
656 "sortable" => false
657 ],
658 [
659 "prop" => "lastBooking",
660 "visible" => true,
661 "width" => 240,
662 "label" => "last_booking",
663 "sortable" => true
664 ],
665 [
666 "prop" => "totalBookings",
667 "visible" => true,
668 "width" => 160,
669 "label" => "total_bookings",
670 "sortable" => true
671 ],
672 [
673 "prop" => "wordPressUser",
674 "visible" => true,
675 "width" => 240,
676 "label" => "wp_user",
677 "sortable" => false
678 ]
679 ],
680
681 "employeesPage" => [
682 [
683 "prop" => "id",
684 "visible" => true,
685 "width" => 80,
686 "label" => "id",
687 "sortable" => false
688 ],
689 [
690 "prop" => "name",
691 "visible" => true,
692 "width" => 320,
693 "label" => "name",
694 "sortable" => true,
695 "required" => true
696 ],
697 [
698 "prop" => "status",
699 "visible" => true,
700 "width" => 160,
701 "label" => "visibility",
702 "sortable" => false
703 ],
704 [
705 "prop" => "availability",
706 "visible" => true,
707 "width" => 160,
708 "label" => "red_availability",
709 "sortable" => false
710 ],
711 [
712 "prop" => "phone",
713 "visible" => true,
714 "width" => 160,
715 "label" => "phone",
716 "sortable" => false
717 ],
718 [
719 "prop" => "email",
720 "visible" => true,
721 "width" => 240,
722 "label" => "email",
723 "sortable" => false
724 ],
725 [
726 "prop" => "actions",
727 "visible" => true,
728 "width" => 240,
729 "label" => "red_actions",
730 "sortable" => false
731 ],
732 ],
733
734 "locationsPage" => [
735 [
736 "prop" => "id",
737 "visible" => true,
738 "width" => 80,
739 "label" => "id",
740 "sortable" => false
741 ],
742 [
743 "prop" => "name",
744 "visible" => true,
745 "width" => 320,
746 "label" => "name",
747 "sortable" => true,
748 "required" => true
749 ],
750 [
751 "prop" => "address",
752 "visible" => true,
753 "width" => 320,
754 "label" => "address",
755 "sortable" => false
756 ],
757 [
758 "prop" => "phone",
759 "visible" => true,
760 "width" => 160,
761 "label" => "phone",
762 "sortable" => false
763 ],
764 [
765 "prop" => "status",
766 "visible" => true,
767 "width" => 160,
768 "label" => "visibility",
769 "sortable" => false
770 ]
771 ],
772
773 "bookingsAppointmentsPage" => [
774 [
775 "prop" => "id",
776 "visible" => true,
777 "width" => 80,
778 "label" => "id",
779 "sortable" => true
780 ],
781 [
782 "prop" => "date",
783 "visible" => true,
784 "width" => 160,
785 "label" => "date",
786 "sortable" => false,
787 "required" => true
788 ],
789 [
790 "prop" => "time",
791 "visible" => true,
792 "width" => 160,
793 "label" => "time",
794 "sortable" => false,
795 "required" => true
796 ],
797 [
798 "prop" => "customer",
799 "visible" => true,
800 "width" => 320,
801 "label" => "customer",
802 "sortable" => true,
803 "required" => true
804 ],
805 [
806 "prop" => "service",
807 "visible" => true,
808 "width" => 240,
809 "label" => "service",
810 "sortable" => true,
811 "required" => true
812 ],
813 [
814 "prop" => "type",
815 "visible" => true,
816 "width" => 160,
817 "label" => "type",
818 "sortable" => false
819 ],
820 [
821 "prop" => "status",
822 "visible" => true,
823 "width" => 200,
824 "label" => "status",
825 "sortable" => false
826 ],
827 [
828 "prop" => "employee",
829 "visible" => true,
830 "width" => 320,
831 "label" => "employee",
832 "sortable" => false
833 ],
834 [
835 "prop" => "location",
836 "visible" => true,
837 "width" => 240,
838 "label" => "location",
839 "sortable" => false
840 ],
841 [
842 "prop" => "duration",
843 "visible" => false,
844 "width" => 160,
845 "label" => "duration",
846 "sortable" => false
847 ],
848 [
849 "prop" => "customerEmail",
850 "visible" => false,
851 "width" => 240,
852 "label" => "customer_email",
853 "sortable" => false
854 ],
855 [
856 "prop" => "customerPhone",
857 "visible" => false,
858 "width" => 240,
859 "label" => "customer_phone",
860 "sortable" => false
861 ],
862 [
863 "prop" => "booked",
864 "visible" => false,
865 "width" => 80,
866 "label" => "booked",
867 "sortable" => false
868 ],
869 [
870 "prop" => "note",
871 "visible" => false,
872 "width" => 80,
873 "label" => "note",
874 "sortable" => false
875 ],
876 [
877 "prop" => "paidPrice",
878 "visible" => false,
879 "width" => 160,
880 "label" => "paid",
881 "sortable" => false
882 ],
883 [
884 "prop" => "payment",
885 "visible" => false,
886 "width" => 160,
887 "label" => "payment",
888 "sortable" => false
889 ],
890 [
891 "prop" => "totalPrice",
892 "visible" => false,
893 "width" => 160,
894 "label" => "total_price",
895 "sortable" => false
896 ],
897 [
898 "prop" => "hostLink",
899 "visible" => false,
900 "width" => 160,
901 "label" => "red_host_link",
902 "sortable" => false
903 ],
904 [
905 "prop" => "joinLink",
906 "visible" => false,
907 "width" => 200,
908 "label" => "red_join_link",
909 "sortable" => false
910 ],
911 [
912 "prop" => "created",
913 "visible" => false,
914 "width" => 160,
915 "label" => "created_on",
916 "sortable" => true,
917 "required" => false
918 ],
919 [
920 "prop" => "bookingSource",
921 "visible" => false,
922 "width" => 64,
923 "label" => "red_booking_source",
924 "sortable" => false,
925 "showLabel" => false
926 ],
927 ],
928
929 "bookingsPackagesPage" => [
930 [
931 "prop" => "id",
932 "visible" => true,
933 "width" => 80,
934 "label" => "id",
935 "sortable" => true
936 ],
937 [
938 "prop" => "date",
939 "visible" => true,
940 "width" => 160,
941 "label" => "package_date_purchased",
942 "sortable" => true
943 ],
944 [
945 "prop" => "customer",
946 "visible" => true,
947 "width" => 320,
948 "label" => "customer",
949 "sortable" => true,
950 "required" => true
951 ],
952 [
953 "prop" => "package",
954 "visible" => true,
955 "width" => 320,
956 "label" => "package",
957 "sortable" => true,
958 "required" => true
959 ],
960 [
961 "prop" => "status",
962 "visible" => true,
963 "width" => 200,
964 "label" => "status",
965 "sortable" => false
966 ],
967 [
968 "prop" => "appointments",
969 "visible" => true,
970 "width" => 160,
971 "label" => "appointments",
972 "sortable" => false
973 ],
974 [
975 "prop" => "employees",
976 "visible" => true,
977 "width" => 320,
978 "label" => "employees",
979 "sortable" => false
980 ],
981 [
982 "prop" => "expirationDate",
983 "visible" => false,
984 "width" => 240,
985 "label" => "expiration_date",
986 "sortable" => false
987 ],
988 [
989 "prop" => "price",
990 "visible" => false,
991 "width" => 160,
992 "label" => "price",
993 "sortable" => false
994 ],
995 [
996 "prop" => "paymentStatus",
997 "visible" => false,
998 "width" => 200,
999 "label" => "payment_status",
1000 "sortable" => false
1001 ]
1002 ],
1003
1004 "bookingsEventsPage" => [
1005 [
1006 "prop" => "code",
1007 "visible" => true,
1008 "width" => 120,
1009 "label" => "code",
1010 "sortable" => false
1011 ],
1012 [
1013 "prop" => "date",
1014 "visible" => true,
1015 "width" => 160,
1016 "label" => "date",
1017 "sortable" => false
1018 ],
1019 [
1020 "prop" => "time",
1021 "visible" => true,
1022 "width" => 160,
1023 "label" => "time",
1024 "sortable" => false
1025 ],
1026 [
1027 "prop" => "attendee",
1028 "visible" => true,
1029 "width" => 240,
1030 "label" => "attendee",
1031 "sortable" => true,
1032 "required" => true
1033 ],
1034 [
1035 "prop" => "event",
1036 "visible" => true,
1037 "width" => 320,
1038 "label" => "event",
1039 "sortable" => true,
1040 "required" => true
1041 ],
1042 [
1043 "prop" => "status",
1044 "visible" => true,
1045 "width" => 200,
1046 "label" => "status",
1047 "sortable" => false
1048 ],
1049 [
1050 "prop" => "spots",
1051 "visible" => true,
1052 "width" => 80,
1053 "label" => "red_booked",
1054 "sortable" => false
1055 ],
1056 [
1057 "prop" => "organizer",
1058 "visible" => false,
1059 "width" => 240,
1060 "label" => "event_organizer",
1061 "sortable" => false
1062 ],
1063 [
1064 "prop" => "staff",
1065 "visible" => false,
1066 "width" => 240,
1067 "label" => "event_staff",
1068 "sortable" => false
1069 ],
1070 [
1071 "prop" => "price",
1072 "visible" => false,
1073 "width" => 160,
1074 "label" => "price",
1075 "sortable" => false
1076 ],
1077 [
1078 "prop" => "paymentStatus",
1079 "visible" => false,
1080 "width" => 200,
1081 "label" => "payment_status",
1082 "sortable" => false
1083 ],
1084 [
1085 "prop" => "created",
1086 "visible" => false,
1087 "width" => 160,
1088 "label" => "created_on",
1089 "sortable" => true,
1090 "required" => false
1091 ],
1092 ],
1093
1094 "eventsPage" => [
1095 [
1096 "prop" => "id",
1097 "visible" => true,
1098 "width" => 80,
1099 "label" => "id",
1100 "sortable" => true
1101 ],
1102 [
1103 "prop" => "dateTime",
1104 "visible" => true,
1105 "width" => 240,
1106 "label" => "date_time",
1107 "sortable" => true,
1108 "required" => true
1109 ],
1110 [
1111 "prop" => "name",
1112 "visible" => true,
1113 "width" => 320,
1114 "label" => "name",
1115 "sortable" => true,
1116 "required" => true
1117 ],
1118 [
1119 "prop" => "status",
1120 "visible" => true,
1121 "width" => 200,
1122 "label" => "status",
1123 "sortable" => false
1124 ],
1125 [
1126 "prop" => "spots",
1127 "visible" => true,
1128 "width" => 80,
1129 "label" => "red_booked",
1130 "sortable" => false
1131 ],
1132 [
1133 "prop" => "organizer",
1134 "visible" => true,
1135 "width" => 240,
1136 "label" => "event_organizer",
1137 "sortable" => false
1138 ],
1139 [
1140 "prop" => "staff",
1141 "visible" => true,
1142 "width" => 240,
1143 "label" => "event_staff",
1144 "sortable" => false
1145 ],
1146 [
1147 "prop" => "recurring",
1148 "visible" => true,
1149 "width" => 120,
1150 "label" => "recurring",
1151 "sortable" => false
1152 ],
1153 [
1154 "prop" => "waitingList",
1155 "visible" => true,
1156 "width" => 200,
1157 "label" => "waiting_list",
1158 "sortable" => false
1159 ],
1160 [
1161 "prop" => "bookingOpens",
1162 "visible" => true,
1163 "width" => 240,
1164 "label" => "red_booking_opens",
1165 "sortable" => true
1166 ],
1167 [
1168 "prop" => "bookingCloses",
1169 "visible" => true,
1170 "width" => 240,
1171 "label" => "red_booking_closes",
1172 "sortable" => true
1173 ],
1174 [
1175 "prop" => "visibility",
1176 "visible" => true,
1177 "width" => 160,
1178 "label" => "visibility",
1179 "sortable" => false
1180 ],
1181 ],
1182
1183 "catalogServicesPage" => [
1184 [
1185 "prop" => "id",
1186 "visible" => true,
1187 "width" => 80,
1188 "label" => "id",
1189 "sortable" => true
1190 ],
1191 [
1192 "prop" => "service",
1193 "visible" => true,
1194 "width" => 320,
1195 "label" => "service",
1196 "sortable" => true,
1197 "required" => true
1198 ],
1199 [
1200 "prop" => "duration",
1201 "visible" => true,
1202 "width" => 160,
1203 "label" => "duration",
1204 "sortable" => true
1205 ],
1206 [
1207 "prop" => "price",
1208 "visible" => true,
1209 "width" => 160,
1210 "label" => "price",
1211 "sortable" => true
1212 ],
1213 [
1214 "prop" => "employees",
1215 "visible" => true,
1216 "width" => 320,
1217 "label" => "employees",
1218 "sortable" => false
1219 ],
1220 [
1221 "prop" => "visibility",
1222 "visible" => true,
1223 "width" => 160,
1224 "label" => "visibility",
1225 "sortable" => false
1226 ],
1227 ],
1228
1229 "catalogPackagesPage" => [
1230 [
1231 "prop" => "id",
1232 "visible" => true,
1233 "width" => 80,
1234 "label" => "id",
1235 "sortable" => true
1236 ],
1237 [
1238 "prop" => "name",
1239 "visible" => true,
1240 "width" => 320,
1241 "label" => "name",
1242 "sortable" => true,
1243 "required" => true
1244 ],
1245 [
1246 "prop" => "services",
1247 "visible" => true,
1248 "width" => 200,
1249 "label" => "services",
1250 "sortable" => true
1251 ],
1252 [
1253 "prop" => "price",
1254 "visible" => true,
1255 "width" => 160,
1256 "label" => "price",
1257 "sortable" => true
1258 ],
1259 [
1260 "prop" => "duration",
1261 "visible" => true,
1262 "width" => 160,
1263 "label" => "duration",
1264 "sortable" => false
1265 ],
1266 [
1267 "prop" => "employees",
1268 "visible" => true,
1269 "width" => 320,
1270 "label" => "employees",
1271 "sortable" => false
1272 ],
1273 [
1274 "prop" => "status",
1275 "visible" => true,
1276 "width" => 160,
1277 "label" => "visibility",
1278 "sortable" => false
1279 ]
1280 ],
1281
1282 "catalogResourcesPage" => [
1283 [
1284 "prop" => "id",
1285 "visible" => true,
1286 "width" => 80,
1287 "label" => "id",
1288 "sortable" => true
1289 ],
1290 [
1291 "prop" => "name",
1292 "visible" => true,
1293 "width" => 320,
1294 "label" => "name",
1295 "sortable" => true,
1296 "required" => true
1297 ],
1298 [
1299 "prop" => "quantity",
1300 "visible" => true,
1301 "width" => 160,
1302 "label" => "quantity",
1303 "sortable" => true
1304 ],
1305 [
1306 "prop" => "services",
1307 "visible" => true,
1308 "width" => 320,
1309 "label" => "services",
1310 "sortable" => false
1311 ],
1312 [
1313 "prop" => "locations",
1314 "visible" => true,
1315 "width" => 320,
1316 "label" => "locations",
1317 "sortable" => false
1318 ],
1319 [
1320 "prop" => "employees",
1321 "visible" => true,
1322 "width" => 320,
1323 "label" => "employees",
1324 "sortable" => false
1325 ],
1326 [
1327 "prop" => "type",
1328 "visible" => true,
1329 "width" => 200,
1330 "label" => "type",
1331 "sortable" => false
1332 ],
1333 [
1334 "prop" => "status",
1335 "visible" => true,
1336 "width" => 160,
1337 "label" => "visibility",
1338 "sortable" => false
1339 ]
1340 ],
1341
1342 "financePaymentsPage" => [
1343 [
1344 "prop" => "id",
1345 "visible" => true,
1346 "width" => 80,
1347 "label" => "id",
1348 "sortable" => true
1349 ],
1350 [
1351 "prop" => "dateTime",
1352 "visible" => true,
1353 "width" => 160,
1354 "label" => "payment_date",
1355 "sortable" => true
1356 ],
1357 [
1358 "prop" => "customer",
1359 "visible" => true,
1360 "width" => 240,
1361 "label" => "customer",
1362 "sortable" => false,
1363 "required" => true
1364 ],
1365 [
1366 "prop" => "employees",
1367 "visible" => true,
1368 "width" => 240,
1369 "label" => "employees",
1370 "sortable" => false
1371 ],
1372 [
1373 "prop" => "booking",
1374 "visible" => true,
1375 "width" => 320,
1376 "label" => "booking",
1377 "sortable" => false
1378 ],
1379 [
1380 "prop" => "status",
1381 "visible" => true,
1382 "width" => 160,
1383 "label" => "status",
1384 "sortable" => true
1385 ],
1386 [
1387 "prop" => "amount",
1388 "visible" => true,
1389 "width" => 160,
1390 "label" => "amount",
1391 "sortable" => true,
1392 "required" => true
1393 ],
1394 [
1395 "prop" => "payment_method",
1396 "visible" => true,
1397 "width" => 160,
1398 "label" => "payment_method",
1399 "sortable" => false
1400 ],
1401 [
1402 "prop" => "location",
1403 "visible" => true,
1404 "width" => 320,
1405 "label" => "location",
1406 "sortable" => false
1407 ],
1408 ],
1409 "financeCouponsPage" => [
1410 [
1411 "prop" => "code",
1412 "visible" => true,
1413 "width" => 120,
1414 "label" => "code",
1415 "sortable" => false,
1416 "required" => true
1417 ],
1418 [
1419 "prop" => "discount",
1420 "visible" => true,
1421 "width" => 120,
1422 "label" => "discount_amount",
1423 "sortable" => true,
1424 "required" => true
1425 ],
1426 [
1427 "prop" => "deduction",
1428 "visible" => true,
1429 "width" => 120,
1430 "label" => "deduction",
1431 "sortable" => true
1432 ],
1433 [
1434 "prop" => "status",
1435 "visible" => true,
1436 "width" => 160,
1437 "label" => "visibility",
1438 "sortable" => false
1439 ],
1440 [
1441 "prop" => "start_date",
1442 "visible" => true,
1443 "width" => 240,
1444 "label" => "start_date",
1445 "sortable" => false
1446 ],
1447 [
1448 "prop" => "expiration_date",
1449 "visible" => true,
1450 "width" => 240,
1451 "label" => "expiration_date",
1452 "sortable" => false
1453 ],
1454 [
1455 "prop" => "service",
1456 "visible" => true,
1457 "width" => 320,
1458 "label" => "services",
1459 "sortable" => false
1460 ],
1461 [
1462 "prop" => "event",
1463 "visible" => true,
1464 "width" => 320,
1465 "label" => "events",
1466 "sortable" => false
1467 ],
1468 [
1469 "prop" => "package",
1470 "visible" => true,
1471 "width" => 320,
1472 "label" => "packages",
1473 "sortable" => false
1474 ],
1475 [
1476 "prop" => "usage_limit",
1477 "visible" => false,
1478 "width" => 120,
1479 "label" => "usage_limit",
1480 "sortable" => false
1481 ],
1482 [
1483 "prop" => "limit_per_customer",
1484 "visible" => false,
1485 "width" => 120,
1486 "label" => "red_limit_per_customer",
1487 "sortable" => false
1488 ],
1489 [
1490 "prop" => "times_used",
1491 "visible" => false,
1492 "width" => 120,
1493 "label" => "times_used",
1494 "sortable" => true
1495 ],
1496 ],
1497 "financeTaxesPage" => [
1498 [
1499 "prop" => "name",
1500 "visible" => true,
1501 "width" => 240,
1502 "label" => "name",
1503 "sortable" => true,
1504 "required" => true
1505 ],
1506 [
1507 "prop" => "type",
1508 "visible" => true,
1509 "width" => 120,
1510 "label" => "type",
1511 "sortable" => true
1512 ],
1513 [
1514 "prop" => "rate",
1515 "visible" => true,
1516 "width" => 80,
1517 "label" => "rate",
1518 "required" => true
1519 ],
1520 [
1521 "prop" => "status",
1522 "visible" => true,
1523 "width" => 160,
1524 "label" => "visibility",
1525 "sortable" => false
1526 ],
1527 [
1528 "prop" => "service",
1529 "visible" => true,
1530 "width" => 320,
1531 "label" => "services",
1532 "sortable" => false
1533 ],
1534 [
1535 "prop" => "event",
1536 "visible" => true,
1537 "width" => 320,
1538 "label" => "events",
1539 "sortable" => false
1540 ],
1541 [
1542 "prop" => "package",
1543 "visible" => true,
1544 "width" => 320,
1545 "label" => "packages",
1546 "sortable" => false
1547 ],
1548 [
1549 "prop" => "extra",
1550 "visible" => true,
1551 "width" => 320,
1552 "label" => "extras",
1553 "sortable" => false
1554 ],
1555
1556 ],
1557 "financeInvoicesPage" => [
1558 [
1559 "prop" => "invoiceNumber",
1560 "visible" => true,
1561 "width" => 160,
1562 "label" => "red_invoice_number",
1563 "sortable" => true,
1564 "required" => true
1565 ],
1566 [
1567 "prop" => "customer",
1568 "visible" => true,
1569 "width" => 240,
1570 "label" => "customer",
1571 "sortable" => false,
1572 "required" => true
1573 ],
1574 [
1575 "prop" => "dateTime",
1576 "visible" => true,
1577 "width" => 160,
1578 "label" => "red_invoice_date",
1579 "sortable" => true
1580 ],
1581 [
1582 "prop" => "employees",
1583 "visible" => true,
1584 "width" => 240,
1585 "label" => "employees",
1586 "sortable" => false
1587 ],
1588 [
1589 "prop" => "booking",
1590 "visible" => true,
1591 "width" => 320,
1592 "label" => "booking",
1593 "sortable" => false
1594 ],
1595 [
1596 "prop" => "status",
1597 "visible" => true,
1598 "width" => 160,
1599 "label" => "status",
1600 "sortable" => true
1601 ],
1602 [
1603 "prop" => "amount",
1604 "visible" => true,
1605 "width" => 160,
1606 "label" => "total",
1607 "sortable" => false
1608 ],
1609 ],
1610 ];
1611 }
1612
1613 /**
1614 * Update Page Column Settings for existing installations
1615 *
1616 * @param array $defaultSettings
1617 */
1618 private static function updatePageColumnSettings($defaultSettings)
1619 {
1620 $settingsService = new SettingsService(new SettingsStorage());
1621 $savedSettings = $settingsService->getCategorySettings('pageColumnSettings');
1622
1623 // If no saved settings exist, nothing to update
1624 if (!$savedSettings) {
1625 return;
1626 }
1627
1628 $needsUpdate = false;
1629 $updatedSettings = $savedSettings;
1630
1631 foreach ($defaultSettings as $pageKey => $defaultColumns) {
1632 // If page doesn't exist in saved settings, add it
1633 if (!isset($savedSettings[$pageKey])) {
1634 $updatedSettings[$pageKey] = $defaultColumns;
1635 $needsUpdate = true;
1636 continue;
1637 }
1638
1639 // Create a map of existing columns by prop for easy lookup, preserving user customizations
1640 $existingColumnsByProp = [];
1641 foreach ($savedSettings[$pageKey] as $column) {
1642 if (isset($column['prop'])) {
1643 $existingColumnsByProp[$column['prop']] = $column;
1644 }
1645 }
1646
1647 // Rebuild the columns array in the default order, preserving user customizations
1648 $mergedColumns = [];
1649 $addedColumns = [];
1650
1651 // First, add columns in the default order
1652 foreach ($defaultColumns as $defaultColumn) {
1653 if (isset($existingColumnsByProp[$defaultColumn['prop']])) {
1654 // Use existing column but merge missing properties from defaults
1655 $existingColumn = $existingColumnsByProp[$defaultColumn['prop']];
1656
1657 // Check if any properties from default are missing or different in existing column
1658 $columnNeedsUpdate = false;
1659 foreach ($defaultColumn as $key => $value) {
1660 if (!isset($existingColumn[$key])) {
1661 // Add missing property
1662 $existingColumn[$key] = $value;
1663 $columnNeedsUpdate = true;
1664 } elseif ($key === 'label' && $existingColumn[$key] !== $value) {
1665 // Update label if it has changed in defaults
1666 $existingColumn[$key] = $value;
1667 $columnNeedsUpdate = true;
1668 } elseif ($key === 'sortable' && $existingColumn[$key] !== $value) {
1669 // Update sortable if it has changed in defaults
1670 $existingColumn[$key] = $value;
1671 $columnNeedsUpdate = true;
1672 }
1673 }
1674
1675 if ($columnNeedsUpdate) {
1676 $needsUpdate = true;
1677 }
1678
1679 $mergedColumns[] = $existingColumn;
1680 $addedColumns[] = $defaultColumn['prop'];
1681 } else {
1682 // Add new column from defaults
1683 $mergedColumns[] = $defaultColumn;
1684 $addedColumns[] = $defaultColumn['prop'];
1685 $needsUpdate = true;
1686 }
1687 }
1688
1689 // Then, add any existing columns that are not in defaults (user-added columns)
1690 foreach ($existingColumnsByProp as $prop => $column) {
1691 if (!in_array($prop, $addedColumns)) {
1692 $mergedColumns[] = $column;
1693 }
1694 }
1695
1696 // Check if the order or content changed
1697 if ($mergedColumns !== $savedSettings[$pageKey]) {
1698 $updatedSettings[$pageKey] = $mergedColumns;
1699 $needsUpdate = true;
1700 }
1701 }
1702
1703 // Save updated settings if changes were made
1704 if ($needsUpdate) {
1705 $settingsService->setCategorySettings('pageColumnSettings', $updatedSettings);
1706 }
1707 }
1708
1709
1710 /**
1711 * Init Ics Settings
1712 */
1713 private static function initIcsSettings()
1714 {
1715 $settingsService = new SettingsService(new SettingsStorage());
1716
1717 $savedSettings = $settingsService->getCategorySettings('general');
1718
1719 $settings = [
1720 'sendIcsAttachment' => isset($savedSettings['sendIcsAttachment']) ? $savedSettings['sendIcsAttachment'] : false,
1721 'sendIcsAttachmentPending' => false,
1722 'description' => [
1723 'appointment' => '',
1724 'event' => '',
1725 'translations' => [
1726 'appointment' => null,
1727 'event' => null,
1728 ],
1729 ],
1730 ];
1731
1732 self::initSettings('ics', $settings);
1733 }
1734
1735 private static function isSquareTestMode(): bool
1736 {
1737 if (!defined('AMELIA_DEV')) {
1738 return false;
1739 }
1740
1741 return filter_var(
1742 constant('AMELIA_DEV'),
1743 FILTER_VALIDATE_BOOLEAN,
1744 FILTER_NULL_ON_FAILURE
1745 ) === true;
1746 }
1747
1748 /**
1749 * Get Payments Settings
1750 *
1751 * @param array $savedSettings
1752 *
1753 * @return array
1754 */
1755 public static function getDefaultPaymentsSettings($savedSettings)
1756 {
1757 return [
1758 'currency' => 'USD',
1759 'symbol' => '$',
1760 'priceSymbolPosition' => 'before',
1761 'priceNumberOfDecimals' => 2,
1762 'priceSeparator' => 1,
1763 'hideCurrencySymbolFrontend' => false,
1764 'defaultPaymentMethod' => 'onSite',
1765 'onSite' => true,
1766 'couponsCaseInsensitive' => false,
1767 'paymentLinks' => [
1768 'enabled' => false,
1769 'changeBookingStatus' => false,
1770 'redirectUrl' => AMELIA_SITE_URL
1771 ],
1772 'taxes' => [
1773 'excluded' => true,
1774 ],
1775 'payPal' => [
1776 'enabled' => false,
1777 'sandboxMode' => false,
1778 'liveApiClientId' => '',
1779 'liveApiSecret' => '',
1780 'testApiClientId' => '',
1781 'testApiSecret' => '',
1782 'description' => [
1783 'enabled' => false,
1784 'appointment' => '',
1785 'package' => '',
1786 'event' => '',
1787 'cart' => '',
1788 ],
1789 ],
1790 'stripe' => [
1791 'enabled' => false,
1792 'testMode' => false,
1793 'livePublishableKey' => '',
1794 'liveSecretKey' => '',
1795 'testPublishableKey' => '',
1796 'testSecretKey' => '',
1797 'address' => false,
1798 'description' => [
1799 'enabled' => false,
1800 'appointment' => '',
1801 'package' => '',
1802 'event' => '',
1803 'cart' => '',
1804 ],
1805 'metaData' => [
1806 'enabled' => false,
1807 'appointment' => null,
1808 'package' => null,
1809 'event' => null,
1810 'cart' => '',
1811 ],
1812 'manualCapture' => false,
1813 'returnUrl' => '',
1814 'connect' => [
1815 'enabled' => false,
1816 'method' => 'transfer',
1817 'amount' => 0,
1818 'type' => 'percentage',
1819 'capabilities' => ['card_payments', 'transfers'],
1820 ],
1821 ],
1822 'wc' => [
1823 'enabled' => false,
1824 'productId' => '',
1825 'onSiteIfFree' => false,
1826 'page' => 'cart',
1827 'dashboard' => true,
1828 'checkoutData' => [
1829 'appointment' => '',
1830 'package' => '',
1831 'event' => '',
1832 'cart' => '',
1833 'translations' => [
1834 'appointment' => null,
1835 'event' => null,
1836 'package' => null,
1837 'cart' => '',
1838 ],
1839 ],
1840 'skipCheckoutGetValueProcessing' => isset($savedSettings['wc']['skipCheckoutGetValueProcessing']) ?
1841 $savedSettings['wc']['skipCheckoutGetValueProcessing'] : true,
1842 'skipGetItemDataProcessing' => !isset($savedSettings['wc']),
1843 'redirectPage' => 1,
1844 'bookMultiple' => false,
1845 'rules' =>
1846 isset($savedSettings['wc']['rules']) ? $savedSettings['wc']['rules'] : [
1847 'appointment' => [
1848 [
1849 'order' => 'pending',
1850 'booking' => 'pending',
1851 'payment' => 'pending',
1852 'update' => false,
1853 ],
1854 [
1855 'order' => 'on-hold',
1856 'booking' => 'default',
1857 'payment' => 'paid',
1858 'update' => true,
1859 ],
1860 [
1861 'order' => 'processing',
1862 'booking' => 'default',
1863 'payment' => 'paid',
1864 'update' => true,
1865 ],
1866 [
1867 'order' => 'completed',
1868 'booking' => 'default',
1869 'payment' => 'paid',
1870 'update' => true,
1871 ],
1872 [
1873 'order' => 'cancelled',
1874 'booking' => 'canceled',
1875 'payment' => 'pending',
1876 'update' => true,
1877 ],
1878 [
1879 'order' => 'failed',
1880 'booking' => 'canceled',
1881 'payment' => 'pending',
1882 'update' => true,
1883 ],
1884 ],
1885 'package' => [
1886 [
1887 'order' => 'on-hold',
1888 'booking' => 'approved',
1889 'payment' => 'paid',
1890 'update' => true,
1891 ],
1892 [
1893 'order' => 'processing',
1894 'booking' => 'approved',
1895 'payment' => 'paid',
1896 'update' => true,
1897 ],
1898 [
1899 'order' => 'completed',
1900 'booking' => 'approved',
1901 'payment' => 'paid',
1902 'update' => true,
1903 ],
1904 [
1905 'order' => 'cancelled',
1906 'booking' => 'canceled',
1907 'payment' => 'pending',
1908 'update' => true,
1909 ],
1910 [
1911 'order' => 'failed',
1912 'booking' => 'canceled',
1913 'payment' => 'pending',
1914 'update' => true,
1915 ],
1916 ],
1917 'event' => [
1918 [
1919 'order' => 'pending',
1920 'booking' => 'pending',
1921 'payment' => 'pending',
1922 'update' => false,
1923 ],
1924 [
1925 'order' => 'on-hold',
1926 'booking' => 'approved',
1927 'payment' => 'paid',
1928 'update' => true,
1929 ],
1930 [
1931 'order' => 'processing',
1932 'booking' => 'approved',
1933 'payment' => 'paid',
1934 'update' => true,
1935 ],
1936 [
1937 'order' => 'completed',
1938 'booking' => 'approved',
1939 'payment' => 'paid',
1940 'update' => true,
1941 ],
1942 [
1943 'order' => 'cancelled',
1944 'booking' => 'canceled',
1945 'payment' => 'pending',
1946 'update' => true,
1947 ],
1948 [
1949 'order' => 'failed',
1950 'booking' => 'canceled',
1951 'payment' => 'pending',
1952 'update' => true,
1953 ],
1954 ],
1955 ],
1956 ],
1957 'mollie' => [
1958 'enabled' => false,
1959 'testMode' => false,
1960 'liveApiKey' => '',
1961 'testApiKey' => '',
1962 'description' => [
1963 'enabled' => false,
1964 'appointment' => '',
1965 'package' => '',
1966 'event' => '',
1967 'cart' => '',
1968 ],
1969 'metaData' => [
1970 'enabled' => false,
1971 'appointment' => null,
1972 'package' => null,
1973 'event' => null,
1974 'cart' => '',
1975 ],
1976 'method' => [],
1977 'cancelBooking' => false
1978 ],
1979 'razorpay' => [
1980 'enabled' => false,
1981 'testMode' => false,
1982 'liveKeyId' => '',
1983 'liveKeySecret' => '',
1984 'testKeyId' => '',
1985 'testKeySecret' => '',
1986 'description' => [
1987 'enabled' => false,
1988 'appointment' => '',
1989 'package' => '',
1990 'event' => '',
1991 'cart' => '',
1992 ],
1993 'name' => [
1994 'enabled' => false,
1995 'appointment' => '',
1996 'package' => '',
1997 'event' => '',
1998 'cart' => '',
1999 ],
2000 'metaData' => [
2001 'enabled' => false,
2002 'appointment' => null,
2003 'package' => null,
2004 'event' => null,
2005 'cart' => '',
2006 ],
2007 ],
2008 'square' => [
2009 'enabled' => false,
2010 'locationId' => '',
2011 'accessToken' => '',
2012 'testMode' => self::isSquareTestMode(),
2013 'clientLiveId' => 'sq0idp-TtDyGP_2RfKYpFzrDqs0lw',
2014 'clientTestId' => 'sandbox-sq0idb-Wxnxasx1NMG_ZyvM--JV4Q',
2015 'countryCode' => '',
2016 'description' => [
2017 'enabled' => false,
2018 'appointment' => '',
2019 'package' => '',
2020 'event' => '',
2021 'cart' => ''
2022 ],
2023 'metaData' => [
2024 'enabled' => false,
2025 'appointment' => null,
2026 'package' => null,
2027 'event' => null,
2028 'cart' => null
2029 ],
2030 ],
2031 'barion' => [
2032 'enabled' => false,
2033 'sandboxMode' => false,
2034 'livePOSKey' => '',
2035 'sandboxPOSKey' => '',
2036 'payeeEmail' => '',
2037 'description' => [
2038 'enabled' => false,
2039 'appointment' => '',
2040 'package' => '',
2041 'event' => '',
2042 'cart' => '',
2043 ],
2044 'metaData' => [
2045 'enabled' => false,
2046 'appointment' => null,
2047 'package' => null,
2048 'event' => null,
2049 'cart' => null
2050 ],
2051 ],
2052 ];
2053 }
2054
2055 /**
2056 * Init Payments Settings
2057 */
2058 private static function initPaymentsSettings()
2059 {
2060 $settingsService = new SettingsService(new SettingsStorage());
2061
2062 $savedSettings = $settingsService->getCategorySettings('payments');
2063
2064 $settings = self::getDefaultPaymentsSettings($savedSettings);
2065
2066 self::initSettings('payments', $settings);
2067
2068 self::setNewSettingsToExistingSettings(
2069 'payments',
2070 [
2071 ['stripe', 'connect'],
2072 ['stripe', 'connect', 'capabilities'],
2073 ['stripe', 'description'],
2074 ['stripe', 'description', 'package'],
2075 ['stripe', 'description', 'cart'],
2076 ['stripe', 'metaData'],
2077 ['stripe', 'metaData', 'package'],
2078 ['stripe', 'metaData', 'cart'],
2079 ['stripe', 'manualCapture'],
2080 ['stripe', 'returnUrl'],
2081 ['stripe', 'address'],
2082 ['payPal', 'description'],
2083 ['payPal', 'description', 'package'],
2084 ['payPal', 'description', 'cart'],
2085 ['wc', 'onSiteIfFree'],
2086 ['wc', 'page'],
2087 ['wc', 'dashboard'],
2088 ['wc', 'skipCheckoutGetValueProcessing'],
2089 ['wc', 'skipGetItemDataProcessing'],
2090 ['wc', 'rules'],
2091 ['wc', 'redirectPage'],
2092 ['wc', 'bookMultiple'],
2093 ['wc', 'checkoutData'],
2094 ['wc', 'checkoutData', 'package'],
2095 ['wc', 'checkoutData', 'cart'],
2096 ['wc', 'checkoutData', 'translations'],
2097 ['wc', 'checkoutData', 'translations', 'appointment'],
2098 ['wc', 'checkoutData', 'translations', 'event'],
2099 ['wc', 'checkoutData', 'translations', 'package'],
2100 ['wc', 'checkoutData', 'translations', 'cart'],
2101 ['razorpay', 'name'],
2102 ['razorpay', 'description', 'cart'],
2103 ['razorpay', 'metaData', 'cart'],
2104 ['razorpay', 'name', 'cart'],
2105 ['mollie', 'description', 'cart'],
2106 ['mollie', 'metaData', 'cart'],
2107 ['mollie', 'cancelBooking'],
2108 ['square', 'enabled'],
2109 ['square', 'description', 'cart'],
2110 ['square', 'metaData', 'cart'],
2111 ['square', 'locationId'],
2112 ['square', 'accessToken'],
2113 ['square', 'testMode'],
2114 ['square', 'clientLiveId'],
2115 ['square', 'clientTestId'],
2116 ['square', 'countryCode'],
2117 ['barion', 'metaData'],
2118 ],
2119 $settings
2120 );
2121
2122 self::syncSquareTestModeForDev();
2123 }
2124
2125 /**
2126 * Ensure Square sandbox mode is enabled on dev environments for existing installations.
2127 */
2128 private static function syncSquareTestModeForDev(): void
2129 {
2130 if (!self::isSquareTestMode()) {
2131 return;
2132 }
2133
2134 $settingsService = new SettingsService(new SettingsStorage());
2135 $savedSettings = $settingsService->getCategorySettings('payments');
2136
2137 if (empty($savedSettings['square']) || !empty($savedSettings['square']['testMode'])) {
2138 return;
2139 }
2140
2141 $savedSettings['square']['testMode'] = true;
2142 self::initSettings('payments', $savedSettings, true);
2143 }
2144
2145 /**
2146 * Init Purchase Code Settings
2147 */
2148 private static function initActivationSettings()
2149 {
2150 $settingsService = new SettingsService(new SettingsStorage());
2151
2152 $savedSettings = $settingsService->getCategorySettings('activation');
2153
2154 $isNewInstallation = empty($savedSettings);
2155
2156 $settings = [
2157 'showActivationSettings' => true,
2158 'active' => false,
2159 'purchaseCodeStore' => '',
2160 'envatoTokenEmail' => '',
2161 'version' => '',
2162 'deleteTables' => false,
2163 'showAmeliaPromoCustomizePopup' => true,
2164 'showAmeliaSurvey' => true,
2165 'showWelcomePage' => true,
2166 'stash' => false,
2167 'responseErrorAsConflict' => $savedSettings ? false : true,
2168 'hideTipsAndSuggestions' => false,
2169 'hideUnavailableFeatures' => false,
2170 'licence' => '',
2171 'disableUrlParams' => $savedSettings ? false : true,
2172 'enableThriveItems' => false,
2173 'customUrl' => [
2174 'enabled' => false,
2175 'pluginPath' => '/wp-content/plugins/ameliabooking/',
2176 'ajaxPath' => '/wp-admin/admin-ajax.php',
2177 'uploadsPath' => '',
2178 ],
2179 'v3RelativePath' => false,
2180 'v3AsyncLoading' => false,
2181 'premiumBannerVisibility' => true,
2182 'dismissibleBannerVisibility' => true,
2183 ];
2184
2185 self::initSettings('activation', $settings);
2186
2187 $savedSettings['showAmeliaPromoCustomizePopup'] = true;
2188
2189 $savedSettings['isNewInstallation'] = $isNewInstallation;
2190
2191 self::initSettings('activation', $savedSettings, true);
2192 }
2193
2194 /**
2195 * Init Labels Settings
2196 */
2197 private static function initLabelsSettings()
2198 {
2199 $settings = [
2200 'enabled' => true,
2201 'employee' => 'employee',
2202 'employees' => 'employees',
2203 'service' => 'service',
2204 'services' => 'services'
2205 ];
2206
2207 self::initSettings('labels', $settings);
2208 }
2209
2210 /**
2211 * Init Roles Settings
2212 *
2213 * @return array
2214 */
2215 public static function getDefaultRolesSettings()
2216 {
2217 $permissionChecker = new PermissionsChecker();
2218
2219 return [
2220 'allowConfigureSchedule' => false,
2221 'allowConfigureDaysOff' => false,
2222 'allowConfigureSpecialDays' => false,
2223 'allowConfigureServices' => false,
2224 'allowWriteAppointments' => false,
2225 'allowWriteCustomers' => false,
2226 'allowReadAllCustomers' => $permissionChecker->hasCapability(
2227 Entities::PROVIDER,
2228 'amelia_read_others_customers'
2229 ),
2230 'automaticallyCreateCustomer' => false,
2231 'inspectCustomerInfo' => false,
2232 'allowCustomerReschedule' => false,
2233 'allowCustomerCancelPackages' => true,
2234 'allowCustomerDeleteProfile' => false,
2235 'allowWriteEvents' => false,
2236 'allowAdminBookAtAnyTime' => false,
2237 'allowAdminBookOverApp' => false,
2238 'adminServiceDurationAsSlot' => false,
2239 'enabledHttpAuthorization' => true,
2240 'customerCabinet' => [
2241 'headerJwtSecret' => (new Token(null, 20))->getValue(),
2242 'urlJwtSecret' => (new Token(null, 20))->getValue(),
2243 'tokenValidTime' => 2592000,
2244 'pageUrl' => '',
2245 'loginEnabled' => true,
2246 'filterDate' => false,
2247 'translations' => [],
2248 'googleRecaptcha' => false,
2249 ],
2250 'providerCabinet' => [
2251 'headerJwtSecret' => (new Token(null, 20))->getValue(),
2252 'urlJwtSecret' => (new Token(null, 20))->getValue(),
2253 'tokenValidTime' => 2592000,
2254 'pageUrl' => '',
2255 'loginEnabled' => true,
2256 'filterDate' => false,
2257 'googleRecaptcha' => false,
2258 ],
2259 'urlAttachment' => [
2260 'enabled' => true,
2261 'headerJwtSecret' => (new Token(null, 20))->getValue(),
2262 'urlJwtSecret' => (new Token(null, 20))->getValue(),
2263 'tokenValidTime' => 2592000,
2264 'pageUrl' => '',
2265 'loginEnabled' => true,
2266 'filterDate' => false,
2267 ],
2268 'limitPerCustomerService' => [
2269 'enabled' => false,
2270 'numberOfApp' => 1,
2271 'timeFrame' => 'day',
2272 'period' => 1,
2273 'from' => 'bookingDate'
2274 ],
2275 'limitPerCustomerPackage' => [
2276 'enabled' => false,
2277 'numberOfApp' => 1,
2278 'timeFrame' => 'day',
2279 'period' => 1,
2280 ],
2281 'limitPerCustomerEvent' => [
2282 'enabled' => false,
2283 'numberOfApp' => 1,
2284 'timeFrame' => 'day',
2285 'period' => 1,
2286 'from' => 'bookingDate'
2287 ],
2288 'limitPerEmployee' => [
2289 'enabled' => false,
2290 'numberOfApp' => 1,
2291 'timeFrame' => 'day',
2292 'period' => 1,
2293 ],
2294 'providerBadges' => [
2295 'counter' => 3,
2296 'badges' => [
2297 [
2298 'id' => 1,
2299 'content' => 'Most Popular',
2300 'color' => '#316bff'
2301 ],
2302 [
2303 'id' => 2,
2304 'content' => 'Top Performer',
2305 'color' => '#06a192'
2306 ],
2307 [
2308 'id' => 3,
2309 'content' => 'Exclusive',
2310 'color' => '#facc15'
2311 ],
2312 ]
2313 ],
2314 ];
2315 }
2316
2317 /**
2318 * Init Roles Settings
2319 */
2320 private static function initRolesSettings()
2321 {
2322 $settings = self::getDefaultRolesSettings();
2323
2324 self::initSettings('roles', $settings);
2325
2326 self::setNewSettingsToExistingSettings(
2327 'roles',
2328 [
2329 ['customerCabinet', 'filterDate'],
2330 ['customerCabinet', 'translations'],
2331 ['customerCabinet', 'headerJwtSecret'],
2332 ['customerCabinet', 'urlJwtSecret'],
2333 ['customerCabinet', 'googleRecaptcha'],
2334 ['providerCabinet', 'headerJwtSecret'],
2335 ['providerCabinet', 'urlJwtSecret'],
2336 ['providerCabinet', 'googleRecaptcha'],
2337 ['urlAttachment', 'headerJwtSecret'],
2338 ['urlAttachment', 'urlJwtSecret'],
2339 ],
2340 $settings
2341 );
2342 }
2343
2344 /**
2345 * Get Appointments Settings
2346 *
2347 * @return array
2348 */
2349 public static function getDefaultAppointmentsSettings()
2350 {
2351 return [
2352 'isGloballyBusySlot' => false,
2353 'bookMultipleTimes' => false,
2354 'allowBookingIfPending' => true,
2355 'allowBookingIfNotMin' => true,
2356 'openedBookingAfterMin' => false,
2357 'cartPlaceholders' => '<!-- Content --><p>DateTime: %appointment_date_time%</p>',
2358 'cartPlaceholdersSms' => 'DateTime: %appointment_date_time%',
2359 'cartPlaceholdersCustomer' => '<!-- Content --><p>DateTime: %appointment_date_time%</p>',
2360 'cartPlaceholdersCustomerSms' => 'DateTime: %appointment_date_time%',
2361 'recurringPlaceholders' => 'DateTime: %appointment_date_time%',
2362 'recurringPlaceholdersSms' => 'DateTime: %appointment_date_time%',
2363 'recurringPlaceholdersCustomer' => 'DateTime: %appointment_date_time%',
2364 'recurringPlaceholdersCustomerSms' => 'DateTime: %appointment_date_time%',
2365 'packagePlaceholders' => 'DateTime: %appointment_date_time%',
2366 'packagePlaceholdersSms' => 'DateTime: %appointment_date_time%',
2367 'packagePlaceholdersCustomer' => 'DateTime: %appointment_date_time%',
2368 'packagePlaceholdersCustomerSms' => 'DateTime: %appointment_date_time%',
2369 'groupAppointmentPlaceholder' => 'Name: %customer_full_name%',
2370 'groupEventPlaceholder' => 'Name: %customer_full_name%',
2371 'groupAppointmentPlaceholderSms' => 'Name: %customer_full_name%',
2372 'groupEventPlaceholderSms' => 'Name: %customer_full_name%',
2373 'translations' => [
2374 'cartPlaceholdersCustomer' => null,
2375 'cartPlaceholdersCustomerSms' => null,
2376 'recurringPlaceholdersCustomer' => null,
2377 'recurringPlaceholdersCustomerSms' => null,
2378 'packagePlaceholdersCustomer' => null,
2379 'packagePlaceholdersCustomerSms' => null,
2380 'groupAppointmentPlaceholder' => 'Name: %customer_full_name%',
2381 'groupEventPlaceholder' => 'Name: %customer_full_name%',
2382 'groupAppointmentPlaceholderSms' => 'Name: %customer_full_name%',
2383 'groupEventPlaceholderSms' => 'Name: %customer_full_name%',
2384 ],
2385 'waitingListEvents' => [
2386 'addingMethod' => 'Manually'
2387 ],
2388 'qrCodeEvents' => [
2389 'enabled' => false,
2390 ],
2391 'waitingListAppointments' => [
2392 'enabled' => false,
2393 'redirectUrlDenied' => ''
2394 ],
2395 'pastDaysEvents' => 0,
2396 'employeeSelection' => 'random',
2397 'bringingAnyoneLogic' => 'additional',
2398 'automaticallyCreateEventCustomPost' => false,
2399 ];
2400 }
2401
2402 /**
2403 * Init Appointments Settings
2404 */
2405 private static function initAppointmentsSettings()
2406 {
2407 $settings = self::getDefaultAppointmentsSettings();
2408
2409 self::initSettings('appointments', $settings);
2410
2411 self::setNewSettingsToExistingSettings(
2412 'appointments',
2413 [
2414 ['translations', 'cartPlaceholdersCustomer'],
2415 ['translations', 'cartPlaceholdersCustomerSms'],
2416 ],
2417 $settings
2418 );
2419 }
2420
2421 /**
2422 * Init Web Hooks Settings
2423 */
2424 private static function initWebHooksSettings()
2425 {
2426 $settings = [];
2427
2428 self::initSettings('webHooks', $settings);
2429 }
2430
2431 /**
2432 * get Back Link Setting
2433 */
2434 private static function getBackLinkSetting()
2435 {
2436 $settingsService = new SettingsService(new SettingsStorage());
2437
2438 $backLinksLabels = [
2439 'Generated with Amelia - WordPress Booking Plugin',
2440 'Powered by Amelia - WordPress Booking Plugin',
2441 'Booking by Amelia - WordPress Booking Plugin',
2442 'Powered by Amelia - Appointment and Events Booking Plugin',
2443 'Powered by Amelia - Appointment and Event Booking Plugin',
2444 'Powered by Amelia - WordPress Booking Plugin',
2445 'Generated with Amelia - Appointment and Event Booking Plugin',
2446 'Booking Enabled by Amelia - Appointment and Event Booking Plugin',
2447 ];
2448
2449 $backLinksUrls = [
2450 'https://wpamelia.com/?utm_source=lite&utm_medium=websites&utm_campaign=powerdby',
2451 'https://wpamelia.com/demos/?utm_source=lite&utm_medium=website&utm_campaign=powerdby#Features-list',
2452 'https://wpamelia.com/pricing/?utm_source=lite&utm_medium=website&utm_campaign=powerdby',
2453 'https://wpamelia.com/documentation/?utm_source=lite&utm_medium=website&utm_campaign=powerdby',
2454 ];
2455
2456 return [
2457 'enabled' => $settingsService->getCategorySettings('general') === null,
2458 'label' => $backLinksLabels[rand(0, 7)],
2459 'url' => $backLinksUrls[rand(0, 3)],
2460 ];
2461 }
2462
2463 /**
2464 * Add new settings ti global parent settings
2465 *
2466 * @param string $category
2467 * @param array $pathsKeys
2468 * @param array $initSettings
2469 */
2470 private static function setNewSettingsToExistingSettings($category, $pathsKeys, $initSettings)
2471 {
2472 $settingsService = new SettingsService(new SettingsStorage());
2473
2474 $savedSettings = $settingsService->getCategorySettings($category);
2475
2476 $activationSettings = $settingsService->getCategorySettings('activation');
2477 $savedVersion = !empty($activationSettings['version']) ? $activationSettings['version'] : '0.0.0';
2478
2479 $setSettings = false;
2480
2481 foreach ($pathsKeys as $keys) {
2482 $current = &$savedSettings;
2483
2484 $currentInit = &$initSettings;
2485
2486 foreach ((array)$keys as $key) {
2487 if (!isset($current[$key])) {
2488 $current[$key] = !empty($currentInit[$key]) ? $currentInit[$key] : null;
2489
2490 $setSettings = true;
2491
2492 continue 2;
2493 }
2494
2495 // If the saved value is a JSON-encoded string but the new schema expects
2496 // a nested array (i.e. there are more keys to traverse), decode it so
2497 // that subsequent keys can be accessed without a PHP 8 TypeError.
2498 // This fix is only applied when upgrading from versions before 9.2
2499 if (version_compare($savedVersion, '9.2', '<') && is_string($current[$key])) {
2500 $decoded = json_decode($current[$key], true);
2501 if (is_array($decoded)) {
2502 $current[$key] = $decoded;
2503 $setSettings = true;
2504 } else {
2505 // Scalar string with no deeper path possible — skip this path.
2506 continue 2;
2507 }
2508 } elseif (!is_array($current[$key])) {
2509 // Boolean / int leaf where a nested array is expected — skip.
2510 continue 2;
2511 }
2512
2513 $current = &$current[$key];
2514
2515 $currentInit = &$currentInit[$key];
2516 }
2517 }
2518
2519 if ($setSettings) {
2520 self::initSettings($category, $savedSettings, true);
2521 }
2522 }
2523
2524 /**
2525 * Init Social Login Settings
2526 */
2527 private static function initSocialLoginSettings()
2528 {
2529 $settings = [
2530 'facebookAppId' => '',
2531 'facebookAppSecret' => '',
2532 ];
2533
2534 self::initSettings('socialLogin', $settings);
2535 }
2536
2537 /**
2538 * Init Features and Integrations Settings
2539 */
2540 private static function initFeaturesIntegrationsSettings()
2541 {
2542 $settingsService = new SettingsService(new SettingsStorage());
2543
2544 $saved = $settingsService->getAllSettingsCategorized();
2545
2546 $old = empty($saved['activation']['isNewInstallation']);
2547
2548 $starterAndUp = Licence::getLicence() === 'Developer' ||
2549 Licence::getLicence() === 'Pro' ||
2550 Licence::getLicence() === 'Basic' ||
2551 Licence::getLicence() === 'Starter';
2552
2553 $basicAndUp = Licence::getLicence() === 'Developer' || Licence::getLicence() === 'Pro' || Licence::getLicence() === 'Basic';
2554
2555 $proAndUp = Licence::getLicence() === 'Developer' || Licence::getLicence() === 'Pro';
2556
2557 $settings = [
2558 'googleCalendar' => [
2559 'enabled' => $old &&
2560 $basicAndUp &&
2561 !empty($saved['googleCalendar']['calendarEnabled']),
2562 ],
2563 'appleCalendar' => [
2564 'enabled' => $old &&
2565 $basicAndUp &&
2566 !empty($saved['appleCalendar']['clientID']) &&
2567 !empty($saved['appleCalendar']['clientSecret']),
2568 ],
2569 'outlookCalendar' => [
2570 'enabled' => $old &&
2571 $basicAndUp &&
2572 !empty($saved['outlookCalendar']['calendarEnabled']),
2573 ],
2574 'zoom' => [
2575 'enabled' => $old &&
2576 $basicAndUp &&
2577 !empty($saved['zoom']['accountId']) &&
2578 !empty($saved['zoom']['clientId']) &&
2579 !empty($saved['zoom']['clientSecret']),
2580 ],
2581 'webhooks' => [
2582 'enabled' => $basicAndUp,
2583 ],
2584 'facebookPixel' => [
2585 'enabled' => $old && $starterAndUp && !empty($saved['facebookPixel']['id']),
2586 ],
2587 'googleAnalytics' => [
2588 'enabled' => $old && $starterAndUp && !empty($saved['googleAnalytics']['id']),
2589 ],
2590 'lessonSpace' => [
2591 'enabled' => $old && $starterAndUp && !empty($saved['lessonSpace']['apiKey']),
2592 ],
2593 'recaptcha' => [
2594 'enabled' => $old &&
2595 $starterAndUp &&
2596 !empty($saved['general']['googleRecaptcha']['enabled']) &&
2597 !empty($saved['general']['googleRecaptcha']['siteKey']) &&
2598 !empty($saved['general']['googleRecaptcha']['secret']),
2599 ],
2600 'mollie' => [
2601 'enabled' => $old && $basicAndUp && !empty($saved['payments']['mollie']['enabled']),
2602 ],
2603 'wc' => [
2604 'enabled' => $old && $basicAndUp && !empty($saved['payments']['wc']['enabled']),
2605 ],
2606 'payPal' => [
2607 'enabled' => $old && $basicAndUp && !empty($saved['payments']['payPal']['enabled']),
2608 ],
2609 'stripe' => [
2610 'enabled' => $old && $basicAndUp && !empty($saved['payments']['stripe']['enabled']),
2611 ],
2612 'razorpay' => [
2613 'enabled' => $old && $basicAndUp && !empty($saved['payments']['razorpay']['enabled']),
2614 ],
2615 'square' => [
2616 'enabled' => $old && !empty($saved['payments']['square']['enabled']),
2617 ],
2618 'barion' => [
2619 'enabled' => $old && $basicAndUp && !empty($saved['payments']['barion']['enabled']),
2620 ],
2621 'packages' => [
2622 'enabled' => $proAndUp,
2623 ],
2624 'resources' => [
2625 'enabled' => $proAndUp,
2626 ],
2627 'customFields' => [
2628 'enabled' => $basicAndUp,
2629 ],
2630 'coupons' => [
2631 'enabled' => $old && $starterAndUp && !empty($saved['payments']['coupons']),
2632 ],
2633 'customNotifications' => [
2634 'enabled' => $basicAndUp,
2635 ],
2636 'tax' => [
2637 'enabled' => $basicAndUp && (!$old || !empty($saved['payments']['taxes']['enabled'])),
2638 ],
2639 'invoices' => [
2640 'enabled' => $basicAndUp,
2641 ],
2642 'whatsapp' => [
2643 'enabled' => $old &&
2644 $proAndUp &&
2645 !empty($saved['notifications']['whatsAppEnabled']) &&
2646 !empty($saved['notifications']['whatsAppPhoneID']) &&
2647 !empty($saved['notifications']['whatsAppAccessToken']) &&
2648 !empty($saved['notifications']['whatsAppBusinessID']),
2649 ],
2650 'recurringEvents' => [
2651 'enabled' => $basicAndUp,
2652 ],
2653 'tickets' => [
2654 'enabled' => $basicAndUp,
2655 ],
2656 'waitingList' => [
2657 'enabled' => $proAndUp && (!$old || !empty($saved['appointments']['waitingListEvents']['enabled'])),
2658 ],
2659 'waitingListAppointments' => [
2660 'enabled' => $proAndUp && (!$old || !empty($saved['appointments']['waitingListAppointments']['enabled'])),
2661 ],
2662 'customPricing' => [
2663 'enabled' => $basicAndUp,
2664 ],
2665 'recurringAppointments' => [
2666 'enabled' => $basicAndUp,
2667 ],
2668 'extras' => [
2669 'enabled' => $starterAndUp,
2670 ],
2671 'cart' => [
2672 'enabled' => $old && $proAndUp && !empty($saved['payments']['cart']),
2673 ],
2674 'timezones' => [
2675 'enabled' => $basicAndUp,
2676 ],
2677 'depositPayment' => [
2678 'enabled' => $basicAndUp,
2679 ],
2680 'noShowTag' => [
2681 'enabled' => $basicAndUp && (!$old || !empty($saved['roles']['enableNoShowTag'])),
2682 ],
2683 'apis' => [
2684 'enabled' => Licence::getLicence() === 'Developer',
2685 ],
2686 'buddyboss' => [
2687 'enabled' => $basicAndUp && $old,
2688 ],
2689 'employeeBadge' => [
2690 'enabled' => $basicAndUp,
2691 ],
2692 'mailchimp' => [
2693 'enabled' => $old && $basicAndUp && !empty($saved['mailchimp']['accessToken']),
2694 ],
2695 'googleSocialLogin' => [
2696 'enabled' => $old && $basicAndUp && !empty($saved['socialLogin']['enableGoogleLogin']),
2697 ],
2698 'facebookSocialLogin' => [
2699 'enabled' => $old && $basicAndUp && !empty($saved['socialLogin']['enableFacebookLogin']),
2700 ],
2701 'eTickets' => [
2702 'enabled' => $proAndUp && (!$old || !empty($saved['appointments']['qrCodeEvents']['enabled'])),
2703 ],
2704 'eventTags' => [
2705 'enabled' => $starterAndUp && (!$old || EventsTagsTable::hasTags()),
2706 ],
2707 'ivy' => [
2708 'enabled' => false,
2709 ],
2710 ];
2711
2712 self::initSettings('featuresIntegrations', $settings);
2713 }
2714 }
2715