Add WooCommerce integration for payments, invoices, and order management (v0.11.0)
All checks were successful
Create Release Package / build-release (push) Successful in 1m11s
All checks were successful
Create Release Package / build-release (push) Successful in 1m11s
- Product sync: Virtual WC products for rooms with bidirectional linking - Cart/Checkout: Booking data in cart items, availability validation, dynamic pricing - Orders: Automatic booking creation on payment, status mapping, guest record creation - Invoices: PDF generation via mPDF, auto-attach to emails, configurable numbering - Refunds: Full refund cancels booking, partial refund records amount only - Admin: Cross-linked columns and row actions between bookings and orders - Settings: WooCommerce tab with subtabs (General, Products, Orders, Invoices) - HPOS compatibility declared for High-Performance Order Storage Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
389
src/Plugin.php
389
src/Plugin.php
@@ -21,6 +21,7 @@ use Magdev\WpBnb\Frontend\Shortcodes;
|
||||
use Magdev\WpBnb\Api\RestApi;
|
||||
use Magdev\WpBnb\Integration\CF7;
|
||||
use Magdev\WpBnb\Integration\Prometheus;
|
||||
use Magdev\WpBnb\Integration\WooCommerce\Manager as WooCommerceManager;
|
||||
use Magdev\WpBnb\Frontend\Widgets\AvailabilityCalendar;
|
||||
use Magdev\WpBnb\Frontend\Widgets\BuildingRooms;
|
||||
use Magdev\WpBnb\Frontend\Widgets\SimilarRooms;
|
||||
@@ -147,6 +148,11 @@ final class Plugin {
|
||||
// Initialize Prometheus metrics integration.
|
||||
Prometheus::init();
|
||||
|
||||
// Initialize WooCommerce integration if WooCommerce is active.
|
||||
if ( class_exists( 'WooCommerce' ) ) {
|
||||
WooCommerceManager::init();
|
||||
}
|
||||
|
||||
// Initialize REST API.
|
||||
$this->init_rest_api();
|
||||
|
||||
@@ -636,6 +642,10 @@ final class Plugin {
|
||||
class="nav-tab <?php echo 'api' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'API', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wp-bnb-settings&tab=woocommerce' ) ); ?>"
|
||||
class="nav-tab <?php echo 'woocommerce' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'WooCommerce', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="tab-content">
|
||||
@@ -656,6 +666,9 @@ final class Plugin {
|
||||
case 'api':
|
||||
$this->render_api_settings();
|
||||
break;
|
||||
case 'woocommerce':
|
||||
$this->render_woocommerce_settings();
|
||||
break;
|
||||
default:
|
||||
$this->render_general_settings();
|
||||
break;
|
||||
@@ -1854,6 +1867,9 @@ final class Plugin {
|
||||
case 'api':
|
||||
$this->save_api_settings();
|
||||
break;
|
||||
case 'woocommerce':
|
||||
$this->save_woocommerce_settings();
|
||||
break;
|
||||
default:
|
||||
$this->save_general_settings();
|
||||
break;
|
||||
@@ -2037,6 +2053,379 @@ final class Plugin {
|
||||
settings_errors( 'wp_bnb_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render WooCommerce settings tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_woocommerce_settings(): void {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Subtab switching only.
|
||||
$active_subtab = isset( $_GET['subtab'] ) ? sanitize_key( $_GET['subtab'] ) : 'general';
|
||||
$base_url = admin_url( 'admin.php?page=wp-bnb-settings&tab=woocommerce' );
|
||||
|
||||
$wc_active = class_exists( 'WooCommerce' );
|
||||
?>
|
||||
<div class="wp-bnb-subtabs">
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=general' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'general' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-admin-generic"></span>
|
||||
<?php esc_html_e( 'General', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=products' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'products' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-products"></span>
|
||||
<?php esc_html_e( 'Products', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=orders' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'orders' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-cart"></span>
|
||||
<?php esc_html_e( 'Orders', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=invoices' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'invoices' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-media-document"></span>
|
||||
<?php esc_html_e( 'Invoices', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ( ! $wc_active ) : ?>
|
||||
<div class="notice notice-warning inline">
|
||||
<p>
|
||||
<strong><?php esc_html_e( 'WooCommerce is not active.', 'wp-bnb' ); ?></strong>
|
||||
<?php esc_html_e( 'Please install and activate WooCommerce to use these features.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
switch ( $active_subtab ) {
|
||||
case 'products':
|
||||
$this->render_wc_products_subtab( $wc_active );
|
||||
break;
|
||||
case 'orders':
|
||||
$this->render_wc_orders_subtab( $wc_active );
|
||||
break;
|
||||
case 'invoices':
|
||||
$this->render_wc_invoices_subtab( $wc_active );
|
||||
break;
|
||||
default:
|
||||
$this->render_wc_general_subtab( $wc_active );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render WooCommerce General subtab.
|
||||
*
|
||||
* @param bool $wc_active Whether WooCommerce is active.
|
||||
* @return void
|
||||
*/
|
||||
private function render_wc_general_subtab( bool $wc_active ): void {
|
||||
?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
<input type="hidden" name="wc_subtab" value="general">
|
||||
|
||||
<h2><?php esc_html_e( 'WooCommerce Integration', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Enable Integration', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label for="wp_bnb_wc_enabled">
|
||||
<input type="checkbox" name="wp_bnb_wc_enabled" id="wp_bnb_wc_enabled" value="yes"
|
||||
<?php checked( 'yes', get_option( WooCommerceManager::OPTION_ENABLED, 'no' ) ); ?>
|
||||
<?php disabled( ! $wc_active ); ?>>
|
||||
<?php esc_html_e( 'Enable WooCommerce integration for bookings', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Allow guests to book and pay through WooCommerce checkout.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Auto-Confirm Bookings', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label for="wp_bnb_wc_auto_confirm_booking">
|
||||
<input type="checkbox" name="wp_bnb_wc_auto_confirm_booking" id="wp_bnb_wc_auto_confirm_booking" value="yes"
|
||||
<?php checked( 'yes', get_option( WooCommerceManager::OPTION_AUTO_CONFIRM, 'yes' ) ); ?>
|
||||
<?php disabled( ! $wc_active ); ?>>
|
||||
<?php esc_html_e( 'Automatically confirm booking when payment is completed', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'If disabled, bookings will remain pending until manually confirmed.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php if ( $wc_active ) : ?>
|
||||
<p class="submit">
|
||||
<input type="submit" name="submit" class="button button-primary"
|
||||
value="<?php esc_attr_e( 'Save Settings', 'wp-bnb' ); ?>">
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render WooCommerce Products subtab.
|
||||
*
|
||||
* @param bool $wc_active Whether WooCommerce is active.
|
||||
* @return void
|
||||
*/
|
||||
private function render_wc_products_subtab( bool $wc_active ): void {
|
||||
$categories = array();
|
||||
if ( $wc_active ) {
|
||||
$categories = get_terms(
|
||||
array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'hide_empty' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
<input type="hidden" name="wc_subtab" value="products">
|
||||
|
||||
<h2><?php esc_html_e( 'Product Synchronization', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Auto-Sync Products', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label for="wp_bnb_wc_auto_sync_products">
|
||||
<input type="checkbox" name="wp_bnb_wc_auto_sync_products" id="wp_bnb_wc_auto_sync_products" value="yes"
|
||||
<?php checked( 'yes', get_option( WooCommerceManager::OPTION_AUTO_SYNC, 'yes' ) ); ?>
|
||||
<?php disabled( ! $wc_active ); ?>>
|
||||
<?php esc_html_e( 'Automatically create/update WooCommerce products when rooms are saved', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_wc_product_category"><?php esc_html_e( 'Product Category', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<select name="wp_bnb_wc_product_category" id="wp_bnb_wc_product_category" <?php disabled( ! $wc_active ); ?>>
|
||||
<option value=""><?php esc_html_e( '— No category —', 'wp-bnb' ); ?></option>
|
||||
<?php foreach ( $categories as $cat ) : ?>
|
||||
<option value="<?php echo esc_attr( $cat->term_id ); ?>"
|
||||
<?php selected( get_option( WooCommerceManager::OPTION_PRODUCT_CATEGORY, 0 ), $cat->term_id ); ?>>
|
||||
<?php echo esc_html( $cat->name ); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Assign synced room products to this WooCommerce category.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php if ( $wc_active ) : ?>
|
||||
<h3><?php esc_html_e( 'Manual Sync', 'wp-bnb' ); ?></h3>
|
||||
<p>
|
||||
<button type="button" class="button bnb-sync-rooms-btn">
|
||||
<span class="dashicons dashicons-update"></span>
|
||||
<?php esc_html_e( 'Sync All Rooms Now', 'wp-bnb' ); ?>
|
||||
</button>
|
||||
<span class="sync-status"></span>
|
||||
</p>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Creates or updates WooCommerce products for all published rooms.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
|
||||
<p class="submit">
|
||||
<input type="submit" name="submit" class="button button-primary"
|
||||
value="<?php esc_attr_e( 'Save Settings', 'wp-bnb' ); ?>">
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render WooCommerce Orders subtab.
|
||||
*
|
||||
* @param bool $wc_active Whether WooCommerce is active.
|
||||
* @return void
|
||||
*/
|
||||
private function render_wc_orders_subtab( bool $wc_active ): void {
|
||||
?>
|
||||
<h2><?php esc_html_e( 'Order-Booking Status Mapping', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'The following table shows how WooCommerce order statuses map to booking statuses.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
|
||||
<table class="widefat fixed striped" style="max-width: 600px; margin-top: 15px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'WooCommerce Status', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Booking Status', 'wp-bnb' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Pending Payment', 'wp-bnb' ); ?></td>
|
||||
<td><span class="bnb-status-badge bnb-status-pending"><?php esc_html_e( 'Pending', 'wp-bnb' ); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'On Hold', 'wp-bnb' ); ?></td>
|
||||
<td><span class="bnb-status-badge bnb-status-pending"><?php esc_html_e( 'Pending', 'wp-bnb' ); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Processing', 'wp-bnb' ); ?></td>
|
||||
<td>
|
||||
<?php if ( get_option( WooCommerceManager::OPTION_AUTO_CONFIRM, 'yes' ) === 'yes' ) : ?>
|
||||
<span class="bnb-status-badge bnb-status-confirmed"><?php esc_html_e( 'Confirmed', 'wp-bnb' ); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="bnb-status-badge bnb-status-pending"><?php esc_html_e( 'Pending', 'wp-bnb' ); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Completed', 'wp-bnb' ); ?></td>
|
||||
<td><span class="bnb-status-badge bnb-status-confirmed"><?php esc_html_e( 'Confirmed', 'wp-bnb' ); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Cancelled / Refunded / Failed', 'wp-bnb' ); ?></td>
|
||||
<td><span class="bnb-status-badge bnb-status-cancelled"><?php esc_html_e( 'Cancelled', 'wp-bnb' ); ?></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Refund Handling', 'wp-bnb' ); ?></h3>
|
||||
<ul style="list-style: disc; margin-left: 20px;">
|
||||
<li><?php esc_html_e( 'Full refunds automatically cancel the linked booking.', 'wp-bnb' ); ?></li>
|
||||
<li><?php esc_html_e( 'Partial refunds are recorded but do not cancel the booking.', 'wp-bnb' ); ?></li>
|
||||
<li><?php esc_html_e( 'Cancellation emails are sent when a booking is cancelled due to refund.', 'wp-bnb' ); ?></li>
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render WooCommerce Invoices subtab.
|
||||
*
|
||||
* @param bool $wc_active Whether WooCommerce is active.
|
||||
* @return void
|
||||
*/
|
||||
private function render_wc_invoices_subtab( bool $wc_active ): void {
|
||||
?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
<input type="hidden" name="wc_subtab" value="invoices">
|
||||
|
||||
<h2><?php esc_html_e( 'Invoice Settings', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Attach to Emails', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label for="wp_bnb_wc_invoice_attach">
|
||||
<input type="checkbox" name="wp_bnb_wc_invoice_attach" id="wp_bnb_wc_invoice_attach" value="yes"
|
||||
<?php checked( 'yes', get_option( WooCommerceManager::OPTION_INVOICE_ATTACH, 'yes' ) ); ?>
|
||||
<?php disabled( ! $wc_active ); ?>>
|
||||
<?php esc_html_e( 'Attach PDF invoice to order confirmation emails', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_invoice_prefix"><?php esc_html_e( 'Invoice Number Prefix', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="wp_bnb_invoice_prefix" id="wp_bnb_invoice_prefix"
|
||||
value="<?php echo esc_attr( get_option( WooCommerceManager::OPTION_INVOICE_PREFIX, 'INV-' ) ); ?>"
|
||||
class="regular-text" <?php disabled( ! $wc_active ); ?>>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Prefix for invoice numbers (e.g., INV- for INV-00001).', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_invoice_start_number"><?php esc_html_e( 'Starting Number', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_invoice_start_number" id="wp_bnb_invoice_start_number"
|
||||
value="<?php echo esc_attr( get_option( WooCommerceManager::OPTION_INVOICE_START_NUMBER, 1000 ) ); ?>"
|
||||
class="small-text" min="1" <?php disabled( ! $wc_active ); ?>>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Starting number for new invoices (only applies if no invoices generated yet).', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_invoice_footer"><?php esc_html_e( 'Footer Text', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<textarea name="wp_bnb_invoice_footer" id="wp_bnb_invoice_footer" rows="3" class="large-text"
|
||||
<?php disabled( ! $wc_active ); ?>><?php echo esc_textarea( get_option( WooCommerceManager::OPTION_INVOICE_FOOTER, '' ) ); ?></textarea>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Custom footer text for invoices (e.g., terms and conditions).', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php if ( $wc_active ) : ?>
|
||||
<p class="submit">
|
||||
<input type="submit" name="submit" class="button button-primary"
|
||||
value="<?php esc_attr_e( 'Save Settings', 'wp-bnb' ); ?>">
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save WooCommerce settings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function save_woocommerce_settings(): void {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in render_settings_page.
|
||||
$subtab = isset( $_POST['wc_subtab'] ) ? sanitize_key( $_POST['wc_subtab'] ) : 'general';
|
||||
|
||||
switch ( $subtab ) {
|
||||
case 'products':
|
||||
$auto_sync = isset( $_POST['wp_bnb_wc_auto_sync_products'] ) ? 'yes' : 'no';
|
||||
$category = isset( $_POST['wp_bnb_wc_product_category'] ) ? absint( $_POST['wp_bnb_wc_product_category'] ) : 0;
|
||||
|
||||
update_option( WooCommerceManager::OPTION_AUTO_SYNC, $auto_sync );
|
||||
update_option( WooCommerceManager::OPTION_PRODUCT_CATEGORY, $category );
|
||||
break;
|
||||
|
||||
case 'invoices':
|
||||
$attach = isset( $_POST['wp_bnb_wc_invoice_attach'] ) ? 'yes' : 'no';
|
||||
$prefix = isset( $_POST['wp_bnb_invoice_prefix'] ) ? sanitize_text_field( wp_unslash( $_POST['wp_bnb_invoice_prefix'] ) ) : 'INV-';
|
||||
$start_number = isset( $_POST['wp_bnb_invoice_start_number'] ) ? absint( $_POST['wp_bnb_invoice_start_number'] ) : 1000;
|
||||
$footer = isset( $_POST['wp_bnb_invoice_footer'] ) ? sanitize_textarea_field( wp_unslash( $_POST['wp_bnb_invoice_footer'] ) ) : '';
|
||||
|
||||
update_option( WooCommerceManager::OPTION_INVOICE_ATTACH, $attach );
|
||||
update_option( WooCommerceManager::OPTION_INVOICE_PREFIX, $prefix );
|
||||
update_option( WooCommerceManager::OPTION_INVOICE_START_NUMBER, $start_number );
|
||||
update_option( WooCommerceManager::OPTION_INVOICE_FOOTER, $footer );
|
||||
break;
|
||||
|
||||
default: // general
|
||||
$enabled = isset( $_POST['wp_bnb_wc_enabled'] ) ? 'yes' : 'no';
|
||||
$auto_confirm = isset( $_POST['wp_bnb_wc_auto_confirm_booking'] ) ? 'yes' : 'no';
|
||||
|
||||
update_option( WooCommerceManager::OPTION_ENABLED, $enabled );
|
||||
update_option( WooCommerceManager::OPTION_AUTO_CONFIRM, $auto_confirm );
|
||||
break;
|
||||
}
|
||||
|
||||
add_settings_error( 'wp_bnb_settings', 'settings_saved', __( 'WooCommerce settings saved.', 'wp-bnb' ), 'success' );
|
||||
settings_errors( 'wp_bnb_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for checking room availability.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user