# Codebase Structure **Analysis Date:** 2026-05-05 ## Directory Layout ``` wp-content/plugins/yacht-booking-system/ ├── yacht-booking-system.php # Plugin entry: constants, autoloader, hooks ├── includes/ # Core PHP classes (autoloaded via spl_autoload_register) │ ├── class-yacht-booking.php # Main Singleton orchestrator │ ├── class-yacht.php # Yacht CPT + static meta accessors │ ├── class-booking.php # Booking CPT + static meta accessors │ ├── class-inquiry.php # Inquiry CPT + static meta accessors + email sending │ ├── class-availability.php # wp_yacht_availability table read/write │ ├── class-installer.php # DB table creation, default options │ ├── class-settings.php # wp_options accessors + formatting helpers │ └── class-email-templates.php # Email template storage, compilation, tag replacement ├── api/ # REST API (loaded via require_once, not autoloader) │ └── class-rest-controller.php # All REST routes under yacht-booking/v1 ├── admin/ # WP admin panel (is_admin() gate) │ ├── class-admin.php # Admin Singleton: menu, form handling, CSV export │ ├── class-booking-list-table.php # WP_List_Table for bookings │ ├── class-yacht-list-table.php # WP_List_Table for yachts │ ├── class-inquiry-list-table.php # WP_List_Table for inquiries │ ├── views/ │ │ └── yacht-edit.php # Add/edit yacht form template │ └── assets/ │ ├── css/admin.css │ └── js/admin.js ├── frontend/ │ ├── class-calendar-widget.php # Elementor widget (yacht-calendar) │ ├── class-shortcode.php # [yacht_calendar] shortcode, Singleton │ └── assets/ │ ├── css/calendar.css # Compiled from calendar.scss │ ├── css/calendar.scss # SCSS source (manual compile required) │ └── js/calendar.js # IIFE jQuery; consumes REST API via yachtBookingData ├── integrations/ │ ├── google-calendar/ # Loaded via explicit require_once (not autoloader) │ │ ├── class-oauth-handler.php # OAuth 2.0 token storage + refresh │ │ ├── class-gcal-service.php # Google Calendar API HTTP calls │ │ └── class-sync-controller.php # Cron sync orchestration, Singleton │ └── ical/ │ ├── class-ical-feed.php # Generate iCal feed, serve via rewrite rule │ └── class-ical-import.php # Import external iCal URLs via cron └── languages/ # .pot / .po / .mo for yacht-booking text domain ``` **Project root (WordPress install root — not plugin directory):** ``` / ├── test-yacht-plugin.php # Manual smoke test (run in browser as admin) ├── test-api-availability.php # Manual integration test (run in browser as admin) └── tmp-fix-polish.php # Leftover artifact — single path string, no PHP code ``` ## Naming Rules | Thing | Convention | Example | |-------|-----------|---------| | PHP class files | `class-{kebab-case}.php` | `class-rest-controller.php` | | PHP class names | `PascalCase` (with underscores) | `Rest_Controller`, `Yacht_Booking` | | Directories | lowercase kebab-case | `google-calendar/`, `yacht-booking-system/` | | Autoloader mapping | `YachtBooking\Foo_Bar` → `includes/class-foo-bar.php` | — | | Sub-namespaces (integrations) | `YachtBooking\Integrations\GoogleCalendar` | — | ## Where to Add New Code **New core feature:** - File: `includes/class-{feature}.php`, namespace `YachtBooking\` - Load: relies on autoloader automatically (for `includes/` only) **New REST endpoint:** - Add method + route registration to `api/class-rest-controller.php` - Public: `'permission_callback' => '__return_true'` + nonce check inside handler - Admin: `'permission_callback' => array($this, 'can_manage_bookings')` **New admin page:** - Add `add_submenu_page()` in `Admin::register_admin_menu()` - Add `render_{page}()` method in `admin/class-admin.php` - Add form processing method hooked on `admin_init` in `Admin::__construct()` - View HTML: extract to `admin/views/{page}.php` **New external integration:** - Create `integrations/{service-name}/` - Follow pattern: `class-{service}-service.php` + `class-sync-controller.php` - Register cron: `static setup_cron()` + `static clear_cron()`, call from activation/deactivation hooks - Load via `require_once` in `Yacht_Booking::load_dependencies()` **New setting:** - Add default in `Installer::create_options()` - Add typed accessor in `Settings` class - Add UI in `Admin::render_general_settings()` or new settings tab - Save in `Admin::save_settings()`