13 Commits
v0.11.0 ... dev

Author SHA1 Message Date
d39abc0dd1 Bump version to 0.12.1
All checks were successful
Create Release Package / build-release (push) Successful in 1m10s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:27:58 +01:00
a1155af6a0 Fix AJAX handler timing: register directly instead of on woocommerce_loaded
The woocommerce_loaded hook may have already fired by the time our plugin
initializes. Register the AJAX handler directly since we've already verified
WooCommerce is active.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:24:31 +01:00
23f073339a Fix WooCommerce sync button: AJAX handler registration and icon alignment
- Register ProductSync AJAX handler independently from full integration init
- AJAX now available on settings page even when integration is not yet enabled
- Improved icon vertical alignment with explicit margin-top adjustment
- Added better error handling and console logging in JS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:22:14 +01:00
c92be303e8 Fix WooCommerce product sync button functionality
- Move sync handler from wc-integration.js to admin.js (uses wpBnbAdmin)
- Add CSS for button icon vertical alignment with inline-flex
- Add spin animation for sync button icon during operation
- Add sync status styling (success/error colors)
- Add i18n strings for syncing messages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:17:17 +01:00
ada838a1e4 Add Dashboard link to plugin action links on plugins page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:09:15 +01:00
dbd0f3f788 Security audit and bug fixes (v0.12.0)
All checks were successful
Create Release Package / build-release (push) Successful in 1m37s
- Complete security audit for WordPress best practices, OWASP Top 10
- Fix Calculator static method calls in API controllers
- Fix EmailNotifier method names in BookingsController
- Fix guest_id type casting in EmailNotifier

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 09:44:23 +01:00
a8e0df99d1 Update CLAUDE.md with v0.11.2/v0.11.3 session history
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:41:43 +01:00
70d588808e Display calendar filters side by side (v0.11.3)
All checks were successful
Create Release Package / build-release (push) Successful in 1m8s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:40:05 +01:00
0bf7f19ac5 Improve calendar room column with building name display (v0.11.2)
All checks were successful
Create Release Package / build-release (push) Successful in 1m1s
- Widen room column to 200px with proper left alignment
- Display building name as second row under room name
- Change table-layout from fixed to auto for flexible columns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:31:45 +01:00
7c0016c244 Bump version to 0.11.1
All checks were successful
Create Release Package / build-release (push) Successful in 1m7s
- Add i18n translation files (German Switzerland)
- Update README with WooCommerce documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:21:17 +01:00
997541ab48 Add i18n translation files for German (Switzerland)
- Extract 1140 translatable strings to wp-bnb.pot
- Create wp-bnb-de_CH.po with 875 (77%) translated strings
- Compile wp-bnb-de_CH.mo for WordPress to use
- Coverage includes: admin UI, post types, taxonomies, settings,
  dashboard, reports, REST API messages, WooCommerce integration,
  CF7 integration, frontend widgets, blocks, and shortcodes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:19:34 +01:00
36a69b0de4 Update README with WooCommerce integration documentation
- Add WooCommerce Integration and REST API to key features
- Add WooCommerce 8.0+ to optional requirements
- Add comprehensive WooCommerce Integration section with:
  - Enabling instructions
  - Product sync, cart/checkout, booking creation features
  - Order-booking synchronization details
  - PDF invoice documentation
  - Settings subtabs description
  - HPOS compatibility note
  - Admin columns info
- Update FAQ to reflect WooCommerce is now implemented

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:01:45 +01:00
5d24cfa6f9 Update CLAUDE.md with v0.11.0 session history
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:53:54 +01:00
18 changed files with 10906 additions and 37 deletions

View File

