PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
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 3 weeks ago ActivationDatabaseHook.php 6 months ago ActivationMultisite.php 1 year ago ActivationNewSiteMultisite.php 1 month ago ActivationRolesHook.php 1 year ago ActivationSettingsHook.php 3 weeks ago AutoUpdateHook.php 1 month ago DeleteDatabaseHook.php 1 year ago DeletionMultisite.php 1 year ago
ActivationSettingsHook.php
2679 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 /**
1736 * Get Payments Settings
1737 *
1738 * @param array $savedSettings
1739 *
1740 * @return array
1741 */
1742 public static function getDefaultPaymentsSettings($savedSettings)
1743 {
1744 return [
1745 'currency' => 'USD',
1746 'symbol' => '$',
1747 'priceSymbolPosition' => 'before',
1748 'priceNumberOfDecimals' => 2,
1749 'priceSeparator' => 1,
1750 'hideCurrencySymbolFrontend' => false,
1751 'defaultPaymentMethod' => 'onSite',
1752 'onSite' => true,
1753 'couponsCaseInsensitive' => false,
1754 'paymentLinks' => [
1755 'enabled' => false,
1756 'changeBookingStatus' => false,
1757 'redirectUrl' => AMELIA_SITE_URL
1758 ],
1759 'taxes' => [
1760 'excluded' => true,
1761 ],
1762 'payPal' => [
1763 'enabled' => false,
1764 'sandboxMode' => false,
1765 'liveApiClientId' => '',
1766 'liveApiSecret' => '',
1767 'testApiClientId' => '',
1768 'testApiSecret' => '',
1769 'description' => [
1770 'enabled' => false,
1771 'appointment' => '',
1772 'package' => '',
1773 'event' => '',
1774 'cart' => '',
1775 ],
1776 ],
1777 'stripe' => [
1778 'enabled' => false,
1779 'testMode' => false,
1780 'livePublishableKey' => '',
1781 'liveSecretKey' => '',
1782 'testPublishableKey' => '',
1783 'testSecretKey' => '',
1784 'address' => false,
1785 'description' => [
1786 'enabled' => false,
1787 'appointment' => '',
1788 'package' => '',
1789 'event' => '',
1790 'cart' => '',
1791 ],
1792 'metaData' => [
1793 'enabled' => false,
1794 'appointment' => null,
1795 'package' => null,
1796 'event' => null,
1797 'cart' => '',
1798 ],
1799 'manualCapture' => false,
1800 'returnUrl' => '',
1801 'connect' => [
1802 'enabled' => false,
1803 'method' => 'transfer',
1804 'amount' => 0,
1805 'type' => 'percentage',
1806 'capabilities' => ['card_payments', 'transfers'],
1807 ],
1808 ],
1809 'wc' => [
1810 'enabled' => false,
1811 'productId' => '',
1812 'onSiteIfFree' => false,
1813 'page' => 'cart',
1814 'dashboard' => true,
1815 'checkoutData' => [
1816 'appointment' => '',
1817 'package' => '',
1818 'event' => '',
1819 'cart' => '',
1820 'translations' => [
1821 'appointment' => null,
1822 'event' => null,
1823 'package' => null,
1824 'cart' => '',
1825 ],
1826 ],
1827 'skipCheckoutGetValueProcessing' => isset($savedSettings['wc']['skipCheckoutGetValueProcessing']) ?
1828 $savedSettings['wc']['skipCheckoutGetValueProcessing'] : true,
1829 'skipGetItemDataProcessing' => !isset($savedSettings['wc']),
1830 'redirectPage' => 1,
1831 'bookMultiple' => false,
1832 'rules' =>
1833 isset($savedSettings['wc']['rules']) ? $savedSettings['wc']['rules'] : [
1834 'appointment' => [
1835 [
1836 'order' => 'pending',
1837 'booking' => 'pending',
1838 'payment' => 'pending',
1839 'update' => false,
1840 ],
1841 [
1842 'order' => 'on-hold',
1843 'booking' => 'default',
1844 'payment' => 'paid',
1845 'update' => true,
1846 ],
1847 [
1848 'order' => 'processing',
1849 'booking' => 'default',
1850 'payment' => 'paid',
1851 'update' => true,
1852 ],
1853 [
1854 'order' => 'completed',
1855 'booking' => 'default',
1856 'payment' => 'paid',
1857 'update' => true,
1858 ],
1859 [
1860 'order' => 'cancelled',
1861 'booking' => 'canceled',
1862 'payment' => 'pending',
1863 'update' => true,
1864 ],
1865 [
1866 'order' => 'failed',
1867 'booking' => 'canceled',
1868 'payment' => 'pending',
1869 'update' => true,
1870 ],
1871 ],
1872 'package' => [
1873 [
1874 'order' => 'on-hold',
1875 'booking' => 'approved',
1876 'payment' => 'paid',
1877 'update' => true,
1878 ],
1879 [
1880 'order' => 'processing',
1881 'booking' => 'approved',
1882 'payment' => 'paid',
1883 'update' => true,
1884 ],
1885 [
1886 'order' => 'completed',
1887 'booking' => 'approved',
1888 'payment' => 'paid',
1889 'update' => true,
1890 ],
1891 [
1892 'order' => 'cancelled',
1893 'booking' => 'canceled',
1894 'payment' => 'pending',
1895 'update' => true,
1896 ],
1897 [
1898 'order' => 'failed',
1899 'booking' => 'canceled',
1900 'payment' => 'pending',
1901 'update' => true,
1902 ],
1903 ],
1904 'event' => [
1905 [
1906 'order' => 'pending',
1907 'booking' => 'pending',
1908 'payment' => 'pending',
1909 'update' => false,
1910 ],
1911 [
1912 'order' => 'on-hold',
1913 'booking' => 'approved',
1914 'payment' => 'paid',
1915 'update' => true,
1916 ],
1917 [
1918 'order' => 'processing',
1919 'booking' => 'approved',
1920 'payment' => 'paid',
1921 'update' => true,
1922 ],
1923 [
1924 'order' => 'completed',
1925 'booking' => 'approved',
1926 'payment' => 'paid',
1927 'update' => true,
1928 ],
1929 [
1930 'order' => 'cancelled',
1931 'booking' => 'canceled',
1932 'payment' => 'pending',
1933 'update' => true,
1934 ],
1935 [
1936 'order' => 'failed',
1937 'booking' => 'canceled',
1938 'payment' => 'pending',
1939 'update' => true,
1940 ],
1941 ],
1942 ],
1943 ],
1944 'mollie' => [
1945 'enabled' => false,
1946 'testMode' => false,
1947 'liveApiKey' => '',
1948 'testApiKey' => '',
1949 'description' => [
1950 'enabled' => false,
1951 'appointment' => '',
1952 'package' => '',
1953 'event' => '',
1954 'cart' => '',
1955 ],
1956 'metaData' => [
1957 'enabled' => false,
1958 'appointment' => null,
1959 'package' => null,
1960 'event' => null,
1961 'cart' => '',
1962 ],
1963 'method' => [],
1964 'cancelBooking' => false
1965 ],
1966 'razorpay' => [
1967 'enabled' => false,
1968 'testMode' => false,
1969 'liveKeyId' => '',
1970 'liveKeySecret' => '',
1971 'testKeyId' => '',
1972 'testKeySecret' => '',
1973 'description' => [
1974 'enabled' => false,
1975 'appointment' => '',
1976 'package' => '',
1977 'event' => '',
1978 'cart' => '',
1979 ],
1980 'name' => [
1981 'enabled' => false,
1982 'appointment' => '',
1983 'package' => '',
1984 'event' => '',
1985 'cart' => '',
1986 ],
1987 'metaData' => [
1988 'enabled' => false,
1989 'appointment' => null,
1990 'package' => null,
1991 'event' => null,
1992 'cart' => '',
1993 ],
1994 ],
1995 'square' => [
1996 'enabled' => false,
1997 'locationId' => '',
1998 'accessToken' => '',
1999 'testMode' => false,
2000 'clientLiveId' => 'sq0idp-TtDyGP_2RfKYpFzrDqs0lw',
2001 'clientTestId' => 'sandbox-sq0idb-Wxnxasx1NMG_ZyvM--JV4Q',
2002 'countryCode' => '',
2003 'description' => [
2004 'enabled' => false,
2005 'appointment' => '',
2006 'package' => '',
2007 'event' => '',
2008 'cart' => ''
2009 ],
2010 'metaData' => [
2011 'enabled' => false,
2012 'appointment' => null,
2013 'package' => null,
2014 'event' => null,
2015 'cart' => null
2016 ],
2017 ],
2018 'barion' => [
2019 'enabled' => false,
2020 'sandboxMode' => false,
2021 'livePOSKey' => '',
2022 'sandboxPOSKey' => '',
2023 'payeeEmail' => '',
2024 'description' => [
2025 'enabled' => false,
2026 'appointment' => '',
2027 'package' => '',
2028 'event' => '',
2029 'cart' => '',
2030 ],
2031 'metaData' => [
2032 'enabled' => false,
2033 'appointment' => null,
2034 'package' => null,
2035 'event' => null,
2036 'cart' => null
2037 ],
2038 ],
2039 ];
2040 }
2041
2042 /**
2043 * Init Payments Settings
2044 */
2045 private static function initPaymentsSettings()
2046 {
2047 $settingsService = new SettingsService(new SettingsStorage());
2048
2049 $savedSettings = $settingsService->getCategorySettings('payments');
2050
2051 $settings = self::getDefaultPaymentsSettings($savedSettings);
2052
2053 self::initSettings('payments', $settings);
2054
2055 self::setNewSettingsToExistingSettings(
2056 'payments',
2057 [
2058 ['stripe', 'connect'],
2059 ['stripe', 'connect', 'capabilities'],
2060 ['stripe', 'description'],
2061 ['stripe', 'description', 'package'],
2062 ['stripe', 'description', 'cart'],
2063 ['stripe', 'metaData'],
2064 ['stripe', 'metaData', 'package'],
2065 ['stripe', 'metaData', 'cart'],
2066 ['stripe', 'manualCapture'],
2067 ['stripe', 'returnUrl'],
2068 ['stripe', 'address'],
2069 ['payPal', 'description'],
2070 ['payPal', 'description', 'package'],
2071 ['payPal', 'description', 'cart'],
2072 ['wc', 'onSiteIfFree'],
2073 ['wc', 'page'],
2074 ['wc', 'dashboard'],
2075 ['wc', 'skipCheckoutGetValueProcessing'],
2076 ['wc', 'skipGetItemDataProcessing'],
2077 ['wc', 'rules'],
2078 ['wc', 'redirectPage'],
2079 ['wc', 'bookMultiple'],
2080 ['wc', 'checkoutData'],
2081 ['wc', 'checkoutData', 'package'],
2082 ['wc', 'checkoutData', 'cart'],
2083 ['wc', 'checkoutData', 'translations'],
2084 ['wc', 'checkoutData', 'translations', 'appointment'],
2085 ['wc', 'checkoutData', 'translations', 'event'],
2086 ['wc', 'checkoutData', 'translations', 'package'],
2087 ['wc', 'checkoutData', 'translations', 'cart'],
2088 ['razorpay', 'name'],
2089 ['razorpay', 'description', 'cart'],
2090 ['razorpay', 'metaData', 'cart'],
2091 ['razorpay', 'name', 'cart'],
2092 ['mollie', 'description', 'cart'],
2093 ['mollie', 'metaData', 'cart'],
2094 ['mollie', 'cancelBooking'],
2095 ['square', 'enabled'],
2096 ['square', 'description', 'cart'],
2097 ['square', 'metaData', 'cart'],
2098 ['square', 'locationId'],
2099 ['square', 'accessToken'],
2100 ['square', 'testMode'],
2101 ['square', 'clientLiveId'],
2102 ['square', 'clientTestId'],
2103 ['square', 'countryCode'],
2104 ['barion', 'metaData'],
2105 ],
2106 $settings
2107 );
2108 }
2109
2110 /**
2111 * Init Purchase Code Settings
2112 */
2113 private static function initActivationSettings()
2114 {
2115 $settingsService = new SettingsService(new SettingsStorage());
2116
2117 $savedSettings = $settingsService->getCategorySettings('activation');
2118
2119 $isNewInstallation = empty($savedSettings);
2120
2121 $settings = [
2122 'showActivationSettings' => true,
2123 'active' => false,
2124 'purchaseCodeStore' => '',
2125 'envatoTokenEmail' => '',
2126 'version' => '',
2127 'deleteTables' => false,
2128 'showAmeliaPromoCustomizePopup' => true,
2129 'showAmeliaSurvey' => true,
2130 'showWelcomePage' => true,
2131 'stash' => false,
2132 'responseErrorAsConflict' => $savedSettings ? false : true,
2133 'hideTipsAndSuggestions' => false,
2134 'hideUnavailableFeatures' => false,
2135 'licence' => '',
2136 'disableUrlParams' => $savedSettings ? false : true,
2137 'enableThriveItems' => false,
2138 'customUrl' => [
2139 'enabled' => false,
2140 'pluginPath' => '/wp-content/plugins/ameliabooking/',
2141 'ajaxPath' => '/wp-admin/admin-ajax.php',
2142 'uploadsPath' => '',
2143 ],
2144 'v3RelativePath' => false,
2145 'v3AsyncLoading' => false,
2146 'premiumBannerVisibility' => true,
2147 'dismissibleBannerVisibility' => true,
2148 ];
2149
2150 self::initSettings('activation', $settings);
2151
2152 $savedSettings['showAmeliaPromoCustomizePopup'] = true;
2153
2154 $savedSettings['isNewInstallation'] = $isNewInstallation;
2155
2156 self::initSettings('activation', $savedSettings, true);
2157 }
2158
2159 /**
2160 * Init Labels Settings
2161 */
2162 private static function initLabelsSettings()
2163 {
2164 $settings = [
2165 'enabled' => true,
2166 'employee' => 'employee',
2167 'employees' => 'employees',
2168 'service' => 'service',
2169 'services' => 'services'
2170 ];
2171
2172 self::initSettings('labels', $settings);
2173 }
2174
2175 /**
2176 * Init Roles Settings
2177 *
2178 * @return array
2179 */
2180 public static function getDefaultRolesSettings()
2181 {
2182 $permissionChecker = new PermissionsChecker();
2183
2184 return [
2185 'allowConfigureSchedule' => false,
2186 'allowConfigureDaysOff' => false,
2187 'allowConfigureSpecialDays' => false,
2188 'allowConfigureServices' => false,
2189 'allowWriteAppointments' => false,
2190 'allowWriteCustomers' => false,
2191 'allowReadAllCustomers' => $permissionChecker->hasCapability(
2192 Entities::PROVIDER,
2193 'amelia_read_others_customers'
2194 ),
2195 'automaticallyCreateCustomer' => false,
2196 'inspectCustomerInfo' => false,
2197 'allowCustomerReschedule' => false,
2198 'allowCustomerCancelPackages' => true,
2199 'allowCustomerDeleteProfile' => false,
2200 'allowWriteEvents' => false,
2201 'allowAdminBookAtAnyTime' => false,
2202 'allowAdminBookOverApp' => false,
2203 'adminServiceDurationAsSlot' => false,
2204 'enabledHttpAuthorization' => true,
2205 'customerCabinet' => [
2206 'headerJwtSecret' => (new Token(null, 20))->getValue(),
2207 'urlJwtSecret' => (new Token(null, 20))->getValue(),
2208 'tokenValidTime' => 2592000,
2209 'pageUrl' => '',
2210 'loginEnabled' => true,
2211 'filterDate' => false,
2212 'translations' => [],
2213 'googleRecaptcha' => false,
2214 ],
2215 'providerCabinet' => [
2216 'headerJwtSecret' => (new Token(null, 20))->getValue(),
2217 'urlJwtSecret' => (new Token(null, 20))->getValue(),
2218 'tokenValidTime' => 2592000,
2219 'pageUrl' => '',
2220 'loginEnabled' => true,
2221 'filterDate' => false,
2222 'googleRecaptcha' => false,
2223 ],
2224 'urlAttachment' => [
2225 'enabled' => true,
2226 'headerJwtSecret' => (new Token(null, 20))->getValue(),
2227 'urlJwtSecret' => (new Token(null, 20))->getValue(),
2228 'tokenValidTime' => 2592000,
2229 'pageUrl' => '',
2230 'loginEnabled' => true,
2231 'filterDate' => false,
2232 ],
2233 'limitPerCustomerService' => [
2234 'enabled' => false,
2235 'numberOfApp' => 1,
2236 'timeFrame' => 'day',
2237 'period' => 1,
2238 'from' => 'bookingDate'
2239 ],
2240 'limitPerCustomerPackage' => [
2241 'enabled' => false,
2242 'numberOfApp' => 1,
2243 'timeFrame' => 'day',
2244 'period' => 1,
2245 ],
2246 'limitPerCustomerEvent' => [
2247 'enabled' => false,
2248 'numberOfApp' => 1,
2249 'timeFrame' => 'day',
2250 'period' => 1,
2251 'from' => 'bookingDate'
2252 ],
2253 'limitPerEmployee' => [
2254 'enabled' => false,
2255 'numberOfApp' => 1,
2256 'timeFrame' => 'day',
2257 'period' => 1,
2258 ],
2259 'providerBadges' => [
2260 'counter' => 3,
2261 'badges' => [
2262 [
2263 'id' => 1,
2264 'content' => 'Most Popular',
2265 'color' => '#316bff'
2266 ],
2267 [
2268 'id' => 2,
2269 'content' => 'Top Performer',
2270 'color' => '#06a192'
2271 ],
2272 [
2273 'id' => 3,
2274 'content' => 'Exclusive',
2275 'color' => '#facc15'
2276 ],
2277 ]
2278 ],
2279 ];
2280 }
2281
2282 /**
2283 * Init Roles Settings
2284 */
2285 private static function initRolesSettings()
2286 {
2287 $settings = self::getDefaultRolesSettings();
2288
2289 self::initSettings('roles', $settings);
2290
2291 self::setNewSettingsToExistingSettings(
2292 'roles',
2293 [
2294 ['customerCabinet', 'filterDate'],
2295 ['customerCabinet', 'translations'],
2296 ['customerCabinet', 'headerJwtSecret'],
2297 ['customerCabinet', 'urlJwtSecret'],
2298 ['customerCabinet', 'googleRecaptcha'],
2299 ['providerCabinet', 'headerJwtSecret'],
2300 ['providerCabinet', 'urlJwtSecret'],
2301 ['providerCabinet', 'googleRecaptcha'],
2302 ['urlAttachment', 'headerJwtSecret'],
2303 ['urlAttachment', 'urlJwtSecret'],
2304 ],
2305 $settings
2306 );
2307 }
2308
2309 /**
2310 * Get Appointments Settings
2311 *
2312 * @return array
2313 */
2314 public static function getDefaultAppointmentsSettings()
2315 {
2316 return [
2317 'isGloballyBusySlot' => false,
2318 'bookMultipleTimes' => false,
2319 'allowBookingIfPending' => true,
2320 'allowBookingIfNotMin' => true,
2321 'openedBookingAfterMin' => false,
2322 'cartPlaceholders' => '<!-- Content --><p>DateTime: %appointment_date_time%</p>',
2323 'cartPlaceholdersSms' => 'DateTime: %appointment_date_time%',
2324 'cartPlaceholdersCustomer' => '<!-- Content --><p>DateTime: %appointment_date_time%</p>',
2325 'cartPlaceholdersCustomerSms' => 'DateTime: %appointment_date_time%',
2326 'recurringPlaceholders' => 'DateTime: %appointment_date_time%',
2327 'recurringPlaceholdersSms' => 'DateTime: %appointment_date_time%',
2328 'recurringPlaceholdersCustomer' => 'DateTime: %appointment_date_time%',
2329 'recurringPlaceholdersCustomerSms' => 'DateTime: %appointment_date_time%',
2330 'packagePlaceholders' => 'DateTime: %appointment_date_time%',
2331 'packagePlaceholdersSms' => 'DateTime: %appointment_date_time%',
2332 'packagePlaceholdersCustomer' => 'DateTime: %appointment_date_time%',
2333 'packagePlaceholdersCustomerSms' => 'DateTime: %appointment_date_time%',
2334 'groupAppointmentPlaceholder' => 'Name: %customer_full_name%',
2335 'groupEventPlaceholder' => 'Name: %customer_full_name%',
2336 'groupAppointmentPlaceholderSms' => 'Name: %customer_full_name%',
2337 'groupEventPlaceholderSms' => 'Name: %customer_full_name%',
2338 'translations' => [
2339 'cartPlaceholdersCustomer' => null,
2340 'cartPlaceholdersCustomerSms' => null,
2341 'recurringPlaceholdersCustomer' => null,
2342 'recurringPlaceholdersCustomerSms' => null,
2343 'packagePlaceholdersCustomer' => null,
2344 'packagePlaceholdersCustomerSms' => null,
2345 'groupAppointmentPlaceholder' => 'Name: %customer_full_name%',
2346 'groupEventPlaceholder' => 'Name: %customer_full_name%',
2347 'groupAppointmentPlaceholderSms' => 'Name: %customer_full_name%',
2348 'groupEventPlaceholderSms' => 'Name: %customer_full_name%',
2349 ],
2350 'waitingListEvents' => [
2351 'addingMethod' => 'Manually'
2352 ],
2353 'qrCodeEvents' => [
2354 'enabled' => false,
2355 ],
2356 'waitingListAppointments' => [
2357 'enabled' => false,
2358 'redirectUrlDenied' => ''
2359 ],
2360 'pastDaysEvents' => 0,
2361 'employeeSelection' => 'random',
2362 'bringingAnyoneLogic' => 'additional',
2363 ];
2364 }
2365
2366 /**
2367 * Init Appointments Settings
2368 */
2369 private static function initAppointmentsSettings()
2370 {
2371 $settings = self::getDefaultAppointmentsSettings();
2372
2373 self::initSettings('appointments', $settings);
2374
2375 self::setNewSettingsToExistingSettings(
2376 'appointments',
2377 [
2378 ['translations', 'cartPlaceholdersCustomer'],
2379 ['translations', 'cartPlaceholdersCustomerSms'],
2380 ],
2381 $settings
2382 );
2383 }
2384
2385 /**
2386 * Init Web Hooks Settings
2387 */
2388 private static function initWebHooksSettings()
2389 {
2390 $settings = [];
2391
2392 self::initSettings('webHooks', $settings);
2393 }
2394
2395 /**
2396 * get Back Link Setting
2397 */
2398 private static function getBackLinkSetting()
2399 {
2400 $settingsService = new SettingsService(new SettingsStorage());
2401
2402 $backLinksLabels = [
2403 'Generated with Amelia - WordPress Booking Plugin',
2404 'Powered by Amelia - WordPress Booking Plugin',
2405 'Booking by Amelia - WordPress Booking Plugin',
2406 'Powered by Amelia - Appointment and Events Booking Plugin',
2407 'Powered by Amelia - Appointment and Event Booking Plugin',
2408 'Powered by Amelia - WordPress Booking Plugin',
2409 'Generated with Amelia - Appointment and Event Booking Plugin',
2410 'Booking Enabled by Amelia - Appointment and Event Booking Plugin',
2411 ];
2412
2413 $backLinksUrls = [
2414 'https://wpamelia.com/?utm_source=lite&utm_medium=websites&utm_campaign=powerdby',
2415 'https://wpamelia.com/demos/?utm_source=lite&utm_medium=website&utm_campaign=powerdby#Features-list',
2416 'https://wpamelia.com/pricing/?utm_source=lite&utm_medium=website&utm_campaign=powerdby',
2417 'https://wpamelia.com/documentation/?utm_source=lite&utm_medium=website&utm_campaign=powerdby',
2418 ];
2419
2420 return [
2421 'enabled' => $settingsService->getCategorySettings('general') === null,
2422 'label' => $backLinksLabels[rand(0, 7)],
2423 'url' => $backLinksUrls[rand(0, 3)],
2424 ];
2425 }
2426
2427 /**
2428 * Add new settings ti global parent settings
2429 *
2430 * @param string $category
2431 * @param array $pathsKeys
2432 * @param array $initSettings
2433 */
2434 private static function setNewSettingsToExistingSettings($category, $pathsKeys, $initSettings)
2435 {
2436 $settingsService = new SettingsService(new SettingsStorage());
2437
2438 $savedSettings = $settingsService->getCategorySettings($category);
2439
2440 $activationSettings = $settingsService->getCategorySettings('activation');
2441 $savedVersion = !empty($activationSettings['version']) ? $activationSettings['version'] : '0.0.0';
2442
2443 $setSettings = false;
2444
2445 foreach ($pathsKeys as $keys) {
2446 $current = &$savedSettings;
2447
2448 $currentInit = &$initSettings;
2449
2450 foreach ((array)$keys as $key) {
2451 if (!isset($current[$key])) {
2452 $current[$key] = !empty($currentInit[$key]) ? $currentInit[$key] : null;
2453
2454 $setSettings = true;
2455
2456 continue 2;
2457 }
2458
2459 // If the saved value is a JSON-encoded string but the new schema expects
2460 // a nested array (i.e. there are more keys to traverse), decode it so
2461 // that subsequent keys can be accessed without a PHP 8 TypeError.
2462 // This fix is only applied when upgrading from versions before 9.2
2463 if (version_compare($savedVersion, '9.2', '<') && is_string($current[$key])) {
2464 $decoded = json_decode($current[$key], true);
2465 if (is_array($decoded)) {
2466 $current[$key] = $decoded;
2467 $setSettings = true;
2468 } else {
2469 // Scalar string with no deeper path possible — skip this path.
2470 continue 2;
2471 }
2472 } elseif (!is_array($current[$key])) {
2473 // Boolean / int leaf where a nested array is expected — skip.
2474 continue 2;
2475 }
2476
2477 $current = &$current[$key];
2478
2479 $currentInit = &$currentInit[$key];
2480 }
2481 }
2482
2483 if ($setSettings) {
2484 self::initSettings($category, $savedSettings, true);
2485 }
2486 }
2487
2488 /**
2489 * Init Social Login Settings
2490 */
2491 private static function initSocialLoginSettings()
2492 {
2493 $settings = [
2494 'facebookAppId' => '',
2495 'facebookAppSecret' => '',
2496 ];
2497
2498 self::initSettings('socialLogin', $settings);
2499 }
2500
2501 /**
2502 * Init Features and Integrations Settings
2503 */
2504 private static function initFeaturesIntegrationsSettings()
2505 {
2506 $settingsService = new SettingsService(new SettingsStorage());
2507
2508 $saved = $settingsService->getAllSettingsCategorized();
2509
2510 $old = empty($saved['activation']['isNewInstallation']);
2511
2512 $starterAndUp = Licence::getLicence() === 'Developer' ||
2513 Licence::getLicence() === 'Pro' ||
2514 Licence::getLicence() === 'Basic' ||
2515 Licence::getLicence() === 'Starter';
2516
2517 $basicAndUp = Licence::getLicence() === 'Developer' || Licence::getLicence() === 'Pro' || Licence::getLicence() === 'Basic';
2518
2519 $proAndUp = Licence::getLicence() === 'Developer' || Licence::getLicence() === 'Pro';
2520
2521 $settings = [
2522 'googleCalendar' => [
2523 'enabled' => $old &&
2524 $basicAndUp &&
2525 !empty($saved['googleCalendar']['calendarEnabled']),
2526 ],
2527 'appleCalendar' => [
2528 'enabled' => $old &&
2529 $basicAndUp &&
2530 !empty($saved['appleCalendar']['clientID']) &&
2531 !empty($saved['appleCalendar']['clientSecret']),
2532 ],
2533 'outlookCalendar' => [
2534 'enabled' => $old &&
2535 $basicAndUp &&
2536 !empty($saved['outlookCalendar']['calendarEnabled']),
2537 ],
2538 'zoom' => [
2539 'enabled' => $old &&
2540 $basicAndUp &&
2541 !empty($saved['zoom']['accountId']) &&
2542 !empty($saved['zoom']['clientId']) &&
2543 !empty($saved['zoom']['clientSecret']),
2544 ],
2545 'webhooks' => [
2546 'enabled' => $basicAndUp,
2547 ],
2548 'facebookPixel' => [
2549 'enabled' => $old && $starterAndUp && !empty($saved['facebookPixel']['id']),
2550 ],
2551 'googleAnalytics' => [
2552 'enabled' => $old && $starterAndUp && !empty($saved['googleAnalytics']['id']),
2553 ],
2554 'lessonSpace' => [
2555 'enabled' => $old && $starterAndUp && !empty($saved['lessonSpace']['apiKey']),
2556 ],
2557 'recaptcha' => [
2558 'enabled' => $old &&
2559 $starterAndUp &&
2560 !empty($saved['general']['googleRecaptcha']['enabled']) &&
2561 !empty($saved['general']['googleRecaptcha']['siteKey']) &&
2562 !empty($saved['general']['googleRecaptcha']['secret']),
2563 ],
2564 'mollie' => [
2565 'enabled' => $old && $basicAndUp && !empty($saved['payments']['mollie']['enabled']),
2566 ],
2567 'wc' => [
2568 'enabled' => $old && $basicAndUp && !empty($saved['payments']['wc']['enabled']),
2569 ],
2570 'payPal' => [
2571 'enabled' => $old && $basicAndUp && !empty($saved['payments']['payPal']['enabled']),
2572 ],
2573 'stripe' => [
2574 'enabled' => $old && $basicAndUp && !empty($saved['payments']['stripe']['enabled']),
2575 ],
2576 'razorpay' => [
2577 'enabled' => $old && $basicAndUp && !empty($saved['payments']['razorpay']['enabled']),
2578 ],
2579 'square' => [
2580 'enabled' => $old && !empty($saved['payments']['square']['enabled']),
2581 ],
2582 'barion' => [
2583 'enabled' => $old && $basicAndUp && !empty($saved['payments']['barion']['enabled']),
2584 ],
2585 'packages' => [
2586 'enabled' => $proAndUp,
2587 ],
2588 'resources' => [
2589 'enabled' => $proAndUp,
2590 ],
2591 'customFields' => [
2592 'enabled' => $basicAndUp,
2593 ],
2594 'coupons' => [
2595 'enabled' => $old && $starterAndUp && !empty($saved['payments']['coupons']),
2596 ],
2597 'customNotifications' => [
2598 'enabled' => $basicAndUp,
2599 ],
2600 'tax' => [
2601 'enabled' => $basicAndUp && (!$old || !empty($saved['payments']['taxes']['enabled'])),
2602 ],
2603 'invoices' => [
2604 'enabled' => $basicAndUp,
2605 ],
2606 'whatsapp' => [
2607 'enabled' => $old &&
2608 $proAndUp &&
2609 !empty($saved['notifications']['whatsAppEnabled']) &&
2610 !empty($saved['notifications']['whatsAppPhoneID']) &&
2611 !empty($saved['notifications']['whatsAppAccessToken']) &&
2612 !empty($saved['notifications']['whatsAppBusinessID']),
2613 ],
2614 'recurringEvents' => [
2615 'enabled' => $basicAndUp,
2616 ],
2617 'tickets' => [
2618 'enabled' => $basicAndUp,
2619 ],
2620 'waitingList' => [
2621 'enabled' => $proAndUp && (!$old || !empty($saved['appointments']['waitingListEvents']['enabled'])),
2622 ],
2623 'waitingListAppointments' => [
2624 'enabled' => $proAndUp && (!$old || !empty($saved['appointments']['waitingListAppointments']['enabled'])),
2625 ],
2626 'customPricing' => [
2627 'enabled' => $basicAndUp,
2628 ],
2629 'recurringAppointments' => [
2630 'enabled' => $basicAndUp,
2631 ],
2632 'extras' => [
2633 'enabled' => $starterAndUp,
2634 ],
2635 'cart' => [
2636 'enabled' => $old && $proAndUp && !empty($saved['payments']['cart']),
2637 ],
2638 'timezones' => [
2639 'enabled' => $basicAndUp,
2640 ],
2641 'depositPayment' => [
2642 'enabled' => $basicAndUp,
2643 ],
2644 'noShowTag' => [
2645 'enabled' => $basicAndUp && (!$old || !empty($saved['roles']['enableNoShowTag'])),
2646 ],
2647 'apis' => [
2648 'enabled' => Licence::getLicence() === 'Developer',
2649 ],
2650 'buddyboss' => [
2651 'enabled' => $basicAndUp && $old,
2652 ],
2653 'employeeBadge' => [
2654 'enabled' => $basicAndUp,
2655 ],
2656 'mailchimp' => [
2657 'enabled' => $old && $basicAndUp && !empty($saved['mailchimp']['accessToken']),
2658 ],
2659 'googleSocialLogin' => [
2660 'enabled' => $old && $basicAndUp && !empty($saved['socialLogin']['enableGoogleLogin']),
2661 ],
2662 'facebookSocialLogin' => [
2663 'enabled' => $old && $basicAndUp && !empty($saved['socialLogin']['enableFacebookLogin']),
2664 ],
2665 'eTickets' => [
2666 'enabled' => $proAndUp && (!$old || !empty($saved['appointments']['qrCodeEvents']['enabled'])),
2667 ],
2668 'eventTags' => [
2669 'enabled' => $starterAndUp && (!$old || EventsTagsTable::hasTags()),
2670 ],
2671 'ivy' => [
2672 'enabled' => false,
2673 ],
2674 ];
2675
2676 self::initSettings('featuresIntegrations', $settings);
2677 }
2678 }
2679