init_hooks(); $this->load_dependencies(); } /** * Initialize WordPress hooks */ private function init_hooks() { // Register Custom Post Types add_action( 'init', array( $this, 'register_post_types' ), 10 ); // Enqueue scripts and styles add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ), 10 ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ), 10 ); // Register REST API routes add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); // Register Elementor widgets add_action( 'elementor/widgets/register', array( $this, 'register_elementor_widgets' ), 10 ); // Register shortcodes add_action( 'init', array( $this, 'register_shortcodes' ), 15 ); // Add custom capabilities add_action( 'admin_init', array( $this, 'add_custom_capabilities' ), 10 ); } /** * Load plugin dependencies */ private function load_dependencies() { // Load CPT handlers require_once YACHT_BOOKING_PLUGIN_DIR . 'includes/class-yacht.php'; require_once YACHT_BOOKING_PLUGIN_DIR . 'includes/class-booking.php'; require_once YACHT_BOOKING_PLUGIN_DIR . 'includes/class-availability.php'; // REST controller — eagerly loaded because View helpers use its color palette + stałe. require_once YACHT_BOOKING_PLUGIN_DIR . 'api/class-rest-controller.php'; // Load admin classes if ( is_admin() ) { require_once YACHT_BOOKING_PLUGIN_DIR . 'admin/class-admin.php'; Admin::get_instance(); } // Load iCal integration (globalna sync z 09-02 — jedyny mechanizm sync z GCal) require_once YACHT_BOOKING_PLUGIN_DIR . 'integrations/ical/class-ical-feed.php'; require_once YACHT_BOOKING_PLUGIN_DIR . 'integrations/ical/class-ical-import.php'; \YachtBooking\Integrations\ICal\ICal_Feed::register(); \YachtBooking\Integrations\ICal\ICal_Import::register(); } /** * Register Custom Post Types */ public function register_post_types() { // Register Yacht CPT Yacht::register(); // Register Booking CPT Booking::register(); // Register Inquiry CPT Inquiry::register(); } /** * Enqueue frontend assets */ public function enqueue_frontend_assets() { // Only load on pages with yacht calendar if ( ! $this->should_load_frontend_assets() ) { return; } // FullCalendar CSS wp_enqueue_style( 'fullcalendar', 'https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.css', array(), '6.1.10' ); // Plugin CSS wp_enqueue_style( 'yacht-booking-calendar', YACHT_BOOKING_PLUGIN_URL . 'frontend/assets/css/calendar.css', array( 'fullcalendar' ), filemtime(YACHT_BOOKING_PLUGIN_DIR . 'frontend/assets/css/calendar.css') ); // FullCalendar JS wp_enqueue_script( 'fullcalendar', 'https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js', array(), '6.1.10', true ); // FullCalendar Polish locale wp_enqueue_script( 'fullcalendar-pl', 'https://cdn.jsdelivr.net/npm/@fullcalendar/core@6.1.10/locales/pl.global.min.js', array( 'fullcalendar' ), '6.1.10', true ); // Plugin JS wp_enqueue_script( 'yacht-booking-calendar', YACHT_BOOKING_PLUGIN_URL . 'frontend/assets/js/calendar.js', array( 'jquery', 'fullcalendar', 'fullcalendar-pl' ), YACHT_BOOKING_VERSION, true ); // Calendar (all yachts) — wspólny widget. Załaduj tylko gdy strona go potrzebuje. if ( $this->should_load_calendar_all_assets() ) { wp_enqueue_style( 'yacht-booking-calendar-all', YACHT_BOOKING_PLUGIN_URL . 'frontend/assets/css/calendar-all.css', array( 'fullcalendar' ), filemtime( YACHT_BOOKING_PLUGIN_DIR . 'frontend/assets/css/calendar-all.css' ) ); wp_enqueue_script( 'yacht-booking-calendar-all', YACHT_BOOKING_PLUGIN_URL . 'frontend/assets/js/calendar-all.js', array( 'jquery', 'fullcalendar', 'fullcalendar-pl' ), filemtime( YACHT_BOOKING_PLUGIN_DIR . 'frontend/assets/js/calendar-all.js' ), true ); } // Localize script wp_localize_script( 'yacht-booking-calendar', 'yachtBookingData', array( 'apiUrl' => esc_url_raw( rest_url( 'yacht-booking/v1' ) ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'bookingEnabled' => Settings::is_booking_enabled(), 'i18n' => array( 'loading' => __( 'Ładowanie...', 'yacht-booking' ), 'submitBooking' => __( 'Wyślij rezerwację', 'yacht-booking' ), 'submitting' => __( 'Wysyłanie...', 'yacht-booking' ), 'successTitle' => __( 'Sukces!', 'yacht-booking' ), 'successMessage' => __( 'Twoja rezerwacja została wysłana. Skontaktujemy się z Tobą wkrótce.', 'yacht-booking' ), 'errorTitle' => __( 'Błąd!', 'yacht-booking' ), 'errorMessage' => __( 'Wystąpił błąd podczas wysyłania rezerwacji. Spróbuj ponownie.', 'yacht-booking' ), 'selectDates' => __( 'Wybierz daty na kalendarzu', 'yacht-booking' ), 'invalidDateRange' => __( 'Nieprawidłowy zakres dat', 'yacht-booking' ), 'unavailableDatesSelected' => __( 'Wybrane daty zawierają niedostępne terminy. Proszę wybrać inne daty.', 'yacht-booking' ), ), ) ); } /** * Enqueue admin assets */ public function enqueue_admin_assets( $hook ) { // Only load on yacht booking pages if ( strpos( $hook, 'yacht-bookings' ) === false ) { return; } wp_enqueue_style( 'yacht-booking-admin', YACHT_BOOKING_PLUGIN_URL . 'admin/assets/css/admin.css', array(), YACHT_BOOKING_VERSION ); // WP color picker on yacht edit form. if ( isset( $_GET['page'] ) && 'yacht-bookings-add-yacht' === $_GET['page'] ) { wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_script( 'wp-color-picker' ); wp_add_inline_script( 'wp-color-picker', 'jQuery(function($){ $(".yacht-color-picker").wpColorPicker(); });' ); } wp_enqueue_script( 'yacht-booking-admin', YACHT_BOOKING_PLUGIN_URL . 'admin/assets/js/admin.js', array( 'jquery' ), YACHT_BOOKING_VERSION, true ); wp_localize_script( 'yacht-booking-admin', 'yachtBookingAdmin', array( 'apiUrl' => esc_url_raw( rest_url( 'yacht-booking/v1' ) ), 'nonce' => wp_create_nonce( 'wp_rest' ), ) ); } /** * Check if frontend assets should be loaded * * @return bool */ private function should_load_frontend_assets() { global $post; // Always load if Elementor is in edit mode if ( class_exists( '\Elementor\Plugin' ) && \Elementor\Plugin::$instance->preview->is_preview_mode() ) { return true; } // Check if post contains yacht calendar shortcode or widget (per-jacht lub wszystkie) if ( $post ) { if ( has_shortcode( $post->post_content, 'yacht_calendar' ) || has_shortcode( $post->post_content, 'yacht_calendar_all' ) || $this->has_yacht_calendar_widget( $post->ID ) || $this->has_yacht_calendar_all_widget( $post->ID ) ) { return true; } } return false; } /** * Check if post contains the wspólny widget kalendarza floty. * * @param int $post_id Post ID. * @return bool */ private function has_yacht_calendar_all_widget( $post_id ) { if ( ! class_exists( '\Elementor\Plugin' ) ) { return false; } $document = \Elementor\Plugin::$instance->documents->get( $post_id ); if ( ! $document ) { return false; } $data = $document->get_elements_data(); return $this->find_widget_recursive( $data, 'yacht-calendar-all' ); } /** * Check if calendar-all (wspólny) assets should be loaded — used to enqueue * dodatkowe pliki tylko na stronach które ich potrzebują. * * @return bool */ private function should_load_calendar_all_assets() { global $post; if ( class_exists( '\Elementor\Plugin' ) && \Elementor\Plugin::$instance->preview->is_preview_mode() ) { return true; } if ( $post && ( has_shortcode( $post->post_content, 'yacht_calendar_all' ) || $this->has_yacht_calendar_all_widget( $post->ID ) ) ) { return true; } return false; } /** * Check if post has yacht calendar Elementor widget * * @param int $post_id Post ID. * @return bool */ private function has_yacht_calendar_widget( $post_id ) { if ( ! class_exists( '\Elementor\Plugin' ) ) { return false; } $document = \Elementor\Plugin::$instance->documents->get( $post_id ); if ( ! $document ) { return false; } $data = $document->get_elements_data(); return $this->find_widget_recursive( $data, 'yacht-calendar' ); } /** * Find widget recursively in Elementor data * * @param array $elements Elements data. * @param string $widget_name Widget name to find. * @return bool */ private function find_widget_recursive( $elements, $widget_name ) { foreach ( $elements as $element ) { if ( isset( $element['widgetType'] ) && $element['widgetType'] === $widget_name ) { return true; } if ( ! empty( $element['elements'] ) ) { if ( $this->find_widget_recursive( $element['elements'], $widget_name ) ) { return true; } } } return false; } /** * Register REST API routes */ public function register_rest_routes() { // Load REST controllers require_once YACHT_BOOKING_PLUGIN_DIR . 'api/class-rest-controller.php'; $controller = new Rest_Controller(); $controller->register_routes(); } /** * Register Elementor widgets * * @param object $widgets_manager Elementor widgets manager. */ public function register_elementor_widgets( $widgets_manager ) { // Load widget classes require_once YACHT_BOOKING_PLUGIN_DIR . 'frontend/class-calendar-widget.php'; require_once YACHT_BOOKING_PLUGIN_DIR . 'frontend/class-calendar-widget-all.php'; // Register widgets $widgets_manager->register( new Calendar_Widget() ); $widgets_manager->register( new Calendar_Widget_All() ); } /** * Register shortcodes */ public function register_shortcodes() { // Load shortcode class require_once YACHT_BOOKING_PLUGIN_DIR . 'frontend/class-shortcode.php'; // Initialize shortcode handler Shortcode::get_instance(); } /** * Add custom capabilities */ public function add_custom_capabilities() { // Only run once if ( get_option( 'yacht_booking_capabilities_added' ) ) { return; } $admin = get_role( 'administrator' ); if ( $admin ) { $capabilities = array( 'yacht_booking_manage_yachts', 'yacht_booking_manage_bookings', 'yacht_booking_manage_settings', ); foreach ( $capabilities as $cap ) { $admin->add_cap( $cap ); } update_option( 'yacht_booking_capabilities_added', true ); } } }