@@ -5,6 +5,71 @@ 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.12.1] - 2026-02-04
### Fixed
- Fixed WooCommerce product sync button not working on settings page
- Fixed AJAX handler registration timing (now registered directly instead of on `woocommerce_loaded` hook)
- Fixed sync button icon vertical alignment
- Added Dashboard link to WordPress plugins list page
### Added
- Better error handling and console logging for WooCommerce sync AJAX requests
## [0.12.0] - 2026-02-04
### Security
- Completed comprehensive security audit (Phase 12)
- Verified WordPress best practices compliance across entire codebase
- Confirmed protection against SQL Injection: all database queries use `$wpdb->prepare()` or WP_Query
- Confirmed protection against XSS: all output properly escaped with `esc_html()`, `esc_attr()`, `esc_url()`
- Confirmed protection against CSRF: nonce verification on all forms and admin AJAX handlers
- Verified REST API endpoint security: proper permission callbacks, rate limiting, input sanitization
- Sensitive data (ID/passport numbers) properly encrypted and not exposed via API
### Fixed
- Fixed Calculator being called statically in API controllers (`BookingsController`, `RoomsController`, `PricingController`)
- Fixed EmailNotifier method names in BookingsController (`send_admin_new_booking`, `send_cancellation`, `send_guest_confirmation`)
- Fixed guest_id type casting in EmailNotifier (string to int from post meta)
### Notes
- Public AJAX endpoints (search, availability, calendar, price calculation) intentionally do not require nonce verification as they are read-only public APIs with proper input sanitization
- All admin AJAX endpoints properly protected with nonce verification and capability checks
## [0.11.3] - 2026-02-03
### Changed
- Calendar filters now display side by side instead of stacked rows
## [0.11.2] - 2026-02-03
### Changed
- Calendar page room column now wider (200px) with proper left alignment
- Room column displays building name on second row for better identification
- Changed calendar table layout from fixed to auto for flexible column widths
## [0.11.1] - 2026-02-03
### Added
- Internationalization (i18n) support:
- Translation template file `languages/wp-bnb.pot` with 1,140 translatable strings
- German (Switzerland) translation `languages/wp-bnb-de_CH.po` with 77% coverage (875 strings)
- Compiled binary `languages/wp-bnb-de_CH.mo` for WordPress use
- Coverage includes: admin UI, post types, taxonomies, settings, dashboard, reports, REST API, WooCommerce, CF7, widgets, blocks, shortcodes
### Changed
- README.md updated with comprehensive WooCommerce integration documentation
- Added REST API to key features list in README
## [0.11.0] - 2026-02-03
### Added

207
CLAUDE.md
View File

