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>
This commit is contained in:
Hotel Raxa Dev
2025-07-11 07:43:22 +02:00
commit 5b1e2453c7
9816 changed files with 2784509 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
<?php
/**
* WordPress Tiny MCE Editor Field.
*
* @package ReduxFramework/Fields
* @author Dovy Paukstys & Kevin Provance (kprovance)
* @version 4.0.0
*/
defined( 'ABSPATH' ) || exit;
// Don't duplicate me!
if ( ! class_exists( 'Redux_Editor', false ) ) {
/**
* Main Redux_editor class
*
* @since 1.0.0
*/
class Redux_Editor extends Redux_Field {
/**
* Field Render Function.
* Takes the vars and outputs the HTML for the field in the settings
*
* @since 1.0.0
* @access public
* @return void
*/
public function render() {
if ( ! isset( $this->field['args'] ) ) {
$this->field['args'] = array();
}
$this->field['args']['onchange_callback'] = "alert('here')";
// Setup up default args.
$defaults = array(
'textarea_name' => esc_attr( $this->field['name'] . $this->field['name_suffix'] ),
'editor_class' => esc_attr( $this->field['class'] ),
'textarea_rows' => 10, // Wordpress default.
'teeny' => true,
);
if ( isset( $this->field['editor_options'] ) && empty( $this->field['args'] ) ) {
$this->field['args'] = $this->field['editor_options'];
unset( $this->field['editor_options'] );
}
$this->field['args'] = wp_parse_args( $this->field['args'], $defaults );
wp_editor( $this->value, $this->field['id'], $this->field['args'] );
}
/**
* Enqueue Function.
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
*
* @since 1.0.0
* @access public
* @return void
*/
public function enqueue() {
if ( $this->parent->args['dev_mode'] ) {
wp_enqueue_style(
'redux-field-editor',
Redux_Core::$url . 'inc/fields/editor/redux-editor.css',
array(),
$this->timestamp
);
}
wp_enqueue_script(
'redux-field-editor',
Redux_Core::$url . 'inc/fields/editor/redux-editor' . Redux_Functions::is_min() . '.js',
array( 'jquery', 'redux-js' ),
$this->timestamp,
true
);
}
}
}
class_alias( 'Redux_Editor', 'ReduxFramework_Editor' );

View File

@@ -0,0 +1,8 @@
<?php
/**
* Silence is golden.
*
* @package Redux Framework
*/
_deprecated_file( 'field_editor.php', '4.3', 'class-redux-editor.php', 'This file has been renamed and is no longer used in Redux 4. Please change any references to it as it will be removed in future versions of Redux.' );

View File

@@ -0,0 +1,8 @@
<?php
/**
* Silence is golden.
*
* @package Redux Framework
*/
echo null;

View File

