file; add_action('admin_menu', static function()use($file):void { add_menu_page('ABeCe Booking','ABeCe Booking','activate_plugins','abece-booking',static function()use($file):void { echo '

ABeCe Booking

'.esc_html__('ABeCe Booking needs a verified database maintenance upgrade before booking operations can resume. Existing data has been retained. Follow the database upgrade instructions or contact your administrator.','abece-booking').'

'; echo '

'.esc_html__('Database upgrade instructions','abece-booking').'

'; }); }); add_action('admin_notices', static function():void { if (current_user_can('activate_plugins')) echo '

'.esc_html__('ABeCe Booking needs a verified database maintenance upgrade before booking operations can resume. Existing data has been retained. Follow the database upgrade instructions or contact your administrator.','abece-booking').'

'; }); add_filter('rest_pre_dispatch',static function($response,$server,$request){ if(str_starts_with($request->get_route(),'/abece-booking/v1/'))return new \WP_Error('abece_booking_database_maintenance',__('Booking operations are temporarily unavailable during maintenance. Please contact the venue operator.','abece-booking'),['status'=>503]); return $response; },-100,3); add_action('init',static function():void {add_shortcode('abece_booking',static fn()=>'

'.esc_html__('Booking operations are temporarily unavailable during maintenance. Please contact the venue operator.','abece-booking').'

');}); return; // No REST/native profile/privacy/cron write path is registered for an incomplete schema. } try { \ABeCe\Booking\Support\LegacyIdentifiers::migrate(); } catch (Throwable $error) { add_action('admin_notices', static function() use ($error): void { if (current_user_can('activate_plugins')) echo '

' . esc_html($error->getMessage()) . '

'; }); return; // Never initialize default settings over a failed/incomplete legacy upgrade. } \ABeCe\Booking\Support\LocaleContext::register(); \ABeCe\Booking\Edition\Modules::current()->registerHooks(); add_action( 'init', [ $this, 'loadTranslations' ], 0 ); add_action( 'init', [ $this, 'upgradeDatabase' ], 1 ); add_action( 'init', [ Capabilities::class, 'maybeUpgrade' ], 2 ); add_action( 'rest_api_init', [ $this, 'registerApi' ] ); ( new Menu( $this->file ) )->register(); (new \ABeCe\Booking\Integration\Privacy())->register(); add_action('plugins_loaded',static fn()=>\ABeCe\Booking\Edition\Modules::current()->registerProfile()); add_action( 'init', fn() => ( new Shortcode( $this->file ) )->register() ); } public function registerApi(): void { global $wpdb; $module=\ABeCe\Booking\Edition\Modules::current();$ports=$module->services($wpdb); $sports=new SportsRepository($wpdb);$resources=new ResourcesRepository($wpdb); (new CatalogController('sports',new SportsService($sports)))->register(); (new CatalogController('resources',new ResourcesService($resources,$sports)))->register(); $seasons=new SeasonsRepository($wpdb);$types=new MembershipTypesRepository($wpdb);$users=new WordPressUsersRepository($wpdb); $members=$ports['members'];$membership=$ports['membership']; $hours=new OpeningHoursRepository($wpdb);$exceptions=new ScheduleExceptionsRepository($wpdb); $location=new LocationService(new LocationRepository()); (new CatalogController('opening-hours',new OpeningHoursService($hours,$resources),Capabilities::MANAGE_RESOURCES,[],true))->register(); foreach(['schedule-exceptions'=>['schedule_exceptions',new ScheduleExceptionsService($exceptions,$resources),false],'resource-blocks'=>['resource_blocks',new ResourceBlocksService(new ResourceBlocksRepository($wpdb),$resources),true]]as $route=>[$kind,$rows,$blocks]) (new CatalogController($route,$module->schedule($wpdb,$kind,$rows,$resources,$blocks),Capabilities::MANAGE_RESOURCES,[],true))->register(); (new LocationController($location))->register(); $schedule=new OperatingScheduleService($hours,$exceptions,new SunService($location)); $availability=new AvailabilityService($resources,$schedule,new AvailabilityRepository($wpdb),$membership); $bookings=new BookingsRepository($wpdb);$settlement=new \ABeCe\Booking\Service\SettlementService(new \ABeCe\Booking\Repository\PaymentTransactionsRepository($wpdb)); $receivables=new \ABeCe\Booking\Service\ReceivablesService(new \ABeCe\Booking\Repository\OperationsRepository($wpdb),$settlement,new \ABeCe\Booking\Repository\PaymentSettingsRepository()); $eligibility=new \ABeCe\Booking\Service\BookingEligibilityService($bookings,new \ABeCe\Booking\Service\BookingRulesService(new \ABeCe\Booking\Repository\SettingsRepository()),$receivables,$ports['usage'],$ports['restrictions']); $calendar_settings=new \ABeCe\Booking\Service\CalendarSettingsService(new \ABeCe\Booking\Repository\CalendarSettingsRepository()); (new \ABeCe\Booking\Api\CalendarController(new \ABeCe\Booking\Service\CalendarService(new \ABeCe\Booking\Repository\CalendarRepository($wpdb),$availability,$schedule,$sports,$calendar_settings,$eligibility),$calendar_settings))->register(); $notifications=new NotificationsRepository($wpdb);$mailer=new NotificationService($notifications,$bookings,$resources,$settlement); $policies=new \ABeCe\Booking\Service\CancellationPolicyService(new \ABeCe\Booking\Repository\CancellationPoliciesRepository($wpdb),$resources,$sports,new ResourceLockRepository($wpdb)); (new CatalogController('cancellation-policies',$policies,Capabilities::MANAGE_CANCELLATION_POLICIES))->register(); (new \ABeCe\Booking\Api\CancellationPoliciesController($policies))->register(); $contacts=new \ABeCe\Booking\Repository\ExternalContactsRepository($wpdb);$directory=new \ABeCe\Booking\Service\ExternalContactsService($contacts); (new CatalogController('external-contacts',$directory,Capabilities::MANAGE_BOOKINGS,['search']))->register(); (new \ABeCe\Booking\Api\ExternalContactsController($directory))->register(); $external=new \ABeCe\Booking\Service\ExternalBookingService($contacts,$directory); $profiles=new BookingProfileService(new BookingProfileRepository());$customers=new BookingCustomerService($membership,$members,$users,$profiles);$participants=new BookingParticipantsService($membership,$members,$customers); $lists=new PriceListsRepository($wpdb);$rules=new PriceRulesRepository($wpdb);$locks=new ResourceLockRepository($wpdb); (new CatalogController('price-lists',$module->priceLists($lists,$rules,$seasons,$locks),Capabilities::MANAGE_PRICES))->register(); (new CatalogController('price-rules',$module->priceRules($rules,$lists,$resources,$sports,$types,$locks),Capabilities::MANAGE_PRICES,['price_list_id']))->register(); $settings=new \ABeCe\Booking\Service\PaymentSettingsService(new \ABeCe\Booking\Repository\PaymentSettingsRepository());$methods=new \ABeCe\Booking\Service\PaymentMethodAvailabilityService($settings,$resources); (new \ABeCe\Booking\Api\SettingsController(new \ABeCe\Booking\Service\MembershipModeService(new \ABeCe\Booking\Repository\SettingsRepository()),new \ABeCe\Booking\Service\FrontendIntegrationService(new \ABeCe\Booking\Repository\SettingsRepository()),$settings,$methods))->register(); $payments=new \ABeCe\Booking\Service\PaymentService(new \ABeCe\Booking\Repository\PaymentTransactionsRepository($wpdb),$ports['credit'],$settings,$bookings,$resources,$settlement,$methods); (new \ABeCe\Booking\Api\OperationsController(new \ABeCe\Booking\Service\DailyOperationsService(new \ABeCe\Booking\Repository\OperationsRepository($wpdb)),$receivables,$payments))->register(); $booking=new BookingService($bookings,$resources,$sports,$availability,$members,$notifications,$mailer,$customers,$participants,$profiles,$module->pricing($rules,$membership),$payments,$policies,$external,$eligibility); $management=new BookingManagementService($booking,$bookings,$resources,$customers,$participants);$cancellation=new BookingCancellationService($booking,$bookings,$resources,$mailer); (new PricingController($booking,$management,new PricingOptionsService($resources,$sports,$seasons,$types)))->register(); (new BookingsController($booking,$cancellation,new BookingNoShowService($booking,$bookings,$resources,$mailer),$management,$customers,$profiles))->register(); (new \ABeCe\Booking\Api\PilotToolsController(new \ABeCe\Booking\Service\PilotToolsService(new \ABeCe\Booking\Repository\PilotToolsRepository($wpdb))))->register(); $module->registerPublic($wpdb,compact('booking','cancellation','customers','profiles','availability','eligibility')); $module->registerExtra($wpdb,compact('ports','booking','bookings','management','cancellation','customers','mailer','resources','sports','seasons','types','users','membership','members','settlement','schedule','settings')); \ABeCe\Booking\Edition\EditionRoutes::register(); } public function loadTranslations(): void { \ABeCe\Booking\Edition\Modules::current()->loadTranslations($this->file); } public function upgradeDatabase(): void { global $wpdb; try { ( new Installer( $wpdb ) )->migrate(); (new \ABeCe\Booking\Repository\SettingsRepository())->initialize(); \ABeCe\Booking\Edition\Modules::current()->initialize(); } catch ( Throwable $error ) { // Keep the previous schema version so the next request can retry. add_action( 'admin_notices', static function () use ( $error ): void { if ( current_user_can( 'activate_plugins' ) ) { echo '

' . esc_html( $error->getMessage() ) . '

'; } } ); } } }