@@ -1128,3 +1128,210 @@ Admin features always work; frontend requires valid license.
- v0.10.1: Committed `3f5adfb` - Configurable rate limiting with settings subtabs
- Tags: `v0.10.0`, `v0.10.1`
- Pushed to origin: dev, main, both tags
### 2026-02-03 - Version 0.11.0 (WooCommerce Integration)
**Completed:**
- Created `src/Integration/WooCommerce/Manager.php` (~435 lines)
- Core integration manager with option constants
- HPOS (High-Performance Order Storage) compatibility declaration
- `is_wc_active()`, `is_enabled()` checks
- `map_wc_status_to_booking()` for status synchronization
- `get_order_for_booking()`, `get_booking_for_order()` bidirectional lookups
- `link_booking_to_order()` for creating relationships
- Created `src/Integration/WooCommerce/ProductSync.php` (~515 lines)
- Virtual WooCommerce products for rooms (SKU: `bnb-room-{id}`)
- Auto-sync on `save_post_bnb_room` hook
- Product deletion on room deletion
- `sync_all_rooms()` for bulk synchronization
- Bidirectional meta linking (room ↔ product)
- Created `src/Integration/WooCommerce/CartHandler.php` (~545 lines)
- Cart item data structure with booking details
- Availability validation on add-to-cart
- Dynamic price calculation using `Calculator` class
- Cart item display with dates, guests, nights
- Services support in cart items
- Created `src/Integration/WooCommerce/CheckoutHandler.php` (~347 lines)
- Special requests textarea field
- Arrival time dropdown field
- Guest data pre-fill from user profile
- Final availability validation before payment
- Booking summary display
- Created `src/Integration/WooCommerce/OrderHandler.php` (~584 lines)
- Booking creation on `woocommerce_payment_complete`
- Guest record creation from billing info
- Booking reference generation (BNB-YYYY-NNNNN)
- Status synchronization on order status changes
- Order-booking bidirectional linking
- Created `src/Integration/WooCommerce/InvoiceGenerator.php` (~633 lines)
- PDF generation using existing mPDF dependency
- Configurable invoice numbering (prefix + start number)
- Auto-attach to WooCommerce order emails
- Secure storage in `wp-content/uploads/wp-bnb-invoices/`
- .htaccess protection for invoice directory
- Created `src/Integration/WooCommerce/RefundHandler.php` (~394 lines)
- Full refund triggers booking cancellation
- Partial refund records amount without cancellation
- Refund meta storage on booking
- `wp_bnb_wc_should_cancel_on_refund` filter for customization
- Created `src/Integration/WooCommerce/AdminColumns.php` (~282 lines)
- "WC Order" column in bookings list
- "Booking" column in WC orders list (supports HPOS)
- Row actions for cross-navigation
- Created `assets/css/wc-integration.css` (~443 lines)
- Cart booking display styles
- Checkout summary styles
- Booking form styles
- Status badge colors
- Created `assets/js/wc-integration.js` (~358 lines)
- `BookingForm` class for frontend forms
- AJAX sync rooms handler
- AJAX generate invoice handler
- Availability checking with debounce
- Updated `src/Plugin.php`
- WooCommerce initialization when WC is active
- WooCommerce settings tab with 4 subtabs (General, Products, Orders, Invoices)
- Asset enqueuing for WooCommerce integration
**Files Created:**
- `src/Integration/WooCommerce/Manager.php`
- `src/Integration/WooCommerce/ProductSync.php`
- `src/Integration/WooCommerce/CartHandler.php`
- `src/Integration/WooCommerce/CheckoutHandler.php`
- `src/Integration/WooCommerce/OrderHandler.php`
- `src/Integration/WooCommerce/InvoiceGenerator.php`
- `src/Integration/WooCommerce/RefundHandler.php`
- `src/Integration/WooCommerce/AdminColumns.php`
- `assets/css/wc-integration.css`
- `assets/js/wc-integration.js`
**Files Changed:**
- `src/Plugin.php` - WooCommerce initialization and settings tab
- `assets/css/admin.css` - Status badge colors for booking statuses
- `wp-bnb.php` - Version bump to 0.11.0
- `CHANGELOG.md` - Added v0.11.0 release notes
- `PLAN.md` - Marked Phase 11 as complete
**Learnings:**
- WooCommerce HPOS compatibility requires `FeaturesUtil::declare_compatibility()` in `before_woocommerce_init` hook
- Use `$order->get_meta()` / `$order->update_meta_data()` instead of `get_post_meta()` for HPOS compatibility
- Virtual products (`virtual => true`, `downloadable => false`) don't require shipping
- Cart item data stored via `woocommerce_add_cart_item_data` filter persists through session
- Dynamic pricing via `woocommerce_before_calculate_totals` hook with priority 20
- `woocommerce_payment_complete` fires after successful payment, ideal for booking creation
- Invoice attachment via `woocommerce_email_attachments` filter with order and email type detection
- Refund detection: `woocommerce_refund_created` for partial, `woocommerce_order_fully_refunded` for full
- Status badge CSS must be in admin.css for settings page (wc-integration.css is frontend only)
- HPOS orders list uses `manage_woocommerce_page_wc-orders_columns` filter (different from legacy)
**Released:**
- Committed: `2865956` on dev branch
- Merged to main (fast-forward)
- Tagged: `v0.11.0`
- Pushed to origin: dev, main, v0.11.0
### 2026-02-03 - Version 0.11.2/0.11.3 (Calendar UI Improvements)
**Completed:**
- Improved Calendar admin page room column
- Increased room column width from narrow to 200px minimum
- Changed `table-layout` from `fixed` to `auto` for flexible column sizing
- Added building name as second row under room name
- Left-aligned room column content for better readability
- Improved Calendar filter layout
- Changed filter form to flexbox layout (side by side instead of stacked)
- Added gap between filter dropdowns
- Updated responsive styles for smaller screens
**Files Changed:**
- `src/Admin/Calendar.php` - Added building name display in room cell
- `assets/css/admin.css` - Calendar table and filter layout improvements
- `wp-bnb.php` - Version bumps to 0.11.2 and 0.11.3
- `CHANGELOG.md` - Added v0.11.2 and v0.11.3 release notes
**Learnings:**
- CSS `table-layout: fixed` forces equal column widths; use `auto` for content-based sizing
- When a parent container has flexbox but content is in a child element, the flex must be applied to the correct container (form element in this case)
- Higher CSS specificity (`.bnb-calendar-table .bnb-calendar-room`) needed to override inherited styles
**Released:**
- v0.11.2: Calendar room column width and building name display
- v0.11.3: Calendar filters side-by-side layout
- Both versions tagged and pushed to origin
### 2026-02-04 - Version 0.12.0 (Security Audit)
**Completed:**
- Comprehensive security audit (Phase 12)
- WordPress best practices compliance verification
- OWASP Top 10 vulnerability review
- Live API endpoint testing against localhost:9080
**Security Audit Findings:**
1. **SQL Injection:** ✓ PROTECTED
- All `$wpdb` queries use `$wpdb->prepare()` with parameterized queries
- WP_Query used throughout for post queries (inherently safe)
- Format specifiers (`%s`, `%d`) properly used in `$wpdb->update()` calls
2. **XSS (Cross-Site Scripting):** ✓ PROTECTED
- PHP output consistently uses `esc_html()`, `esc_attr()`, `esc_url()`
- JavaScript uses `escapeHtml()` function (textContent/innerHTML pattern)
- Form values properly escaped before output
3. **CSRF (Cross-Site Request Forgery):** ✓ PROTECTED
- All forms use `wp_nonce_field()`
- Admin AJAX handlers use `check_ajax_referer()` or `wp_verify_nonce()`
- Capability checks with `current_user_can()` on privileged operations
- Public AJAX endpoints are read-only and don't modify data
4. **REST API Security:** ✓ PROTECTED
- Permission callbacks on all admin endpoints (`admin_permission`)
- Rate limiting via transient-based `RateLimiter` class
- Input sanitization via `sanitize_callback` on all parameters
- Sensitive data (ID/passport) not exposed via API
5. **Data Encryption:** ✓ IMPLEMENTED
- Guest ID/passport numbers encrypted with AES-256-CBC
- IV stored with encrypted data for secure decryption
**Bugs Fixed During Audit:**
- Fixed `Calculator::calculate()` being called statically (non-static method)
- `src/Api/Controllers/BookingsController.php`
- `src/Api/Controllers/RoomsController.php`
- `src/Api/Controllers/PricingController.php`
- Fixed incorrect EmailNotifier method names in BookingsController
- `send_admin_notification``send_admin_new_booking`
- `send_cancellation_email``send_cancellation`
- `send_confirmation_email``send_guest_confirmation`
- Fixed guest_id type casting in EmailNotifier (string from post meta → int)
**Files Changed:**
- `src/Api/Controllers/BookingsController.php` - Calculator instantiation, EmailNotifier method names
- `src/Api/Controllers/RoomsController.php` - Calculator instantiation
- `src/Api/Controllers/PricingController.php` - Calculator instantiation
- `src/Booking/EmailNotifier.php` - guest_id type casting
- `wp-bnb.php` - Version bump to 0.12.0
- `CHANGELOG.md` - Added v0.12.0 security audit notes
- `PLAN.md` - Marked Phase 12 complete
**Learnings:**
- `get_post_meta()` always returns strings; cast to `(int)` when needed for type-hinted methods
- Static vs instance method calls must match the method declaration
- Public frontend AJAX endpoints can safely skip nonce verification if they're read-only
- Rate limiting headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`) provide client feedback
- WordPress REST API permission callbacks should use capability checks, not user login status alone

11
PLAN.md
View File

@@ -211,11 +211,12 @@ This document outlines the implementation plan for the WP BnB Management plugin.
- [x] Order management
- [x] Refund handling
## Phase 12: Security Audit (v0.12.0)
## Phase 12: Security Audit (v0.12.0) - Complete
- [ ] Check for Wordpress best-practices
- [ ] Review the code for OWASP Top 10, including XSS, XSRF, SQLi and other critical threads
- [ ] Test the API-Endpoints against a local live system under <http://localhost:9080/> for common vulnerabilities
- [x] Check for WordPress best-practices
- [x] Review the code for OWASP Top 10, including XSS, CSRF, SQLi and other critical threats
- [x] Test the API-Endpoints against a local live system under <http://localhost:9080/> for common vulnerabilities
- [x] Fix bugs discovered during security audit
## Future Considerations (v1.0.0+)
@@ -360,5 +361,5 @@ The plugin will provide extensive hooks for customization:
| 0.9.0 | Prometheus Metrics | Complete |
| 0.10.0 | API Endpoints | Complete |
| 0.11.0 | WooCommerce Integration | Complete |
| 0.12.0 | Security Audit | TBD |
| 0.12.0 | Security Audit | Complete |
| 1.0.0 | Stable Release | TBD |

View File

@@ -19,9 +19,11 @@ WP BnB Management enables WordPress to act as a full management system for B&B h
- **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 and inquiries through CF7 forms
- **WooCommerce Integration**: Accept payments, auto-sync rooms as products, generate invoices
- **Dashboard**: Comprehensive admin dashboard with statistics and charts
- **Reports**: Detailed reports with CSV and PDF export
- **Prometheus Metrics**: Expose operational metrics for monitoring with Grafana
- **REST API**: Comprehensive API for external integrations
### Requirements
@@ -29,6 +31,7 @@ WP BnB Management enables WordPress to act as a full management system for B&B h
- PHP 8.3 or higher
- Valid license key
- Contact Form 7 (optional, for booking forms)
- WooCommerce 8.0+ (optional, for payments and invoicing)
## Installation
@@ -444,6 +447,95 @@ The dashboard includes:
- Today's check-ins/check-outs
- Trend indicators
## WooCommerce Integration
The plugin integrates with WooCommerce to enable payment processing, automatic invoicing, and seamless order management.
### Enabling WooCommerce Integration
1. Install and activate WooCommerce 8.0 or higher
2. Navigate to **WP BnB → Settings → WooCommerce**
3. Enable "Enable WooCommerce Integration"
4. Configure product sync and invoice settings
### Features
**Product Synchronization:**
- Rooms are automatically synced as virtual WooCommerce products
- Products use SKU format `bnb-room-{id}` for tracking
- Price, description, and images are kept in sync
- Products created/updated on room save, deleted on room deletion
- Manual "Sync All Rooms" button in settings
**Cart & Checkout:**
- Add room bookings to WooCommerce cart with dates and guest count
- Real-time availability validation prevents double-booking
- Dynamic pricing calculated from room rates and services
- Special checkout fields for arrival time and special requests
- Guest information pre-filled from user profile
**Booking Creation:**
- Bookings automatically created on successful payment
- Guest records created from billing information
- Booking linked to WooCommerce order for reference
- Booking reference displayed on order confirmation
**Order-Booking Synchronization:**
- Order status changes sync to booking status:
- Order completed → Booking confirmed
- Order cancelled → Booking cancelled
- Order refunded → Booking cancelled (full refund)
- Partial refunds recorded without cancellation
- Bidirectional linking between orders and bookings
**PDF Invoices:**
- Automatic PDF invoice generation
- Configurable invoice number prefix (default: `INV-`)
- Sequential invoice numbering with configurable start number
- Auto-attach to WooCommerce order emails
- Secure storage in `wp-content/uploads/wp-bnb-invoices/`
- Manual generation from order admin
### WooCommerce Settings
**General Subtab:**
- Enable/disable WooCommerce integration
- Enable automatic product sync
- Enable auto-attach invoices to emails
**Products Subtab:**
- View sync status and product count
- Manual "Sync All Rooms Now" button
- Product category assignment
**Orders Subtab:**
- Order-booking status mapping
- View linked orders and bookings
**Invoices Subtab:**
- Invoice number prefix
- Starting invoice number
- Company details for invoice header
- PDF styling options
### HPOS Compatibility
The integration is fully compatible with WooCommerce High-Performance Order Storage (HPOS). Order meta is accessed using the modern `$order->get_meta()` and `$order->update_meta_data()` methods.
### Admin Columns
- **Bookings list**: "WC Order" column with link to order
- **WooCommerce Orders list**: "Booking" column with link to booking
## REST API
The plugin provides a comprehensive REST API for integration with external applications, mobile apps, and third-party services.
@@ -668,7 +760,7 @@ Yes, guest data can be exported and deleted on request, and consent is tracked a
### Does it integrate with WooCommerce?
WooCommerce integration for payments is planned for a future release.
Yes! WooCommerce integration is available for payment processing and invoicing. Rooms are synced as virtual products, bookings are created on successful payment, and PDF invoices are auto-generated and attached to order emails. Navigate to **WP BnB → Settings → WooCommerce** to enable and configure the integration.
### How is guest data secured?

View File

@@ -950,13 +950,17 @@
/* Calendar Filters */
.bnb-calendar-filters {
display: flex;
gap: 15px;
padding: 15px 20px;
border-bottom: 1px solid #c3c4c7;
background: #f9f9f9;
}
.bnb-calendar-filters form {
display: flex;
align-items: center;
gap: 20px;
}
.bnb-calendar-filters label {
display: flex;
align-items: center;
@@ -976,7 +980,7 @@
.bnb-calendar-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
table-layout: auto;
}
.bnb-calendar-table th,
@@ -997,7 +1001,8 @@
.bnb-calendar-table th.room-header {
text-align: left;
padding-left: 10px;
min-width: 150px;
width: 200px;
min-width: 200px;
}
/* Calendar Day Cell */
@@ -1068,16 +1073,31 @@
}
/* Room Row in Multi-Room Calendar */
.bnb-calendar-room {
.bnb-calendar-table .bnb-calendar-room {
font-weight: 600;
text-align: left;
padding: 8px 10px;
background: #f6f7f7;
min-width: 200px;
white-space: nowrap;
}
.bnb-calendar-room small {
.bnb-calendar-room a {
display: block;
}
.bnb-calendar-room .room-number {
font-weight: normal;
color: #646970;
margin-left: 5px;
}
.bnb-calendar-room .building-name {
display: block;
font-weight: normal;
font-size: 12px;
color: #646970;
margin-top: 2px;
}
/* Calendar Legend */
@@ -1157,8 +1177,9 @@
/* Responsive */
@media screen and (max-width: 782px) {
.bnb-calendar-filters {
.bnb-calendar-filters form {
flex-direction: column;
align-items: stretch;
}
.bnb-calendar-filters select {
@@ -2077,3 +2098,49 @@
width: 16px;
height: 16px;
}
/* ============================================
WooCommerce Sync Button
============================================ */
.bnb-sync-rooms-btn {
display: inline-flex !important;
align-items: center !important;
gap: 6px;
vertical-align: middle;
}
.bnb-sync-rooms-btn .dashicons {
font-size: 16px;
width: 16px;
height: 16px;
line-height: 16px;
display: inline-block;
vertical-align: middle;
margin-top: -2px;
}
.bnb-sync-rooms-btn .dashicons.bnb-spin {
animation: bnb-spin 1s linear infinite;
}
@keyframes bnb-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.sync-status {
margin-left: 10px;
font-style: italic;
}
.sync-status .bnb-sync-success {
color: #00a32a;
}
.sync-status .bnb-sync-error {
color: #d63638;
}

View File

@@ -1199,6 +1199,59 @@
});
}
/**
* Initialize WooCommerce sync button.
*/
function initWooCommerceSync() {
var $syncBtn = $('.bnb-sync-rooms-btn');
if (!$syncBtn.length) {
return;
}
$syncBtn.on('click', function(e) {
e.preventDefault();
var $btn = $(this);
var $status = $btn.parent().find('.sync-status');
$btn.prop('disabled', true);
$btn.find('.dashicons').addClass('bnb-spin');
$status.text(wpBnbAdmin.i18n.syncing || 'Syncing...');
$.ajax({
url: wpBnbAdmin.ajaxUrl,
type: 'POST',
data: {
action: 'wp_bnb_sync_all_rooms',
nonce: wpBnbAdmin.nonce
},
success: function(response) {
if (response.success) {
$status.html('<span class="bnb-sync-success">' + response.data.message + '</span>');
} else {
var errorMsg = response.data && response.data.message ? response.data.message : 'Unknown error';
$status.html('<span class="bnb-sync-error">' + errorMsg + '</span>');
}
},
error: function(xhr, status, error) {
var errorMsg = wpBnbAdmin.i18n.error || 'Error occurred';
if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
errorMsg = xhr.responseJSON.data.message;
} else if (error) {
errorMsg = error;
}
$status.html('<span class="bnb-sync-error">' + errorMsg + '</span>');
console.error('WP-BnB Sync Error:', status, error, xhr.responseText);
},
complete: function() {
$btn.prop('disabled', false);
$btn.find('.dashicons').removeClass('bnb-spin');
}
});
});
}
// Initialize on document ready.
$(document).ready(function() {
initLicenseManagement();
@@ -1214,6 +1267,7 @@
initBookingServices();
initDashboardCharts();
initReportsPage();
initWooCommerceSync();
});
})(jQuery);

BIN
languages/wp-bnb-de_CH.mo Normal file

Binary file not shown.

5162
languages/wp-bnb-de_CH.po Normal file

File diff suppressed because it is too large Load Diff

5163
languages/wp-bnb.pot Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -257,15 +257,19 @@ final class Calendar {
<?php foreach ( $rooms as $room ) : ?>
<?php
$room_number = get_post_meta( $room->ID, '_bnb_room_room_number', true );
$room_building = Room::get_building( $room->ID );
$booked_dates = Availability::get_booked_dates( $room->ID, $year, $month );
?>
<tr>
<td class="bnb-calendar-room">
<a href="<?php echo esc_url( get_edit_post_link( $room->ID ) ); ?>">
<?php echo esc_html( $room->post_title ); ?>
</a>
<?php if ( $room_number ) : ?>
<br><small>#<?php echo esc_html( $room_number ); ?></small>
<span class="room-number">#<?php echo esc_html( $room_number ); ?></span>
<?php endif; ?>
</a>
<?php if ( $room_building ) : ?>
<span class="building-name"><?php echo esc_html( $room_building->post_title ); ?></span>
<?php endif; ?>
</td>
<?php for ( $day = 1; $day <= $days_in_month; $day++ ) : ?>

View File

@@ -338,9 +338,9 @@ final class BookingsController extends AbstractController {
$guest_id = $this->find_or_create_guest( $guest );
// Calculate price.
$price = Calculator::calculate( $room_id, $check_in, $check_out );
$calculator = new Calculator( $room_id, $check_in, $check_out );
$room_price = $calculator->calculate();
$services = $request->get_param( 'services' ) ?? array();
$room_price = $price['price'] ?? 0;
// Calculate services total.
$services_total = 0;
@@ -410,7 +410,7 @@ final class BookingsController extends AbstractController {
// Send notification email.
if ( class_exists( EmailNotifier::class ) ) {
EmailNotifier::send_admin_notification( $post_id );
EmailNotifier::send_admin_new_booking( $post_id );
}
// Prepare response.
@@ -532,7 +532,7 @@ final class BookingsController extends AbstractController {
// Send cancellation email.
if ( class_exists( EmailNotifier::class ) ) {
EmailNotifier::send_cancellation_email( $id );
EmailNotifier::send_cancellation( $id );
}
return $this->formatter->no_content();
@@ -607,7 +607,7 @@ final class BookingsController extends AbstractController {
if ( 'confirmed' === $new_status ) {
update_post_meta( $id, '_bnb_booking_confirmed_at', current_time( 'mysql' ) );
if ( class_exists( EmailNotifier::class ) ) {
EmailNotifier::send_confirmation_email( $id );
EmailNotifier::send_guest_confirmation( $id );
}
}

View File

@@ -136,9 +136,9 @@ final class PricingController extends AbstractController {
$nights = (int) $check_in_date->diff( $check_out_date )->days;
// Calculate room price.
$price = Calculator::calculate( $room_id, $check_in, $check_out );
$room_total = $price['price'] ?? 0;
$breakdown = $price['breakdown'] ?? array();
$calculator = new Calculator( $room_id, $check_in, $check_out );
$room_total = $calculator->calculate();
$breakdown = $calculator->getBreakdown();
$currency = get_option( 'wp_bnb_currency', 'CHF' );
// Build night-by-night breakdown.

View File

@@ -400,14 +400,16 @@ final class RoomsController extends AbstractController {
if ( $is_available ) {
// Calculate pricing.
$price = Calculator::calculate( $room_id, $check_in, $check_out );
$calculator = new Calculator( $room_id, $check_in, $check_out );
$price = $calculator->calculate();
$breakdown = $calculator->getBreakdown();
$data['pricing'] = array(
'tier' => $price['breakdown']['tier']->value ?? 'short_term',
'base_rate' => $price['breakdown']['base_price_per_night'] ?? 0,
'total' => $price['price'] ?? 0,
'formatted' => $price['price_formatted'] ?? '',
'tier' => $breakdown['tier']->value ?? 'short_term',
'base_rate' => $breakdown['base_price_per_night'] ?? 0,
'total' => $price,
'formatted' => Calculator::formatPrice( $price ),
'currency' => get_option( 'wp_bnb_currency', 'CHF' ),
'breakdown' => $price['breakdown'] ?? array(),
'breakdown' => $breakdown,
);
} else {
// Get conflicts.

View File

@@ -263,10 +263,10 @@ final class EmailNotifier {
* @return array Guest data with keys: name, first_name, last_name, email, phone, notes, full_address.
*/
private static function get_guest_data( int $booking_id ): array {
$guest_id = get_post_meta( $booking_id, '_bnb_booking_guest_id', true );
$guest_id = (int) get_post_meta( $booking_id, '_bnb_booking_guest_id', true );
// Try to get data from Guest CPT.
if ( $guest_id ) {
if ( $guest_id > 0 ) {
$guest = get_post( $guest_id );
if ( $guest && Guest::POST_TYPE === $guest->post_type ) {
$first_name = get_post_meta( $guest_id, '_bnb_guest_first_name', true );

View File

@@ -130,7 +130,11 @@ final class Manager {
// Declare HPOS compatibility.
add_action( 'before_woocommerce_init', array( self::class, 'declare_hpos_compatibility' ) );
// Only initialize components if integration is enabled.
// Always register admin AJAX handlers immediately (for settings page).
// Must be called directly, not via hook, since woocommerce_loaded may have already fired.
ProductSync::init_admin_ajax();
// Only initialize full components if integration is enabled.
if ( ! self::is_enabled() ) {
return;
}

View File

@@ -25,6 +25,13 @@ use Magdev\WpBnb\Taxonomies\RoomType;
*/
final class ProductSync {
/**
* Track if admin AJAX has been initialized.
*
* @var bool
*/
private static bool $admin_ajax_initialized = false;
/**
* Initialize product synchronization.
*
@@ -40,8 +47,27 @@ final class ProductSync {
// Add linked room info to product edit screen.
add_action( 'woocommerce_product_options_general_product_data', array( self::class, 'add_product_room_info' ) );
// Register admin AJAX if not already done.
self::init_admin_ajax();
}
/**
* Initialize admin AJAX handlers only.
*
* Called separately from init() to ensure AJAX is available on settings page
* even when full integration is not yet enabled.
*
* @return void
*/
public static function init_admin_ajax(): void {
if ( self::$admin_ajax_initialized ) {
return;
}
// AJAX handler for syncing all rooms.
add_action( 'wp_ajax_wp_bnb_sync_all_rooms', array( self::class, 'ajax_sync_all_rooms' ) );
self::$admin_ajax_initialized = true;
}
/**

View File

@@ -350,6 +350,8 @@ final class Plugin {
'checkingUpdates' => __( 'Checking for updates...', 'wp-bnb' ),
'occupancy' => __( 'Occupancy %', 'wp-bnb' ),
'revenue' => __( 'Revenue', 'wp-bnb' ),
'syncing' => __( 'Syncing...', 'wp-bnb' ),
'syncComplete' => __( 'Sync complete', 'wp-bnb' ),
),
);

View File

@@ -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.11.0
* Version: 0.12.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.11.0' );
define( 'WP_BNB_VERSION', '0.12.1' );
// Plugin path constants.
define( 'WP_BNB_PATH', plugin_dir_path( __FILE__ ) );
@@ -189,3 +189,23 @@ function wp_bnb_deactivate(): void {
}
register_deactivation_hook( __FILE__, 'wp_bnb_deactivate' );
/**
* Add action links to the plugins page.
*
* @param array $links Existing plugin action links.
* @return array Modified plugin action links.
*/
function wp_bnb_plugin_action_links( array $links ): array {
$dashboard_link = sprintf(
'<a href="%s">%s</a>',
esc_url( admin_url( 'admin.php?page=wp-bnb' ) ),
esc_html__( 'Dashboard', 'wp-bnb' )
);
array_unshift( $links, $dashboard_link );
return $links;
}
add_filter( 'plugin_action_links_' . WP_BNB_BASENAME, 'wp_bnb_plugin_action_links' );