File: /mnt/data/dreamstour-wp/wp-content/plugins/dreamstour-widgets/widgets/class-hero-banner.php
<?php
namespace Dreamstourelementor\Widgets;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use \Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Elementor Hero Banner Widget
*
* Elementor widget for tour hero banner with search functionality.
*
* @since 1.0.0
*/
class DTS_hero_banner extends Widget_Base {
/**
* Retrieve the widget name.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'dreamstour_elementor_hero_banner';
}
/**
* Retrieve the widget title.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Dreams Tour Hero Banner', 'dreamstour_elementor' );
}
/**
* Retrieve the widget icon.
*
* @since 1.0.0
*
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'eicon-banner';
}
/**
* Retrieve the list of categories the widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* Note that currently Elementor supports only one category.
* When multiple categories passed, Elementor uses the first one.
*
* @since 1.0.0
*
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'dreamstourelemetortheme' ];
}
/**
* Retrieve the list of scripts the widget depended on.
*
* Used to set scripts dependencies required to run the widget.
*
* @since 1.0.0
*
* @access public
*
* @return array Widget scripts dependencies.
*/
public function get_script_depends() {
return [ 'dreamstourelementor-elementor' ];
}
/**
* Register the widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 1.0.0
*
* @access protected
*/
protected function register_controls() {
$this->start_controls_section(
'section_content',
[
'label' => __( 'Content', 'dreamstour_elementor' ),
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'dreamstour_elementor' ),
'type' => Controls_Manager::TEXT,
"default" => __( 'Get Closer to the Dream: <span>Your Tour</span> Essentials Await', 'dreamstour_elementor' ),
]
);
$this->add_control(
'subtitle',
[
'label' => __( 'Subtitle', 'dreamstour_elementor' ),
'type' => Controls_Manager::TEXT,
"default" => __( 'Your ultimate destination for all things help you celebrate & remember tour experience.', 'dreamstour_elementor' ),
]
);
$this->add_control(
'search_page_url',
[
'label' => __( 'Search Results Page URL', 'dreamstour_elementor' ),
'type' => Controls_Manager::TEXT,
"default" => __( '/tour-list/', 'dreamstour_elementor' ),
'description' => __( 'Enter the URL where search results should be displayed', 'dreamstour_elementor' ),
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_slider',
[
'label' => __( 'Slider Images', 'dreamstour_elementor' ),
]
);
$this->add_control(
'slider_images',
[
'label' => __( 'Slider Images', 'dreamstour_elementor' ),
'type' => Controls_Manager::GALLERY,
'default' => [
[
'url' => get_template_directory_uri() . '/assets/images/banner/banner-01.jpg',
],
[
'url' => get_template_directory_uri() . '/assets/images/banner/banner-02.jpg',
],
[
'url' => get_template_directory_uri() . '/assets/images/banner/banner-03.jpg',
],
[
'url' => get_template_directory_uri() . '/assets/images/banner/banner-04.jpg',
],
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style',
[
'label' => __( 'Style', 'dreamstour_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Title Color', 'dreamstour_elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '#ffffff',
'selectors' => [
'{{WRAPPER}} .hero-content h1' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'subtitle_color',
[
'label' => __( 'Subtitle Color', 'dreamstour_elementor' ),
'type' => Controls_Manager::COLOR,
'default' => '#ffffff',
'selectors' => [
'{{WRAPPER}} .hero-content h6' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
\Elementor\Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'label' => __( 'Title Typography', 'dreamstour_elementor' ),
'selector' => '{{WRAPPER}} .hero-content h1',
]
);
$this->add_group_control(
\Elementor\Group_Control_Typography::get_type(),
[
'name' => 'subtitle_typography',
'label' => __( 'Subtitle Typography', 'dreamstour_elementor' ),
'selector' => '{{WRAPPER}} .hero-content h6',
]
);
$this->end_controls_section();
}
/**
* Render the widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.0.0
*
* @access protected
*/
protected function render() {
$settings = $this->get_settings();
$search_page_url = $settings['search_page_url'] ? $settings['search_page_url'] : '/tour-list/';
// Get tour duration terms
$duration_days = get_terms(array(
'taxonomy' => 'tour_duration_days',
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC'
));
?>
<!-- Hero Section -->
<section class="hero-section">
<div class="banner-slider banner-sec owl-carousel">
<?php if (!empty($settings['slider_images'])): ?>
<?php foreach ($settings['slider_images'] as $image): ?>
<div class="slider-img">
<img src="<?php echo esc_url($image['url']); ?>" alt="Banner Image">
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="slider-img">
<img src="<?php echo get_template_directory_uri(); ?>/assets/images/banner/banner-01.jpg" alt="Banner Image">
</div>
<?php endif; ?>
</div>
<div class="container">
<div class="hero-content">
<div class="row align-items-center">
<div class="col-md-12 mx-auto wow fadeInUp" data-wow-delay="0.3s">
<div class="banner-content mx-auto">
<h1 class="text-white display-5 mb-2"><?php echo wp_kses_post($settings['title']); ?></h1>
<h6 class="text-light mx-auto"><?php echo esc_html($settings['subtitle']); ?></h6>
</div>
<div class="banner-form card mb-0">
<div class="card-body">
<div class="banner-form">
<form class="d-lg-flex" id="tour-search-form" action="<?php echo esc_url(home_url($search_page_url)); ?>" method="get">
<div class="d-flex form-info">
<div class="form-item dropdown">
<div data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" role="menu">
<label class="form-label fs-14 text-default mb-1"><?php esc_html_e('Where would like to go?', 'dreamstour_elementor' ); ?></label>
<input type="text" class="form-control" name="destination" value="<?php echo isset($_GET['destination']) ? esc_attr($_GET['destination']) : ''; ?>" placeholder="Enter destination">
<p class="fs-12 mb-0"><?php esc_html_e('Enter destination', 'dreamstour_elementor' ); ?></p>
</div>
</div>
<div class="form-item">
<label class="form-label fs-14 text-default mb-1"><?php esc_html_e('Check In', 'dreamstour_elementor' ); ?></label>
<input type="text" class="form-control datetimepicker" name="check_in" value="<?php echo isset($_GET['check_in']) ? esc_attr($_GET['check_in']) : ''; ?>" placeholder="Check-in date">
<p class="fs-12 mb-0"><?php esc_html_e('Select date', 'dreamstour_elementor' ); ?></p>
</div>
<div class="form-item dropdown">
<div data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" role="menu">
<label class="form-label fs-14 text-default mb-1"><?php esc_html_e('Duration (Days)', 'dreamstour_elementor'); ?></label>
<input type="text" class="form-control" id="durationInput" name="duration" placeholder="<?php esc_attr_e('Select duration', 'dreamstour_elementor'); ?>" readonly value="<?php echo isset($_GET['duration']) ? esc_attr($_GET['duration']) : ''; ?>">
<input type="hidden" id="durationIdInput" name="tour_duration_days" value="<?php echo isset($_GET['tour_duration_days']) ? esc_attr($_GET['tour_duration_days']) : ''; ?>">
<p class="fs-12 mb-0"><?php esc_html_e('Select duration in days', 'dreamstour_elementor'); ?></p>
</div>
<div class="dropdown-menu dropdown-md p-0">
<ul id="durationList">
<!-- Add an option to clear selection -->
<li class="border-bottom">
<a class="dropdown-item" href="javascript:void(0);" data-value="" data-name=""><?php esc_html_e('Clear selection', 'dreamstour_elementor'); ?></a>
</li>
<?php
// ✅ Fetch all duration terms
$duration_days = get_terms(array(
'taxonomy' => 'tour_duration_days',
'hide_empty' => false,
));
if (!empty($duration_days) && !is_wp_error($duration_days)) {
// ✅ Sort numerically by number in term name (e.g., 1 Day, 2 Days...)
usort($duration_days, function ($a, $b) {
$a_num = (int) filter_var($a->name, FILTER_SANITIZE_NUMBER_INT);
$b_num = (int) filter_var($b->name, FILTER_SANITIZE_NUMBER_INT);
return $a_num - $b_num;
});
// ✅ Display sorted list
foreach ($duration_days as $term) {
$selected = (isset($_GET['tour_duration_days']) && $_GET['tour_duration_days'] == $term->term_id) ? 'selected' : '';
echo '<li class="border-bottom">
<a class="dropdown-item ' . esc_attr($selected) . '" href="javascript:void(0);"
data-value="' . esc_attr($term->term_id) . '"
data-name="' . esc_attr($term->name) . '">' . esc_html($term->name) . '</a>
</li>';
}
}
?>
</ul>
</div>
</div>
<div class="form-item dropdown w-100">
<div data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" role="menu" class="w-100">
<label class="form-label fs-14 text-default mb-1"><?php esc_html_e('Travellers', 'dreamstour_elementor' ); ?></label>
<h6 class="mb-0"><span class="traveller-count"><?php echo isset($_GET['travellers']) ? intval($_GET['travellers']) : 1; ?></span> <span class="fw-normal fs-14"><?php esc_html_e('Persons', 'dreamstour_elementor' ); ?></span></h6>
<p class="fs-12 mb-0"><span class="adult-count"><?php echo isset($_GET['adults']) ? intval($_GET['adults']) : 1; ?></span> Adult</p>
<input type="hidden" name="travellers" id="travellers-input" value="<?php echo isset($_GET['travellers']) ? intval($_GET['travellers']) : 1; ?>">
<input type="hidden" name="adults" id="adults-input" value="<?php echo isset($_GET['adults']) ? intval($_GET['adults']) : 1; ?>">
<input type="hidden" name="children" id="children-input" value="<?php echo isset($_GET['children']) ? intval($_GET['children']) : 0; ?>">
<input type="hidden" name="infants" id="infants-input" value="<?php echo isset($_GET['infants']) ? intval($_GET['infants']) : 0; ?>">
</div>
<!-- Traveller dropdown menu -->
<div class="dropdown-menu dropdown-menu-end dropdown-xl p-3">
<h5 class="mb-3"><?php esc_html_e('Select Travelers & Class', 'dreamstour_elementor' ); ?></h5>
<!-- Adults -->
<div class="mb-3 border br-10 info-item pb-1">
<div class="col-md-12">
<div class="mb-3 d-flex align-items-center justify-content-between">
<label class="form-label text-gray-9 mb-2"><?php esc_html_e('Adults', 'dreamstour_elementor' ); ?></label>
<div class="custom-increment">
<div class="input-group">
<span class="input-group-btn float-start">
<button type="button" class="quantity-left-minus btn btn-light btn-number" data-type="minus" data-field="adults">
<span><i class="isax isax-minus"></i></span>
</button>
</span>
<input type="text" name="adults_count" class="input-number adults-count" value="<?php echo isset($_GET['adults']) ? intval($_GET['adults']) : 1; ?>" min="1" max="20">
<span class="input-group-btn float-end">
<button type="button" class="quantity-right-plus btn btn-light btn-number" data-type="plus" data-field="adults">
<span><i class="isax isax-add"></i></span>
</button>
</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="mb-3 d-flex align-items-center justify-content-between">
<label class="form-label text-gray-9 mb-2"><?php esc_html_e('Children', 'dreamstour_elementor' ); ?> <span class="text-default fw-normal">(<?php esc_html_e(' 2-12 Yrs', 'dreamstour_elementor' ); ?> )</span></label>
<div class="custom-increment">
<div class="input-group">
<span class="input-group-btn float-start">
<button type="button" class="quantity-left-minus btn btn-light btn-number" data-type="minus" data-field="children">
<span><i class="isax isax-minus"></i></span>
</button>
</span>
<input type="text" name="children_count" class="input-number children-count" value="<?php echo isset($_GET['children']) ? intval($_GET['children']) : 0; ?>" min="0" max="10">
<span class="input-group-btn float-end">
<button type="button" class="quantity-right-plus btn btn-light btn-number" data-type="plus" data-field="children">
<span><i class="isax isax-add"></i></span>
</button>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-end">
<a href="javascript:void(0);" class="btn btn-light btn-sm me-2 cancel-travellers"><?php esc_html_e('Cancel', 'dreamstour_elementor' ); ?></a>
<button type="button" class="btn btn-primary btn-sm apply-travellers"><?php esc_html_e('Apply', 'dreamstour_elementor' ); ?></button>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary search-btn rounded"><?php esc_html_e('Search', 'dreamstour_elementor' ); ?></button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- /Hero Section -->
<script>
jQuery(document).ready(function($) {
// Duration dropdown functionality
$('#durationList .dropdown-item').click(function(e) {
e.preventDefault();
var termId = $(this).data('value');
var termName = $(this).data('name');
// Update the visible input field
$('#durationInput').val(termName);
// Update the hidden input field with term ID
$('#durationIdInput').val(termId);
// Close the dropdown
$(this).closest('.dropdown-menu').removeClass('show');
});
// Handle increment/decrement buttons for travelers
$('.quantity-right-plus').click(function(e) {
e.preventDefault();
var field = $(this).data('field');
var input = $('.' + field + '-count');
var currentVal = parseInt(input.val());
if (!isNaN(currentVal)) {
input.val(currentVal + 1);
} else {
input.val(1);
}
});
$('.quantity-left-minus').click(function(e) {
e.preventDefault();
var field = $(this).data('field');
var input = $('.' + field + '-count');
var currentVal = parseInt(input.val());
if (!isNaN(currentVal) && currentVal > (field === 'adults' ? 1 : 0)) {
input.val(currentVal - 1);
}
});
// Apply traveler selection
$('.apply-travellers').click(function(){
var adults = parseInt($('.adults-count').val()) || 1;
var children = parseInt($('.children-count').val()) || 0;
var infants = parseInt($('.infants-count').val()) || 0;
var total = adults + children + infants;
// Update display
$('.traveller-count').text(total);
$('.adult-count').text(adults);
// Update hidden inputs
$('#travellers-input').val(total);
$('#adults-input').val(adults);
$('#children-input').val(children);
$('#infants-input').val(infants);
// Close dropdown
$('.form-item.dropdown .dropdown-menu').removeClass('show');
});
// Cancel traveler selection
$('.cancel-travellers').click(function(){
$('.form-item.dropdown .dropdown-menu').removeClass('show');
});
});
</script>
<?php
}
/**
* Render the widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 1.0.0
*
* @access protected
*/
protected function content_template() {
?>
<div class="hero-section">
<div class="banner-slider banner-sec owl-carousel">
<# if (settings.slider_images && settings.slider_images.length > 0) { #>
<# _.each(settings.slider_images, function(image) { #>
<div class="slider-img">
<img src="{{{ image.url }}}" alt="Banner Image">
</div>
<# }); #>
<# } else { #>
<div class="slider-img">
<img src="<?php echo get_template_directory_uri(); ?>/assets/images/banner/banner-01.jpg" alt="Banner Image">
</div>
<# } #>
</div>
<div class="container">
<div class="hero-content">
<div class="row align-items-center">
<div class="col-md-12 mx-auto wow fadeInUp" data-wow-delay="0.3s">
<div class="banner-content mx-auto">
<h1 class="text-white display-5 mb-2">{{{ settings.title }}}</h1>
<h6 class="text-light mx-auto">{{{ settings.subtitle }}}</h6>
</div>
<div class="banner-form card mb-0">
<div class="card-body">
<div class="banner-form">
<form class="d-lg-flex" id="tour-search-form" action="{{{ settings.search_page_url }}}" method="get">
<div class="d-flex form-info">
<div class="form-item dropdown">
<div data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" role="menu">
<label class="form-label fs-14 text-default mb-1">Where would like to go?</label>
<input type="text" class="form-control" name="destination" placeholder="Enter destination">
<p class="fs-12 mb-0">Enter destination</p>
</div>
</div>
<div class="form-item">
<label class="form-label fs-14 text-default mb-1">Check In</label>
<input type="text" class="form-control datetimepicker" name="check_in" placeholder="Check-in date">
<p class="fs-12 mb-0">Select date</p>
</div>
<div class="form-item dropdown">
<div data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" role="menu">
<label class="form-label fs-14 text-default mb-1">Duration (Days)</label>
<input type="text" class="form-control" id="durationInput" name="duration" placeholder="Select duration" readonly>
<input type="hidden" id="durationIdInput" name="tour_duration_days">
<p class="fs-12 mb-0">Select duration in days</p>
</div>
</div>
<div class="form-item dropdown w-100">
<div data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" role="menu" class="w-100">
<label class="form-label fs-14 text-default mb-1">Travellers</label>
<h6 class="mb-0"><span class="traveller-count">1</span> <span class="fw-normal fs-14">Persons</span></h6>
<p class="fs-12 mb-0"><span class="adult-count">1</span> Adult</p>
<input type="hidden" name="travellers" id="travellers-input" value="1">
<input type="hidden" name="adults" id="adults-input" value="1">
<input type="hidden" name="children" id="children-input" value="0">
<input type="hidden" name="infants" id="infants-input" value="0">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary search-btn rounded">Search</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
}
}