Release v0.6.1 - Bug fixes and enhancements
All checks were successful
Create Release Package / build-release (push) Successful in 1m1s
All checks were successful
Create Release Package / build-release (push) Successful in 1m1s
New Features: - Auto-update system with configurable check frequency - Updates tab in settings with manual check button - Localhost development mode bypasses license validation - Extended general settings (address, contact, social media) - Pricing settings split into subtabs - Guest ID/passport encryption using AES-256-CBC - Guest auto-creation from booking form Bug Fixes: - Fixed Booking admin issues with auto-draft status - Fixed guest dropdown loading in booking form - Fixed booking history display on Guest edit page - Fixed service pricing meta box (Gutenberg hiding meta boxes) Changes: - Admin submenu reordered for better organization - Booking title shows guest name and dates (room removed) - Service, Guest, Booking use classic editor (not Gutenberg) - Settings tabs flush with content (no gap) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
712
src/Plugin.php
712
src/Plugin.php
@@ -20,6 +20,8 @@ use Magdev\WpBnb\Frontend\Widgets\AvailabilityCalendar;
|
||||
use Magdev\WpBnb\Frontend\Widgets\BuildingRooms;
|
||||
use Magdev\WpBnb\Frontend\Widgets\SimilarRooms;
|
||||
use Magdev\WpBnb\License\Manager as LicenseManager;
|
||||
use Magdev\WpBnb\License\Updater as LicenseUpdater;
|
||||
use Magdev\WcLicensedProductClient\Dto\UpdateInfo;
|
||||
use Magdev\WpBnb\PostTypes\Booking;
|
||||
use Magdev\WpBnb\PostTypes\Building;
|
||||
use Magdev\WpBnb\PostTypes\Guest;
|
||||
@@ -128,6 +130,9 @@ final class Plugin {
|
||||
// Initialize License Manager (always active for admin).
|
||||
LicenseManager::get_instance();
|
||||
|
||||
// Initialize auto-updater (requires license configuration).
|
||||
$this->init_updater();
|
||||
|
||||
// Initialize admin components.
|
||||
if ( is_admin() ) {
|
||||
$this->init_admin();
|
||||
@@ -139,6 +144,19 @@ final class Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the plugin auto-updater.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function init_updater(): void {
|
||||
$updater = new LicenseUpdater(
|
||||
plugin_file: WP_BNB_PATH . 'wp-bnb.php',
|
||||
current_version: WP_BNB_VERSION,
|
||||
);
|
||||
$updater->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize admin components.
|
||||
*
|
||||
@@ -147,6 +165,7 @@ final class Plugin {
|
||||
private function init_admin(): void {
|
||||
// Admin menu and settings will be added here.
|
||||
add_action( 'admin_menu', array( $this, 'register_admin_menu' ) );
|
||||
add_action( 'admin_menu', array( $this, 'reorder_admin_menu' ), 99 );
|
||||
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
||||
|
||||
// Initialize seasons admin page.
|
||||
@@ -280,6 +299,10 @@ final class Plugin {
|
||||
'guestBlocked' => __( 'Blocked', 'wp-bnb' ),
|
||||
'perNightDescription' => __( 'This price will be charged per night of the stay.', 'wp-bnb' ),
|
||||
'perBookingDescription' => __( 'This price will be charged once for the booking.', 'wp-bnb' ),
|
||||
'justNow' => __( 'Just now', 'wp-bnb' ),
|
||||
'updateAvailable' => __( 'Update available!', 'wp-bnb' ),
|
||||
'upToDate' => __( '(You are up to date)', 'wp-bnb' ),
|
||||
'checkingUpdates' => __( 'Checking for updates...', 'wp-bnb' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
@@ -392,6 +415,59 @@ final class Plugin {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder the admin submenu items.
|
||||
*
|
||||
* Places Dashboard at top, Settings at bottom, and organizes
|
||||
* the remaining items in logical order.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reorder_admin_menu(): void {
|
||||
global $submenu;
|
||||
|
||||
if ( ! isset( $submenu['wp-bnb'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Define the desired order of menu slugs.
|
||||
$desired_order = array(
|
||||
'wp-bnb', // Dashboard.
|
||||
'edit.php?post_type=bnb_building', // Buildings.
|
||||
'edit.php?post_type=bnb_room', // Rooms.
|
||||
'edit.php?post_type=bnb_booking', // Bookings.
|
||||
'edit.php?post_type=bnb_guest', // Guests.
|
||||
'edit.php?post_type=bnb_service', // Services.
|
||||
'wp-bnb-calendar', // Calendar.
|
||||
'wp-bnb-seasons', // Seasons.
|
||||
'wp-bnb-settings', // Settings (always last).
|
||||
);
|
||||
|
||||
$current_menu = $submenu['wp-bnb'];
|
||||
$ordered_menu = array();
|
||||
$index = 0;
|
||||
|
||||
// Add items in the desired order.
|
||||
foreach ( $desired_order as $slug ) {
|
||||
foreach ( $current_menu as $key => $item ) {
|
||||
if ( $item[2] === $slug ) {
|
||||
$ordered_menu[ $index ] = $item;
|
||||
unset( $current_menu[ $key ] );
|
||||
++$index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Append any remaining items not in the desired order.
|
||||
foreach ( $current_menu as $item ) {
|
||||
$ordered_menu[ $index ] = $item;
|
||||
++$index;
|
||||
}
|
||||
|
||||
$submenu['wp-bnb'] = $ordered_menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register plugin settings.
|
||||
*
|
||||
@@ -408,12 +484,21 @@ final class Plugin {
|
||||
* @return void
|
||||
*/
|
||||
public function render_dashboard_page(): void {
|
||||
$license_status = LicenseManager::get_cached_status();
|
||||
$license_valid = LicenseManager::is_license_valid();
|
||||
$is_localhost = LicenseManager::is_localhost();
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php esc_html_e( 'WP BnB Dashboard', 'wp-bnb' ); ?></h1>
|
||||
|
||||
<?php if ( 'valid' !== $license_status ) : ?>
|
||||
<?php if ( $is_localhost ) : ?>
|
||||
<div class="notice notice-info">
|
||||
<p>
|
||||
<span class="dashicons dashicons-info" style="color: #72aee6;"></span>
|
||||
<strong><?php esc_html_e( 'Development Mode', 'wp-bnb' ); ?></strong>
|
||||
<?php esc_html_e( 'You are running on a local development environment. All features are enabled.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php elseif ( ! $license_valid ) : ?>
|
||||
<div class="notice notice-warning">
|
||||
<p>
|
||||
<?php
|
||||
@@ -464,6 +549,10 @@ final class Plugin {
|
||||
class="nav-tab <?php echo 'license' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'License', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wp-bnb-settings&tab=updates' ) ); ?>"
|
||||
class="nav-tab <?php echo 'updates' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'Updates', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="tab-content">
|
||||
@@ -475,6 +564,9 @@ final class Plugin {
|
||||
case 'license':
|
||||
$this->render_license_settings();
|
||||
break;
|
||||
case 'updates':
|
||||
$this->render_updates_settings();
|
||||
break;
|
||||
default:
|
||||
$this->render_general_settings();
|
||||
break;
|
||||
@@ -495,6 +587,8 @@ final class Plugin {
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
|
||||
<h2><?php esc_html_e( 'Business Information', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
@@ -532,6 +626,143 @@ final class Plugin {
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><?php esc_html_e( 'Address', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_address_street"><?php esc_html_e( 'Street Address', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="wp_bnb_address_street" id="wp_bnb_address_street"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_address_street', '' ) ); ?>"
|
||||
class="regular-text">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_address_city"><?php esc_html_e( 'City', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="wp_bnb_address_city" id="wp_bnb_address_city"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_address_city', '' ) ); ?>"
|
||||
class="regular-text">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_address_postal"><?php esc_html_e( 'Postal Code', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="wp_bnb_address_postal" id="wp_bnb_address_postal"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_address_postal', '' ) ); ?>"
|
||||
class="small-text">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_address_country"><?php esc_html_e( 'Country', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="wp_bnb_address_country" id="wp_bnb_address_country"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_address_country', '' ) ); ?>"
|
||||
class="regular-text">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><?php esc_html_e( 'Contact Information', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_contact_email"><?php esc_html_e( 'Email Address', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="email" name="wp_bnb_contact_email" id="wp_bnb_contact_email"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_contact_email', '' ) ); ?>"
|
||||
class="regular-text">
|
||||
<p class="description"><?php esc_html_e( 'Primary contact email for bookings and inquiries.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_contact_phone"><?php esc_html_e( 'Phone Number', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="tel" name="wp_bnb_contact_phone" id="wp_bnb_contact_phone"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_contact_phone', '' ) ); ?>"
|
||||
class="regular-text" placeholder="+41 12 345 67 89">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_contact_website"><?php esc_html_e( 'Website', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="wp_bnb_contact_website" id="wp_bnb_contact_website"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_contact_website', '' ) ); ?>"
|
||||
class="regular-text" placeholder="https://">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><?php esc_html_e( 'Social Media', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_social_facebook"><?php esc_html_e( 'Facebook', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="wp_bnb_social_facebook" id="wp_bnb_social_facebook"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_social_facebook', '' ) ); ?>"
|
||||
class="regular-text" placeholder="https://facebook.com/yourpage">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_social_instagram"><?php esc_html_e( 'Instagram', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="wp_bnb_social_instagram" id="wp_bnb_social_instagram"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_social_instagram', '' ) ); ?>"
|
||||
class="regular-text" placeholder="https://instagram.com/yourprofile">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_social_x"><?php esc_html_e( 'X (Twitter)', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="wp_bnb_social_x" id="wp_bnb_social_x"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_social_x', '' ) ); ?>"
|
||||
class="regular-text" placeholder="https://x.com/yourhandle">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_social_linkedin"><?php esc_html_e( 'LinkedIn', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="wp_bnb_social_linkedin" id="wp_bnb_social_linkedin"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_social_linkedin', '' ) ); ?>"
|
||||
class="regular-text" placeholder="https://linkedin.com/company/yourcompany">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_social_tripadvisor"><?php esc_html_e( 'TripAdvisor', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="wp_bnb_social_tripadvisor" id="wp_bnb_social_tripadvisor"
|
||||
value="<?php echo esc_attr( get_option( 'wp_bnb_social_tripadvisor', '' ) ); ?>"
|
||||
class="regular-text" placeholder="https://tripadvisor.com/...">
|
||||
<p class="description"><?php esc_html_e( 'Link to your TripAdvisor listing.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php submit_button( __( 'Save Settings', 'wp-bnb' ) ); ?>
|
||||
</form>
|
||||
<?php
|
||||
@@ -543,12 +774,14 @@ final class Plugin {
|
||||
* @return void
|
||||
*/
|
||||
private function render_pricing_settings(): void {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Subtab switching only.
|
||||
$active_subtab = isset( $_GET['subtab'] ) ? sanitize_key( $_GET['subtab'] ) : 'tiers';
|
||||
$short_term_max = get_option( 'wp_bnb_short_term_max_nights', 6 );
|
||||
$mid_term_max = get_option( 'wp_bnb_mid_term_max_nights', 27 );
|
||||
$weekend_days = get_option( 'wp_bnb_weekend_days', '5,6' );
|
||||
$seasons = Season::all();
|
||||
|
||||
$days_of_week = array(
|
||||
$days_of_week = array(
|
||||
1 => __( 'Monday', 'wp-bnb' ),
|
||||
2 => __( 'Tuesday', 'wp-bnb' ),
|
||||
3 => __( 'Wednesday', 'wp-bnb' ),
|
||||
@@ -558,118 +791,155 @@ final class Plugin {
|
||||
7 => __( 'Sunday', 'wp-bnb' ),
|
||||
);
|
||||
$selected_days = array_map( 'intval', explode( ',', $weekend_days ) );
|
||||
|
||||
$base_url = admin_url( 'admin.php?page=wp-bnb-settings&tab=pricing' );
|
||||
?>
|
||||
|
||||
<!-- Pricing Subtabs -->
|
||||
<div class="wp-bnb-subtabs">
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=tiers' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'tiers' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-chart-bar"></span>
|
||||
<?php esc_html_e( 'Pricing Tiers', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=weekend' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'weekend' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-calendar-alt"></span>
|
||||
<?php esc_html_e( 'Weekend Days', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=seasons' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'seasons' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-image-filter"></span>
|
||||
<?php esc_html_e( 'Seasons', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
|
||||
<h2><?php esc_html_e( 'Pricing Tier Thresholds', 'wp-bnb' ); ?></h2>
|
||||
<p class="description"><?php esc_html_e( 'Define the number of nights that determine which pricing tier applies.', 'wp-bnb' ); ?></p>
|
||||
<?php if ( 'tiers' === $active_subtab ) : ?>
|
||||
<!-- Pricing Tiers Subtab -->
|
||||
<h2><?php esc_html_e( 'Pricing Tier Thresholds', 'wp-bnb' ); ?></h2>
|
||||
<p class="description"><?php esc_html_e( 'Define the number of nights that determine which pricing tier applies.', 'wp-bnb' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_short_term_max_nights"><?php esc_html_e( 'Short-term (Nightly)', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_short_term_max_nights" id="wp_bnb_short_term_max_nights"
|
||||
value="<?php echo esc_attr( $short_term_max ); ?>"
|
||||
class="small-text" min="1" max="30">
|
||||
<?php esc_html_e( 'nights or fewer', 'wp-bnb' ); ?>
|
||||
<p class="description"><?php esc_html_e( 'Stays up to this many nights use the nightly rate.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_mid_term_max_nights"><?php esc_html_e( 'Mid-term (Weekly)', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_mid_term_max_nights" id="wp_bnb_mid_term_max_nights"
|
||||
value="<?php echo esc_attr( $mid_term_max ); ?>"
|
||||
class="small-text" min="7" max="90">
|
||||
<?php esc_html_e( 'nights or fewer', 'wp-bnb' ); ?>
|
||||
<p class="description"><?php esc_html_e( 'Stays longer than short-term but up to this many nights use the weekly rate.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Long-term (Monthly)', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: number of nights */
|
||||
esc_html__( 'Stays longer than %s nights use the monthly rate.', 'wp-bnb' ),
|
||||
'<strong id="wp-bnb-long-term-min">' . esc_html( $mid_term_max ) . '</strong>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><?php esc_html_e( 'Weekend Days', 'wp-bnb' ); ?></h2>
|
||||
<p class="description"><?php esc_html_e( 'Select which days are considered weekend days for weekend surcharges.', 'wp-bnb' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Weekend Days', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<?php foreach ( $days_of_week as $day_num => $day_name ) : ?>
|
||||
<label style="display: inline-block; margin-right: 15px;">
|
||||
<input type="checkbox" name="wp_bnb_weekend_days[]" value="<?php echo esc_attr( $day_num ); ?>"
|
||||
<?php checked( in_array( $day_num, $selected_days, true ) ); ?>>
|
||||
<?php echo esc_html( $day_name ); ?>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</fieldset>
|
||||
<p class="description"><?php esc_html_e( 'Weekend surcharges (configured per room) apply to nights starting on these days.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><?php esc_html_e( 'Seasonal Pricing', 'wp-bnb' ); ?></h2>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: Link to seasons page */
|
||||
esc_html__( 'Manage seasonal pricing periods in the %s.', 'wp-bnb' ),
|
||||
'<a href="' . esc_url( admin_url( 'admin.php?page=wp-bnb-seasons' ) ) . '">' . esc_html__( 'Seasons Manager', 'wp-bnb' ) . '</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
|
||||
<?php if ( ! empty( $seasons ) ) : ?>
|
||||
<table class="widefat striped" style="max-width: 600px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Season', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Period', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Modifier', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Status', 'wp-bnb' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ( $seasons as $season ) : ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html( $season->name ); ?></td>
|
||||
<td><?php echo esc_html( $season->start_date . ' - ' . $season->end_date ); ?></td>
|
||||
<td><?php echo esc_html( $season->getModifierLabel() ); ?></td>
|
||||
<td>
|
||||
<?php if ( $season->active ) : ?>
|
||||
<span class="dashicons dashicons-yes-alt" style="color: #00a32a;"></span>
|
||||
<?php else : ?>
|
||||
<span class="dashicons dashicons-marker" style="color: #646970;"></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_short_term_max_nights"><?php esc_html_e( 'Short-term (Nightly)', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_short_term_max_nights" id="wp_bnb_short_term_max_nights"
|
||||
value="<?php echo esc_attr( $short_term_max ); ?>"
|
||||
class="small-text" min="1" max="30">
|
||||
<?php esc_html_e( 'nights or fewer', 'wp-bnb' ); ?>
|
||||
<p class="description"><?php esc_html_e( 'Stays up to this many nights use the nightly rate.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_mid_term_max_nights"><?php esc_html_e( 'Mid-term (Weekly)', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_mid_term_max_nights" id="wp_bnb_mid_term_max_nights"
|
||||
value="<?php echo esc_attr( $mid_term_max ); ?>"
|
||||
class="small-text" min="7" max="90">
|
||||
<?php esc_html_e( 'nights or fewer', 'wp-bnb' ); ?>
|
||||
<p class="description"><?php esc_html_e( 'Stays longer than short-term but up to this many nights use the weekly rate.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Long-term (Monthly)', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: number of nights */
|
||||
esc_html__( 'Stays longer than %s nights use the monthly rate.', 'wp-bnb' ),
|
||||
'<strong id="wp-bnb-long-term-min">' . esc_html( $mid_term_max ) . '</strong>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<p><?php esc_html_e( 'No seasons configured yet.', 'wp-bnb' ); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php submit_button( __( 'Save Pricing Settings', 'wp-bnb' ) ); ?>
|
||||
<?php submit_button( __( 'Save Pricing Tiers', 'wp-bnb' ) ); ?>
|
||||
|
||||
<?php elseif ( 'weekend' === $active_subtab ) : ?>
|
||||
<!-- Weekend Days Subtab -->
|
||||
<h2><?php esc_html_e( 'Weekend Days', 'wp-bnb' ); ?></h2>
|
||||
<p class="description"><?php esc_html_e( 'Select which days are considered weekend days for weekend surcharges.', 'wp-bnb' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Weekend Days', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<?php foreach ( $days_of_week as $day_num => $day_name ) : ?>
|
||||
<label style="display: inline-block; margin-right: 15px;">
|
||||
<input type="checkbox" name="wp_bnb_weekend_days[]" value="<?php echo esc_attr( $day_num ); ?>"
|
||||
<?php checked( in_array( $day_num, $selected_days, true ) ); ?>>
|
||||
<?php echo esc_html( $day_name ); ?>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</fieldset>
|
||||
<p class="description"><?php esc_html_e( 'Weekend surcharges (configured per room) apply to nights starting on these days.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php submit_button( __( 'Save Weekend Days', 'wp-bnb' ) ); ?>
|
||||
|
||||
<?php else : ?>
|
||||
<!-- Seasons Subtab -->
|
||||
<h2><?php esc_html_e( 'Seasonal Pricing', 'wp-bnb' ); ?></h2>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Seasonal pricing allows you to adjust room rates based on time of year. Prices are multiplied by the season modifier.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wp-bnb-seasons' ) ); ?>" class="button button-primary">
|
||||
<span class="dashicons dashicons-admin-settings" style="vertical-align: text-top;"></span>
|
||||
<?php esc_html_e( 'Manage Seasons', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<?php if ( ! empty( $seasons ) ) : ?>
|
||||
<table class="widefat striped" style="max-width: 700px; margin-top: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Season', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Period', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Modifier', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Priority', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Status', 'wp-bnb' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ( $seasons as $season ) : ?>
|
||||
<tr>
|
||||
<td><strong><?php echo esc_html( $season->name ); ?></strong></td>
|
||||
<td><?php echo esc_html( $season->start_date . ' - ' . $season->end_date ); ?></td>
|
||||
<td><?php echo esc_html( $season->getModifierLabel() ); ?></td>
|
||||
<td><?php echo esc_html( $season->priority ); ?></td>
|
||||
<td>
|
||||
<?php if ( $season->active ) : ?>
|
||||
<span class="bnb-status-active"><?php esc_html_e( 'Active', 'wp-bnb' ); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="bnb-status-inactive"><?php esc_html_e( 'Inactive', 'wp-bnb' ); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<div class="notice notice-info inline" style="margin: 20px 0;">
|
||||
<p><?php esc_html_e( 'No seasons configured yet. Create seasons to apply price modifiers during specific periods.', 'wp-bnb' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
@@ -685,10 +955,21 @@ final class Plugin {
|
||||
$license_status = LicenseManager::get_cached_status();
|
||||
$license_data = LicenseManager::get_cached_data();
|
||||
$last_check = LicenseManager::get_last_check();
|
||||
$is_localhost = LicenseManager::is_localhost();
|
||||
?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
|
||||
<?php if ( $is_localhost ) : ?>
|
||||
<div class="notice notice-info inline" style="margin: 0 0 20px 0;">
|
||||
<p>
|
||||
<span class="dashicons dashicons-info" style="color: #72aee6;"></span>
|
||||
<strong><?php esc_html_e( 'Development Mode', 'wp-bnb' ); ?></strong>
|
||||
<?php esc_html_e( 'You are running on a local development environment. License validation is bypassed and all features are enabled.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><?php esc_html_e( 'License Status', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
@@ -773,6 +1054,160 @@ final class Plugin {
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render updates settings tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_updates_settings(): void {
|
||||
$updater = LicenseUpdater::get_instance();
|
||||
|
||||
if ( null === $updater ) {
|
||||
?>
|
||||
<p><?php esc_html_e( 'Update checker is not available.', 'wp-bnb' ); ?></p>
|
||||
<?php
|
||||
return;
|
||||
}
|
||||
|
||||
$current_version = $updater->get_current_version();
|
||||
$last_check = LicenseUpdater::get_last_check();
|
||||
$update_info = $updater->get_cached_update_info();
|
||||
$update_available = false;
|
||||
$latest_version = $current_version;
|
||||
$notifications_enabled = LicenseUpdater::is_notifications_enabled();
|
||||
$auto_install_enabled = LicenseUpdater::is_auto_install_enabled();
|
||||
$check_frequency = LicenseUpdater::get_check_frequency();
|
||||
$license_valid = LicenseManager::is_license_valid();
|
||||
|
||||
if ( $update_info instanceof UpdateInfo && $update_info->updateAvailable ) {
|
||||
$latest_version = $update_info->version ?? $current_version;
|
||||
$update_available = version_compare( $current_version, $latest_version, '<' );
|
||||
}
|
||||
?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
|
||||
<h2><?php esc_html_e( 'Update Status', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Current Version', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<strong><?php echo esc_html( $current_version ); ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Latest Version', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<span id="wp-bnb-latest-version">
|
||||
<?php if ( $update_available ) : ?>
|
||||
<span style="color: #00a32a; font-weight: 600;">
|
||||
<?php echo esc_html( $latest_version ); ?>
|
||||
</span>
|
||||
<span class="dashicons dashicons-yes" style="color: #00a32a;"></span>
|
||||
<em><?php esc_html_e( 'Update available!', 'wp-bnb' ); ?></em>
|
||||
<?php else : ?>
|
||||
<?php echo esc_html( $latest_version ); ?>
|
||||
<span style="color: #646970;">
|
||||
<?php esc_html_e( '(You are up to date)', 'wp-bnb' ); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Last Check', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<span id="wp-bnb-update-last-check">
|
||||
<?php if ( $last_check > 0 ) : ?>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: Time ago string */
|
||||
esc_html__( '%s ago', 'wp-bnb' ),
|
||||
esc_html( human_time_diff( $last_check, time() ) )
|
||||
);
|
||||
?>
|
||||
<?php else : ?>
|
||||
<?php esc_html_e( 'Never', 'wp-bnb' ); ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin-bottom: 30px;">
|
||||
<button type="button" id="wp-bnb-check-updates" class="button button-secondary">
|
||||
<span class="dashicons dashicons-update" style="vertical-align: text-top;"></span>
|
||||
<?php esc_html_e( 'Check for Updates', 'wp-bnb' ); ?>
|
||||
</button>
|
||||
<span class="spinner" id="wp-bnb-update-spinner"></span>
|
||||
<?php if ( $update_available ) : ?>
|
||||
<a href="<?php echo esc_url( admin_url( 'plugins.php' ) ); ?>" class="button button-primary">
|
||||
<?php esc_html_e( 'Go to Plugins Page', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
|
||||
<div id="wp-bnb-update-message" style="display: none; margin-bottom: 20px;"></div>
|
||||
|
||||
<h2><?php esc_html_e( 'Update Settings', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Enable Update Notifications', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="wp_bnb_update_notifications_enabled"
|
||||
value="yes" <?php checked( $notifications_enabled ); ?>>
|
||||
<?php esc_html_e( 'Check for updates from the license server', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'When enabled, the plugin will check for updates and show notifications in the WordPress admin.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Automatic Updates', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="wp_bnb_auto_install_enabled"
|
||||
value="yes" <?php checked( $auto_install_enabled ); ?>
|
||||
<?php disabled( ! $license_valid ); ?>>
|
||||
<?php esc_html_e( 'Automatically install updates', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<?php if ( ! $license_valid ) : ?>
|
||||
<span style="color: #d63638; margin-left: 10px;">
|
||||
<?php esc_html_e( '(Requires valid license)', 'wp-bnb' ); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'When enabled, updates will be automatically installed during WordPress background updates.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wp_bnb_update_check_frequency"><?php esc_html_e( 'Check Frequency', 'wp-bnb' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_update_check_frequency" id="wp_bnb_update_check_frequency"
|
||||
value="<?php echo esc_attr( $check_frequency ); ?>"
|
||||
min="1" max="168" class="small-text">
|
||||
<?php esc_html_e( 'hours', 'wp-bnb' ); ?>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'How often to check for updates (1-168 hours). Default: 12 hours.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="submit">
|
||||
<?php submit_button( __( 'Save Update Settings', 'wp-bnb' ), 'primary', 'submit', false ); ?>
|
||||
</p>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render license status badge.
|
||||
*
|
||||
@@ -841,6 +1276,9 @@ final class Plugin {
|
||||
case 'license':
|
||||
$this->save_license_settings();
|
||||
break;
|
||||
case 'updates':
|
||||
$this->save_updates_settings();
|
||||
break;
|
||||
default:
|
||||
$this->save_general_settings();
|
||||
break;
|
||||
@@ -853,6 +1291,7 @@ final class Plugin {
|
||||
* @return void
|
||||
*/
|
||||
private function save_general_settings(): void {
|
||||
// Business Information.
|
||||
if ( isset( $_POST['wp_bnb_business_name'] ) ) {
|
||||
update_option( 'wp_bnb_business_name', sanitize_text_field( wp_unslash( $_POST['wp_bnb_business_name'] ) ) );
|
||||
}
|
||||
@@ -860,6 +1299,35 @@ final class Plugin {
|
||||
update_option( 'wp_bnb_currency', sanitize_text_field( wp_unslash( $_POST['wp_bnb_currency'] ) ) );
|
||||
}
|
||||
|
||||
// Address fields.
|
||||
$address_fields = array( 'street', 'city', 'postal', 'country' );
|
||||
foreach ( $address_fields as $field ) {
|
||||
$key = 'wp_bnb_address_' . $field;
|
||||
if ( isset( $_POST[ $key ] ) ) {
|
||||
update_option( $key, sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Contact fields.
|
||||
if ( isset( $_POST['wp_bnb_contact_email'] ) ) {
|
||||
update_option( 'wp_bnb_contact_email', sanitize_email( wp_unslash( $_POST['wp_bnb_contact_email'] ) ) );
|
||||
}
|
||||
if ( isset( $_POST['wp_bnb_contact_phone'] ) ) {
|
||||
update_option( 'wp_bnb_contact_phone', sanitize_text_field( wp_unslash( $_POST['wp_bnb_contact_phone'] ) ) );
|
||||
}
|
||||
if ( isset( $_POST['wp_bnb_contact_website'] ) ) {
|
||||
update_option( 'wp_bnb_contact_website', esc_url_raw( wp_unslash( $_POST['wp_bnb_contact_website'] ) ) );
|
||||
}
|
||||
|
||||
// Social media fields.
|
||||
$social_fields = array( 'facebook', 'instagram', 'x', 'linkedin', 'tripadvisor' );
|
||||
foreach ( $social_fields as $field ) {
|
||||
$key = 'wp_bnb_social_' . $field;
|
||||
if ( isset( $_POST[ $key ] ) ) {
|
||||
update_option( $key, esc_url_raw( wp_unslash( $_POST[ $key ] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
add_settings_error( 'wp_bnb_settings', 'settings_saved', __( 'Settings saved.', 'wp-bnb' ), 'success' );
|
||||
settings_errors( 'wp_bnb_settings' );
|
||||
}
|
||||
@@ -912,6 +1380,34 @@ final class Plugin {
|
||||
settings_errors( 'wp_bnb_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save updates settings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function save_updates_settings(): void {
|
||||
$notifications_enabled = isset( $_POST['wp_bnb_update_notifications_enabled'] ) ? 'yes' : 'no';
|
||||
update_option( LicenseUpdater::OPTION_NOTIFICATIONS_ENABLED, $notifications_enabled );
|
||||
|
||||
$auto_install_enabled = isset( $_POST['wp_bnb_auto_install_enabled'] ) ? 'yes' : 'no';
|
||||
update_option( LicenseUpdater::OPTION_AUTO_INSTALL_ENABLED, $auto_install_enabled );
|
||||
|
||||
if ( isset( $_POST['wp_bnb_update_check_frequency'] ) ) {
|
||||
$frequency = absint( $_POST['wp_bnb_update_check_frequency'] );
|
||||
$frequency = max( 1, min( 168, $frequency ) ); // Clamp between 1-168 hours.
|
||||
update_option( LicenseUpdater::OPTION_CHECK_FREQUENCY, $frequency );
|
||||
|
||||
// Clear update cache when frequency changes so new frequency takes effect.
|
||||
$updater = LicenseUpdater::get_instance();
|
||||
if ( null !== $updater ) {
|
||||
$updater->clear_cache();
|
||||
}
|
||||
}
|
||||
|
||||
add_settings_error( 'wp_bnb_settings', 'settings_saved', __( 'Update settings saved.', 'wp-bnb' ), 'success' );
|
||||
settings_errors( 'wp_bnb_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for checking room availability.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user