File: /mnt/data/dreamstour-wp/wp-content/plugins/dreams-tour/templates/page-template-add-tour.php
<?php
/**
* Template Name: Dreams Template Add Tour
*/
if (!is_user_logged_in()) {
wp_redirect(home_url());
exit;
}
$current_user = wp_get_current_user();
if (!in_array('administrator', $current_user->roles) && !in_array('agent', $current_user->roles)) {
wp_redirect(home_url());
exit;
}
$edit_mode = false;
$tour_data = array();
$tour_id = 0;
$booking_allow_customer_dates = function_exists('dreamstour_fl_framework_getoptions') ? dreamstour_fl_framework_getoptions('booking_allow_customer_dates') : false;
if (isset($_GET['post_id']) && !empty($_GET['post_id'])) {
$tour_id = intval($_GET['post_id']);
$tour_post = get_post($tour_id);
if ($tour_post && $tour_post->post_type === 'tour') {
if ((int) $tour_post->post_author !== (int) $current_user->ID) {
wp_redirect(home_url());
exit;
}
$edit_mode = true;
migrate_itenary_images_to_attachments($tour_id);
$tour_data = array(
'post_title' => $tour_post->post_title,
'post_content' => $tour_post->post_content,
'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_price' => get_post_meta($tour_id, 'tour_price', true),
'tour_offer_price' => get_post_meta($tour_id, 'tour_offer_price', true),
'tour_min_age' => get_post_meta($tour_id, 'tour_min_age', 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),
'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_gallery' => get_post_meta($tour_id, 'tour_gallery', true),
);
$tour_data['tour_category'] = wp_get_post_terms($tour_id, 'tour_category', array('fields' => 'ids'));
$tour_data['tour_activities'] = wp_get_post_terms($tour_id, 'tour_activities', array('fields' => 'ids'));
$tour_data['tour_includes'] = wp_get_post_terms($tour_id, 'tour_includes', array('fields' => 'ids'));
$tour_data['tour_excludes'] = wp_get_post_terms($tour_id, 'tour_excludes', array('fields' => 'ids'));
$tour_data['tour_country'] = wp_get_post_terms($tour_id, 'tour_country', array('fields' => 'ids'));
$tour_data['tour_duration_days'] = wp_get_post_terms($tour_id, 'tour_duration_days', array('fields' => 'ids'));
$tour_data['tour_duration_nights'] = wp_get_post_terms($tour_id, 'tour_duration_nights', array('fields' => 'ids'));
$tour_data['tour_why_book'] = wp_get_post_terms($tour_id, 'tour_why_book', array('fields' => 'ids'));
} else {
wp_redirect(home_url());
exit;
}
}
function get_itenary_image_url($image_data)
{
if (empty($image_data)) {
return '';
}
if (is_numeric($image_data)) {
$attachment_id = intval($image_data);
$image_url = wp_get_attachment_image_url($attachment_id, 'medium');
return $image_url ? $image_url : '';
}
if (strpos($image_data, 'data:image/') === 0) {
return $image_data;
}
return '';
}
function handle_base64_image($base64_data, $post_id, $filename_prefix = 'image')
{
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
if (preg_match('/^data:image\/(\w+);base64,/', $base64_data, $type)) {
$base64_data = substr($base64_data, strpos($base64_data, ',') + 1);
$type = strtolower($type[1]);
if (!in_array($type, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
return false;
}
$base64_data = str_replace(' ', '+', $base64_data);
$image_data = base64_decode($base64_data);
if ($image_data === false) {
return false;
}
$upload_dir = wp_upload_dir();
$filename = $filename_prefix . '_' . time() . '.' . $type;
$file_path = $upload_dir['path'] . '/' . $filename;
if (file_put_contents($file_path, $image_data)) {
// Create attachment
$attachment = array(
'post_mime_type' => 'image/' . $type,
'post_title' => sanitize_file_name($filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $file_path, $post_id);
if (!is_wp_error($attach_id)) {
$attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
wp_update_attachment_metadata($attach_id, $attach_data);
return $attach_id;
} else {
}
}
}
return false;
}
function migrate_itenary_images_to_attachments($tour_id)
{
$itenary = get_post_meta($tour_id, 'tour_itenary', true);
if (empty($itenary) || !is_array($itenary)) {
return false;
}
$updated = false;
foreach ($itenary as $key => $item) {
if (!empty($item['image']) && strpos($item['image'], 'data:image/') === 0) {
$attachment_id = handle_base64_image($item['image'], $tour_id, 'itenary_migrated_' . $key);
if ($attachment_id) {
$itenary[$key]['image'] = $attachment_id;
$updated = true;
}
}
}
if ($updated) {
update_post_meta($tour_id, 'tour_itenary', $itenary);
return true;
}
return false;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['tour_nonce']) && wp_verify_nonce($_POST['tour_nonce'], 'save_tour')) {
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
if (function_exists('wp_defer_term_counting')) { wp_defer_term_counting(true); }
$user_id = get_current_user_id();
$is_edit = isset($_POST['edit_tour_id']) && !empty($_POST['edit_tour_id']);
if ($is_edit) {
$tour_id = intval($_POST['edit_tour_id']);
$tour_id = wp_update_post(array(
'ID' => $tour_id,
'post_title' => sanitize_text_field($_POST['tour_name']),
'post_content' => wp_kses_post($_POST['tour_description']),
'post_excerpt' => isset($_POST['tour_description']) ? wp_trim_words(wp_kses_post($_POST['tour_description']), 40, '') : '',
'post_name' => isset($_POST['tour_name']) ? sanitize_title(wp_unslash($_POST['tour_name'])) : '',
));
} else {
$tour_id = wp_insert_post(array(
'post_type' => 'tour',
'post_status' => 'publish',
'post_title' => sanitize_text_field($_POST['tour_name']),
'post_content' => wp_kses_post($_POST['tour_description']),
'post_excerpt' => isset($_POST['tour_description']) ? wp_trim_words(wp_kses_post($_POST['tour_description']), 40, '') : '',
'post_author' => $user_id,
'post_name' => isset($_POST['tour_name']) ? sanitize_title(wp_unslash($_POST['tour_name'])) : '',
'comment_status' => 'closed',
'ping_status' => 'closed',
));
}
if ($tour_id && !is_wp_error($tour_id)) {
$fields = [
'start_date' => 'tour_start_date',
'end_date' => 'tour_end_date',
'destination' => 'tour_destination',
'people_limit' => 'tour_people_limit',
'price' => 'tour_price',
'_price' => 'tour_price',
'_regular_price' => 'tour_price',
'offer_price' => 'tour_offer_price',
'min_age' => 'tour_min_age',
'city' => 'tour_city',
'state' => 'tour_state',
'zip' => 'tour_zip',
'address' => 'tour_address',
'address1' => 'tour_address_1',
];
foreach ($fields as $field => $meta_key) {
if (!empty($_POST[$field])) {
$value = sanitize_text_field($_POST[$field]);
if ($field === 'start_date' || $field === 'end_date') {
$date = DateTime::createFromFormat('d-m-Y', $value);
if ($date instanceof DateTime) {
$value = $date->format('Y-m-d'); // Reformat to YYYY-MM-DD
}
}
update_post_meta($tour_id, $meta_key, $value);
}
}
$start_ts = null;
$end_ts = null;
if (! empty($_POST['start_date']) && ! empty($_POST['end_date'])) {
$start_dt = DateTime::createFromFormat('d/m/Y', sanitize_text_field($_POST['start_date']));
$end_dt = DateTime::createFromFormat('d/m/Y', sanitize_text_field($_POST['end_date']));
if ($start_dt instanceof DateTime && $end_dt instanceof DateTime) {
$start_dt->setTime(0, 0, 0);
$end_dt->setTime(23, 59, 59);
$start_ts = $start_dt->getTimestamp();
$end_ts = $end_dt->getTimestamp();
}
}
if (!empty($_POST['highlights'])) {
update_post_meta($tour_id, 'tour_highlights', array_map('sanitize_text_field', $_POST['highlights']));
}
if (!empty($_POST['itenary_title'])) {
$itenary = [];
$invalid_itenary_dates = [];
foreach ($_POST['itenary_title'] as $i => $title) {
if (!empty($title)) {
$image_id = '';
if (!empty($_POST['itenary_image'][$i])) {
$image_data = $_POST['itenary_image'][$i];
if (is_numeric($image_data)) {
$image_id = intval($image_data);
}
elseif (strpos($image_data, 'data:image/') === 0) {
$image_id = handle_base64_image($image_data, $tour_id, 'itenary_' . $i);
}
elseif (strpos($image_data, wp_upload_dir()['baseurl']) === 0) {
// Extract attachment ID from URL
$attachment_id = attachment_url_to_postid($image_data);
if ($attachment_id) {
$image_id = $attachment_id;
}
} else {
$image_id = intval($image_data);
}
}
$it_date_raw = isset($_POST['itenary_date'][$i]) ? sanitize_text_field($_POST['itenary_date'][$i]) : '';
if ($it_date_raw !== '' && $start_ts && $end_ts) {
$it_dt = DateTime::createFromFormat('d/m/Y', $it_date_raw);
if ($it_dt instanceof DateTime) {
$it_dt->setTime(12, 0, 0);
$it_ts = $it_dt->getTimestamp();
if ($it_ts < $start_ts || $it_ts > $end_ts) {
$invalid_itenary_dates[] = $it_date_raw;
}
}
}
$itenary[] = [
'title' => sanitize_text_field($title),
'date' => $it_date_raw,
'time' => sanitize_text_field($_POST['itenary_time'][$i] ?? ''),
'description' => wp_kses_post($_POST['itenary_description'][$i] ?? ''),
'location' => sanitize_text_field($_POST['itenary_location'][$i] ?? ''),
'lat' => sanitize_text_field($_POST['itenary_lat'][$i] ?? ''),
'lng' => sanitize_text_field($_POST['itenary_lng'][$i] ?? ''),
'image' => $image_id,
];
}
}
// If any invalid itinerary dates were found, stop and show an error
if (! empty($invalid_itenary_dates)) {
wp_die(esc_html__('One or more itinerary dates must be between Start Date and End Date. Invalid dates: ', 'dreams-tour') . esc_html(implode(', ', array_unique($invalid_itenary_dates))), esc_html__('Invalid Itinerary Dates', 'dreams-tour'), ['back_link' => true]);
}
if (!empty($itenary)) {
update_post_meta($tour_id, 'tour_itenary', $itenary);
}
}
// FAQ
if (!empty($_POST['faq_question'])) {
$faq = [];
foreach ($_POST['faq_question'] as $i => $q) {
if (!empty($q)) {
$faq[] = [
'question' => sanitize_text_field($q),
'answer' => sanitize_textarea_field($_POST['faq_answer'][$i] ?? ''),
];
}
}
if (!empty($faq)) {
update_post_meta($tour_id, 'tour_faq', $faq);
}
}
// Taxonomies
$taxonomy_map = [
'category' => 'tour_category',
'activities' => 'tour_activities',
'includes' => 'tour_includes',
'excludes' => 'tour_excludes',
'country' => 'tour_country',
'duration_days' => 'tour_duration_days',
'duration_nights' => 'tour_duration_nights',
'why_book' => 'tour_why_book',
];
foreach ($taxonomy_map as $field => $taxonomy) {
if (!empty($_POST[$field])) {
$terms = is_array($_POST[$field]) ? array_map('intval', $_POST[$field]) : intval($_POST[$field]);
wp_set_object_terms($tour_id, $terms, $taxonomy);
}
}
// Handle gallery deletions first
if (!empty($_POST['delete_gallery_images'])) {
$existing_gallery = get_post_meta($tour_id, 'tour_gallery', true);
if (is_array($existing_gallery)) {
$delete_ids = array_map('intval', $_POST['delete_gallery_images']);
$updated_gallery = array_diff($existing_gallery, $delete_ids);
update_post_meta($tour_id, 'tour_gallery', array_values($updated_gallery));
// Preserve media library attachments; do not delete files
}
}
// Handle gallery images (sync to submitted list: remaining + newly added)
if (array_key_exists('gallery_images', $_POST)) {
$submitted_gallery_ids = array_filter(array_map('intval', (array) $_POST['gallery_images']));
$submitted_gallery_ids = array_values(array_unique($submitted_gallery_ids));
// Persist exact order as submitted (can be an empty array if all removed)
update_post_meta($tour_id, 'tour_gallery', $submitted_gallery_ids);
}
// Create WooCommerce product immediately with fallback
if (function_exists('wc') && class_exists('WC_Product_Simple')) {
$product_id = get_post_meta($tour_id, '_linked_product_id', true);
// Prepare common fields
$product_name = isset($_POST['tour_name']) ? sanitize_text_field($_POST['tour_name']) : get_the_title($tour_id);
$product_description = isset($_POST['tour_description']) ? wp_kses_post($_POST['tour_description']) : get_post_field('post_content', $tour_id);
// Raw values from form
$regular_price_raw = isset($_POST['price']) ? wp_unslash($_POST['price']) : '';
$sale_price_raw = isset($_POST['offer_price']) ? wp_unslash($_POST['offer_price']) : '';
// Normalize prices to handle thousands separators like "1,200" -> "1200"
$regular_price_normalized = str_replace(',', '', $regular_price_raw);
$sale_price_normalized = str_replace(',', '', $sale_price_raw);
$regular_price = is_numeric($regular_price_normalized) ? (string) (float) $regular_price_normalized : '';
$sale_price = is_numeric($sale_price_normalized) && $sale_price_normalized !== '' ? (string) (float) $sale_price_normalized : '';
// Select an image from gallery or featured image
$product_image_id = 0;
$gallery_ids = get_post_meta($tour_id, 'tour_gallery', true);
if (is_array($gallery_ids) && ! empty($gallery_ids)) {
$product_image_id = (int) reset($gallery_ids);
} else {
$thumb_id = get_post_thumbnail_id($tour_id);
if ($thumb_id) {
$product_image_id = (int) $thumb_id;
}
}
if ($product_id && get_post($product_id) instanceof WP_Post) {
// Update existing product
$product = wc_get_product($product_id);
if ($product) {
$product->set_name($product_name);
$product->set_description($product_description);
if ($regular_price !== '') {
$product->set_regular_price($regular_price);
}
if ($sale_price !== '') {
$product->set_sale_price($sale_price);
} else {
$product->set_sale_price('');
}
$product->set_virtual(true);
$product->set_catalog_visibility('visible');
$product->set_status('publish');
if ($product_image_id) {
$product->set_image_id($product_image_id);
}
// Ensure SKU exists and remains tied to tour
if (! $product->get_sku()) {
$product->set_sku('tour-' . $tour_id);
}
$product->save();
}
} else {
// Create new product and link
$product = new WC_Product_Simple();
$product->set_name($product_name);
$product->set_description($product_description);
if ($regular_price !== '') {
$product->set_regular_price($regular_price);
}
if ($sale_price !== '') {
$product->set_sale_price($sale_price);
}
$product->set_virtual(true);
$product->set_catalog_visibility('visible');
$product->set_status('publish');
$product->set_sku('tour-' . $tour_id);
if ($product_image_id) {
$product->set_image_id($product_image_id);
}
$new_product_id = $product->save();
if ($new_product_id) {
update_post_meta($tour_id, '_linked_product_id', (int) $new_product_id);
update_post_meta($new_product_id, '_linked_tour_id', (int) $tour_id);
}
}
}
// Redirect to tour page
if (function_exists('wp_defer_term_counting')) { wp_defer_term_counting(false); }
wp_redirect(get_permalink($tour_id));
exit;
}
}
get_header();
// Enqueue WordPress media scripts for media uploader
wp_enqueue_media();
?>
<!-- Page Wrapper -->
<div class="content">
<div class="container">
<div class="row">
<!-- Sidebar -->
<div class="col-lg-3 theiaStickySidebar">
<div class="card border-0 mb-4 mb-lg-0">
<div class="card-body">
<div>
<h5 class="mb-3"><?php echo $edit_mode ? esc_html__('Edit Tour', 'dreams-tour') : esc_html__('Add Tour', 'dreams-tour'); ?></h5>
<ul class="add-tab-list">
<li><a href="#basic_info" class="active"><?php esc_html_e('Tour Details', 'dreams-tour'); ?></a></li>
<li><a href="#location"><?php esc_html_e('Locations', 'dreams-tour'); ?></a></li>
<li><a href="#highlights"><?php esc_html_e('Highlights', 'dreams-tour'); ?></a></li>
<li><a href="#room_types"><?php esc_html_e('Activities', 'dreams-tour'); ?></a></li>
<li><a href="#popular_amenities"><?php esc_html_e('Includes', 'dreams-tour'); ?></a></li>
<li><a href="#excludes"><?php esc_html_e('Excludes', 'dreams-tour'); ?></a></li>
<li><a href="#itenary"><?php esc_html_e('Itenary', 'dreams-tour'); ?></a></li>
<li><a href="#faq"><?php esc_html_e('FAQ', 'dreams-tour'); ?></a></li>
<li><a href="#gallery"><?php esc_html_e('Gallery', 'dreams-tour'); ?></a></li>
<li><a href="#description"><?php esc_html_e('Description', 'dreams-tour'); ?></a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- /Sidebar -->
<!-- Add Tour -->
<div class="col-lg-9">
<form action="" method="post" enctype="multipart/form-data">
<?php wp_nonce_field('save_tour', 'tour_nonce'); ?>
<?php if ($edit_mode): ?>
<input type="hidden" name="edit_tour_id" value="<?php echo esc_attr($tour_id); ?>" />
<?php endif; ?>
<div class="card shadow-none" id="basic_info">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Tour Details', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body pb-1">
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Tour Name', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="text" class="form-control" name="tour_name" value="<?php echo $edit_mode ? esc_attr($tour_data['post_title']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Category', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<select class="select" name="category" required="">
<option value=""><?php esc_html_e('Select', 'dreams-tour'); ?></option>
<?php
$dt_categories = get_terms(array('taxonomy' => 'tour_category', 'hide_empty' => false));
$selected_category = $edit_mode && !empty($tour_data['tour_category']) ? $tour_data['tour_category'][0] : '';
if (!is_wp_error($dt_categories)) {
foreach ($dt_categories as $dt_cat) {
$selected = ($selected_category == $dt_cat->term_id) ? 'selected' : '';
echo '<option value="' . esc_attr($dt_cat->term_id) . '" ' . $selected . '>' . esc_html($dt_cat->name) . '</option>';
}
}
?>
</select>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Start Date', 'dreams-tour'); ?><?php if (! $booking_allow_customer_dates) : ?><span class="text-danger">*</span><?php endif; ?></label>
<div class="input-icon-end position-relative">
<input type="text" class="form-control <?php if($edit_mode){ ?> datetimepicker_edit <?php } else { ?> datetimepicker <?php } ?>" placeholder="<?php esc_attr_e('dd/mm/yyyy', 'dreams-tour'); ?>" name="start_date" value="<?php echo $edit_mode ? esc_html($tour_data['tour_start_date']) : ''; ?>" <?php echo $booking_allow_customer_dates ? '' : 'required=""'; ?>>
<span class="input-icon-addon">
<i class="isax isax-calendar"></i>
</span>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('End Date', 'dreams-tour'); ?><?php if (! $booking_allow_customer_dates) : ?><span class="text-danger">*</span><?php endif; ?></label>
<div class="input-icon-end position-relative">
<input type="text" class="form-control <?php if($edit_mode){ ?> datetimepicker_edit <?php } else { ?> datetimepicker <?php } ?>" placeholder="<?php esc_attr_e('dd/mm/yyyy', 'dreams-tour'); ?>" name="end_date" value="<?php echo $edit_mode ? esc_html($tour_data['tour_end_date']) : ''; ?>" <?php echo $booking_allow_customer_dates ? '' : 'required=""'; ?>>
<span class="input-icon-addon">
<i class="isax isax-calendar"></i>
</span>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Destination', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="destination" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_destination']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Duration (Days)', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<select class="select" name="duration_days" required="">
<option value=""><?php esc_html_e('Select', 'dreams-tour'); ?></option>
<?php
$dt_days_selected = $edit_mode && !empty($tour_data['tour_duration_days']) ? $tour_data['tour_duration_days'][0] : 0;
$dt_days_terms = get_terms(array(
'taxonomy' => 'tour_duration_days',
'hide_empty' => false
));
if (!is_wp_error($dt_days_terms)) {
// Sort numerically based on the number in the term name
usort($dt_days_terms, function($a, $b) {
preg_match('/\d+/', $a->name, $a_num);
preg_match('/\d+/', $b->name, $b_num);
return (int)$a_num[0] - (int)$b_num[0];
});
foreach ($dt_days_terms as $term) {
echo '<option value="' . esc_attr($term->term_id) . '"' . selected($dt_days_selected, $term->term_id, false) . '>' . esc_html($term->name) . '</option>';
}
}
?>
</select>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Duration (Nights)', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<select class="select" name="duration_nights" required="">
<option value=""><?php esc_html_e('Select', 'dreams-tour'); ?></option>
<?php
$dt_nights_selected = $edit_mode && !empty($tour_data['tour_duration_nights']) ? $tour_data['tour_duration_nights'][0] : 0;
$dt_nights_terms = get_terms(array(
'taxonomy' => 'tour_duration_nights',
'hide_empty' => false
));
if (!is_wp_error($dt_nights_terms)) {
// Sort numerically based on the number in the term name
usort($dt_nights_terms, function($a, $b) {
preg_match('/\d+/', $a->name, $a_num);
preg_match('/\d+/', $b->name, $b_num);
return (int)$a_num[0] - (int)$b_num[0];
});
foreach ($dt_nights_terms as $term) {
echo '<option value="' . esc_attr($term->term_id) . '"' . selected($dt_nights_selected, $term->term_id, false) . '>' . esc_html($term->name) . '</option>';
}
}
?>
</select>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Total Number Of Peoples Alloted', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="people_limit" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_people_limit']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Pricing (USD)', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="price" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_price']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Offer Price (USD)', 'dreams-tour'); ?></label>
<input type="text" class="form-control" name="offer_price" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_offer_price']) : ''; ?>" />
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Min Age', 'dreams-tour'); ?></label>
<input type="text" class="form-control" name="min_age" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_min_age']) : ''; ?>" />
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-none" id="location">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Location', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body pb-1">
<div class="row">
<div class="col-xl-3 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Country', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<select class="select" name="country" required="">
<option value=""><?php esc_html_e('Select', 'dreams-tour'); ?></option>
<?php
$dt_countries = get_terms(array('taxonomy' => 'tour_country', 'hide_empty' => false));
$selected_country = $edit_mode && !empty($tour_data['tour_country']) ? $tour_data['tour_country'][0] : '';
if (!is_wp_error($dt_countries)) {
foreach ($dt_countries as $dt_country) {
$selected = ($selected_country == $dt_country->term_id) ? 'selected' : '';
echo '<option value="' . esc_attr($dt_country->term_id) . '" ' . $selected . '>' . esc_html($dt_country->name) . '</option>';
}
}
?>
</select>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('State', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="text" class="form-control" name="state" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_state']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('City', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="text" class="form-control" name="city" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_city']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Zip Code', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="text" class="form-control" name="zip" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_zip']) : ''; ?>" required=""/>
</div>
</div>
<div class="col-md-12">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Address', 'dreams-tour'); ?><span class="text-danger">*</span></label>
<input type="text" class="form-control" name="address" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_address']) : ''; ?>" />
</div>
</div>
<div class="col-md-12">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Address 1', 'dreams-tour'); ?></label>
<input type="text" class="form-control" name="address1" value="<?php echo $edit_mode ? esc_attr($tour_data['tour_address_1']) : ''; ?>" />
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-none" id="highlights">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Highlights', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body">
<div class="row add-highlight-info">
<?php if ($edit_mode && !empty($tour_data['tour_highlights'])): ?>
<?php foreach ($tour_data['tour_highlights'] as $highlight): ?>
<div class="col-md-12 highlight-info">
<div class="mb-3">
<div class="d-flex align-items-center">
<input type="text" class="form-control me-2" name="highlights[]" value="<?php echo esc_attr($highlight); ?>" placeholder="<?php esc_attr_e('Enter highlight', 'dreams-tour'); ?>">
<a href="javascript:void(0);" class="text-danger trash-icon d-flex align-items-center justify-content-center ms-3 remove-highlight"><i class="isax isax-trash"></i></a>
</div>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="col-md-12">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Highlights', 'dreams-tour'); ?></label>
<input type="text" class="form-control" name="highlights[]" />
</div>
</div>
<?php endif; ?>
</div>
<div>
<a href="javascript:void(0);" class="btn btn-primary btn-sm add-highlight"><i class="isax isax-add-circle me-1"></i><?php esc_html_e('Add New', 'dreams-tour'); ?></a>
</div>
</div>
</div>
<div class="card shadow-none" id="room_types">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Activities', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body pb-1">
<div class="row">
<?php
$dt_activities = get_terms(array('taxonomy' => 'tour_activities', 'hide_empty' => false));
$selected_activities = $edit_mode && !empty($tour_data['tour_activities']) ? $tour_data['tour_activities'] : array();
if (!is_wp_error($dt_activities) && !empty($dt_activities)) {
$chunks = array_chunk($dt_activities, ceil(count($dt_activities) / 3));
foreach ($chunks as $chunk) {
echo '<div class="col-lg-4 col-md-6"><div class="mb-3">';
foreach ($chunk as $term) {
$id = 'activity-' . esc_attr($term->term_id);
$checked = in_array($term->term_id, $selected_activities) ? 'checked' : '';
echo '<div class="form-check d-flex align-items-center ps-0 mb-2">';
echo '<input class="form-check-input ms-0 mt-0" type="checkbox" id="' . $id . '" name="activities[]" value="' . esc_attr($term->term_id) . '" ' . $checked . '>';
echo '<label class="form-check-label ms-2" for="' . $id . '">';
echo esc_html($term->name);
echo '</label></div>';
}
echo '</div></div>';
}
}
?>
</div>
</div>
</div>
<!-- Why Book With Us -->
<div class="card shadow-none" id="why_book_with_us">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Why Book With Us', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body pb-1">
<div class="row">
<?php
$dt_why = get_terms(array('taxonomy' => 'tour_why_book', 'hide_empty' => false));
$selected_why = $edit_mode && !empty($tour_data['tour_why_book']) ? $tour_data['tour_why_book'] : array();
if (!is_wp_error($dt_why) && !empty($dt_why)) {
$chunks = array_chunk($dt_why, ceil(count($dt_why) / 3));
foreach ($chunks as $chunk) {
echo '<div class="col-lg-4 col-md-6"><div class="mb-3">';
foreach ($chunk as $term) {
$id = 'why-' . esc_attr($term->term_id);
$checked = in_array($term->term_id, $selected_why) ? 'checked' : '';
echo '<div class="form-check d-flex align-items-center ps-0 mb-2">';
echo '<input class="form-check-input ms-0 mt-0" type="checkbox" id="' . $id . '" name="why_book[]" value="' . esc_attr($term->term_id) . '" ' . $checked . '>';
echo '<label class="form-check-label ms-2" for="' . $id . '">';
echo esc_html($term->name);
echo '</label></div>';
}
echo '</div></div>';
}
}
?>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="card shadow-none" id="popular_amenities">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Includes', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body pb-1">
<div>
<div class="mb-3">
<?php
$dt_includes = get_terms(array('taxonomy' => 'tour_includes', 'hide_empty' => false));
$selected_includes = $edit_mode && !empty($tour_data['tour_includes']) ? $tour_data['tour_includes'] : array();
if (!is_wp_error($dt_includes)) {
foreach ($dt_includes as $term) {
$id = 'include-' . esc_attr($term->term_id);
$checked = in_array($term->term_id, $selected_includes) ? 'checked' : '';
echo '<div class="form-check d-flex align-items-center ps-0 mb-2">';
echo '<input class="form-check-input ms-0 mt-0" type="checkbox" id="' . $id . '" name="includes[]" value="' . esc_attr($term->term_id) . '" ' . $checked . '>';
echo '<label class="form-check-label ms-2" for="' . $id . '">';
echo esc_html($term->name);
echo '</label></div>';
}
}
?>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card shadow-none" id="excludes">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<h5 class="fs-18"><?php esc_html_e('Excludes', 'dreams-tour'); ?></h5>
</div>
</div>
<div class="card-body pb-1">
<div>
<div class="mb-3">
<?php
$dt_excludes = get_terms(array('taxonomy' => 'tour_excludes', 'hide_empty' => false));
$selected_excludes = $edit_mode && !empty($tour_data['tour_excludes']) ? $tour_data['tour_excludes'] : array();
if (!is_wp_error($dt_excludes)) {
foreach ($dt_excludes as $term) {
$id = 'exclude-' . esc_attr($term->term_id);
$checked = in_array($term->term_id, $selected_excludes) ? 'checked' : '';
echo '<div class="form-check d-flex align-items-center ps-0 mb-2">';
echo '<input class="form-check-input ms-0 mt-0" type="checkbox" id="' . $id . '" name="excludes[]" value="' . esc_attr($term->term_id) . '" ' . $checked . '>';
echo '<label class="form-check-label ms-2" for="' . $id . '">';
echo esc_html($term->name);
echo '</label></div>';
}
}
?>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-none" id="itenary">
<div class="card-header">
<h5 class="fs-18"><?php esc_html_e('Itenary', 'dreams-tour'); ?></h5>
</div>
<div class="card-body ">
<div>
<a href="javascript:void(0);" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#add_itenary">
<i class="isax isax-add-circle me-1"></i><?php esc_html_e('Add New', 'dreams-tour'); ?>
</a>
</div>
<?php
if ($edit_mode && !empty($tour_data['tour_itenary'])) {
foreach ($tour_data['tour_itenary'] as $idx => $itenary_item) {
$title = isset($itenary_item['title']) ? $itenary_item['title'] : '';
$date = isset($itenary_item['date']) ? $itenary_item['date'] : '';
$description = isset($itenary_item['description']) ? $itenary_item['description'] : '';
$image = isset($itenary_item['image']) ? $itenary_item['image'] : '';
echo '<div class="card shadow-none mb-0 mt-3 itenary-item" data-index="' . $idx . '">';
echo '<div class="card-body px-3 py-2">';
echo '<div class="d-flex align-items-start justify-content-between flex-wrap row-gap-3">';
echo '<div class="flex-grow-1">';
echo '<h6><a href="javascript:void(0);">' . esc_html($title) . '</a></h6>';
// Location display if present
$loc = isset($itenary_item['location']) ? trim($itenary_item['location']) : '';
if ($loc !== '') {
echo '<p class="text-muted mb-1 mt-1"><i class="isax isax-location me-1"></i>' . esc_html($loc) . '</p>';
}
if ($date) {
$display_dt = $date;
$display_tm = isset($itenary_item['time']) ? trim($itenary_item['time']) : '';
if ($display_tm !== '') {
$display_dt .= ' ' . $display_tm;
}
echo '<p class="text-muted mb-1 mt-2"><i class="isax isax-calendar me-1"></i>' . esc_html($display_dt) . '</p>';
}
if ($description) {
echo '<p class="mb-2">' . esc_html(wp_trim_words($description, 20, '...')) . '</p>';
}
if ($image) {
$image_url = get_itenary_image_url($image);
if ($image_url) {
echo '<div class="itenary-image-preview mb-2">';
echo '<img src="' . esc_url($image_url) . '" alt="Itinerary Image" style="max-width: 100px; height: auto; border-radius: 4px;">';
echo '</div>';
}
}
echo '</div>';
echo '<div class="d-flex align-items-center">';
echo '<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#edit_itenary" class="rounded-edit d-flex align-items-center justify-content-center me-2 edit-itenary-btn" data-index="' . $idx . '"><i class="isax isax-edit-2"></i></a>';
echo '<a href="javascript:void(0);" class="trash-icon d-flex align-items-center justify-content-center remove-itenary"><i class="isax isax-trash text-danger"></i></a>';
echo '</div></div></div></div>';
echo '<input type="hidden" name="itenary_title[]" value="' . esc_attr($title) . '" />';
echo '<input type="hidden" name="itenary_date[]" value="' . esc_attr($date) . '" />';
$time = isset($itenary_item['time']) ? $itenary_item['time'] : '';
echo '<input type="hidden" name="itenary_time[]" value="' . esc_attr($time) . '" />';
echo '<textarea name="itenary_description[]" style="display:none;">' . esc_textarea($description) . '</textarea>';
$lat = isset($itenary_item['lat']) ? $itenary_item['lat'] : '';
$lng = isset($itenary_item['lng']) ? $itenary_item['lng'] : '';
echo '<input type="hidden" name="itenary_location[]" value="' . esc_attr($loc) . '" />';
echo '<input type="hidden" name="itenary_lat[]" value="' . esc_attr($lat) . '" />';
echo '<input type="hidden" name="itenary_lng[]" value="' . esc_attr($lng) . '" />';
echo '<input type="hidden" name="itenary_image[]" value="' . esc_attr($image) . '" />';
}
} else {
$dt_itenary_titles = isset($_POST['itenary_title']) && is_array($_POST['itenary_title']) ? array_map('sanitize_text_field', $_POST['itenary_title']) : array();
$dt_itenary_dates = isset($_POST['itenary_date']) && is_array($_POST['itenary_date']) ? array_map('sanitize_text_field', $_POST['itenary_date']) : array();
$dt_itenary_times = isset($_POST['itenary_time']) && is_array($_POST['itenary_time']) ? array_map('sanitize_text_field', $_POST['itenary_time']) : array();
$dt_itenary_descriptions = isset($_POST['itenary_description']) && is_array($_POST['itenary_description']) ? array_map('sanitize_textarea_field', $_POST['itenary_description']) : array();
$dt_itenary_locations = isset($_POST['itenary_location']) && is_array($_POST['itenary_location']) ? array_map('sanitize_text_field', $_POST['itenary_location']) : array();
$dt_itenary_lats = isset($_POST['itenary_lat']) && is_array($_POST['itenary_lat']) ? array_map('sanitize_text_field', $_POST['itenary_lat']) : array();
$dt_itenary_lngs = isset($_POST['itenary_lng']) && is_array($_POST['itenary_lng']) ? array_map('sanitize_text_field', $_POST['itenary_lng']) : array();
$dt_itenary_images = isset($_POST['itenary_image']) && is_array($_POST['itenary_image']) ? array_map('sanitize_text_field', $_POST['itenary_image']) : array();
if (!empty($dt_itenary_titles)) {
foreach ($dt_itenary_titles as $idx => $title) {
$date = isset($dt_itenary_dates[$idx]) ? $dt_itenary_dates[$idx] : '';
$description = isset($dt_itenary_descriptions[$idx]) ? $dt_itenary_descriptions[$idx] : '';
$image = isset($dt_itenary_images[$idx]) ? $dt_itenary_images[$idx] : '';
echo '<div class="card shadow-none mb-0 mt-3 itenary-item" data-index="' . $idx . '">';
echo '<div class="card-body px-3 py-2">';
echo '<div class="d-flex align-items-start justify-content-between flex-wrap row-gap-3">';
echo '<div class="flex-grow-1">';
echo '<h6><a href="javascript:void(0);">' . esc_html($title) . '</a></h6>';
$loc = isset($dt_itenary_locations[$idx]) ? trim($dt_itenary_locations[$idx]) : '';
if ($loc !== '') {
echo '<p class="text-muted mb-1 mt-1"><i class="isax isax-location me-1"></i>' . esc_html($loc) . '</p>';
}
if ($date) {
$display_dt = $date;
$display_tm = isset($dt_itenary_times[$idx]) ? trim($dt_itenary_times[$idx]) : '';
if ($display_tm !== '') {
$display_dt .= ' ' . $display_tm;
}
echo '<p class="text-muted mb-1 mt-2"><i class="isax isax-calendar me-1"></i>' . esc_html($display_dt) . '</p>';
}
if ($description) {
echo '<p class="mb-2">' . esc_html(wp_trim_words($description, 20, '...')) . '</p>';
}
if ($image) {
$image_url = get_itenary_image_url($image);
if ($image_url) {
echo '<div class="itenary-image-preview mb-2">';
echo '<img src="' . esc_url($image_url) . '" alt="Itinerary Image" style="max-width: 100px; height: auto; border-radius: 4px;">';
echo '</div>';
}
}
echo '</div>';
echo '<div class="d-flex align-items-center">';
echo '<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#edit_itenary" class="rounded-edit d-flex align-items-center justify-content-center me-2 edit-itenary-btn" data-index="' . $idx . '"><i class="isax isax-edit-2"></i></a>';
echo '<a href="javascript:void(0);" class="trash-icon d-flex align-items-center justify-content-center remove-itenary"><i class="isax isax-trash text-danger"></i></a>';
echo '</div></div></div></div>';
echo '<input type="hidden" name="itenary_title[]" value="' . esc_attr($title) . '" />';
echo '<input type="hidden" name="itenary_date[]" value="' . esc_attr($date) . '" />';
$time = isset($dt_itenary_times[$idx]) ? $dt_itenary_times[$idx] : '';
echo '<input type="hidden" name="itenary_time[]" value="' . esc_attr($time) . '" />';
echo '<textarea name="itenary_description[]" style="display:none;">' . esc_textarea($description) . '</textarea>';
// Hidden location/lat/lng
$lat = isset($dt_itenary_lats[$idx]) ? $dt_itenary_lats[$idx] : '';
$lng = isset($dt_itenary_lngs[$idx]) ? $dt_itenary_lngs[$idx] : '';
echo '<input type="hidden" name="itenary_location[]" value="' . esc_attr($loc) . '" />';
echo '<input type="hidden" name="itenary_lat[]" value="' . esc_attr($lat) . '" />';
echo '<input type="hidden" name="itenary_lng[]" value="' . esc_attr($lng) . '" />';
echo '<input type="hidden" name="itenary_image[]" value="' . esc_attr($image) . '" />';
}
}
}
?>
<div class="itenary_append"></div>
</div>
</div>
<div class="card shadow-none" id="faq">
<div class="card-header">
<h5 class="fs-18"><?php esc_html_e('FAQ', 'dreams-tour'); ?></h5>
</div>
<div class="card-body ">
<div>
<a href="javascript:void(0);" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#add_faq">
<i class="isax isax-add-circle me-1"></i><?php esc_html_e('Add New', 'dreams-tour'); ?>
</a>
</div>
<?php
// Check if we have existing FAQ data from edit mode
if ($edit_mode && !empty($tour_data['tour_faq'])) {
foreach ($tour_data['tour_faq'] as $i => $faq_item) {
$q = isset($faq_item['question']) ? $faq_item['question'] : '';
$a = isset($faq_item['answer']) ? $faq_item['answer'] : '';
if ($q) { ?>
<div class="card shadow-none mb-0 mt-3 faq-item">
<div class="card-body px-3 py-2">
<div class="d-flex align-items-center justify-content-between flex-wrap row-gap-3">
<h6><a href="javascript:void(0);"> <?php echo esc_html($q); ?></a></h6>
<div class="d-flex align-items-center">
<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#edit_faq" class="rounded-edit d-flex align-items-center justify-content-center me-2 edit-faq-btn"><i class="isax isax-edit-2"></i></a>
<a href="javascript:void(0);" class="trash-icon d-flex align-items-center justify-content-center remove-faq"><i class="isax isax-trash text-danger"></i></a>
</div>
</div>
</div>
</div>
<input type="hidden" name="faq_question[]" value="<?php echo esc_attr($q); ?>" />
<textarea name="faq_answer[]" style="display:none;"><?php echo esc_textarea($a); ?></textarea>
<?php }
}
} else {
// Handle POST data for new additions
$dt_faq_q = isset($_POST['faq_question']) && is_array($_POST['faq_question']) ? array_map('sanitize_text_field', $_POST['faq_question']) : array();
$dt_faq_a = isset($_POST['faq_answer']) && is_array($_POST['faq_answer']) ? array_map('sanitize_textarea_field', $_POST['faq_answer']) : array();
if (!empty($dt_faq_q)) {
foreach ($dt_faq_q as $i => $q) {
$a = isset($dt_faq_a[$i]) ? $dt_faq_a[$i] : ''; ?>
<div class="card shadow-none mb-0 mt-3 faq-item">
<div class="card-body px-3 py-2">
<div class="d-flex align-items-center justify-content-between flex-wrap row-gap-3">
<h6><a href="javascript:void(0);"> <?php echo esc_html($q); ?></a></h6>
<div class="d-flex align-items-center">
<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#edit_faq" class="rounded-edit d-flex align-items-center justify-content-center me-2 edit-faq-btn"><i class="isax isax-edit-2"></i></a>
<a href="javascript:void(0);" class="trash-icon d-flex align-items-center justify-content-center remove-faq"><i class="isax isax-trash text-danger"></i></a>
</div>
</div>
</div>
</div>
<input type="hidden" name="faq_question[]" value="<?php echo esc_attr($q); ?>" />
<textarea name="faq_answer[]" style="display:none;"><?php echo esc_textarea($a); ?></textarea>
<?php }
}
}
?>
<div class="faq_append">
</div>
</div>
</div>
<div class="card shadow-none" id="gallery">
<div class="card-header">
<h5 class="fs-18"><?php esc_html_e('Gallery', 'dreams-tour'); ?></h5>
</div>
<div class="card-body">
<div class="gallery-media-uploader mb-3">
<button type="button" class="btn btn-outline-primary" id="gallery_media_uploader">
<i class="isax isax-document-upload me-1"></i><?php esc_html_e('Add Gallery Images', 'dreams-tour'); ?>
</button>
<p class="text-muted mt-2 mb-0"><?php esc_html_e('Select multiple images from your media library', 'dreams-tour'); ?></p>
</div>
<div class="gallery-preview d-flex align-items-center flex-wrap">
<?php if ($edit_mode && !empty($tour_data['tour_gallery'])): ?>
<?php foreach ($tour_data['tour_gallery'] as $image_id): ?>
<?php $image_url = wp_get_attachment_url($image_id); ?>
<?php if ($image_url): ?>
<div class="gallery-upload-img me-2 mb-2 position-relative">
<img src="<?php echo esc_url($image_url); ?>" alt="Gallery Image" style=" object-fit: cover; border-radius: 4px;">
<span class="trash-icon d-flex align-items-center justify-content-center text-danger gallery-trash" data-image-id="<?php echo esc_attr($image_id); ?>"><i class="isax isax-trash"></i></span>
<input type="hidden" name="gallery_images[]" value="<?php echo esc_attr($image_id); ?>">
</div>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<div class="card shadow-none" id="description">
<div class="card-header">
<h5 class="fs-18"><?php esc_html_e('Description', 'dreams-tour'); ?></h5>
</div>
<div class="card-body text-editor">
<?php
$content = $edit_mode ? $tour_data['post_content'] : '';
$editor_id = 'tour_description';
wp_editor(
$content,
$editor_id,
array(
'textarea_name' => 'tour_description',
'media_buttons' => true,
'teeny' => true,
'quicktags' => true,
'textarea_rows' => 8,
)
);
?>
</div>
</div>
<div class="d-flex align-items-center justify-content-center">
<button type="button" class="btn btn-light me-2"><?php esc_html_e('Reset', 'dreams-tour'); ?></button>
<button type="submit" class="btn btn-primary"><?php echo $edit_mode ? esc_html__('Update Tour', 'dreams-tour') : esc_html__('Add New Tour', 'dreams-tour'); ?></button>
</div>
</form>
</div>
<!-- /Add Tour -->
</div>
</div>
</div>
<!-- /Page Wrapper -->
<!-- Add Faq Modal -->
<div class="modal fade" id="add_faq">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5>Add New FAQ</h5>
<button data-bs-dismiss="modal" aria-label="close" class="btn-close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Question', 'dreams-tour'); ?> <span class="text-danger"> *</span></label>
<input type="text" class="form-control" id="faq_question_input">
</div>
<div>
<label class="form-label"><?php esc_html_e('Answer', 'dreams-tour'); ?> <span class="text-danger"> *</span></label>
<textarea class="form-control" id="faq_answer_input" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<div class="d-flex align-items-center justify-content-end m-0">
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-light me-2"><?php esc_html_e('Cancel', 'dreams-tour'); ?></button>
<button type="button" id="add_faq_btn" class="btn btn-sm btn-primary"><?php esc_html_e('Add FAQ', 'dreams-tour'); ?></button>
</div>
</div>
</div>
</div>
</div>
<!-- /Add Faq Modal -->
<!-- Faq Modal -->
<div class="modal fade" id="edit_faq">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5>Edit FAQ</h5>
<button data-bs-dismiss="modal" aria-label="close" class="btn-close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Question', 'dreams-tour'); ?> <span class="text-danger"> *</span></label>
<input type="text" class="form-control" id="edit_faq_question_input" placeholder="<?php esc_attr_e('Enter question', 'dreams-tour'); ?>">
</div>
<div>
<label class="form-label"><?php esc_html_e('Answer', 'dreams-tour'); ?> <span class="text-danger"> *</span></label>
<textarea class="form-control" id="edit_faq_answer_input" rows="3" placeholder="<?php esc_attr_e('Enter answer', 'dreams-tour'); ?>"></textarea>
</div>
</div>
<div class="modal-footer">
<div class="d-flex align-items-center justify-content-end m-0">
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-light me-2"><?php esc_html_e('Cancel', 'dreams-tour'); ?></button>
<button type="button" id="save_faq_btn" class="btn btn-sm btn-primary"><?php esc_html_e('Save FAQ', 'dreams-tour'); ?></button>
</div>
</div>
</div>
</div>
</div>
<!-- /Faq Modal -->
<!-- Add Itenary -->
<div class="modal fade" id="add_itenary">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5><?php esc_html_e('Add New Itenary', 'dreams-tour'); ?></h5>
<button data-bs-dismiss="modal" aria-label="close" class="btn-close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Title', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="itenary_title_input" placeholder="<?php esc_attr_e('Enter itenary title', 'dreams-tour'); ?>" required="">
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Location', 'dreams-tour'); ?></label>
<input type="text" class="form-control" id="itenary_location_input" placeholder="<?php esc_attr_e('Search location', 'dreams-tour'); ?>" required="">
<input type="hidden" id="itenary_lat_input" value="">
<input type="hidden" id="itenary_lng_input" value="">
<div class="mt-2" id="itenary_selected_places"></div>
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Date & Time', 'dreams-tour'); ?></label>
<div class="input-group gap-3">
<div class="input-icon-end position-relative flex-fill">
<input type="text" class="form-control datetimepicker" id="itenary_date_input" placeholder="<?php esc_attr_e('dd/mm/yyyy', 'dreams-tour'); ?>" required="">
<span class="input-icon-addon">
<i class="isax isax-calendar"></i>
</span>
</div>
<div class="input-icon-end position-relative flex-fill">
<input type="text" class="form-control timepicker" id="itenary_time_input" placeholder="<?php esc_attr_e('hh:mm', 'dreams-tour'); ?>" required="">
<span class="input-icon-addon">
<i class="isax isax-calendar"></i>
</span>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Description', 'dreams-tour'); ?></label>
<?php
// Itinerary description editor (add)
wp_editor(
'',
'itenary_description_editor',
array(
'textarea_name' => 'itenary_description_editor',
'media_buttons' => true,
'teeny' => true,
'quicktags' => true,
'textarea_rows' => 6,
)
);
?>
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Image', 'dreams-tour'); ?></label>
<div class="itenary-media-uploader">
<button type="button" class="btn btn-outline-primary itenary-upload-btn" id="itenary_media_uploader">
<i class="isax isax-document-upload me-1"></i><?php esc_html_e('Select Image', 'dreams-tour'); ?>
</button>
<div id="itenary_image_preview" class="mt-2" style="display: none;">
<img id="itenary_preview_img" src="" alt="Preview" style="max-width: 200px; height: auto; border-radius: 4px;">
<button type="button" class="btn btn-sm btn-danger ms-2" id="itenary_remove_image">
<i class="isax isax-trash"></i>
</button>
</div>
<input type="hidden" id="itenary_image_id" value="">
</div>
</div>
</div>
<div class="modal-footer">
<div class="d-flex align-items-center justify-content-end m-0">
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-light me-2"><?php esc_html_e('Cancel', 'dreams-tour'); ?></button>
<button type="button" id="add_itenary_btn" class="btn btn-sm btn-primary"><?php esc_html_e('Add Itenary', 'dreams-tour'); ?></button>
</div>
</div>
</div>
</div>
</div>
<!-- Add Itenary -->
<!-- Edit Itenary -->
<div class="modal fade" id="edit_itenary">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5><?php esc_html_e('Edit Itenary', 'dreams-tour'); ?></h5>
<button data-bs-dismiss="modal" aria-label="close" class="btn-close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Title', 'dreams-tour'); ?> <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="edit_itenary_title_input" placeholder="<?php esc_attr_e('Enter itenary title', 'dreams-tour'); ?>" required="">
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Location', 'dreams-tour'); ?></label>
<input type="text" class="form-control" id="edit_itenary_location_input" placeholder="<?php esc_attr_e('Search location', 'dreams-tour'); ?>" required="">
<input type="hidden" id="edit_itenary_lat_input" value="">
<input type="hidden" id="edit_itenary_lng_input" value="">
<div class="mt-2" id="edit_itenary_selected_places"></div>
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Date & Time', 'dreams-tour'); ?></label>
<div class="input-group gap-3">
<div class="input-icon-end position-relative flex-fill">
<input type="text" class="form-control datetimepicker" id="edit_itenary_date_input" placeholder="<?php esc_attr_e('dd/mm/yyyy', 'dreams-tour'); ?>" required="">
<span class="input-icon-addon">
<i class="isax isax-calendar"></i>
</span>
</div>
<div class="input-icon-end position-relative flex-fill">
<input type="text" class="form-control timepicker" id="edit_itenary_time_input" placeholder="<?php esc_attr_e('hh:mm', 'dreams-tour'); ?>" required="">
<span class="input-icon-addon">
<i class="isax isax-calendar"></i>
</span>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Description', 'dreams-tour'); ?></label>
<?php
// Itinerary description editor (edit)
wp_editor(
'',
'edit_itenary_description_editor',
array(
'textarea_name' => 'edit_itenary_description_editor',
'media_buttons' => true,
'teeny' => true,
'quicktags' => true,
'textarea_rows' => 6,
)
);
?>
</div>
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Image', 'dreams-tour'); ?></label>
<div class="edit-itenary-media-uploader">
<button type="button" class="btn btn-outline-primary edit-itenary-upload-btn" id="edit_itenary_media_uploader">
<i class="isax isax-document-upload me-1"></i><?php esc_html_e('Select Image', 'dreams-tour'); ?>
</button>
<div id="edit_itenary_image_preview" class="mt-2" style="display: none;">
<img id="edit_itenary_preview_img" src="" alt="Preview" style="max-width: 200px; height: auto; border-radius: 4px;">
<button type="button" class="btn btn-sm btn-danger ms-2" id="edit_itenary_remove_image">
<i class="isax isax-trash"></i>
</button>
</div>
<input type="hidden" id="edit_itenary_image_id" value="">
</div>
</div>
</div>
<div class="modal-footer">
<div class="d-flex align-items-center justify-content-end m-0">
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-light me-2"><?php esc_html_e('Cancel', 'dreams-tour'); ?></button>
<button type="button" id="save_itenary_btn" class="btn btn-sm btn-primary"><?php esc_html_e('Save Itenary', 'dreams-tour'); ?></button>
</div>
</div>
</div>
</div>
</div>
<!-- /Edit Itenary -->
<script>
jQuery(document).ready(function($) {
(function initPlacesAutocomplete(){
try {
if (window.google && google.maps && google.maps.places) {
var addInput = document.getElementById('itenary_location_input');
if (addInput) {
var addAutocomplete = new google.maps.places.Autocomplete(addInput, { types: ['geocode'], fields: ['geometry','formatted_address','name'] });
addAutocomplete.addListener('place_changed', function(){
var place = addAutocomplete.getPlace();
if (place && place.geometry && place.geometry.location) {
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
$('#itenary_lat_input').val(lat);
$('#itenary_lng_input').val(lng);
if (place.formatted_address) {
addInput.value = place.formatted_address;
}
}
});
$(addInput).on('keydown', function(e){ if (e.key === 'Enter') { e.preventDefault(); } });
}
var editInput = document.getElementById('edit_itenary_location_input');
if (editInput) {
var editAutocomplete = new google.maps.places.Autocomplete(editInput, { types: ['geocode'], fields: ['geometry','formatted_address','name'] });
editAutocomplete.addListener('place_changed', function(){
var place = editAutocomplete.getPlace();
if (place && place.geometry && place.geometry.location) {
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
$('#edit_itenary_lat_input').val(lat);
$('#edit_itenary_lng_input').val(lng);
if (place.formatted_address) {
editInput.value = place.formatted_address;
}
}
});
$(editInput).on('keydown', function(e){ if (e.key === 'Enter') { e.preventDefault(); } });
}
}
} catch (e) {}
})();
var itenaryUploader;
$('#itenary_media_uploader').on('click', function(e) {
e.preventDefault();
if (itenaryUploader) {
itenaryUploader.open();
return;
}
itenaryUploader = wp.media({
title: 'Select Itinerary Image',
button: {
text: 'Use This Image'
},
multiple: false,
library: {
type: 'image'
}
});
itenaryUploader.on('select', function() {
var attachment = itenaryUploader.state().get('selection').first().toJSON();
$('#itenary_image_id').val(attachment.id);
$('#itenary_preview_img').attr('src', attachment.sizes.medium ? attachment.sizes.medium.url : attachment.url);
$('#itenary_image_preview').show();
});
itenaryUploader.open();
});
$('#itenary_remove_image').on('click', function() {
$('#itenary_image_id').val('');
$('#itenary_image_preview').hide();
$('#itenary_preview_img').attr('src', '');
});
var editItenaryUploader;
$('#edit_itenary_media_uploader').on('click', function(e) {
e.preventDefault();
if (editItenaryUploader) {
editItenaryUploader.open();
return;
}
editItenaryUploader = wp.media({
title: 'Select Itinerary Image',
button: {
text: 'Use This Image'
},
multiple: false,
library: {
type: 'image'
}
});
editItenaryUploader.on('select', function() {
var attachment = editItenaryUploader.state().get('selection').first().toJSON();
$('#edit_itenary_image_id').val(attachment.id);
$('#edit_itenary_preview_img').attr('src', attachment.sizes.medium ? attachment.sizes.medium.url : attachment.url);
$('#edit_itenary_image_preview').show();
});
editItenaryUploader.open();
});
$('#edit_itenary_remove_image').on('click', function() {
$('#edit_itenary_image_id').val('');
$('#edit_itenary_image_preview').hide();
$('#edit_itenary_preview_img').attr('src', '');
});
var galleryUploader;
$('#gallery_media_uploader').on('click', function(e) {
e.preventDefault();
if (galleryUploader) {
galleryUploader.open();
return;
}
galleryUploader = wp.media({
title: 'Select Gallery Images',
button: {
text: 'Add to Gallery'
},
multiple: true,
library: {
type: 'image'
}
});
galleryUploader.on('select', function() {
var attachments = galleryUploader.state().get('selection').toJSON();
$.each(attachments, function(index, attachment) {
var imageUrl = attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
var galleryHtml = '<div class="gallery-upload-img me-2 mb-2 position-relative">' +
'<img src="' + imageUrl + '" alt="Gallery Image" style="width: 100px; height: 100px; object-fit: cover; border-radius: 4px;">' +
'<span class="trash-icon d-flex align-items-center justify-content-center text-danger gallery-trash" data-image-id="' + attachment.id + '"><i class="isax isax-trash"></i></span>' +
'<input type="hidden" name="gallery_images[]" value="' + attachment.id + '">' +
'</div>';
$('.gallery-preview').append(galleryHtml);
});
});
galleryUploader.open();
});
$(document).on('click', '.remove-faq', function(e) {
e.preventDefault();
var item = $(this).closest('.faq-item');
var questionInput = item.nextAll('input[name="faq_question[]"]').first();
var answerInput = item.nextAll('textarea[name="faq_answer[]"]').first();
item.remove();
questionInput.remove();
answerInput.remove();
});
$(document).on('click', '.remove-itenary', function(e) {
e.preventDefault();
var item = $(this).closest('.itenary-item');
var titleInput = item.nextAll('input[name="itenary_title[]"]').first();
var dateInput = item.nextAll('input[name="itenary_date[]"]').first();
var descInput = item.nextAll('textarea[name="itenary_description[]"]').first();
var imageInput = item.nextAll('input[name="itenary_image[]"]').first();
var locInput = item.nextAll('input[name="itenary_location[]"]').first();
var latInput = item.nextAll('input[name="itenary_lat[]"]').first();
var lngInput = item.nextAll('input[name="itenary_lng[]"]').first();
item.remove();
titleInput.remove();
dateInput.remove();
descInput.remove();
imageInput.remove();
locInput.remove();
latInput.remove();
lngInput.remove();
});
$(document).on('click', '.remove-highlight', function(e) {
e.preventDefault();
$(this).closest('.highlight-info').remove();
});
function parseDMY(dateStr) {
if (!dateStr || typeof dateStr !== 'string') return null;
var parts = dateStr.split('/');
if (parts.length !== 3) return null;
var d = parseInt(parts[0], 10);
var m = parseInt(parts[1], 10) - 1;
var y = parseInt(parts[2], 10);
var dt = new Date(y, m, d, 12, 0, 0, 0);
return isNaN(dt.getTime()) ? null : dt;
}
function getStartEndDatesFromForm() {
var startStr = $('input[name="start_date"]').val();
var endStr = $('input[name="end_date"]').val();
var start = parseDMY(startStr);
var end = parseDMY(endStr);
return { start: start, end: end };
}
function isDateWithinRange(dateStr, start, end) {
if (!dateStr) return true;
var dt = parseDMY(dateStr);
if (!dt || !start || !end) return true;
return dt.getTime() >= start.getTime() && dt.getTime() <= (new Date(end.getFullYear(), end.getMonth(), end.getDate(), 23, 59, 59, 999)).getTime();
}
$('#add_faq_btn').on('click', function() {
var question = $('#faq_question_input').val().trim();
var answer = $('#faq_answer_input').val().trim();
if (question && answer) {
var faqHtml = '<div class="card shadow-none mb-0 mt-3 faq-item">' +
'<div class="card-body px-3 py-2">' +
'<div class="d-flex align-items-center justify-content-between flex-wrap row-gap-3">' +
'<h6><a href="javascript:void(0);">' + question + '</a></h6>' +
'<div class="d-flex align-items-center">' +
'<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#edit_faq" class="rounded-edit d-flex align-items-center justify-content-center me-2 edit-faq-btn"><i class="isax isax-edit-2"></i></a>' +
'<a href="javascript:void(0);" class="trash-icon d-flex align-items-center justify-content-center remove-faq"><i class="isax isax-trash text-danger"></i></a>' +
'</div></div></div></div>' +
'<input type="hidden" name="faq_question[]" value="' + question + '" />' +
'<textarea name="faq_answer[]" style="display:none;">' + answer + '</textarea>';
$('#faq .faq_append').append(faqHtml);
$('#faq_question_input').val('');
$('#faq_answer_input').val('');
$('#add_faq').modal('hide');
}
});
function dtGetEditorContent(editorId) {
if (typeof tinyMCE !== 'undefined' && tinyMCE.get(editorId)) {
return tinyMCE.get(editorId).getContent();
}
var $el = jQuery('#' + editorId);
return $el.length ? $el.val() : '';
}
function dtSetEditorContent(editorId, content) {
if (typeof tinyMCE !== 'undefined' && tinyMCE.get(editorId)) {
tinyMCE.get(editorId).setContent(content || '');
}
var $el = jQuery('#' + editorId);
if ($el.length) {
$el.val(content || '');
}
}
$('#add_itenary_btn').on('click', function() {
var title = $('#itenary_title_input').val().trim();
var date = $('#itenary_date_input').val().trim();
var time = $('#itenary_time_input').val().trim();
var description = dtGetEditorContent('itenary_description_editor');
var locationText = $('#itenary_location_input').val().trim();
var latVal = $('#itenary_lat_input').val().trim();
var lngVal = $('#itenary_lng_input').val().trim();
var imageId = $('#itenary_image_id').val();
var imageUrl = $('#itenary_preview_img').attr('src') || '';
if (title) {
var range = getStartEndDatesFromForm();
if (!isDateWithinRange(date, range.start, range.end)) {
alert('Itinerary date must be between Start Date and End Date.');
return;
}
addItineraryItem(title, date, time, description, imageUrl, imageId, locationText, latVal, lngVal);
}
});
function addItineraryItem(title, date, time, description, imageUrl, imageId, locationText, latVal, lngVal) {
var itenaryHtml = '<div class="card shadow-none mb-0 mt-3 itenary-item">' +
'<div class="card-body px-3 py-2">' +
'<div class="d-flex align-items-start justify-content-between flex-wrap row-gap-3">' +
'<div class="flex-grow-1">' +
'<h6><a href="javascript:void(0);">' + title + '</a></h6>';
if (locationText) {
itenaryHtml += '<p class="text-muted mb-1 mt-1"><i class="isax isax-location me-1"></i>' + locationText + '</p>';
}
if (date) {
var displayDT = date;
if (time) {
displayDT += ' ' + time;
}
itenaryHtml += '<p class="text-muted mb-1 mt-2"><i class="isax isax-calendar me-1"></i>' + displayDT + '</p>';
}
if (description) {
itenaryHtml += '<p class="mb-2">' + (description.length > 100 ? description.substring(0, 100) + '...' : description) + '</p>';
}
if (imageUrl) {
itenaryHtml += '<div class="itenary-image-preview mb-2">' +
'<img src="' + imageUrl + '" alt="Itinerary Image" style="max-width: 100px; height: auto; border-radius: 4px;">' +
'</div>';
}
itenaryHtml += '</div>' +
'<div class="d-flex align-items-center">' +
'<a href="javascript:void(0);" data-bs-toggle="modal" data-bs-target="#edit_itenary" class="rounded-edit d-flex align-items-center justify-content-center me-2 edit-itenary-btn"><i class="isax isax-edit-2"></i></a>' +
'<a href="javascript:void(0);" class="trash-icon d-flex align-items-center justify-content-center remove-itenary"><i class="isax isax-trash text-danger"></i></a>' +
'</div></div></div></div>' +
'<input type="hidden" name="itenary_title[]" value="' + title + '" />' +
'<input type="hidden" name="itenary_date[]" value="' + date + '" />' +
'<input type="hidden" name="itenary_time[]" value="' + time + '" />' +
'<textarea name="itenary_description[]" style="display:none;">' + description + '</textarea>' +
'<input type="hidden" name="itenary_location[]" value="' + (locationText || '') + '" />' +
'<input type="hidden" name="itenary_lat[]" value="' + (latVal || '') + '" />' +
'<input type="hidden" name="itenary_lng[]" value="' + (lngVal || '') + '" />' +
'<input type="hidden" name="itenary_image[]" value="' + (imageId || imageUrl) + '" />';
$('#itenary .itenary_append').append(itenaryHtml);
$('#itenary_title_input').val('');
$('#itenary_date_input').val('');
$('#itenary_time_input').val('');
dtSetEditorContent('itenary_description_editor', '');
$('#itenary_location_input').val('');
$('#itenary_lat_input').val('');
$('#itenary_lng_input').val('');
$('#itenary_image_id').val('');
$('#itenary_image_preview').hide();
$('#add_itenary').modal('hide');
}
$(document).on('click', '.edit-faq-btn', function(e) {
e.preventDefault();
var item = $(this).closest('.faq-item');
var question = item.nextAll('input[name="faq_question[]"]').first().val();
var answer = item.nextAll('textarea[name="faq_answer[]"]').first().val();
$('#edit_faq_question_input').val(question || '');
$('#edit_faq_answer_input').val(answer || '');
$('#edit_faq').data('edit-item', item);
});
$('#save_faq_btn').on('click', function() {
var editItem = $('#edit_faq').data('edit-item');
var question = $('#edit_faq_question_input').val().trim();
var answer = $('#edit_faq_answer_input').val().trim();
if (question && editItem) {
updateFAQItem(editItem, question, answer);
}
});
function updateFAQItem(item, question, answer) {
item.find('h6 a').text(question);
var questionInput = item.nextAll('input[name="faq_question[]"]').first();
var answerInput = item.nextAll('textarea[name="faq_answer[]"]').first();
questionInput.val(question);
answerInput.val(answer);
}
$(document).on('click', '.edit-itenary-btn', function(e) {
e.preventDefault();
var item = $(this).closest('.itenary-item');
$('#edit_itenary').data('edit-item', item);
populateEditModal(item);
});
$('#save_itenary_btn').on('click', function() {
var editItem = $('#edit_itenary').data('edit-item');
var title = $('#edit_itenary_title_input').val().trim();
var date = $('#edit_itenary_date_input').val().trim();
var time = $('#edit_itenary_time_input').val().trim();
var description = dtGetEditorContent('edit_itenary_description_editor');
var locationText = $('#edit_itenary_location_input').val().trim();
var latVal = $('#edit_itenary_lat_input').val().trim();
var lngVal = $('#edit_itenary_lng_input').val().trim();
var imageId = $('#edit_itenary_image_id').val();
var imageUrl = $('#edit_itenary_preview_img').attr('src') || '';
if (title && editItem) {
var range = getStartEndDatesFromForm();
if (!isDateWithinRange(date, range.start, range.end)) {
alert('Itinerary date must be between Start Date and End Date.');
return;
}
updateItineraryItem(editItem, title, date, time, description, imageUrl, imageId, locationText, latVal, lngVal);
// Close modal after successful update
$('#edit_itenary').modal('hide');
}
});
function updateItineraryItem(item, title, date, time, description, imageUrl, imageId, locationText, latVal, lngVal) {
item.find('h6 a').text(title);
// Target only the calendar line to avoid duplicating location line
var dateElement = item.find('p.text-muted').filter(function(){ return $(this).find('.isax.isax-calendar').length > 0; });
if (date && date.trim() !== '') {
var displayDT = date;
if (time && time.trim() !== '') {
displayDT += ' ' + time;
}
if (dateElement.length) {
dateElement.html('<i class="isax isax-calendar me-1"></i>' + displayDT);
} else {
item.find('h6').after('<p class="text-muted mb-1 mt-2"><i class="isax isax-calendar me-1"></i>' + displayDT + '</p>');
}
} else if (dateElement.length) {
dateElement.remove();
}
var descElement = item.find('p:not(.text-muted):not(.mb-1)');
if (description && description.trim() !== '') {
var shortDesc = description.length > 100 ? description.substring(0, 100) + '...' : description;
if (descElement.length) {
descElement.text(shortDesc);
} else {
item.find('.flex-grow-1').append('<p class="mb-2">' + shortDesc + '</p>');
}
} else {
descElement.remove();
}
var imagePreview = item.find('.itenary-image-preview');
if (imageUrl && imageUrl.trim() !== '' && imageUrl !== 'undefined') {
if (imagePreview.length) {
imagePreview.find('img').attr('src', imageUrl);
imagePreview.show();
} else {
item.find('.flex-grow-1').append('<div class="itenary-image-preview mb-2"><img src="' + imageUrl + '" alt="Itinerary Image" style="max-width: 100px; height: auto; border-radius: 4px;"></div>');
}
} else {
imagePreview.remove();
}
var locElement = item.find('p.text-muted').filter(function(){ return $(this).find('.isax.isax-location').length > 0; });
if (locationText && locationText.trim() !== '') {
if (locElement.length) {
locElement.html('<i class="isax isax-location me-1"></i>' + locationText);
} else {
item.find('h6').after('<p class="text-muted mb-1 mt-1"><i class="isax isax-location me-1"></i>' + locationText + '</p>');
}
} else {
locElement.remove();
}
var titleInput = item.nextAll('input[name="itenary_title[]"]').first();
var dateInput = item.nextAll('input[name="itenary_date[]"]').first();
var timeInput = item.nextAll('input[name="itenary_time[]"]').first();
var descInput = item.nextAll('textarea[name="itenary_description[]"]').first();
var imageInput = item.nextAll('input[name="itenary_image[]"]').first();
var locationInput = item.nextAll('input[name="itenary_location[]"]').first();
var latInput = item.nextAll('input[name="itenary_lat[]"]').first();
var lngInput = item.nextAll('input[name="itenary_lng[]"]').first();
var currentImageValue = imageInput.val();
var newImageValue = imageId || imageUrl || currentImageValue || '';
titleInput.val(title);
dateInput.val(date);
timeInput.val(time);
descInput.val(description);
imageInput.val(newImageValue);
locationInput.val(locationText || '');
latInput.val(latVal || '');
lngInput.val(lngVal || '');
}
function populateEditModal(item) {
if (!item || !item.length) {
return;
}
var title = item.nextAll('input[name="itenary_title[]"]').first().val();
var date = item.nextAll('input[name="itenary_date[]"]').first().val();
var time = item.nextAll('input[name="itenary_time[]"]').first().val();
var description = item.nextAll('textarea[name="itenary_description[]"]').first().val();
var image = item.nextAll('input[name="itenary_image[]"]').first().val();
var locationText = item.nextAll('input[name="itenary_location[]"]').first().val();
var latVal = item.nextAll('input[name="itenary_lat[]"]').first().val();
var lngVal = item.nextAll('input[name="itenary_lng[]"]').first().val();
// Clear and populate fields
$('#edit_itenary_title_input').val(title || '');
$('#edit_itenary_date_input').val(date || '');
$('#edit_itenary_time_input').val(time || '');
dtSetEditorContent('edit_itenary_description_editor', description || '');
$('#edit_itenary_location_input').val(locationText || '');
$('#edit_itenary_lat_input').val(latVal || '');
$('#edit_itenary_lng_input').val(lngVal || '');
// Handle image - get URL from existing preview or use the stored value
if (image && image !== '' && image !== 'undefined') {
// First, try to get the URL from the existing preview image
var existingPreview = item.find('.itenary-image-preview img');
if (existingPreview.length) {
var existingImageUrl = existingPreview.attr('src');
$('#edit_itenary_preview_img').attr('src', existingImageUrl);
$('#edit_itenary_image_id').val(image);
$('#edit_itenary_image_preview').show();
} else {
// Check if it's a numeric ID (attachment ID)
if (/^\d+$/.test(image)) {
// It's an attachment ID, set the ID and let the user re-select if needed
$('#edit_itenary_image_id').val(image);
$('#edit_itenary_image_preview').hide();
} else {
// It's a URL (legacy or base64)
$('#edit_itenary_preview_img').attr('src', image);
$('#edit_itenary_image_id').val('');
$('#edit_itenary_image_preview').show();
}
}
} else {
$('#edit_itenary_preview_img').attr('src', '');
$('#edit_itenary_image_id').val('');
$('#edit_itenary_image_preview').hide();
}
}
// Clear edit modal when closed
$('#edit_itenary').on('hidden.bs.modal', function() {
// Clear all fields when modal is closed
$('#edit_itenary_title_input').val('');
$('#edit_itenary_date_input').val('');
$('#edit_itenary_time_input').val('');
$('#edit_itenary_description_input').val('');
$('#edit_itenary_image_id').val('');
$('#edit_itenary_image_preview').hide();
$('#edit_itenary_preview_img').attr('src', '');
});
$('#edit_itenary').on('show.bs.modal', function(e) {
var editItem = $('#edit_itenary').data('edit-item');
if (!editItem && !$(e.relatedTarget).hasClass('edit-itenary-btn')) {
$('#edit_itenary_title_input').val('');
$('#edit_itenary_date_input').val('');
$('#edit_itenary_time_input').val('');
$('#edit_itenary_description_input').val('');
$('#edit_itenary_image_id').val('');
$('#edit_itenary_image_preview').hide();
$('#edit_itenary_preview_img').attr('src', '');
}
});
$(document).on('click', '.gallery-trash', function() {
var imageId = $(this).data('image-id');
var imageElement = $(this).parent();
if (imageId) {
var deleteInput = '<input type="hidden" name="delete_gallery_images[]" value="' + imageId + '">';
imageElement.after(deleteInput);
}
imageElement.remove();
});
$('form').on('submit', function(e) {
var range = getStartEndDatesFromForm();
if (!range.start || !range.end) {
return;
}
var invalid = [];
$('input[name="itenary_date[]"]').each(function() {
var val = ($(this).val() || '').trim();
if (val && !isDateWithinRange(val, range.start, range.end)) {
invalid.push(val);
}
});
if (invalid.length) {
alert('One or more itinerary dates are outside the Start/End range. Invalid: ' + Array.from(new Set(invalid)).join(', '));
e.preventDefault();
return false;
}
});
});
</script>
<?php get_footer(); ?>