@@ -0,0 +1,15 @@
.redux-container-editor .mceLayout td { border-width: 1px; margin: 0; padding: 1px; }
.redux-container-editor input, .redux-container-editor textarea { margin: inherit; }
.redux-container-editor textarea { border: 0 none; }
.redux-container-editor .wp-editor-container { border-radius: 3px; }
.redux-container-editor .wp-editor-container textarea { border-radius: 0; border-style: inherit; }
.redux-container-editor .quicktags-toolbar input { margin: 2px 1px 4px; display: inline-block; min-width: 26px; padding: 2px 4px; font: 12px/18px Arial, Helvetica, sans-serif normal; color: #464646; border: 1px solid #c3c3c3; border-radius: 3px; background: #eee; background-image: -webkit-gradient(linear, left bottom, left top, from(#e3e3e3), to(#fff)); background-image: -webkit-linear-gradient(bottom, #e3e3e3, #fff); background-image: linear-gradient(to top, #e3e3e3, #fff); }
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtZWRpdG9yLmNzcyIsInNvdXJjZXMiOlsicmVkdXgtZWRpdG9yLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsQUFDSSx1QkFEbUIsQ0FDbkIsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUNWLFlBQVksRUFBRSxHQUFHLEVBQ2pCLE1BQU0sRUFBRSxDQUFDLEVBQ1QsT0FBTyxFQUFFLEdBQUcsR0FDZjs7QUFMTCxBQU9JLHVCQVBtQixDQU9uQixLQUFLLEVBUFQsdUJBQXVCLENBUW5CLFFBQVEsQ0FBQyxFQUNMLE1BQU0sRUFBRSxPQUFPLEdBQ2xCOztBQVZMLEFBWUksdUJBWm1CLENBWW5CLFFBQVEsQ0FBQyxFQUNMLE1BQU0sRUFBRSxNQUFNLEdBQ2pCOztBQWRMLEFBZ0JJLHVCQWhCbUIsQ0FnQm5CLG9CQUFvQixDQUFDLEVBQ2pCLHFCQUFxQixFQUFFLEdBQUcsRUFDMUIsa0JBQWtCLEVBQUUsR0FBRyxFQUN2QixhQUFhLEVBQUUsR0FBRyxHQVFyQjs7QUEzQkwsQUFxQlEsdUJBckJlLENBZ0JuQixvQkFBb0IsQ0FLaEIsUUFBUSxDQUFDLEVBQ0wscUJBQXFCLEVBQUUsQ0FBQyxFQUN4QixrQkFBa0IsRUFBRSxDQUFDLEVBQ3JCLGFBQWEsRUFBRSxDQUFDLEVBQ2hCLFlBQVksRUFBRSxPQUFPLEdBQ3hCOztBQTFCVCxBQTZCSSx1QkE3Qm1CLENBNkJuQixrQkFBa0IsQ0FBQyxLQUFLLENBQUMsRUFDckIsTUFBTSxFQUFFLFdBQVcsRUFDbkIsT0FBTyxFQUFFLFlBQVksRUFDckIsU0FBUyxFQUFFLElBQUksRUFDZixPQUFPLEVBQUUsT0FBTyxFQUNoQixJQUFJLEVBQUUsNkNBQTZDLEVBQ25ELEtBQUssRUFBRSxPQUFPLEVBQ2QsTUFBTSxFQUFFLGlCQUFpQixFQUN6QixxQkFBcUIsRUFBRSxHQUFHLEVBQzFCLGFBQWEsRUFBRSxHQUFHLEVBQ2xCLFVBQVUsRUFBRSxJQUFJLEVBQ2hCLGdCQUFnQixFQUFFLHdFQUF3RSxFQUMxRixnQkFBZ0IsRUFBRSw4Q0FBOEMsRUFDaEUsZ0JBQWdCLEVBQUUsMkNBQTJDLEVBQzdELGdCQUFnQixFQUFFLHlDQUF5QyxFQUMzRCxnQkFBZ0IsRUFBRSxzQ0FBc0MsR0FDM0QifQ== */
/*# sourceMappingURL=redux-editor.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["redux-editor.scss","redux-editor.css"],"names":[],"mappings":"AAAA,wCAAA,iBAOI,ECJI,SAAS,EDHjB,YAAA,EAAA;;AAAA,kECSQ,eAAe,EAAA;;ADTvB,mCCaQ,cAAc,EAAA;;ADbtB,+CCmBQ,kBAAkB,EAAA;;ADnB1B,wDCwBY,gBAAgB,EAChB,qBAAqB,EAAA;;ADzBjC,mDC8BQ,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,mDAAmD,EACnD,cAAc,EACd,yBAAyB,EAEzB,kBAAkB,EAClB,gBAAgB,EAChB,0FAA0F,EAC1F,gEAAgE,EAGhE,wDAAwD,EAAA;;AAhChE,q3CAAq3C","file":"redux-editor.css","sourcesContent":[".redux-container-editor {\n .mceLayout td {\n border-width: 1px;\n margin: 0;\n padding: 1px;\n }\n\n input,\n textarea {\n margin: inherit;\n }\n\n textarea {\n border: 0 none;\n }\n\n .wp-editor-container {\n -webkit-border-radius: 3px;\n -moz-border-radius: 3px;\n border-radius: 3px;\n\n textarea {\n -webkit-border-radius: 0;\n -moz-border-radius: 0;\n border-radius: 0;\n border-style: inherit;\n }\n }\n\n .quicktags-toolbar input {\n margin: 2px 1px 4px;\n display: inline-block;\n min-width: 26px;\n padding: 2px 4px;\n font: 12px/18px Arial, Helvetica, sans-serif normal;\n color: #464646;\n border: 1px solid #c3c3c3;\n -webkit-border-radius: 3px;\n border-radius: 3px;\n background: #eee;\n background-image: -webkit-gradient(linear, left bottom, left top, from(#e3e3e3), to(#fff));\n background-image: -webkit-linear-gradient(bottom, #e3e3e3, #fff);\n background-image: -moz-linear-gradient(bottom, #e3e3e3, #fff);\n background-image: -o-linear-gradient(bottom, #e3e3e3, #fff);\n background-image: linear-gradient(to top, #e3e3e3, #fff);\n }\n}\n\n",".redux-container-editor .mceLayout td { border-width: 1px; margin: 0; padding: 1px; }\n\n.redux-container-editor input, .redux-container-editor textarea { margin: inherit; }\n\n.redux-container-editor textarea { border: 0 none; }\n\n.redux-container-editor .wp-editor-container { border-radius: 3px; }\n\n.redux-container-editor .wp-editor-container textarea { border-radius: 0; border-style: inherit; }\n\n.redux-container-editor .quicktags-toolbar input { margin: 2px 1px 4px; display: inline-block; min-width: 26px; padding: 2px 4px; font: 12px/18px Arial, Helvetica, sans-serif normal; color: #464646; border: 1px solid #c3c3c3; border-radius: 3px; background: #eee; background-image: -webkit-gradient(linear, left bottom, left top, from(#e3e3e3), to(#fff)); background-image: -webkit-linear-gradient(bottom, #e3e3e3, #fff); background-image: linear-gradient(to top, #e3e3e3, #fff); }\n\n/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtZWRpdG9yLmNzcyIsInNvdXJjZXMiOlsicmVkdXgtZWRpdG9yLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsQUFDSSx1QkFEbUIsQ0FDbkIsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUNWLFlBQVksRUFBRSxHQUFHLEVBQ2pCLE1BQU0sRUFBRSxDQUFDLEVBQ1QsT0FBTyxFQUFFLEdBQUcsR0FDZjs7QUFMTCxBQU9JLHVCQVBtQixDQU9uQixLQUFLLEVBUFQsdUJBQXVCLENBUW5CLFFBQVEsQ0FBQyxFQUNMLE1BQU0sRUFBRSxPQUFPLEdBQ2xCOztBQVZMLEFBWUksdUJBWm1CLENBWW5CLFFBQVEsQ0FBQyxFQUNMLE1BQU0sRUFBRSxNQUFNLEdBQ2pCOztBQWRMLEFBZ0JJLHVCQWhCbUIsQ0FnQm5CLG9CQUFvQixDQUFDLEVBQ2pCLHFCQUFxQixFQUFFLEdBQUcsRUFDMUIsa0JBQWtCLEVBQUUsR0FBRyxFQUN2QixhQUFhLEVBQUUsR0FBRyxHQVFyQjs7QUEzQkwsQUFxQlEsdUJBckJlLENBZ0JuQixvQkFBb0IsQ0FLaEIsUUFBUSxDQUFDLEVBQ0wscUJBQXFCLEVBQUUsQ0FBQyxFQUN4QixrQkFBa0IsRUFBRSxDQUFDLEVBQ3JCLGFBQWEsRUFBRSxDQUFDLEVBQ2hCLFlBQVksRUFBRSxPQUFPLEdBQ3hCOztBQTFCVCxBQTZCSSx1QkE3Qm1CLENBNkJuQixrQkFBa0IsQ0FBQyxLQUFLLENBQUMsRUFDckIsTUFBTSxFQUFFLFdBQVcsRUFDbkIsT0FBTyxFQUFFLFlBQVksRUFDckIsU0FBUyxFQUFFLElBQUksRUFDZixPQUFPLEVBQUUsT0FBTyxFQUNoQixJQUFJLEVBQUUsNkNBQTZDLEVBQ25ELEtBQUssRUFBRSxPQUFPLEVBQ2QsTUFBTSxFQUFFLGlCQUFpQixFQUN6QixxQkFBcUIsRUFBRSxHQUFHLEVBQzFCLGFBQWEsRUFBRSxHQUFHLEVBQ2xCLFVBQVUsRUFBRSxJQUFJLEVBQ2hCLGdCQUFnQixFQUFFLHdFQUF3RSxFQUMxRixnQkFBZ0IsRUFBRSw4Q0FBOEMsRUFDaEUsZ0JBQWdCLEVBQUUsMkNBQTJDLEVBQzdELGdCQUFnQixFQUFFLHlDQUF5QyxFQUMzRCxnQkFBZ0IsRUFBRSxzQ0FBc0MsR0FDM0QifQ== */\n\n/*# sourceMappingURL=redux-editor.css.map */\n"]}

View File

@@ -0,0 +1,46 @@
/**
* Redux Editor on change callback
* Dependencies : jquery
* Feature added by : Dovy Paukstys
* : Kevin Provance (who helped) :P
* Date : 07 June 2014
*/
/*global redux_change, tinymce, redux*/
(function( $ ) {
'use strict';
redux.field_objects = redux.field_objects || {};
redux.field_objects.editor = redux.field_objects.editor || {};
redux.field_objects.editor.init = function() {
var i;
var len;
setTimeout(
function() {
if ( 'undefined' !== typeof ( tinymce ) ) {
len = tinymce.editors.length;
for ( i = 0; i < len; i += 1 ) {
redux.field_objects.editor.onChange( i );
}
}
},
1000
);
};
redux.field_objects.editor.onChange = function( i ) {
tinymce.editors[i].on(
'change',
function( e ) {
var el = jQuery( e.target.contentAreaContainer );
if ( 0 !== el.parents( '.redux-container-editor:first' ).length ) {
redux_change( $( '.wp-editor-area' ) );
}
}
);
};
})( jQuery );

View File

@@ -0,0 +1 @@
!function(t){"use strict";redux.field_objects=redux.field_objects||{},redux.field_objects.editor=redux.field_objects.editor||{},redux.field_objects.editor.init=function(){var e,t;setTimeout(function(){if("undefined"!=typeof tinymce)for(t=tinymce.editors.length,e=0;e<t;e+=1)redux.field_objects.editor.onChange(e)},1e3)},redux.field_objects.editor.onChange=function(e){tinymce.editors[e].on("change",function(e){0!==jQuery(e.target.contentAreaContainer).parents(".redux-container-editor:first").length&&redux_change(t(".wp-editor-area"))})}}(jQuery);

View File

@@ -0,0 +1,48 @@
.redux-container-editor {
.mceLayout td {
border-width: 1px;
margin: 0;
padding: 1px;
}
input,
textarea {
margin: inherit;
}
textarea {
border: 0 none;
}
.wp-editor-container {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
textarea {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
border-style: inherit;
}
}
.quicktags-toolbar input {
margin: 2px 1px 4px;
display: inline-block;
min-width: 26px;
padding: 2px 4px;
font: 12px/18px Arial, Helvetica, sans-serif normal;
color: #464646;
border: 1px solid #c3c3c3;
-webkit-border-radius: 3px;
border-radius: 3px;
background: #eee;
background-image: -webkit-gradient(linear, left bottom, left top, from(#e3e3e3), to(#fff));
background-image: -webkit-linear-gradient(bottom, #e3e3e3, #fff);
background-image: -moz-linear-gradient(bottom, #e3e3e3, #fff);
background-image: -o-linear-gradient(bottom, #e3e3e3, #fff);
background-image: linear-gradient(to top, #e3e3e3, #fff);
}
}