Files
Hotel Raxa Dev 5b1e2453c7 Hotel Raxa - Advanced Booking System Implementation
🏨 Hotel Booking Enhancements:
- Implemented Eagle Booking Advanced Pricing add-on
- Added Booking.com-style rate management system
- Created professional calendar interface for pricing
- Integrated deals and discounts functionality

💰 Advanced Pricing Features:
- Dynamic pricing models (per room, per person, per adult)
- Base rates, adult rates, and child rates management
- Length of stay discounts and early bird deals
- Mobile rates and secret deals implementation
- Seasonal promotions and flash sales

📅 Availability Management:
- Real-time availability tracking
- Stop sell and restriction controls
- Closed to arrival/departure functionality
- Minimum/maximum stay requirements
- Automatic sold-out management

💳 Payment Integration:
- Maintained Redsys payment gateway integration
- Seamless integration with existing Eagle Booking
- No modifications to core Eagle Booking plugin

🛠️ Technical Implementation:
- Custom database tables for advanced pricing
- WordPress hooks and filters integration
- AJAX-powered admin interface
- Data migration from existing Eagle Booking
- Professional calendar view for revenue management

📊 Admin Interface:
- Booking.com-style management dashboard
- Visual rate and availability calendar
- Bulk operations for date ranges
- Statistics and analytics dashboard
- Modal dialogs for quick editing

🔧 Code Quality:
- WordPress coding standards compliance
- Secure database operations with prepared statements
- Proper input validation and sanitization
- Error handling and logging
- Responsive admin interface

🤖 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 07:43:22 +02:00

189 lines
5.4 KiB
PHP

<?php
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
use YahnisElsts\PluginUpdateChecker\v5p4\PucFactory;
if ( !class_exists(Package::class, false) ):
class Package extends InstalledPackage {
/**
* @var UpdateChecker
*/
protected $updateChecker;
/**
* @var string Full path of the main plugin file.
*/
protected $pluginAbsolutePath = '';
/**
* @var string Plugin basename.
*/
private $pluginFile;
/**
* @var string|null
*/
private $cachedInstalledVersion = null;
public function __construct($pluginAbsolutePath, $updateChecker) {
$this->pluginAbsolutePath = $pluginAbsolutePath;
$this->pluginFile = plugin_basename($this->pluginAbsolutePath);
parent::__construct($updateChecker);
//Clear the version number cache when something - anything - is upgraded or WP clears the update cache.
add_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
}
public function getInstalledVersion() {
if ( isset($this->cachedInstalledVersion) ) {
return $this->cachedInstalledVersion;
}
$pluginHeader = $this->getPluginHeader();
if ( isset($pluginHeader['Version']) ) {
$this->cachedInstalledVersion = $pluginHeader['Version'];
return $pluginHeader['Version'];
} else {
//This can happen if the filename points to something that is not a plugin.
$this->updateChecker->triggerError(
sprintf(
"Cannot read the Version header for '%s'. The filename is incorrect or is not a plugin.",
$this->updateChecker->pluginFile
),
E_USER_WARNING
);
return null;
}
}
/**
* Clear the cached plugin version. This method can be set up as a filter (hook) and will
* return the filter argument unmodified.
*
* @param mixed $filterArgument
* @return mixed
*/
public function clearCachedVersion($filterArgument = null) {
$this->cachedInstalledVersion = null;
return $filterArgument;
}
public function getAbsoluteDirectoryPath() {
return dirname($this->pluginAbsolutePath);
}
/**
* Get the value of a specific plugin or theme header.
*
* @param string $headerName
* @param string $defaultValue
* @return string Either the value of the header, or $defaultValue if the header doesn't exist or is empty.
*/
public function getHeaderValue($headerName, $defaultValue = '') {
$headers = $this->getPluginHeader();
if ( isset($headers[$headerName]) && ($headers[$headerName] !== '') ) {
return $headers[$headerName];
}
return $defaultValue;
}
protected function getHeaderNames() {
return array(
'Name' => 'Plugin Name',
'PluginURI' => 'Plugin URI',
'Version' => 'Version',
'Description' => 'Description',
'Author' => 'Author',
'AuthorURI' => 'Author URI',
'TextDomain' => 'Text Domain',
'DomainPath' => 'Domain Path',
'Network' => 'Network',
//The newest WordPress version that this plugin requires or has been tested with.
//We support several different formats for compatibility with other libraries.
'Tested WP' => 'Tested WP',
'Requires WP' => 'Requires WP',
'Tested up to' => 'Tested up to',
'Requires at least' => 'Requires at least',
);
}
/**
* Get the translated plugin title.
*
* @return string
*/
public function getPluginTitle() {
$title = '';
$header = $this->getPluginHeader();
if ( $header && !empty($header['Name']) && isset($header['TextDomain']) ) {
$title = translate($header['Name'], $header['TextDomain']);
}
return $title;
}
/**
* Get plugin's metadata from its file header.
*
* @return array
*/
public function getPluginHeader() {
if ( !is_file($this->pluginAbsolutePath) ) {
//This can happen if the plugin filename is wrong.
$this->updateChecker->triggerError(
sprintf(
"Can't to read the plugin header for '%s'. The file does not exist.",
$this->updateChecker->pluginFile
),
E_USER_WARNING
);
return array();
}
if ( !function_exists('get_plugin_data') ) {
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
}
return get_plugin_data($this->pluginAbsolutePath, false, false);
}
public function removeHooks() {
remove_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
remove_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
}
/**
* Check if the plugin file is inside the mu-plugins directory.
*
* @return bool
*/
public function isMuPlugin() {
static $cachedResult = null;
if ( $cachedResult === null ) {
if ( !defined('WPMU_PLUGIN_DIR') || !is_string(WPMU_PLUGIN_DIR) ) {
$cachedResult = false;
return $cachedResult;
}
//Convert both paths to the canonical form before comparison.
$muPluginDir = realpath(WPMU_PLUGIN_DIR);
$pluginPath = realpath($this->pluginAbsolutePath);
//If realpath() fails, just normalize the syntax instead.
if (($muPluginDir === false) || ($pluginPath === false)) {
$muPluginDir = PucFactory::normalizePath(WPMU_PLUGIN_DIR);
$pluginPath = PucFactory::normalizePath($this->pluginAbsolutePath);
}
$cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
}
return $cachedResult;
}
}
endif;