Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a784d92cc9 | |||
| f61dca5f45 | |||
| 28350aabfa | |||
| 3579904bad | |||
| 602549208f | |||
| 45a73e15aa |
58
CHANGELOG.md
58
CHANGELOG.md
@@ -5,6 +5,64 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.7.1] - 2026-02-03
|
||||
|
||||
### Added
|
||||
|
||||
- CF7 Admin Tag Generator buttons:
|
||||
- Tag generator buttons appear in CF7 form editor for all WP BnB custom tags
|
||||
- BnB Building select with first option label configuration
|
||||
- BnB Room select with building field linking and price display options
|
||||
- BnB Check-in date with min/max advance booking days
|
||||
- BnB Check-out date with check-in field linking and min/max nights
|
||||
- BnB Guests count with room field linking and min/max/default values
|
||||
- All generators support id and class attribute configuration
|
||||
|
||||
## [0.7.0] - 2026-02-03
|
||||
|
||||
### Added
|
||||
|
||||
- Contact Form 7 Integration:
|
||||
- New `src/Integration/CF7.php` class for CF7 integration
|
||||
- Custom form tags: `[bnb_building_select]`, `[bnb_room_select]`, `[bnb_date_checkin]`, `[bnb_date_checkout]`, `[bnb_guests]`
|
||||
- Server-side validation for all custom tags
|
||||
- Availability checking before form submission
|
||||
- Automatic booking creation on form submission with 'pending' status
|
||||
- Guest record creation/linking using existing `find_or_create_guest` pattern
|
||||
- Price calculation using existing Calculator class
|
||||
- Email notifications via existing EmailNotifier
|
||||
- CF7 Frontend Assets:
|
||||
- `assets/js/cf7-integration.js` for dynamic form behavior
|
||||
- Building-based room filtering
|
||||
- Date linking (checkout min = checkin + 1)
|
||||
- Capacity validation against selected room
|
||||
- AJAX availability checking with status display
|
||||
- Dynamic price calculation display
|
||||
- `assets/css/cf7-integration.css` for form styling
|
||||
- Availability status indicators (checking/available/unavailable)
|
||||
- Price display formatting
|
||||
- Capacity warning styling
|
||||
- Responsive design with dark mode support
|
||||
- Custom CF7 Mail Tags:
|
||||
- `[_bnb_booking_reference]` - Generated booking reference
|
||||
- `[_bnb_booking_id]` - Booking post ID
|
||||
- `[_bnb_room_name]` - Selected room title
|
||||
- `[_bnb_calculated_price]` - Formatted price
|
||||
- `[_bnb_nights]` - Number of nights
|
||||
- Form Type Detection:
|
||||
- Auto-detects booking forms by presence of `[bnb_room_select]`, `[bnb_date_checkin]`, `[bnb_date_checkout]`
|
||||
- CSS class `wp-bnb-booking-form` for explicit form type declaration
|
||||
- Inquiry forms use default CF7 email handling without booking creation
|
||||
|
||||
### Changed
|
||||
|
||||
- Plugin.php updated to conditionally initialize CF7 integration when CF7 is active
|
||||
- Frontend assets now include CF7-specific CSS and JavaScript when CF7 is detected
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Contact Form 7 plugin required for CF7 integration features (optional)
|
||||
|
||||
## [0.6.1] - 2026-02-03
|
||||
|
||||
### Added
|
||||
|
||||
71
CLAUDE.md
71
CLAUDE.md
@@ -40,7 +40,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
|
||||
|
||||
### Known Bugs
|
||||
|
||||
No known bugs at this time.
|
||||
(none)
|
||||
|
||||
## Technical Stack
|
||||
|
||||
@@ -260,6 +260,8 @@ wp-bnb/
|
||||
│ │ ├── Calculator.php # Price calculation
|
||||
│ │ ├── PricingTier.php # Pricing tier enum
|
||||
│ │ └── Season.php # Seasonal pricing
|
||||
│ ├── Integration/ # Third-party integrations
|
||||
│ │ └── CF7.php # Contact Form 7 integration
|
||||
│ └── Taxonomies/ # Custom taxonomies
|
||||
│ ├── Amenity.php # Amenity taxonomy (tags)
|
||||
│ └── RoomType.php # Room type taxonomy (categories)
|
||||
@@ -270,10 +272,12 @@ wp-bnb/
|
||||
│ ├── css/
|
||||
│ │ ├── admin.css # Admin styles
|
||||
│ │ ├── blocks-editor.css # Gutenberg editor styles
|
||||
│ │ ├── cf7-integration.css # CF7 form styles
|
||||
│ │ └── frontend.css # Frontend styles (~1250 lines)
|
||||
│ └── js/
|
||||
│ ├── admin.js # Admin scripts
|
||||
│ ├── blocks-editor.js # Gutenberg editor scripts
|
||||
│ ├── cf7-integration.js # CF7 form scripts
|
||||
│ └── frontend.js # Frontend scripts (~825 lines)
|
||||
├── templates/ # Twig templates (future)
|
||||
├── languages/ # Translation files (future)
|
||||
@@ -338,7 +342,7 @@ Admin features always work; frontend requires valid license.
|
||||
- Implemented license settings page with validation/activation buttons
|
||||
- Created admin CSS and JavaScript for license management
|
||||
- Created Gitea CI/CD pipeline at `.gitea/workflows/release.yml`
|
||||
- Created `PLAN.md` with full implementation roadmap (8 phases)
|
||||
- Created `PLAN.md` with full implementation roadmap (10 phases)
|
||||
- Created `README.md` with user documentation
|
||||
- Created `CHANGELOG.md` following Keep a Changelog format
|
||||
- Updated `CLAUDE.md` with architecture details
|
||||
@@ -658,7 +662,6 @@ Admin features always work; frontend requires valid license.
|
||||
- Tagged: `v0.6.0`
|
||||
- Pushed to origin: dev, main, v0.6.0
|
||||
|
||||
|
||||
### 2026-02-03 - Bug Fixes and Enhancements
|
||||
|
||||
**Completed:**
|
||||
@@ -743,3 +746,65 @@ Admin features always work; frontend requires valid license.
|
||||
- `use_block_editor_for_post_type` filter disables Gutenberg per post type
|
||||
- Post types with `show_in_rest => true` get Gutenberg by default, which hides traditional meta boxes
|
||||
- Form-based admin interfaces (data entry) should use classic editor, not block editor
|
||||
|
||||
### 2026-02-03 - Version 0.7.0 (Contact Form 7 Integration)
|
||||
|
||||
**Completed:**
|
||||
|
||||
- Created `src/Integration/CF7.php` (~750 lines)
|
||||
- Custom form tags: `[bnb_building_select]`, `[bnb_room_select]`, `[bnb_date_checkin]`, `[bnb_date_checkout]`, `[bnb_guests]`
|
||||
- Server-side validation for all custom tags
|
||||
- Availability validation in `wpcf7_before_send_mail` hook
|
||||
- Automatic booking creation on form submission via `wpcf7_mail_sent`
|
||||
- Guest record creation/linking using `find_or_create_guest()` pattern
|
||||
- Custom mail tags: `[_bnb_room_name]`, `[_bnb_building_name]`, `[_bnb_calculated_price]`, `[_bnb_nights]`, `[_bnb_booking_reference]`
|
||||
- Form type detection via CSS class `wp-bnb-booking-form`
|
||||
- Created `assets/js/cf7-integration.js` (~230 lines)
|
||||
- Building-based room filtering (rooms dropdown updates when building selected)
|
||||
- Date validation (check-out after check-in, no past dates)
|
||||
- Guest capacity validation against room limits
|
||||
- AJAX availability checking with status display
|
||||
- AJAX price calculation with formatted display
|
||||
- Debounced updates to prevent excessive requests
|
||||
- Created `assets/css/cf7-integration.css` (~200 lines)
|
||||
- Two-column responsive form layout
|
||||
- Availability status indicators (checking spinner, available checkmark, unavailable X)
|
||||
- Price display formatting
|
||||
- Capacity warning styling
|
||||
- Dark mode support via `prefers-color-scheme`
|
||||
- Print styles (hide interactive elements)
|
||||
- Updated `src/Plugin.php`
|
||||
- Added `use Magdev\WpBnb\Integration\CF7` import
|
||||
- CF7 initialization in `init_frontend()` when WPCF7 class exists
|
||||
- CF7 assets enqueuing with localized i18n strings
|
||||
- Updated `README.md` with comprehensive CF7 documentation
|
||||
- Custom form tags reference with options
|
||||
- Example booking form template
|
||||
- Example inquiry form template
|
||||
- Custom mail tags documentation
|
||||
|
||||
**Files Created:**
|
||||
|
||||
- `src/Integration/CF7.php` - Main CF7 integration class
|
||||
- `assets/js/cf7-integration.js` - Frontend JavaScript
|
||||
- `assets/css/cf7-integration.css` - Form styling
|
||||
|
||||
**Learnings:**
|
||||
|
||||
- CF7 custom tags registered via `wpcf7_add_form_tag()` with callback functions
|
||||
- Validation filters follow pattern `wpcf7_validate_{tag_name}`
|
||||
- `wpcf7_before_send_mail` can abort submission by setting `$abort` to true and adding validation error
|
||||
- `wpcf7_mail_sent` fires after successful email, ideal for booking creation
|
||||
- Custom mail tags via `wpcf7_special_mail_tags` filter receive submission data
|
||||
- Form type detection by CSS class more reliable than checking for specific tags
|
||||
- Room dropdown with `data-building` attributes enables client-side filtering
|
||||
- AJAX endpoints reuse existing `wp_bnb_get_availability` and `wp_bnb_calculate_price` actions
|
||||
- CF7 assets should depend on `contact-form-7` script/style handles
|
||||
- Guest linking uses email as unique identifier for find-or-create pattern
|
||||
|
||||
**Released:**
|
||||
|
||||
- Committed: `28350aa` on dev branch
|
||||
- Merged to main (fast-forward)
|
||||
- Tagged: `v0.7.0`
|
||||
- Pushed to origin: dev, main, v0.7.0
|
||||
|
||||
53
PLAN.md
53
PLAN.md
@@ -149,20 +149,20 @@ This document outlines the implementation plan for the WP BnB Management plugin.
|
||||
- [x] Building rooms widget
|
||||
- [x] Availability calendar widget
|
||||
|
||||
## Phase 7: Contact Form 7 Integration (v0.7.0)
|
||||
## Phase 7: Contact Form 7 Integration (v0.7.0) - Complete
|
||||
|
||||
### Booking Request Form
|
||||
|
||||
- [ ] Custom CF7 tags for rooms/dates
|
||||
- [ ] Form validation
|
||||
- [ ] Booking creation on submission
|
||||
- [ ] Email notifications
|
||||
- [x] Custom CF7 tags for rooms/dates
|
||||
- [x] Form validation
|
||||
- [x] Booking creation on submission
|
||||
- [x] Email notifications
|
||||
|
||||
### Inquiry Form
|
||||
|
||||
- [ ] General inquiry handling
|
||||
- [ ] Room-specific inquiries
|
||||
- [ ] Auto-response templates
|
||||
- [x] General inquiry handling
|
||||
- [x] Room-specific inquiries
|
||||
- [x] Auto-response templates (uses default CF7 mail templates)
|
||||
|
||||
## Phase 8: Dashboard & Reports (v0.8.0)
|
||||
|
||||
@@ -180,6 +180,17 @@ This document outlines the implementation plan for the WP BnB Management plugin.
|
||||
- [ ] Guest statistics
|
||||
- [ ] Export functionality (CSV, PDF)
|
||||
|
||||
## Phase 9: Prometheus Metrics (v0.9.0)
|
||||
|
||||
- [ ] Meanigful Metrics for this Plugin, see <https://src.bundespruefstelle.ch/magdev/wp-prometheus/raw/branch/main/README.md> for implementation details
|
||||
- [ ] Example Grafana-Dashboard, see <https://src.bundespruefstelle.ch/magdev/wp-prometheus/raw/branch/main/README.md> for implementation details
|
||||
- [ ] Update settings page to enable/disable metrics
|
||||
|
||||
## Phase 10: Security Audit (v0.10.0)
|
||||
|
||||
- [ ] Check for Wordpress best-practises
|
||||
- [ ] Review the code for OWASP Top 10, including XSS, XSRF, SQLi and other critical threads
|
||||
|
||||
## Future Considerations (v1.0.0+)
|
||||
|
||||
### WooCommerce Integration (Optional)
|
||||
@@ -286,15 +297,17 @@ The plugin will provide extensive hooks for customization:
|
||||
|
||||
## Version Milestones
|
||||
|
||||
| Version | Focus | Target |
|
||||
| ------- | --------------- | -------- |
|
||||
| 0.0.1 | Initial setup | Complete |
|
||||
| 0.1.0 | Data structures | Complete |
|
||||
| 0.2.0 | Pricing | Complete |
|
||||
| 0.3.0 | Bookings | Complete |
|
||||
| 0.4.0 | Guests | Complete |
|
||||
| 0.5.0 | Services | Complete |
|
||||
| 0.6.0 | Frontend | Complete |
|
||||
| 0.7.0 | CF7 Integration | TBD |
|
||||
| 0.8.0 | Dashboard | TBD |
|
||||
| 1.0.0 | Stable Release | TBD |
|
||||
| Version | Focus | Target |
|
||||
| ------- | ------------------ | -------- |
|
||||
| 0.0.1 | Initial setup | Complete |
|
||||
| 0.1.0 | Data structures | Complete |
|
||||
| 0.2.0 | Pricing | Complete |
|
||||
| 0.3.0 | Bookings | Complete |
|
||||
| 0.4.0 | Guests | Complete |
|
||||
| 0.5.0 | Services | Complete |
|
||||
| 0.6.0 | Frontend | Complete |
|
||||
| 0.7.0 | CF7 Integration | Complete |
|
||||
| 0.8.0 | Dashboard | TBD |
|
||||
| 0.9.0 | Prometheus Metrics | TBD |
|
||||
| 0.10.0 | Security Audit | TBD |
|
||||
| 1.0.0 | Stable Release | TBD |
|
||||
|
||||
149
README.md
149
README.md
@@ -18,13 +18,14 @@ WP BnB Management enables WordPress to act as a full management system for B&B h
|
||||
- **Frontend Integration**: Gutenberg blocks, widgets, and shortcodes
|
||||
- **Auto-Updates**: Automatic update checks and installation from license server
|
||||
- **Development Mode**: License bypass for local development environments
|
||||
- **Contact Form 7 Integration**: Accept booking requests through forms (planned)
|
||||
- **Contact Form 7 Integration**: Accept booking requests and inquiries through CF7 forms
|
||||
|
||||
### Requirements
|
||||
|
||||
- WordPress 6.0 or higher
|
||||
- PHP 8.3 or higher
|
||||
- Valid license key
|
||||
- Contact Form 7 (optional, for booking forms)
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -143,6 +144,152 @@ Available sidebar widgets:
|
||||
- **Building Rooms** - List all rooms in a building
|
||||
- **Availability Calendar** - Mini calendar showing booking status
|
||||
|
||||
## Contact Form 7 Integration
|
||||
|
||||
The plugin integrates with Contact Form 7 to accept booking requests and inquiries. Custom form tags are provided for room selection, date pickers, and guest counts.
|
||||
|
||||
### Custom Form Tags
|
||||
|
||||
Use these tags in your CF7 forms:
|
||||
|
||||
- `[bnb_building_select name]` - Building dropdown (optional filter for rooms)
|
||||
- `[bnb_room_select* name]` - Room dropdown with capacity data
|
||||
- `[bnb_date_checkin* name]` - Check-in date picker
|
||||
- `[bnb_date_checkout* name]` - Check-out date picker
|
||||
- `[bnb_guests* name]` - Guest count input
|
||||
|
||||
### Tag Options
|
||||
|
||||
**`[bnb_building_select]`**:
|
||||
|
||||
- `first_as_label:"text"` - Placeholder text (default: "All Locations")
|
||||
|
||||
**`[bnb_room_select]`**:
|
||||
|
||||
- `building_field:"name"` - Link to building field for filtering
|
||||
- `first_as_label:"text"` - Placeholder text (default: "Select Room")
|
||||
|
||||
**`[bnb_guests]`**:
|
||||
|
||||
- `min:N` - Minimum guests (default: 1)
|
||||
- `max:N` - Maximum guests (default: 10)
|
||||
- `default:N` - Default value (default: 1)
|
||||
|
||||
### Example Booking Form
|
||||
|
||||
```txt
|
||||
<div class="wp-bnb-booking-form">
|
||||
<h3>Book Your Stay</h3>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
[bnb_building_select building first_as_label:"All Locations"]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
[bnb_room_select* room building_field:"building" first_as_label:"Select a Room"]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row-2col">
|
||||
<div class="wp-bnb-form-field">
|
||||
<label>Check-in</label>
|
||||
[bnb_date_checkin* check_in]
|
||||
</div>
|
||||
<div class="wp-bnb-form-field">
|
||||
<label>Check-out</label>
|
||||
[bnb_date_checkout* check_out]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-availability-status"></div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Number of Guests</label>
|
||||
[bnb_guests* guests min:1 max:10 default:2]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-price-display"></div>
|
||||
|
||||
<h4>Your Information</h4>
|
||||
|
||||
<div class="wp-bnb-form-row-2col">
|
||||
<div class="wp-bnb-form-field">
|
||||
<label>First Name</label>
|
||||
[text* first_name]
|
||||
</div>
|
||||
<div class="wp-bnb-form-field">
|
||||
<label>Last Name</label>
|
||||
[text* last_name]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Email</label>
|
||||
[email* your_email]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Phone</label>
|
||||
[tel your_phone]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Message</label>
|
||||
[textarea your_message]
|
||||
</div>
|
||||
|
||||
[submit "Request Booking"]
|
||||
</div>
|
||||
```
|
||||
|
||||
### Example Inquiry Form
|
||||
|
||||
For room-specific inquiries, add the `wp-bnb-inquiry-form` class:
|
||||
|
||||
```txt
|
||||
<div class="wp-bnb-inquiry-form">
|
||||
<h3>Inquire About This Room</h3>
|
||||
|
||||
[hidden room default:123]
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Your Name</label>
|
||||
[text* your_name]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Email</label>
|
||||
[email* your_email]
|
||||
</div>
|
||||
|
||||
<div class="wp-bnb-form-row">
|
||||
<label>Your Question</label>
|
||||
[textarea* your_message]
|
||||
</div>
|
||||
|
||||
[submit "Send Inquiry"]
|
||||
</div>
|
||||
```
|
||||
|
||||
### Form Features
|
||||
|
||||
- **Availability Checking**: Real-time AJAX validation shows room availability
|
||||
- **Price Display**: Estimated total calculated and displayed automatically
|
||||
- **Room Filtering**: Rooms filter by building selection
|
||||
- **Date Validation**: Check-out must be after check-in, no past dates
|
||||
- **Capacity Validation**: Guest count validated against room capacity
|
||||
- **Automatic Booking**: Booking record created with "pending" status on submission
|
||||
- **Guest Linking**: Guest records created or linked by email address
|
||||
|
||||
### Custom Mail Tags
|
||||
|
||||
Use these in your CF7 mail templates:
|
||||
|
||||
- `[_bnb_room_name]` - Room title
|
||||
- `[_bnb_building_name]` - Building name
|
||||
- `[_bnb_calculated_price]` - Formatted price
|
||||
- `[_bnb_nights]` - Number of nights
|
||||
- `[_bnb_booking_reference]` - Booking reference (after creation)
|
||||
|
||||
## Hooks and Filters
|
||||
|
||||
Developers can customize behavior using these hooks:
|
||||
|
||||
344
assets/css/cf7-integration.css
Normal file
344
assets/css/cf7-integration.css
Normal file
@@ -0,0 +1,344 @@
|
||||
/**
|
||||
* WP BnB Contact Form 7 Integration Styles
|
||||
*
|
||||
* Styling for CF7 booking forms.
|
||||
*
|
||||
* @package Magdev\WpBnb
|
||||
*/
|
||||
|
||||
/* Custom Properties */
|
||||
:root {
|
||||
--wp-bnb-cf7-primary: #2271b1;
|
||||
--wp-bnb-cf7-success: #00a32a;
|
||||
--wp-bnb-cf7-warning: #dba617;
|
||||
--wp-bnb-cf7-error: #d63638;
|
||||
--wp-bnb-cf7-text: #1d2327;
|
||||
--wp-bnb-cf7-text-light: #646970;
|
||||
--wp-bnb-cf7-border: #c3c4c7;
|
||||
--wp-bnb-cf7-bg: #f0f0f1;
|
||||
--wp-bnb-cf7-radius: 4px;
|
||||
--wp-bnb-cf7-spacing: 1rem;
|
||||
}
|
||||
|
||||
/* Form Layout */
|
||||
.wp-bnb-booking-form,
|
||||
.wp-bnb-inquiry-form {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wp-bnb-booking-form h3,
|
||||
.wp-bnb-booking-form h4,
|
||||
.wp-bnb-inquiry-form h3,
|
||||
.wp-bnb-inquiry-form h4 {
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.75em;
|
||||
padding-bottom: 0.5em;
|
||||
border-bottom: 1px solid var(--wp-bnb-cf7-border);
|
||||
}
|
||||
|
||||
.wp-bnb-booking-form h3:first-child,
|
||||
.wp-bnb-inquiry-form h3:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Form Rows */
|
||||
.wp-bnb-form-row {
|
||||
margin-bottom: var(--wp-bnb-cf7-spacing);
|
||||
}
|
||||
|
||||
.wp-bnb-form-row-2col {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: var(--wp-bnb-cf7-spacing);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.wp-bnb-form-row-2col {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Form Fields */
|
||||
.wp-bnb-form-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wp-bnb-form-field label {
|
||||
display: block;
|
||||
margin-bottom: 0.25rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
color: var(--wp-bnb-cf7-text);
|
||||
}
|
||||
|
||||
/* Custom CF7 Tags Styling */
|
||||
.wp-bnb-building-select,
|
||||
.wp-bnb-room-select,
|
||||
.wp-bnb-date-checkin,
|
||||
.wp-bnb-date-checkout,
|
||||
.wp-bnb-guests {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
border: 1px solid var(--wp-bnb-cf7-border);
|
||||
border-radius: var(--wp-bnb-cf7-radius);
|
||||
background-color: #fff;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.wp-bnb-building-select:focus,
|
||||
.wp-bnb-room-select:focus,
|
||||
.wp-bnb-date-checkin:focus,
|
||||
.wp-bnb-date-checkout:focus,
|
||||
.wp-bnb-guests:focus {
|
||||
outline: none;
|
||||
border-color: var(--wp-bnb-cf7-primary);
|
||||
box-shadow: 0 0 0 2px rgba(34, 113, 177, 0.25);
|
||||
}
|
||||
|
||||
/* Select dropdown */
|
||||
.wp-bnb-room-select optgroup {
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
color: var(--wp-bnb-cf7-text);
|
||||
}
|
||||
|
||||
/* Date inputs */
|
||||
.wp-bnb-date-checkin,
|
||||
.wp-bnb-date-checkout {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Number input */
|
||||
.wp-bnb-guests {
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
/* Availability Status */
|
||||
.wp-bnb-availability-status {
|
||||
padding: var(--wp-bnb-cf7-spacing);
|
||||
margin: var(--wp-bnb-cf7-spacing) 0;
|
||||
background-color: var(--wp-bnb-cf7-bg);
|
||||
border-radius: var(--wp-bnb-cf7-radius);
|
||||
text-align: center;
|
||||
min-height: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wp-bnb-availability-status:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wp-bnb-checking {
|
||||
color: var(--wp-bnb-cf7-text-light);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.wp-bnb-checking::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
border: 2px solid var(--wp-bnb-cf7-border);
|
||||
border-top-color: var(--wp-bnb-cf7-primary);
|
||||
border-radius: 50%;
|
||||
animation: wp-bnb-spin 0.8s linear infinite;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@keyframes wp-bnb-spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.wp-bnb-available {
|
||||
color: var(--wp-bnb-cf7-success);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wp-bnb-available::before {
|
||||
content: "\2713";
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.wp-bnb-unavailable {
|
||||
color: var(--wp-bnb-cf7-error);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wp-bnb-unavailable::before {
|
||||
content: "\2717";
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
/* Price Display */
|
||||
.wp-bnb-price-display {
|
||||
padding: var(--wp-bnb-cf7-spacing);
|
||||
margin: var(--wp-bnb-cf7-spacing) 0;
|
||||
background-color: #e7f5ea;
|
||||
border: 1px solid var(--wp-bnb-cf7-success);
|
||||
border-radius: var(--wp-bnb-cf7-radius);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wp-bnb-price-display:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wp-bnb-price-label {
|
||||
color: var(--wp-bnb-cf7-text-light);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.wp-bnb-price-amount {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--wp-bnb-cf7-success);
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
.wp-bnb-nights {
|
||||
color: var(--wp-bnb-cf7-text-light);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
/* Capacity Warning */
|
||||
.wp-bnb-capacity-warning {
|
||||
display: block;
|
||||
margin-top: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.8125rem;
|
||||
color: var(--wp-bnb-cf7-error);
|
||||
background-color: #fcf0f1;
|
||||
border-radius: var(--wp-bnb-cf7-radius);
|
||||
}
|
||||
|
||||
/* Validation Errors */
|
||||
.wpcf7-form-control-wrap .wpcf7-not-valid-tip {
|
||||
color: var(--wp-bnb-cf7-error);
|
||||
font-size: 0.8125rem;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.wpcf7-form-control.wpcf7-not-valid {
|
||||
border-color: var(--wp-bnb-cf7-error);
|
||||
}
|
||||
|
||||
/* Response Messages */
|
||||
.wpcf7 form.sent .wpcf7-response-output {
|
||||
border-color: var(--wp-bnb-cf7-success);
|
||||
background-color: #e7f5ea;
|
||||
color: var(--wp-bnb-cf7-success);
|
||||
}
|
||||
|
||||
.wpcf7 form.failed .wpcf7-response-output,
|
||||
.wpcf7 form.aborted .wpcf7-response-output,
|
||||
.wpcf7 form.spam .wpcf7-response-output,
|
||||
.wpcf7 form.invalid .wpcf7-response-output {
|
||||
border-color: var(--wp-bnb-cf7-error);
|
||||
background-color: #fcf0f1;
|
||||
color: var(--wp-bnb-cf7-error);
|
||||
}
|
||||
|
||||
/* Submit Button */
|
||||
.wp-bnb-booking-form .wpcf7-submit,
|
||||
.wp-bnb-inquiry-form .wpcf7-submit {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
background-color: var(--wp-bnb-cf7-primary);
|
||||
border: none;
|
||||
border-radius: var(--wp-bnb-cf7-radius);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.wp-bnb-booking-form .wpcf7-submit:hover,
|
||||
.wp-bnb-inquiry-form .wpcf7-submit:hover {
|
||||
background-color: #135e96;
|
||||
}
|
||||
|
||||
.wp-bnb-booking-form .wpcf7-submit:disabled,
|
||||
.wp-bnb-inquiry-form .wpcf7-submit:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Spinner */
|
||||
.wpcf7 .wpcf7-spinner {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
/* Hidden Room Field (for inquiry forms) */
|
||||
.wp-bnb-inquiry-form input[type="hidden"] + .wpcf7-form-control-wrap {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Form Section Headers */
|
||||
.wp-bnb-booking-form hr,
|
||||
.wp-bnb-inquiry-form hr {
|
||||
margin: 1.5rem 0;
|
||||
border: none;
|
||||
border-top: 1px solid var(--wp-bnb-cf7-border);
|
||||
}
|
||||
|
||||
/* Dark Mode Support */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--wp-bnb-cf7-text: #f0f0f1;
|
||||
--wp-bnb-cf7-text-light: #a7aaad;
|
||||
--wp-bnb-cf7-border: #50575e;
|
||||
--wp-bnb-cf7-bg: #2c3338;
|
||||
}
|
||||
|
||||
.wp-bnb-building-select,
|
||||
.wp-bnb-room-select,
|
||||
.wp-bnb-date-checkin,
|
||||
.wp-bnb-date-checkout,
|
||||
.wp-bnb-guests {
|
||||
background-color: #3c434a;
|
||||
color: var(--wp-bnb-cf7-text);
|
||||
}
|
||||
|
||||
.wp-bnb-price-display {
|
||||
background-color: #1a3320;
|
||||
border-color: var(--wp-bnb-cf7-success);
|
||||
}
|
||||
|
||||
.wp-bnb-capacity-warning {
|
||||
background-color: #3c1618;
|
||||
}
|
||||
|
||||
.wpcf7 form.sent .wpcf7-response-output {
|
||||
background-color: #1a3320;
|
||||
}
|
||||
|
||||
.wpcf7 form.failed .wpcf7-response-output,
|
||||
.wpcf7 form.aborted .wpcf7-response-output,
|
||||
.wpcf7 form.spam .wpcf7-response-output,
|
||||
.wpcf7 form.invalid .wpcf7-response-output {
|
||||
background-color: #3c1618;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Styles */
|
||||
@media print {
|
||||
.wp-bnb-availability-status,
|
||||
.wp-bnb-price-display,
|
||||
.wpcf7-submit {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
375
assets/js/cf7-integration.js
Normal file
375
assets/js/cf7-integration.js
Normal file
@@ -0,0 +1,375 @@
|
||||
/**
|
||||
* WP BnB Contact Form 7 Integration
|
||||
*
|
||||
* Handles dynamic form behavior for booking forms.
|
||||
*
|
||||
* @package Magdev\WpBnb
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const WpBnbCF7 = {
|
||||
config: window.wpBnbCF7 || {},
|
||||
|
||||
/**
|
||||
* Initialize all CF7 integration features.
|
||||
*/
|
||||
init: function() {
|
||||
this.initBuildingRoomFilter();
|
||||
this.initDateValidation();
|
||||
this.initCapacityValidation();
|
||||
this.initAvailabilityCheck();
|
||||
this.initPriceDisplay();
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter rooms dropdown when building is selected.
|
||||
*/
|
||||
initBuildingRoomFilter: function() {
|
||||
document.querySelectorAll('[data-bnb-building-select]').forEach(function(buildingSelect) {
|
||||
const form = buildingSelect.closest('form');
|
||||
const roomSelect = form ? form.querySelector('[data-bnb-room-select]') : null;
|
||||
|
||||
if (!roomSelect) return;
|
||||
|
||||
// Store all options for filtering
|
||||
const allOptions = Array.from(roomSelect.querySelectorAll('option, optgroup'));
|
||||
const originalHTML = roomSelect.innerHTML;
|
||||
|
||||
buildingSelect.addEventListener('change', function() {
|
||||
const selectedBuilding = buildingSelect.value;
|
||||
|
||||
// Show all options if no building selected
|
||||
if (!selectedBuilding) {
|
||||
roomSelect.innerHTML = originalHTML;
|
||||
roomSelect.dispatchEvent(new Event('change'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter options by building
|
||||
roomSelect.innerHTML = '';
|
||||
|
||||
// Add placeholder option
|
||||
const placeholder = document.createElement('option');
|
||||
placeholder.value = '';
|
||||
placeholder.textContent = WpBnbCF7.config.i18n?.selectRoom || '-- Select Room --';
|
||||
roomSelect.appendChild(placeholder);
|
||||
|
||||
allOptions.forEach(function(el) {
|
||||
if (el.tagName === 'OPTGROUP') {
|
||||
// Check if any options in this optgroup match
|
||||
const matchingOptions = Array.from(el.querySelectorAll('option')).filter(function(opt) {
|
||||
return opt.dataset.building === selectedBuilding;
|
||||
});
|
||||
|
||||
if (matchingOptions.length > 0) {
|
||||
const clonedGroup = el.cloneNode(false);
|
||||
matchingOptions.forEach(function(opt) {
|
||||
clonedGroup.appendChild(opt.cloneNode(true));
|
||||
});
|
||||
roomSelect.appendChild(clonedGroup);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger change to update dependent fields
|
||||
roomSelect.dispatchEvent(new Event('change'));
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate and link check-in/check-out dates.
|
||||
*/
|
||||
initDateValidation: function() {
|
||||
document.querySelectorAll('[data-bnb-checkin]').forEach(function(checkinInput) {
|
||||
const form = checkinInput.closest('form');
|
||||
const checkoutInput = form ? form.querySelector('[data-bnb-checkout]') : null;
|
||||
|
||||
if (!checkoutInput) return;
|
||||
|
||||
// Set minimum check-in to today
|
||||
const today = WpBnbCF7.formatDate(new Date());
|
||||
if (!checkinInput.getAttribute('min') || checkinInput.getAttribute('min') < today) {
|
||||
checkinInput.setAttribute('min', today);
|
||||
}
|
||||
|
||||
checkinInput.addEventListener('change', function() {
|
||||
if (checkinInput.value) {
|
||||
// Set checkout minimum to checkin + 1 day
|
||||
const minCheckout = new Date(checkinInput.value);
|
||||
minCheckout.setDate(minCheckout.getDate() + 1);
|
||||
checkoutInput.setAttribute('min', WpBnbCF7.formatDate(minCheckout));
|
||||
|
||||
// Clear checkout if it's now invalid
|
||||
if (checkoutInput.value && checkoutInput.value <= checkinInput.value) {
|
||||
checkoutInput.value = '';
|
||||
}
|
||||
|
||||
// Trigger availability check
|
||||
WpBnbCF7.triggerAvailabilityCheck(form);
|
||||
}
|
||||
});
|
||||
|
||||
checkoutInput.addEventListener('change', function() {
|
||||
if (checkoutInput.value && checkinInput.value) {
|
||||
if (checkoutInput.value <= checkinInput.value) {
|
||||
alert(WpBnbCF7.config.i18n?.invalidDateRange || 'Check-out must be after check-in');
|
||||
checkoutInput.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger availability check
|
||||
WpBnbCF7.triggerAvailabilityCheck(form);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate guest count against room capacity.
|
||||
*/
|
||||
initCapacityValidation: function() {
|
||||
document.querySelectorAll('[data-bnb-guests]').forEach(function(guestsInput) {
|
||||
const form = guestsInput.closest('form');
|
||||
const roomSelect = form ? form.querySelector('[data-bnb-room-select]') : null;
|
||||
|
||||
if (!roomSelect) return;
|
||||
|
||||
const validateCapacity = function() {
|
||||
const selectedOption = roomSelect.selectedOptions[0];
|
||||
const capacity = parseInt(selectedOption?.dataset.capacity || 99, 10);
|
||||
const guests = parseInt(guestsInput.value || 0, 10);
|
||||
|
||||
// Update max attribute
|
||||
guestsInput.setAttribute('max', capacity);
|
||||
|
||||
// Show warning if over capacity
|
||||
const wrapper = guestsInput.closest('.wpcf7-form-control-wrap');
|
||||
let warning = wrapper ? wrapper.querySelector('.wp-bnb-capacity-warning') : null;
|
||||
|
||||
if (guests > capacity) {
|
||||
if (!warning && wrapper) {
|
||||
warning = document.createElement('span');
|
||||
warning.className = 'wp-bnb-capacity-warning';
|
||||
wrapper.appendChild(warning);
|
||||
}
|
||||
if (warning) {
|
||||
warning.textContent = (WpBnbCF7.config.i18n?.capacityExceeded || 'Maximum %d guests for this room').replace('%d', capacity);
|
||||
}
|
||||
} else if (warning) {
|
||||
warning.remove();
|
||||
}
|
||||
};
|
||||
|
||||
roomSelect.addEventListener('change', validateCapacity);
|
||||
guestsInput.addEventListener('change', validateCapacity);
|
||||
guestsInput.addEventListener('input', validateCapacity);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize AJAX availability checking.
|
||||
*/
|
||||
initAvailabilityCheck: function() {
|
||||
// Find forms with availability display
|
||||
document.querySelectorAll('.wp-bnb-availability-status').forEach(function(statusEl) {
|
||||
const form = statusEl.closest('form');
|
||||
if (form) {
|
||||
form._availabilityStatus = statusEl;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger availability check for a form.
|
||||
*
|
||||
* @param {HTMLFormElement} form Form element.
|
||||
*/
|
||||
triggerAvailabilityCheck: function(form) {
|
||||
const roomSelect = form.querySelector('[data-bnb-room-select]');
|
||||
const checkinInput = form.querySelector('[data-bnb-checkin]');
|
||||
const checkoutInput = form.querySelector('[data-bnb-checkout]');
|
||||
const statusEl = form._availabilityStatus || form.querySelector('.wp-bnb-availability-status');
|
||||
const priceEl = form.querySelector('.wp-bnb-price-display');
|
||||
|
||||
if (!roomSelect || !checkinInput || !checkoutInput) return;
|
||||
|
||||
const roomId = roomSelect.value;
|
||||
const checkIn = checkinInput.value;
|
||||
const checkOut = checkoutInput.value;
|
||||
|
||||
if (!roomId || !checkIn || !checkOut) {
|
||||
if (statusEl) statusEl.innerHTML = '';
|
||||
if (priceEl) priceEl.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
if (statusEl) {
|
||||
statusEl.innerHTML = '<span class="wp-bnb-checking">' + (WpBnbCF7.config.i18n?.checking || 'Checking availability...') + '</span>';
|
||||
}
|
||||
|
||||
// Make AJAX request
|
||||
WpBnbCF7.ajax('wp_bnb_get_availability', {
|
||||
room_id: roomId,
|
||||
check_in: checkIn,
|
||||
check_out: checkOut
|
||||
})
|
||||
.then(function(response) {
|
||||
if (statusEl) {
|
||||
if (response.available) {
|
||||
let html = '<span class="wp-bnb-available">' + (WpBnbCF7.config.i18n?.available || 'Room is available!') + '</span>';
|
||||
statusEl.innerHTML = html;
|
||||
} else {
|
||||
statusEl.innerHTML = '<span class="wp-bnb-unavailable">' + (WpBnbCF7.config.i18n?.unavailable || 'Room is not available for these dates') + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// Update price display
|
||||
if (priceEl && response.available && response.price_formatted) {
|
||||
priceEl.innerHTML = '<span class="wp-bnb-price-label">' + (WpBnbCF7.config.i18n?.estimatedTotal || 'Estimated Total') + ':</span> ' +
|
||||
'<span class="wp-bnb-price-amount">' + response.price_formatted + '</span> ' +
|
||||
'<span class="wp-bnb-nights">(' + response.nights + ' ' + (WpBnbCF7.config.i18n?.nights || 'nights') + ')</span>';
|
||||
} else if (priceEl) {
|
||||
priceEl.innerHTML = '';
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Availability check failed:', error);
|
||||
if (statusEl) {
|
||||
statusEl.innerHTML = '';
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize price display updates.
|
||||
*/
|
||||
initPriceDisplay: function() {
|
||||
const self = this;
|
||||
|
||||
document.querySelectorAll('.wp-bnb-price-display').forEach(function(priceEl) {
|
||||
const form = priceEl.closest('form');
|
||||
if (!form) return;
|
||||
|
||||
const updatePrice = self.debounce(function() {
|
||||
const roomSelect = form.querySelector('[data-bnb-room-select]');
|
||||
const checkinInput = form.querySelector('[data-bnb-checkin]');
|
||||
const checkoutInput = form.querySelector('[data-bnb-checkout]');
|
||||
|
||||
if (!roomSelect?.value || !checkinInput?.value || !checkoutInput?.value) {
|
||||
priceEl.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
self.ajax('wp_bnb_calculate_price', {
|
||||
room_id: roomSelect.value,
|
||||
check_in: checkinInput.value,
|
||||
check_out: checkoutInput.value
|
||||
})
|
||||
.then(function(response) {
|
||||
priceEl.innerHTML = '<span class="wp-bnb-price-label">' + (self.config.i18n?.estimatedTotal || 'Estimated Total') + ':</span> ' +
|
||||
'<span class="wp-bnb-price-amount">' + response.price_formatted + '</span> ' +
|
||||
'<span class="wp-bnb-nights">(' + response.nights + ' ' + (self.config.i18n?.nights || 'nights') + ')</span>';
|
||||
})
|
||||
.catch(function() {
|
||||
priceEl.innerHTML = '';
|
||||
});
|
||||
}, 500);
|
||||
|
||||
// Bind to relevant field changes
|
||||
form.querySelectorAll('[data-bnb-room-select], [data-bnb-checkin], [data-bnb-checkout]')
|
||||
.forEach(function(input) {
|
||||
input.addEventListener('change', updatePrice);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Make AJAX request.
|
||||
*
|
||||
* @param {string} action AJAX action name.
|
||||
* @param {object} data Request data.
|
||||
* @return {Promise}
|
||||
*/
|
||||
ajax: function(action, data) {
|
||||
data = data || {};
|
||||
const formData = new FormData();
|
||||
formData.append('action', action);
|
||||
formData.append('nonce', this.config.nonce || '');
|
||||
|
||||
Object.keys(data).forEach(function(key) {
|
||||
if (data[key] !== null && data[key] !== undefined) {
|
||||
formData.append(key, data[key]);
|
||||
}
|
||||
});
|
||||
|
||||
return fetch(this.config.ajaxUrl || '/wp-admin/admin-ajax.php', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(function(response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function(responseData) {
|
||||
if (!responseData.success) {
|
||||
throw new Error(responseData.data?.message || 'Request failed');
|
||||
}
|
||||
return responseData.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Format date as YYYY-MM-DD.
|
||||
*
|
||||
* @param {Date} date Date object.
|
||||
* @return {string}
|
||||
*/
|
||||
formatDate: function(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return year + '-' + month + '-' + day;
|
||||
},
|
||||
|
||||
/**
|
||||
* Debounce function.
|
||||
*
|
||||
* @param {function} func Function to debounce.
|
||||
* @param {number} wait Milliseconds to wait.
|
||||
* @return {function}
|
||||
*/
|
||||
debounce: function(func, wait) {
|
||||
let timeout;
|
||||
return function() {
|
||||
const context = this;
|
||||
const args = arguments;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(function() {
|
||||
func.apply(context, args);
|
||||
}, wait);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize on DOM ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
WpBnbCF7.init();
|
||||
});
|
||||
} else {
|
||||
WpBnbCF7.init();
|
||||
}
|
||||
|
||||
// Re-initialize on CF7 form reset
|
||||
document.addEventListener('wpcf7reset', function(event) {
|
||||
setTimeout(function() {
|
||||
WpBnbCF7.init();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Export to window for external access
|
||||
window.WpBnbCF7 = WpBnbCF7;
|
||||
})();
|
||||
1654
src/Integration/CF7.php
Normal file
1654
src/Integration/CF7.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@ use Magdev\WpBnb\Booking\Availability;
|
||||
use Magdev\WpBnb\Booking\EmailNotifier;
|
||||
use Magdev\WpBnb\Frontend\Search;
|
||||
use Magdev\WpBnb\Frontend\Shortcodes;
|
||||
use Magdev\WpBnb\Integration\CF7;
|
||||
use Magdev\WpBnb\Frontend\Widgets\AvailabilityCalendar;
|
||||
use Magdev\WpBnb\Frontend\Widgets\BuildingRooms;
|
||||
use Magdev\WpBnb\Frontend\Widgets\SimilarRooms;
|
||||
@@ -202,6 +203,11 @@ final class Plugin {
|
||||
|
||||
// Register widgets.
|
||||
add_action( 'widgets_init', array( $this, 'register_widgets' ) );
|
||||
|
||||
// Initialize Contact Form 7 integration if CF7 is active.
|
||||
if ( class_exists( 'WPCF7' ) ) {
|
||||
CF7::init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,6 +368,43 @@ final class Plugin {
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Load CF7 integration assets if CF7 is active.
|
||||
if ( class_exists( 'WPCF7' ) ) {
|
||||
wp_enqueue_style(
|
||||
'wp-bnb-cf7',
|
||||
WP_BNB_URL . 'assets/css/cf7-integration.css',
|
||||
array( 'contact-form-7' ),
|
||||
WP_BNB_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wp-bnb-cf7',
|
||||
WP_BNB_URL . 'assets/js/cf7-integration.js',
|
||||
array( 'contact-form-7' ),
|
||||
WP_BNB_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'wp-bnb-cf7',
|
||||
'wpBnbCF7',
|
||||
array(
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'wp_bnb_frontend_nonce' ),
|
||||
'i18n' => array(
|
||||
'selectRoom' => __( '-- Select Room --', 'wp-bnb' ),
|
||||
'checking' => __( 'Checking availability...', 'wp-bnb' ),
|
||||
'available' => __( 'Room is available!', 'wp-bnb' ),
|
||||
'unavailable' => __( 'Room is not available for these dates', 'wp-bnb' ),
|
||||
'invalidDateRange' => __( 'Check-out must be after check-in', 'wp-bnb' ),
|
||||
'capacityExceeded' => __( 'Maximum %d guests for this room', 'wp-bnb' ),
|
||||
'estimatedTotal' => __( 'Estimated Total', 'wp-bnb' ),
|
||||
'nights' => __( 'nights', 'wp-bnb' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: WP BnB Management
|
||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wp-bnb
|
||||
* Description: A comprehensive Bed & Breakfast management system for WordPress. Manage buildings, rooms, bookings, and guests.
|
||||
* Version: 0.6.1
|
||||
* Version: 0.7.1
|
||||
* Requires at least: 6.0
|
||||
* Requires PHP: 8.3
|
||||
* Author: Marco Graetsch
|
||||
@@ -24,7 +24,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
}
|
||||
|
||||
// Plugin version constant - MUST match Version in header above.
|
||||
define( 'WP_BNB_VERSION', '0.6.1' );
|
||||
define( 'WP_BNB_VERSION', '0.7.1' );
|
||||
|
||||
// Plugin path constants.
|
||||
define( 'WP_BNB_PATH', plugin_dir_path( __FILE__ ) );
|
||||
|
||||
Reference in New Issue
Block a user