File: /mnt/data/dreamstour-wp/wp-content/plugins/dreams-tour/templates/single-tour.php
<?php
get_header();
// Get tour meta data (using field names from frontend form)
$tour_id = get_the_ID();
$tour_gallery = get_post_meta($tour_id, 'tour_gallery', true);
$tour_price = get_post_meta($tour_id, 'tour_price', true);
$tour_offer_price = get_post_meta($tour_id, 'tour_offer_price', true);
$tour_start_date = get_post_meta($tour_id, 'tour_start_date', true);
$tour_end_date = get_post_meta($tour_id, 'tour_end_date', true);
$tour_destination = get_post_meta($tour_id, 'tour_destination', true);
$tour_people_limit = get_post_meta($tour_id, 'tour_people_limit', true);
$tour_min_age = get_post_meta($tour_id, 'tour_min_age', true);
$tour_highlights = get_post_meta($tour_id, 'tour_highlights', true);
$tour_itenary = get_post_meta($tour_id, 'tour_itenary', true);
$tour_faq = get_post_meta($tour_id, 'tour_faq', true);
$tour_city = get_post_meta($tour_id, 'tour_city', true);
$tour_state = get_post_meta($tour_id, 'tour_state', true);
$tour_zip = get_post_meta($tour_id, 'tour_zip', true);
$tour_address = get_post_meta($tour_id, 'tour_address', true);
$tour_address_1 = get_post_meta($tour_id, 'tour_address_1', true);
$booking_allow_customer_dates = function_exists('dreamstour_fl_framework_getoptions') ? dreamstour_fl_framework_getoptions('booking_allow_customer_dates') : false;
$booking_allow_guest_booking = function_exists('dreamstour_fl_framework_getoptions') ? dreamstour_fl_framework_getoptions('booking_allow_guest_booking') : false;
// Capacity / seats available calculation
global $wpdb;
$book_table = $wpdb->prefix . 'dreamstour_booking';
// Sum confirmed/paid travellers (adults + children) for this tour
$booked_total = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COALESCE(SUM(adults + children), 0)
FROM {$book_table}
WHERE tour_id = %d
AND (payment_status IN ('paid','completed')
OR booking_status IN ('confirmed','completed'))",
(int) $tour_id
)
);
$capacity = (int) $tour_people_limit;
$seats_left = $capacity > 0 ? max(0, $capacity - $booked_total) : -1; // -1 means unlimited
$is_sold_out = ($capacity > 0 && $seats_left <= 0);
// Get tour reviews
$reviews_args = array(
'post_id' => $tour_id,
'status' => 'approve',
'orderby' => 'comment_date',
'order' => 'DESC'
);
$reviews = get_comments($reviews_args);
// Calculate average rating
$average_rating = 0;
$rating_counts = array(5 => 0, 4 => 0, 3 => 0, 2 => 0, 1 => 0);
if ($reviews) {
$total_ratings = 0;
$rating_count = 0;
foreach ($reviews as $review) {
$rating = get_comment_meta($review->comment_ID, 'rating', true);
if ($rating) {
$total_ratings += intval($rating);
$rating_count++;
// Count ratings for distribution
if (isset($rating_counts[$rating])) {
$rating_counts[$rating]++;
}
}
}
if ($rating_count > 0) {
$average_rating = round($total_ratings / $rating_count, 1);
}
}
// Optional: rating and review count
//$tour_rating = get_post_meta($tour_id, 'tour_rating', true);
//$tour_review_count = get_post_meta($tour_id, 'tour_review_count', true);
// Get tour categories and taxonomies
$tour_categories = get_the_terms($tour_id, 'tour_category');
$tour_activities = get_the_terms($tour_id, 'tour_activities');
$tour_includes = get_the_terms($tour_id, 'tour_includes');
$tour_excludes = get_the_terms($tour_id, 'tour_excludes');
$tour_country = get_the_terms($tour_id, 'tour_country');
$tour_duration_days = get_the_terms($tour_id, 'tour_duration_days');
$tour_duration_nights = get_the_terms($tour_id, 'tour_duration_nights');
// Get featured image
$featured_image = get_the_post_thumbnail_url($tour_id, 'large');
// Normalize and order data by id/index ascending
if (is_array($tour_itenary)) {
// Order by array key ascending (acts like id)
ksort($tour_itenary);
}
if (is_array($tour_faq)) {
ksort($tour_faq);
}
// Check if user is logged in
$current_user = wp_get_current_user();
$user_logged_in = is_user_logged_in();
// Only allow reviews from customers who have a booking for this tour
$can_review = false;
if ($user_logged_in) {
global $wpdb;
$book_table = $wpdb->prefix . 'dreamstour_booking';
// Consider either booking status or payment status that indicates a real purchase
$sql = "SELECT COUNT(*) FROM {$book_table} WHERE user_id = %d AND tour_id = %d AND (payment_status IN ('paid','completed') OR booking_status IN ('confirmed','completed'))";
$count = (int) $wpdb->get_var($wpdb->prepare($sql, get_current_user_id(), (int) $tour_id));
$can_review = $count > 0;
}
$name = $current_user->display_name;
//$role = $current_user->roles[0];
// Check if roles exist and safely get the first one
$role = !empty($current_user->roles) ? $current_user->roles[0] : '';
?>
<!-- Page Wrapper -->
<div class="content">
<div class="container">
<div class="row">
<div class="col-xl-8">
<!-- Slider -->
<div>
<div class="service-wrap mb-4">
<div class="slider-wrap vertical-slider tour-vertical-slide d-flex align-items-center">
<div class="slider-for nav-center" id="large-img">
<?php if ($tour_gallery && is_array($tour_gallery)): ?>
<?php foreach ($tour_gallery as $image_id): ?>
<div class="service-img">
<?php echo wp_get_attachment_image($image_id, 'large', false, array('class' => 'img-fluid', 'alt' => 'Slider Img')); ?>
</div>
<?php endforeach; ?>
<?php elseif ($featured_image): ?>
<div class="service-img">
<img src="<?php echo esc_url($featured_image); ?>" class="img-fluid" alt="Slider Img">
</div>
<?php endif; ?>
</div>
<?php if ($tour_gallery && is_array($tour_gallery)): ?>
<a href="<?php echo wp_get_attachment_url($tour_gallery[0]); ?>" data-fancybox="gallery" class="btn btn-white btn-xs view-btn">
<i class="isax isax-image me-1"></i><?php esc_html_e('See All', 'dreams-tour'); ?>
</a>
<?php endif; ?>
<div class="slider-nav nav-center" id="small-img">
<?php if ($tour_gallery && is_array($tour_gallery)): ?>
<?php foreach ($tour_gallery as $image_id): ?>
<div><?php echo wp_get_attachment_image($image_id, 'thumbnail', false, array('class' => 'img-fluid', 'alt' => 'Slider Img')); ?></div>
<?php endforeach; ?>
<?php elseif ($featured_image): ?>
<div><img src="<?php echo esc_url($featured_image); ?>" class="img-fluid" alt="Slider Img"></div>
<?php endif; ?>
</div>
</div>
</div>
<div class="d-flex align-items-center justify-content-between mb-2">
<div class="mb-2">
<h4 class="mb-1 d-flex align-items-center flex-wrap mb-2">
<?php the_title(); ?>
<span class="badge badge-xs bg-success rounded-pill ms-2">
<i class="isax isax-ticket-star me-1"></i><?php esc_html_e('Verified', 'dreams-tour'); ?>
</span>
</h4>
<div class="d-flex align-items-center flex-wrap">
<?php if ($tour_categories): ?>
<p class="fs-14 mb-2 me-3 pe-3 border-end">
<i class="isax isax-receipt text-primary me-2"></i>
<?php echo esc_html($tour_categories[0]->name); ?>
</p>
<?php endif; ?>
<?php if ($tour_destination): ?>
<p class="fs-14 mb-2 me-3 pe-3 border-end">
<i class="isax isax-location5 me-2"></i><?php echo esc_html($tour_destination); ?>
<a href="#location" class="link-primary text-decoration-underline fw-medium ms-2"><?php esc_html_e('View Location', 'dreams-tour'); ?></a>
</p>
<?php endif; ?>
<div class="d-flex align-items-center mb-2">
<span class="badge badge-warning badge-xs text-gray-9 fs-13 fw-medium me-2">
<?php echo $average_rating ? esc_html($average_rating) : '0.0'; ?>
</span>
<p class="fs-14">
<a href="#reviews">(<?php echo count($reviews); ?> <?php esc_html_e('Reviews', 'dreams-tour'); ?>)</a>
</p>
</div>
</div>
</div>
<div class="d-flex align-items-center mb-3">
<?php $wishlist_active = is_user_logged_in() ? (function_exists('dreamstour_is_in_wishlist') ? dreamstour_is_in_wishlist(get_current_user_id(), $tour_id) : false) : false; ?>
<a href="javascript:void(0);" id="dt-wishlist-btn" data-tour-id="<?php echo (int) $tour_id; ?>" data-tour-title="<?php echo esc_attr(get_the_title($tour_id)); ?>" class="btn btn-outline-light btn-sm d-inline-flex align-items-center <?php echo $wishlist_active ? 'active' : ''; ?>">
<i class="isax isax-heart5 me-1 <?php echo $wishlist_active ? 'text-danger' : 'text-danger'; ?>"></i>
<span class="dt-wishlist-label"><?php echo $wishlist_active ? esc_html__('Saved', 'dreams-tour') : esc_html__('Save', 'dreams-tour'); ?></span>
</a>
</div>
</div>
</div>
<!-- /Slider -->
<!-- Description -->
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Description', 'dreams-tour'); ?></h5>
<div class="mb-2">
<?php the_content(); ?>
</div>
</div>
<!-- /Description -->
<!-- Highlights -->
<?php if ($tour_highlights): ?>
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Highlights', 'dreams-tour'); ?></h5>
<div>
<?php
$highlights = is_array($tour_highlights) ? $tour_highlights : explode("\n", $tour_highlights);
foreach ($highlights as $highlight):
if (trim($highlight)):
?>
<div class="d-flex align-items-center mb-2">
<span class="avatar avatar-md bg-primary-transparent rounded-circle me-2">
<i class="isax isax-send-sqaure-2 fs-16"></i>
</span>
<p><?php echo esc_html(trim($highlight)); ?></p>
</div>
<?php
endif;
endforeach;
?>
</div>
</div>
<?php endif; ?>
<!-- /Highlights -->
<!-- Activities -->
<?php if ($tour_activities && !is_wp_error($tour_activities)): ?>
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Activities', 'dreams-tour'); ?></h5>
<div>
<?php foreach ($tour_activities as $activity): ?>
<div class="d-flex align-items-center mb-2">
<span class="avatar avatar-md bg-primary-transparent rounded-circle me-2">
<i class="isax isax-menu fs-16"></i>
</span>
<p><?php echo esc_html($activity->name); ?></p>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- /Activities -->
<!-- Itinerary -->
<?php if ($tour_itenary): ?>
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Itinerary', 'dreams-tour'); ?></h5>
<div class="card shadow-none mb-0">
<div class="card-body p-3">
<div class="stage-flow">
<?php
$itinerary_items = is_array($tour_itenary) ? $tour_itenary : array();
if ($itinerary_items):
$day_count = 1;
foreach ($itinerary_items as $item):
if (is_array($item) && isset($item['title']) && isset($item['description'])):
?>
<div class="d-flex align-items-center flows-step">
<span class="flow-step"><?php echo str_pad($day_count, 2, '0', STR_PAD_LEFT); ?></span>
<div class="flow-content flex-fill">
<div class="d-flex align-items-center justify-content-between mb-2">
<div>
<h6 class="fw-medium mb-1"><?php if($item['title']) { echo esc_html($item['title']); ?><?php } ?> </h6>
<?php if (isset($item['date']) && $item['date']): ?>
<p><?php echo esc_html($item['date']); ?> <?php echo esc_html($item['time']); ?></p>
<?php endif; ?>
</div>
<?php if (isset($item['image']) && $item['image']): ?>
<span class="avatar avatar-lg avatar-rounded flex-shrink-0">
<?php
// Handle both attachment ID and base64 data
if (is_numeric($item['image'])) {
echo wp_get_attachment_image($item['image'], 'thumbnail', false, array('alt' => 'Img'));
} else {
echo '<img src="' . esc_url($item['image']) . '" alt="Img" style="width: 60px; height: 60px; object-fit: cover; border-radius: 4px;">';
}
?>
</span>
<?php endif; ?>
</div>
<?php if (!empty($item['description'])): ?>
<div class="itinerary-description">
<?php echo wp_kses_post(wpautop($item['description'])); ?>
</div>
<?php endif; ?>
</div>
</div>
<?php
$day_count++;
endif;
endforeach;
endif;
?>
</div>
</div>
</div>
</div>
<?php endif; ?>
<!-- /Itinerary -->
<!-- Includes & Excludes -->
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Includes & Excludes', 'dreams-tour'); ?></h5>
<div class="row gy-2">
<div class="col-md-6">
<h6 class="fw-medium mb-3"><?php esc_html_e('Includes', 'dreams-tour'); ?></h6>
<?php
if ($tour_includes && !is_wp_error($tour_includes)):
foreach ($tour_includes as $include):
?>
<p class="d-flex align-items-center mb-2">
<i class="isax isax-tick-square5 text-success me-2"></i> <?php echo esc_html($include->name); ?>
</p>
<?php
endforeach;
else:
?>
<p class="text-muted"><?php esc_html_e('No includes specified', 'dreams-tour'); ?></p>
<?php endif; ?>
</div>
<div class="col-md-6">
<h6 class="fw-medium mb-3"><?php esc_html_e('Excludes', 'dreams-tour'); ?></h6>
<?php
if ($tour_excludes && !is_wp_error($tour_excludes)):
foreach ($tour_excludes as $exclude):
?>
<p class="d-flex align-items-center mb-2">
<i class="isax isax-close-square5 text-danger me-2"></i> <?php echo esc_html($exclude->name); ?>
</p>
<?php
endforeach;
else:
?>
<p class="text-muted"><?php esc_html_e('No excludes specified', 'dreams-tour'); ?></p>
<?php endif; ?>
</div>
</div>
</div>
<!-- /Includes & Excludes -->
<!-- Gallery -->
<?php if ($tour_gallery && is_array($tour_gallery) && count($tour_gallery) > 1): ?>
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Gallery', 'dreams-tour'); ?></h5>
<div class="tour-gallery-slider owl-carousel">
<?php foreach ($tour_gallery as $image_id): ?>
<a class="galley-wrap" data-fancybox="gallery" href="<?php echo wp_get_attachment_url($image_id); ?>">
<?php echo wp_get_attachment_image($image_id, 'medium', false, array('alt' => 'img')); ?>
</a>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- /Gallery -->
<!-- Location -->
<?php if ($tour_address || $tour_city || $tour_state || $tour_country): ?>
<div class="bg-light-200 card-bg-light mb-4" id="location">
<h5 class="fs-18 mb-3"><?php esc_html_e('Location', 'dreams-tour'); ?></h5>
<div>
<div class="mb-3">
<div class="row">
<?php if ($tour_address): ?>
<div class="col-md-4">
<p><strong><?php esc_html_e('Address', 'dreams-tour'); ?>:</strong> <?php echo esc_html($tour_address); ?></p>
</div>
<?php endif; ?>
<?php if ($tour_address_1): ?>
<div class="col-md-4">
<p><strong><?php esc_html_e('Address 2', 'dreams-tour'); ?>:</strong> <?php echo esc_html($tour_address_1); ?></p>
</div>
<?php endif; ?>
<?php if ($tour_city): ?>
<div class="col-md-4">
<p><strong><?php esc_html_e('City', 'dreams-tour'); ?>:</strong> <?php echo esc_html($tour_city); ?></p>
</div>
<?php endif; ?>
</div>
</div>
<div class="row ">
<?php if ($tour_state): ?>
<div class="col-md-4">
<p><strong><?php esc_html_e('State', 'dreams-tour'); ?>:</strong> <?php echo esc_html($tour_state); ?></p>
</div>
<?php endif; ?>
<?php if ($tour_country && !is_wp_error($tour_country)): ?>
<div class="col-md-4">
<p><strong><?php esc_html_e('Country', 'dreams-tour'); ?>:</strong>
<?php
$country_names = array();
foreach ($tour_country as $country) {
$country_names[] = $country->name;
}
echo esc_html(implode(', ', $country_names));
?>
</p>
</div>
<?php endif; ?>
<?php if ($tour_zip): ?>
<div class="col-md-4">
<p><strong><?php esc_html_e('ZIP', 'dreams-tour'); ?>:</strong> <?php echo esc_html($tour_zip); ?></p>
</div>
<?php endif; ?>
</div>
<!-- Map placeholder - you can integrate with Google Maps API if needed -->
</div>
</div>
<?php endif; ?>
<?php $api_key = dreamstour_fl_framework_getoptions('map_api_key');
if ($api_key) {?>
<div class="bg-light-200 card-bg-light mb-4" id="location">
<h5 class="fs-18 mb-3"><?php esc_html_e('Location', 'dreams-tour'); ?></h5>
<!-- Map -->
<div>
<div id="map_tour"></div>
</div>
<!-- /Map -->
</div>
<?php } ?>
<!-- FAQ -->
<?php if ($tour_faq): ?>
<div class="bg-light-200 card-bg-light mb-4">
<h5 class="fs-18 mb-3"><?php esc_html_e('Frequently Asked Questions', 'dreams-tour'); ?></h5>
<div class="accordion faq-accordion" id="accordionFaq">
<?php
$faq_items = is_array($tour_faq) ? $tour_faq : array();
if ($faq_items):
$faq_count = 0;
foreach ($faq_items as $faq):
if (is_array($faq) && isset($faq['question']) && isset($faq['answer'])):
$faq_count++;
$is_first = $faq_count === 1;
?>
<div class="accordion-item <?php echo $is_first ? 'show' : ''; ?> mb-2">
<div class="accordion-header">
<button class="accordion-button fw-medium <?php echo $is_first ? '' : 'collapsed'; ?>" type="button" data-bs-toggle="collapse" data-bs-target="#faq-collapse<?php echo $faq_count; ?>" aria-expanded="<?php echo $is_first ? 'true' : 'false'; ?>" aria-controls="faq-collapse<?php echo $faq_count; ?>">
<?php echo esc_html($faq['question']); ?>
</button>
</div>
<div id="faq-collapse<?php echo $faq_count; ?>" class="accordion-collapse collapse <?php echo $is_first ? 'show' : ''; ?>" data-bs-parent="#accordionFaq">
<div class="accordion-body">
<p class="mb-0"><?php echo esc_html($faq['answer']); ?></p>
</div>
</div>
</div>
<?php
endif;
endforeach;
endif;
?>
</div>
</div>
<?php endif; ?>
<!-- /FAQ -->
<!-- Reviews -->
<div class="d-flex align-items-center justify-content-between flex-wrap mb-2" id="reviews">
<h5 class="fs-18 mb-3"><?php esc_html_e('Reviews', 'dreams-tour'); ?></h5>
<?php if ($user_logged_in && $can_review): ?>
<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#add_review" class="btn btn-primary btn-md mb-3">
<i class="isax isax-edit-2 me-1"></i><?php esc_html_e('Write a Review', 'dreams-tour'); ?>
</a>
<?php elseif ($user_logged_in && !$can_review): ?>
<span class="text-muted mb-3"><?php esc_html_e('Only customers who booked this tour can write a review.', 'dreams-tour'); ?></span>
<?php else:
if (in_array('redux-framework/redux-framework.php', apply_filters('active_plugins', get_option('active_plugins')), true)) {
$sign_page_id = dreamstour_fl_framework_getoptions('header_login_link');
$sign_page_url = ! empty($sign_page_id) ? get_permalink($sign_page_id) : site_url('/');
}
?>
<a href="<?php echo esc_url($sign_page_url); ?>" class="btn btn-primary btn-md mb-3">
<i class="isax isax-login me-1"></i><?php esc_html_e('Login to Review', 'dreams-tour'); ?>
</a>
<?php endif; ?>
</div>
<div class="row">
<div class="col-md-6 d-flex">
<div class="rating-item bg-light-200 text-center flex-fill mb-3">
<h6 class="fw-medium mb-3"><?php esc_html_e('Customer Reviews & Ratings', 'dreams-tour'); ?></h6>
<h5 class="display-6"><?php echo $average_rating; ?> / 5.0</h5>
<div class="d-inline-flex align-items-center justify-content-center mb-3">
<?php for ($i = 1; $i <= 5; $i++): ?>
<i class="ti ti-star-filled <?php echo $i <= $average_rating ? 'text-primary' : 'text-muted'; ?> <?php echo $i < 5 ? 'me-1' : ''; ?>"></i>
<?php endfor; ?>
</div>
<p><?php printf(esc_html__('Based On %d Reviews', 'dreams-tour'), count($reviews)); ?></p>
</div>
</div>
<div class="col-md-6 d-flex">
<div class="card rating-progress shadow-none flex-fill mb-3">
<div class="card-body">
<?php for ($i = 5; $i >= 1; $i--): ?>
<div class="d-flex align-items-center mb-2">
<div class="d-flex align-items-center me-3">
<span class="fs-14 me-1"><?php echo $i; ?></span>
<i class="ti ti-star-filled text-primary"></i>
</div>
<div class="progress flex-fill">
<div class="progress-bar bg-primary" role="progressbar"
style="width: <?php echo count($reviews) > 0 ? ($rating_counts[$i] / count($reviews)) * 100 : 0; ?>%"
aria-valuenow="<?php echo $rating_counts[$i]; ?>"
aria-valuemin="0"
aria-valuemax="<?php echo count($reviews); ?>">
</div>
</div>
<span class="fs-14 ms-3"><?php echo $rating_counts[$i]; ?></span>
</div>
<?php endfor; ?>
</div>
</div>
</div>
</div>
<!-- Reviews List -->
<div class="reviews-list mt-4">
<?php if ($reviews): ?>
<?php
// Group comments by parent
$reviews_by_parent = [];
foreach ($reviews as $review) {
$reviews_by_parent[$review->comment_parent][] = $review;
}
// Recursive function to render comments
function render_review_list($parent_id, $reviews_by_parent) {
if (empty($reviews_by_parent[$parent_id])) return;
foreach ($reviews_by_parent[$parent_id] as $review):
$rating = get_comment_meta($review->comment_ID, 'rating', true);
$review_images = get_comment_meta($review->comment_ID, 'review_images', true);
$review_images = $review_images ? maybe_unserialize($review_images) : array();
// Avatar
$avatar_url = get_avatar_url(
$review->user_id ? $review->user_id : $review->comment_author_email,
array('size' => 60)
);
?>
<div class="card review-item shadow-none mb-3 ms-<?php echo ($parent_id ? '4' : '0'); ?>">
<div class="card-body p-3">
<div class="review-info">
<div class="d-flex align-items-center justify-content-between flex-wrap">
<div class="d-flex align-items-center mb-2">
<span class="avatar avatar-lg me-2 flex-shrink-0">
<img src="<?php echo esc_url($avatar_url); ?>" class="rounded-circle" alt="User Avatar">
</span>
<div>
<h6 class="fs-16 fw-medium mb-1 text-capitalize"><?php echo esc_html($review->comment_author); ?></h6>
<div class="d-flex align-items-center flex-wrap date-info">
<p class="fs-14 mb-0">
<?php echo human_time_diff(strtotime($review->comment_date), current_time('timestamp')) . ' ago'; ?>
</p>
<?php if ($rating): ?>
<p class="fs-14 d-inline-flex align-items-center mb-0 ms-0">
<span class="badge badge-warning badge-xs text-gray-9 fs-13 fw-medium me-2">
<?php echo esc_html($rating); ?>.0
</span>
</p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<p class="mb-2"><?php echo esc_html($review->comment_content); ?></p>
<?php if (!empty($review_images)): ?>
<div class="d-flex align-items-center flex-wrap">
<?php foreach ($review_images as $image_id): ?>
<div class="avatar avatar-md me-2 mb-2" data-fancybox="review-gallery-<?php echo $review->comment_ID; ?>" href="<?php echo wp_get_attachment_url($image_id); ?>">
<?php echo wp_get_attachment_image($image_id, 'thumbnail', false, array('class' => 'br-10', 'alt' => 'Review Image')); ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php
// Recursive call for child comments
render_review_list($review->comment_ID, $reviews_by_parent);
endforeach;
}
// Render top-level reviews (parent_id = 0)
render_review_list(0, $reviews_by_parent);
?>
<?php else: ?>
<div class="alert alert-info">
<p class="mb-0"><?php esc_html_e('No reviews yet. Be the first to review this tour!', 'dreams-tour'); ?></p>
</div>
<?php endif; ?>
</div>
<!-- /Reviews List -->
<!-- /Reviews -->
</div>
<!-- Tour Sidebar -->
<div class="col-xl-4 theiaStickySidebar">
<!-- Tour Details Card -->
<div class="card bg-light-200">
<div class="card-body">
<h5 class="d-flex align-items-center fs-18 mb-3">
<span class="avatar avatar-md rounded-circle bg-primary me-2">
<i class="isax isax-signpost5"></i>
</span>
<?php esc_html_e('Tour Details', 'dreams-tour'); ?>
</h5>
<div>
<?php if (!$booking_allow_customer_dates): ?>
<?php if ($tour_start_date && $tour_end_date): ?>
<?php
$t_start_date = date_i18n( 'd M Y', strtotime( $tour_start_date ) );
$t_end_date = date_i18n( 'd M Y', strtotime( $tour_end_date ) );
?>
<div class="d-flex align-items-center justify-content-between details-info">
<h6 class="fw-medium"><?php esc_html_e('Date', 'dreams-tour'); ?></h6>
<p class="flex-fill"><?php echo esc_html($t_start_date); ?> - <?php echo esc_html($t_end_date); ?></p>
</div>
<?php endif; ?>
<?php endif; ?>
<?php if ($tour_destination): ?>
<div class="d-flex align-items-center justify-content-between details-info">
<h6 class="fw-medium"><?php esc_html_e('Destination', 'dreams-tour'); ?></h6>
<p class="flex-fill"><?php echo esc_html($tour_destination); ?></p>
</div>
<?php endif; ?>
<?php if ($tour_duration_days || $tour_duration_nights): ?>
<div class="d-flex align-items-center justify-content-between details-info">
<h6 class="fw-medium"><?php esc_html_e('Duration', 'dreams-tour'); ?></h6>
<p class="flex-fill">
<?php
$duration_parts = array();
if ($tour_duration_days && !is_wp_error($tour_duration_days)) {
foreach ($tour_duration_days as $day_term) {
$duration_parts[] = $day_term->name;
}
}
if ($tour_duration_nights && !is_wp_error($tour_duration_nights)) {
foreach ($tour_duration_nights as $night_term) {
$duration_parts[] = $night_term->name;
}
}
echo esc_html(implode(', ', $duration_parts));
?>
</p>
</div>
<?php endif; ?>
<?php if (!$booking_allow_customer_dates): ?>
<?php if ($tour_start_date): ?>
<div class="d-flex align-items-center justify-content-between details-info">
<h6 class="fw-medium"><?php esc_html_e('Start Date', 'dreams-tour'); ?></h6>
<p class="flex-fill"><?php echo esc_html($t_start_date); ?></p>
</div>
<?php endif; ?>
<?php if ($tour_end_date): ?>
<div class="d-flex align-items-center justify-content-between details-info">
<h6 class="fw-medium"><?php esc_html_e('End Date', 'dreams-tour'); ?></h6>
<p class="flex-fill"><?php echo esc_html($t_end_date); ?></p>
</div>
<?php endif; ?>
<?php if ($tour_people_limit): ?>
<div class="d-flex align-items-center justify-content-between details-info">
<h6 class="fw-medium"><?php esc_html_e('Max People', 'dreams-tour'); ?></h6>
<p class="flex-fill"><?php echo esc_html($tour_people_limit); ?></p>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
</div>
<!-- Booking Form -->
<div class="card shadow-none">
<div class="card-body">
<div class="mb-3">
<p class="fs-13 fw-medium mb-1"><?php esc_html_e('Starts From', 'dreams-tour'); ?></p>
<?php
// Determine effective price: use offer price if set and different, otherwise regular price.
$effective_price = $tour_offer_price && $tour_offer_price !== '' ? $tour_offer_price : $tour_price;
?>
<h5 class="text-primary mb-1">
<?php echo get_woocommerce_currency_symbol(); ?><?php echo esc_html($effective_price); ?>
<span class="fs-14 text-default fw-normal"><?php esc_html_e('/ Person', 'dreams-tour'); ?></span>
</h5>
<?php if ($tour_offer_price && $tour_offer_price != $tour_price): ?>
<p class="fs-12 text-muted">
<del><?php echo get_woocommerce_currency_symbol(); ?><?php echo esc_html($tour_price); ?></del>
<span class="text-success"><?php esc_html_e('Special Offer!', 'dreams-tour'); ?></span>
</p>
<?php endif; ?>
</div>
<?php if ($is_sold_out): ?>
<div class="alert alert-danger mb-0 d-flex align-items-center" role="alert">
<i class="isax isax-info-circle me-1"></i>
<?php esc_html_e('No seats available for this tour.', 'dreams-tour'); ?>
</div>
<?php else: ?>
<?php
$prefill_adults = isset($_GET['adults']) ? max(0, (int) $_GET['adults']) : 1;
$prefill_children = isset($_GET['children']) ? max(0, (int) $_GET['children']) : 0;
$login_url = '';
if (!is_user_logged_in()) {
if (in_array('redux-framework/redux-framework.php', apply_filters('active_plugins', get_option('active_plugins')), true)) {
$sign_page_id = dreamstour_fl_framework_getoptions('header_login_link');
$login_url = ! empty($sign_page_id) ? get_permalink($sign_page_id) : wp_login_url(get_permalink());
} else {
$login_url = wp_login_url(get_permalink());
}
}
?>
<div class="banner-form">
<form action="<?php echo admin_url('admin-ajax.php'); ?>" method="post" id="tour-booking-form">
<?php wp_nonce_field('tour_booking_nonce', 'tour_booking_nonce'); ?>
<input type="hidden" name="action" value="process_tour_booking">
<input type="hidden" name="tour_id" value="<?php echo $tour_id; ?>">
<input type="hidden" name="tour_price" value="<?php echo $tour_offer_price ? $tour_offer_price : $tour_price; ?>">
<input type="hidden" name="tour_title" value="<?php echo esc_attr(get_the_title($tour_id)); ?>">
<?php if ($booking_allow_customer_dates): ?>
<?php
// Derive duration days from taxonomy (fallback to fixed dates if needed)
$duration_days = 0;
if (!empty($tour_duration_days) && !is_wp_error($tour_duration_days)) {
$duration_term = reset($tour_duration_days);
if ($duration_term && isset($duration_term->name)) {
// Extract numeric part from term name like "7 Days"
$duration_days = (int) preg_replace('/\D/', '', $duration_term->name);
}
}
// Fallback: calculate from fixed dates if taxonomy not set
if ($duration_days <= 0 && $tour_start_date && $tour_end_date) {
$start = new DateTime($tour_start_date);
$end = new DateTime($tour_end_date);
$duration_days = $start->diff($end)->days + 1;
}
// Default departure to tour start date, enforce future date
$default_departure = $tour_start_date ? date('Y-m-d', strtotime($tour_start_date)) : '';
$today = date('Y-m-d');
$min_date = max($today, $default_departure);
?>
<input type="hidden" name="duration_days" value="<?php echo esc_attr($duration_days); ?>">
<div class="form-info border-0">
<div class="form-item border rounded p-3 mb-3 w-100">
<label class="form-label fs-14 text-default mb-0"><?php esc_html_e('From', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="date" name="departure_date" value="<?php echo esc_attr($default_departure); ?>" min="<?php echo esc_attr($min_date); ?>" class="form-control" required>
</div>
</div>
<input type="hidden" name="return_date" value="">
<script>
(function($){
var $form = $('#tour-booking-form');
var $departure = $form.find('input[name="departure_date"]');
var $return = $form.find('input[name="return_date"]');
var durationDays = <?php echo (int) $duration_days; ?>;
function updateReturnDate() {
if ($departure.val() && durationDays > 0) {
var dep = new Date($departure.val());
dep.setDate(dep.getDate() + durationDays - 1);
var y = dep.getFullYear(), m = String(dep.getMonth() + 1).padStart(2, '0'), d = String(dep.getDate()).padStart(2, '0');
$return.val(y + '-' + m + '-' + d);
}
}
$departure.on('change', updateReturnDate);
updateReturnDate(); // init
})(jQuery);
</script>
<?php else: ?>
<?php
// Derive duration days from taxonomy (fallback to fixed dates if taxonomy not set)
$duration_days = 0;
if (!empty($tour_duration_days) && !is_wp_error($tour_duration_days)) {
$duration_term = reset($tour_duration_days);
if ($duration_term && isset($duration_term->name)) {
// Extract numeric part from term name like "7 Days"
$duration_days = (int) preg_replace('/\D/', '', $duration_term->name);
}
}
// Fallback: calculate from fixed dates if taxonomy not set
if ($duration_days <= 0 && $tour_start_date && $tour_end_date) {
$start = new DateTime($tour_start_date);
$end = new DateTime($tour_end_date);
$duration_days = $start->diff($end)->days + 1;
}
?>
<input type="hidden" name="duration_days" value="<?php echo esc_attr($duration_days); ?>">
<input type="hidden" name="departure_date" value="<?php echo esc_attr($tour_start_date); ?>" class="form-control" readonly>
<input type="hidden" name="return_date" value="<?php echo esc_attr($tour_end_date); ?>" class="form-control" readonly>
<div class="form-info border-0">
<div class="form-item border rounded p-3 mb-3 w-100">
<label class="form-label fs-14 text-default mb-0"><?php esc_html_e('From', 'dreams-tour'); ?></label>
<input type="text" name="departure_date_dis" value="<?php echo esc_attr($t_start_date); ?>" class="form-control" readonly>
</div>
<div class="form-item border rounded p-3 mb-3 w-100">
<label class="form-label fs-14 text-default mb-0"><?php esc_html_e('To', 'dreams-tour'); ?></label>
<input type="text" name="return_date_dis" value="<?php echo esc_attr($t_end_date); ?>" class="form-control" readonly>
</div>
</div>
<?php endif; ?>
<div class="card shadow-none mb-3">
<div class="card-body p-3 pb-0">
<div class="border-bottom pb-2 mb-2">
<h6><?php esc_html_e('Details', 'dreams-tour'); ?></h6>
</div>
<div class="custom-increment">
<div class="mb-3 d-flex align-items-center justify-content-between">
<label class="form-label text-gray-9 mb-0"><?php esc_html_e('Adults', 'dreams-tour'); ?></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" class="input-number" value="<?php echo esc_attr($prefill_adults); ?>" 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="adults">
<span><i class="isax isax-add"></i></span>
</button>
</span>
</div>
</div>
</div>
<div class="mb-3 d-flex align-items-center justify-content-between">
<label class="form-label text-gray-9 mb-0"><?php esc_html_e('Children', 'dreams-tour'); ?> <span class="text-default fw-normal"><?php esc_html_e('( 2-12 Yrs )', 'dreams-tour'); ?></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" class="input-number" value="<?php echo esc_attr($prefill_children); ?>" 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>
<div class="card shadow-none mb-3">
<div class="card-body p-3">
<div class="d-flex align-items-center justify-content-between mb-2">
<span class="text-gray-9"><?php esc_html_e('Adults Price', 'dreams-tour'); ?></span>
<span class="adults-price fw-medium"></span>
</div>
<div class="d-flex align-items-center justify-content-between mb-2 children-price-row">
<span class="text-gray-9"><?php esc_html_e('Children Price', 'dreams-tour'); ?></span>
<span class="children-price fw-medium"></span>
</div>
<div class="d-flex align-items-center justify-content-between border-top pt-2 mt-2">
<span class="text-gray-9 fw-medium"><?php esc_html_e('Total Price', 'dreams-tour'); ?></span>
<span class="total-price fw-semibold"></span>
</div>
</div>
</div>
<?php if (!is_user_logged_in() && ! $booking_allow_guest_booking) : ?>
<a href="<?php echo esc_url($login_url); ?>" class="btn btn-primary btn-lg search-btn ms-0 w-100 fs-14"><?php esc_html_e('Login to Book', 'dreams-tour'); ?></a>
<?php else : ?>
<button type="submit" class="btn btn-primary btn-lg search-btn ms-0 w-100 fs-14"><?php esc_html_e('Book Now', 'dreams-tour'); ?></button>
<?php endif; ?>
<div id="dt-booking-error" class="alert alert-danger d-none mt-2" role="alert"></div>
</form>
</div>
<?php endif; ?>
</div>
</div>
<!-- Why Book With Us -->
<?php
$why_book_terms = get_the_terms($tour_id, 'tour_why_book');
if ($why_book_terms && ! is_wp_error($why_book_terms)) {
?>
<div class="card shadow-none">
<div class="card-body">
<h5 class="fs-18 mb-3"><?php esc_html_e('Why Book With Us', 'dreams-tour'); ?></h5>
<div>
<?php
foreach ($why_book_terms as $index => $term) {
$icon_class = get_term_meta($term->term_id, 'dreamstour-why-book-icon', true);
$icon_class = $icon_class ? $icon_class : 'isax isax-star';
$is_last = ($index === count($why_book_terms) - 1);
?>
<p class="d-flex align-items-center <?php echo $is_last ? 'mb-0' : 'mb-3'; ?>">
<i class="<?php echo esc_attr($icon_class); ?> text-primary me-2"></i>
<?php echo esc_html($term->name); ?>
</p>
<?php
}
?>
</div>
</div>
</div>
<?php } ?>
<!-- Enquire Us -->
<div class="card shadow-none">
<div class="card-body">
<h5 class="fs-18 mb-3"><?php esc_html_e('Enquire Us', 'dreams-tour'); ?></h5>
<div class="banner-form">
<form action="<?php echo admin_url('admin-ajax.php'); ?>" method="post" id="tour-enquiry-form">
<input type="hidden" name="action" value="submit_tour_enquiry">
<input type="hidden" name="tour_id" value="<?php echo $tour_id; ?>">
<?php wp_nonce_field('tour_enquiry_nonce', 'tour_enquiry_nonce'); ?>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Name', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="text" name="enquiry_name" class="form-control">
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Email', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="email" name="enquiry_email" class="form-control">
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Phone', 'dreams-tour'); ?></label>
<input type="text" name="enquiry_phone" class="form-control">
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Message', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<textarea name="enquiry_message" class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary btn-lg search-btn ms-0 w-100 fs-14"><?php esc_html_e('Submit Enquiry', 'dreams-tour'); ?></button>
</form>
</div>
</div>
</div>
<div class="card shadow-none mb-0">
<div class="card-body">
<h5 class="fs-18 mb-3"><?php esc_html_e('Provider Details', 'dreams-tour'); ?></h5>
<div class="py-1 pb-0">
<?php
$author_id = get_post_field('post_author', isset($tour_id) ? $tour_id : get_the_ID());
$author = $author_id ? get_user_by('id', $author_id) : null;
$author_name = $author ? $author->display_name : '';
$author_since = $author ? mysql2date('d M Y', $author->user_registered) : '';
$author_phone = $author_id ? get_user_meta($author_id, 'phone', true) : '';
if (!$author_phone && $author_id) {
$author_phone = get_user_meta($author_id, 'billing_phone', true);
}
$author_email = $author_id ? get_user_meta($author_id, 'contact_email', true) : '';
if (!$author_email && $author) {
$author_email = $author->user_email;
}
$author_avatar = $author ? get_avatar_url($author_id, array('size' => 96)) : '';
// Build Author Tours page link
$author_tours_page = function_exists('dreamstour_fl_framework_getoptions') ? dreamstour_fl_framework_getoptions('author_tours_page') : 0;
$author_tours_page_url = $author_tours_page ? get_permalink($author_tours_page) : '';
$author_url = ($author && $author_tours_page_url) ? add_query_arg('author_id', (int) $author_id, $author_tours_page_url) : 'javascript:void(0);';
?>
<div class="bg-light-500 br-10 mb-3 d-flex align-items-center p-3">
<a href="<?php echo esc_url($author_url); ?>" class="avatar avatar-lg flex-shrink-0">
<?php if ($author_avatar): ?><img src="<?php echo esc_url($author_avatar); ?>" alt="<?php echo esc_attr($author_name); ?>" class="rounded-circle"><?php endif; ?>
</a>
<div class="ms-2 overflow-hidden">
<h6 class="fw-medium text-truncate text-capitalize"><a href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a></h6>
<?php if ($author_since): ?><p class="fs-14"><?php printf(esc_html__('Member Since : %s', 'dreams-tour'), esc_html($author_since)); ?></p><?php endif; ?>
</div>
</div>
<div class="border br-10 mb-0 p-3">
<?php
if ($author_phone): ?>
<div class="d-flex align-items-center border-bottom pb-3 mb-3">
<span class="avatar avatar-sm me-2 rounded-circle flex-shrink-0 bg-primary"><i class="isax isax-call-outgoing5"></i></span>
<p><?php esc_html_e('Call Us', 'dreams-tour'); ?> : <?php echo esc_html($author_phone); ?></p>
</div>
<?php endif; ?>
<?php if ($author_email): ?>
<div class="d-flex align-items-center">
<span class="avatar avatar-sm me-2 rounded-circle flex-shrink-0 bg-primary"><i class="isax isax-message-search5"></i></span>
<p><?php esc_html_e('Email', 'dreams-tour'); ?> : <?php echo esc_html($author_email); ?></p>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<!-- /Tour Sidebar -->
</div>
</div>
</div>
<!-- /Page Wrapper -->
<!-- Review Modal -->
<div class="modal fade" id="add_review">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header d-flex align-items-center justify-content-between">
<h5><?php esc_html_e('Write a Review', 'dreams-tour'); ?></h5>
<a href="javascript:void(0);" data-bs-dismiss="modal" aria-label="Close">
<i class="ti ti-x fs-16"></i>
</a>
</div>
<?php
$current_user = wp_get_current_user();
if (!in_array('regular_user', $current_user->roles) ) {
?>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger my-3" role="alert">
<?php esc_html_e('Only customers who have booked can leave a review.','dreams-tour'); ?>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="d-flex align-items-center justify-content-end m-0">
<button data-bs-dismiss="modal" aria-label="Close" class="btn btn-primary btn-md"><?php esc_html_e('Close', 'dreams-tour'); ?> </button>
</div>
</div>
<?php } else { ?>
<form action="<?php echo admin_url('admin-ajax.php'); ?>" method="post" id="tour-review-form">
<input type="hidden" name="action" value="submit_tour_review">
<input type="hidden" name="tour_id" value="<?php echo $tour_id; ?>">
<?php wp_nonce_field('tour_review_nonce', 'tour_review_nonce'); ?>
<div class="modal-body pb-0">
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Your Rating', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<div class="selection-wrap">
<div class="d-inline-block">
<div class="rating-selction">
<input type="radio" name="rating" value="5" id="rating5">
<label for="rating5"><i class="fa-solid fa-star"></i></label>
<input type="radio" name="rating" value="4" id="rating4">
<label for="rating4"><i class="fa-solid fa-star"></i></label>
<input type="radio" name="rating" value="3" id="rating3">
<label for="rating3"><i class="fa-solid fa-star"></i></label>
<input type="radio" name="rating" value="2" id="rating2">
<label for="rating2"><i class="fa-solid fa-star"></i></label>
<input type="radio" name="rating" value="1" id="rating1">
<label for="rating1"><i class="fa-solid fa-star"></i></label>
</div>
</div>
</div>
</div>
</div>
<?php if (is_user_logged_in()) : ?>
<?php $__cu = wp_get_current_user(); ?>
<input type="hidden" name="reviewer_name" value="<?php echo esc_attr($__cu->display_name); ?>">
<input type="hidden" name="reviewer_email" value="<?php echo esc_attr($__cu->user_email); ?>">
<!-- <div class="col-md-12">
<div class="mb-3">
<p class="mb-0 text-muted"><?php echo sprintf(esc_html__('Logged in as %s', 'dreams-tour'), esc_html($__cu->display_name)); ?></p>
</div>
</div> -->
<?php else : ?>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Name', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="text" name="reviewer_name" class="form-control" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Email', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="email" name="reviewer_email" class="form-control" required>
</div>
</div>
<?php endif; ?>
<div class="col-md-12">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Write Your Review', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<textarea class="form-control" name="review_content" rows="3" required></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="d-flex align-items-center justify-content-end m-0">
<button type="submit" class="btn btn-primary btn-md"><i class="isax isax-edit-2 me-1"></i><?php esc_html_e('Submit Review', 'dreams-tour'); ?> </button>
</div>
</div>
</form>
<?php } ?>
</div>
</div>
</div>
<!-- /Review Modal -->
<?php
// Transform tour itinerary into Google Maps format
$places = [];
if (!empty($tour_itenary)) {
foreach ($tour_itenary as $item) {
$places[] = [
"name" => $item['title'] . ' - ' . $item['location'],
"lat" => floatval($item['lat']),
"lng" => floatval($item['lng']),
];
}
}
// Encode PHP array into JSON for JS
$places_json = json_encode($places);
?>
<?php
// Get favicon (site icon)
$site_icon = get_site_icon_url();
// If no site icon, use fallback image from theme
if (empty($site_icon)) {
$site_icon = get_template_directory_uri() . '/assets/images/favicon.png';
}
?>
<?php
$api_key = dreamstour_fl_framework_getoptions('map_api_key');
if ($api_key) {
?>
<script>
function initMap() {
let places = <?php echo $places_json; ?>;
if (!places.length) return;
// Center map on first place
let map = new google.maps.Map(document.getElementById("map_tour"), {
zoom: 4,
center: { lat: places[0].lat, lng: places[0].lng }
});
// Add markers and info windows
let pathCoordinates = [];
places.forEach(function(place) {
let marker = new google.maps.Marker({
position: { lat: place.lat, lng: place.lng },
map: map,
title: place.name,
icon: {
url: "<?php echo esc_url($site_icon); ?>", // WordPress favicon
scaledSize: new google.maps.Size(32, 32) // adjust size
}
});
let infowindow = new google.maps.InfoWindow({
content: "<b>" + place.name + "</b>"
});
marker.addListener("click", function() {
infowindow.open(map, marker);
});
// Add coordinate to path
pathCoordinates.push({ lat: place.lat, lng: place.lng });
});
// Draw polyline (route)
let tourPath = new google.maps.Polyline({
path: pathCoordinates,
geodesic: true,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 4
});
tourPath.setMap(map);
}
</script>
<?php } ?>
<?php
get_footer();