init(); self::register_capabilities(); try { self::seed_default_categories(); self::seed_holiday_calendar(); self::auto_subscribe_holidays(); } catch ( \PDOException $e ) { self::log_seeding_failure( $e ); } catch ( \Throwable $e ) { self::log_seeding_failure( $e ); } if ( SingleEventPage::get_mode() !== 'off' ) { $event_page = new SingleEventPage(); $event_page->add_rewrite_rules(); } flush_rewrite_rules(); } /** * Log a seeding failure without halting activation. * * @param \Throwable $e The exception thrown during seeding. */ private static function log_seeding_failure( \Throwable $e ): void { if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Activation diagnostics only fire when WP_DEBUG_LOG is enabled. error_log( 'WebCalendar activation: deferred data seeding due to ' . get_class( $e ) . ': ' . $e->getMessage() ); } set_transient( 'webcal_pending_seed', 1, DAY_IN_SECONDS ); } /** * Seed default categories into webcal_categories table. */ public static function seed_default_categories(): void { $container = Container::get_instance(); $cat_repo = $container->get_category_repository(); $categories = [ 1 => [ 'name' => 'Meeting', 'color' => '#0073aa', ], 2 => [ 'name' => 'Appointment', 'color' => '#46b450', ], 3 => [ 'name' => 'Holiday', 'color' => '#dc3232', ], 4 => [ 'name' => 'Personal', 'color' => '#826eb4', ], ]; foreach ( $categories as $cat_id => $cat ) { $cat_repo->save( new Category( $cat_id, null, $cat['name'], $cat['color'] ) ); } } /** * Seed the holiday nonuser calendar entry. */ public static function seed_holiday_calendar(): void { $container = Container::get_instance(); $resource_repo = $container->get_resource_repository(); if ( $resource_repo->findByLogin( '__holidays__' ) !== null ) { return; } $admin_login = 'admin'; $admins = get_users( [ 'role' => 'administrator', 'number' => 1, ] ); if ( ! empty( $admins ) ) { $admin_login = $admins[0]->user_login; } $resource_repo->save( new Resource( '__holidays__', 'Holidays', $admin_login, true ) ); } /** * Auto-subscribe all users with webcal_can_view to __holidays__. * * Ensures backward compatibility — existing installs don't lose holiday display * when switching to layer-based visibility. */ public static function auto_subscribe_holidays(): void { $container = Container::get_instance(); $layer_service = $container->get_layer_service(); $resource_repo = $container->get_resource_repository(); // Only if holidays calendar exists if ( $resource_repo->findByLogin( '__holidays__' ) === null ) { return; } $wp_users = get_users( [ 'number' => 1000 ] ); foreach ( $wp_users as $wp_user ) { if ( ! user_can( $wp_user, 'webcal_can_view' ) ) { continue; } $existing = $layer_service->getLayersForUser( $wp_user->user_login ); $already = false; foreach ( $existing as $layer ) { if ( $layer->layerUser() === '__holidays__' ) { $already = true; break; } } if ( ! $already ) { $layer_service->addLayer( new \WebCalendar\Core\Domain\Entity\Layer( id: 0, owner: $wp_user->user_login, layerUser: '__holidays__', color: '#dc3232', ) ); } } } /** * Register custom WebCalendar capabilities. */ public static function register_capabilities(): void { $admin = get_role( 'administrator' ); $editor = get_role( 'editor' ); $author = get_role( 'author' ); $all_caps = [ 'webcal_can_view', 'webcal_can_view_all_events', 'webcal_can_edit', 'webcal_can_edit_others', 'webcal_can_approve', 'webcal_can_delete', 'webcal_can_delete_others', 'webcal_can_view_details', 'webcal_can_view_participants', 'webcal_can_edit_participants', 'webcal_can_manage_categories', 'webcal_can_manage_users', 'webcal_can_manage_settings', 'webcal_can_export', 'webcal_can_import', 'webcal_can_manage_holidays', 'webcal_can_view_statistics', 'webcal_can_manage_reminders', 'webcal_can_manage_notifications', 'webcal_can_manage_bookings', 'webcal_can_view_bookings', 'webcal_can_manage_resources', 'webcal_can_view_resources', 'webcal_can_manage_templates', 'webcal_can_view_templates', 'webcal_can_manage_filters', 'webcal_can_view_filters', 'webcal_can_manage_views', 'webcal_can_view_views', 'webcal_can_manage_reports', 'webcal_can_view_reports', 'webcal_can_manage_security', 'webcal_can_view_calendar', 'webcal_can_manage_shared_calendars', 'webcal_can_manage_layers', 'webcal_can_submit', ]; if ( $admin ) { foreach ( $all_caps as $cap ) { $admin->add_cap( $cap ); } } if ( $editor ) { $editor_caps = [ 'webcal_can_view', 'webcal_can_view_all_events', 'webcal_can_edit', 'webcal_can_delete', 'webcal_can_view_details', 'webcal_can_view_participants', 'webcal_can_edit_participants', 'webcal_can_manage_categories', 'webcal_can_view_statistics', 'webcal_can_view_bookings', 'webcal_can_view_resources', 'webcal_can_view_filters', 'webcal_can_view_views', 'webcal_can_view_reports', 'webcal_can_view_calendar', 'webcal_can_manage_layers', 'webcal_can_submit', ]; foreach ( $editor_caps as $cap ) { $editor->add_cap( $cap ); } } if ( $author ) { $author_caps = [ 'webcal_can_view', 'webcal_can_view_calendar', 'webcal_can_edit', 'webcal_can_delete', 'webcal_can_view_details', 'webcal_can_view_participants', 'webcal_can_export', 'webcal_can_manage_layers', 'webcal_can_submit', ]; foreach ( $author_caps as $cap ) { $author->add_cap( $cap ); } } self::grant_contributor_capabilities(); $subscriber = get_role( 'subscriber' ); if ( $subscriber ) { $subscriber_caps = [ 'webcal_can_view', 'webcal_can_view_calendar', 'webcal_can_submit', ]; foreach ( $subscriber_caps as $cap ) { $subscriber->add_cap( $cap ); } } } /** * Let contributors view the calendar and submit events for approval. * * Contributor is WordPress's own "may submit, may not publish" role, yet * it was the one standard role left without webcal_can_submit. Separate * from register_capabilities() so the 1.6.2 migration can grant exactly * this on existing sites without re-adding capabilities a site owner * removed from other roles. */ public static function grant_contributor_capabilities(): void { $contributor = get_role( 'contributor' ); if ( ! $contributor ) { return; } foreach ( [ 'webcal_can_view', 'webcal_can_view_calendar', 'webcal_can_submit' ] as $cap ) { $contributor->add_cap( $cap ); } } }