943 lines
39 KiB
PHP
943 lines
39 KiB
PHP
<?php
|
||
/**
|
||
* Additional fields for Individual Tour
|
||
*/
|
||
|
||
// Registracija meta boxov za Individual Tour
|
||
function register_individual_tour_meta_boxes() {
|
||
add_meta_box(
|
||
'individual_tour_details',
|
||
'Tour Details',
|
||
'render_individual_tour_meta_box',
|
||
'individual_tour',
|
||
'normal',
|
||
'high'
|
||
);
|
||
}
|
||
add_action('add_meta_boxes', 'register_individual_tour_meta_boxes');
|
||
|
||
// Render meta box za Individual Tour
|
||
function render_individual_tour_meta_box($post) {
|
||
$price = get_post_meta($post->ID, '_tour_price', true);
|
||
$duration = get_post_meta($post->ID, '_tour_duration', true);
|
||
$location = get_post_meta($post->ID, '_tour_location', true);
|
||
$experience_journey = get_post_meta($post->ID, '_experience_journey', true);
|
||
$daily_program = get_post_meta($post->ID, '_daily_program', true);
|
||
$included_items = get_post_meta($post->ID, '_included_items', true);
|
||
$not_included_items = get_post_meta($post->ID, '_not_included_items', true);
|
||
$available_extras = get_post_meta($post->ID, '_available_extras', true);
|
||
$day_type_label = get_post_meta($post->ID, '_day_type_label', true);
|
||
$hero_image = get_post_meta($post->ID, '_hero_image', true);
|
||
$guide_image = get_post_meta($post->ID, '_guide_image', true);
|
||
$guide_name = get_post_meta($post->ID, '_guide_name', true);
|
||
$guide_title = get_post_meta($post->ID, '_guide_title', true);
|
||
|
||
if (!is_array($daily_program)) $daily_program = array();
|
||
if (!is_array($included_items)) $included_items = array();
|
||
if (!is_array($not_included_items)) $not_included_items = array();
|
||
if (!is_array($available_extras)) $available_extras = array();
|
||
if (empty($day_type_label)) $day_type_label = 'Day';
|
||
|
||
wp_nonce_field('individual_tour_nonce', 'individual_tour_nonce');
|
||
?>
|
||
<div class="tour-meta-box">
|
||
<style>
|
||
.tour-meta-box {
|
||
max-width: 800px;
|
||
}
|
||
.form-group {
|
||
margin-bottom: 1.5rem;
|
||
background: #fff;
|
||
padding: 1.5rem;
|
||
border-radius: 8px;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||
}
|
||
.form-group label {
|
||
display: block;
|
||
margin-bottom: 0.5rem;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
.form-group input[type="text"],
|
||
.form-group input[type="number"],
|
||
.form-group select,
|
||
.form-group textarea {
|
||
width: 100%;
|
||
padding: 8px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px;
|
||
font-size: 14px;
|
||
}
|
||
.form-group input[type="text"]:focus,
|
||
.form-group input[type="number"]:focus,
|
||
.form-group select:focus,
|
||
.form-group textarea:focus {
|
||
border-color: #00798c;
|
||
outline: none;
|
||
box-shadow: 0 0 0 2px rgba(0,121,140,0.1);
|
||
}
|
||
.daily-program-list {
|
||
margin-top: 1rem;
|
||
}
|
||
.program-day {
|
||
background: #f9f9f9;
|
||
padding: 1.5rem;
|
||
margin-bottom: 1rem;
|
||
border-radius: 8px;
|
||
border: 1px solid #eee;
|
||
}
|
||
.program-day input,
|
||
.program-day textarea {
|
||
width: 100%;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
.items-list {
|
||
margin-top: 1rem;
|
||
}
|
||
.item-row {
|
||
display: flex;
|
||
gap: 1rem;
|
||
margin-bottom: 0.5rem;
|
||
align-items: center;
|
||
}
|
||
.item-row input {
|
||
flex-grow: 1;
|
||
}
|
||
.btn-add {
|
||
background: #00798c;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 16px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
transition: background-color 0.3s ease;
|
||
}
|
||
.btn-add:hover {
|
||
background: #30638e;
|
||
}
|
||
.btn-remove {
|
||
background: #dc3232;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 16px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
transition: background-color 0.3s ease;
|
||
}
|
||
.btn-remove:hover {
|
||
background: #b32d2e;
|
||
}
|
||
.section-title {
|
||
font-size: 1.2rem;
|
||
color: #333;
|
||
margin: 2rem 0 1rem;
|
||
padding-bottom: 0.5rem;
|
||
border-bottom: 2px solid #00798c;
|
||
}
|
||
.guide-section {
|
||
margin: 2rem 0;
|
||
padding: 1.5rem;
|
||
background: #f8f9fa;
|
||
border-radius: 8px;
|
||
border: 1px solid #e9ecef;
|
||
}
|
||
.guide-image-preview {
|
||
max-width: 150px;
|
||
height: 150px;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
margin: 1rem 0;
|
||
border: 3px solid #fff;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
.guide-image-container {
|
||
text-align: center;
|
||
margin-bottom: 1.5rem;
|
||
}
|
||
.guide-details {
|
||
margin-top: 1rem;
|
||
}
|
||
.guide-details input {
|
||
width: 100%;
|
||
padding: 8px;
|
||
margin: 5px 0 15px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px;
|
||
}
|
||
</style>
|
||
|
||
<!-- Basic Tour Details -->
|
||
<h3 class="section-title">Basic Information</h3>
|
||
<div class="form-group">
|
||
<label for="tour_price">Price (€)</label>
|
||
<input type="number" id="tour_price" name="tour_price" step="0.01" value="<?php echo esc_attr($price); ?>" placeholder="Enter tour price">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="tour_duration">Duration (days)</label>
|
||
<input type="number" id="tour_duration" name="tour_duration" value="<?php echo esc_attr($duration); ?>" placeholder="Enter number of days">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="tour_location">Location</label>
|
||
<input type="text" id="tour_location" name="tour_location" value="<?php echo esc_attr($location); ?>" placeholder="Enter tour location">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="experience_journey">Experience Journey</label>
|
||
<select id="experience_journey" name="experience_journey">
|
||
<option value="">Select Experience Journey</option>
|
||
<?php
|
||
$journeys = get_posts(array(
|
||
'post_type' => 'experience_journey',
|
||
'posts_per_page' => -1,
|
||
'orderby' => 'title',
|
||
'order' => 'ASC'
|
||
));
|
||
foreach ($journeys as $journey) {
|
||
printf(
|
||
'<option value="%s" %s>%s</option>',
|
||
esc_attr($journey->ID),
|
||
selected($experience_journey, $journey->ID, false),
|
||
esc_html($journey->post_title)
|
||
);
|
||
}
|
||
?>
|
||
</select>
|
||
<p class="description">Select which Experience Journey this tour belongs to.</p>
|
||
</div>
|
||
|
||
<!-- Hero Image -->
|
||
<h3 class="section-title">Hero Image</h3>
|
||
<div class="form-group">
|
||
<div class="hero-image-upload">
|
||
<?php
|
||
$hero_image_url = wp_get_attachment_image_url($hero_image, 'full');
|
||
?>
|
||
<input type="hidden" name="hero_image" id="hero_image" value="<?php echo esc_attr($hero_image); ?>">
|
||
<div class="hero-image-preview" style="margin-bottom: 1rem;">
|
||
<?php if ($hero_image_url) : ?>
|
||
<img src="<?php echo esc_url($hero_image_url); ?>"
|
||
style="max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"
|
||
class="hero-preview-img">
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="hero-image-buttons">
|
||
<button type="button" class="button upload-hero-image">
|
||
<i class="dashicons dashicons-upload" style="margin-top: 3px;"></i>
|
||
<?php echo $hero_image ? 'Change Hero Image' : 'Upload Hero Image'; ?>
|
||
</button>
|
||
<?php if ($hero_image) : ?>
|
||
<button type="button" class="button remove-hero-image" style="margin-left: 10px;">
|
||
<i class="dashicons dashicons-no" style="margin-top: 3px;"></i>
|
||
Remove Image
|
||
</button>
|
||
<?php endif; ?>
|
||
</div>
|
||
<p class="description" style="margin-top: 0.5rem;">
|
||
Recommended size: 1920x1080px. This image will be displayed at the top of your tour page.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tour Gallery -->
|
||
<h3 class="section-title">Tour Gallery</h3>
|
||
<div class="form-group">
|
||
<div class="gallery-upload">
|
||
<?php
|
||
$gallery_images = get_post_meta($post->ID, '_tour_gallery', true);
|
||
if (!is_array($gallery_images)) {
|
||
$gallery_images = array();
|
||
}
|
||
?>
|
||
<input type="hidden" name="tour_gallery" id="tour_gallery" value="<?php echo esc_attr(implode(',', $gallery_images)); ?>">
|
||
<div class="gallery-preview" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; margin-bottom: 1rem;">
|
||
<?php
|
||
foreach ($gallery_images as $image_id) :
|
||
$image_url = wp_get_attachment_image_url($image_id, 'medium');
|
||
if ($image_url) :
|
||
?>
|
||
<div class="gallery-item" data-id="<?php echo esc_attr($image_id); ?>">
|
||
<img src="<?php echo esc_url($image_url); ?>" style="width: 100%; height: 150px; object-fit: cover; border-radius: 4px;">
|
||
<button type="button" class="remove-gallery-image" style="position: absolute; top: 5px; right: 5px; background: #dc3232; color: white; border: none; border-radius: 50%; width: 25px; height: 25px; cursor: pointer;">×</button>
|
||
</div>
|
||
<?php
|
||
endif;
|
||
endforeach;
|
||
?>
|
||
</div>
|
||
<div class="gallery-buttons">
|
||
<button type="button" class="button upload-gallery-images">
|
||
<i class="dashicons dashicons-images-alt2" style="margin-top: 3px;"></i>
|
||
Add Gallery Images
|
||
</button>
|
||
</div>
|
||
<p class="description" style="margin-top: 0.5rem;">
|
||
Add multiple images to showcase your tour. Recommended size: 1200x800px.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Daily Program -->
|
||
<h3 class="section-title">Daily Program</h3>
|
||
<div class="form-group">
|
||
<label for="day_type_label">Day Type Label</label>
|
||
<input type="text" id="day_type_label" name="day_type_label" value="<?php echo esc_attr($day_type_label); ?>" placeholder="Enter word to use instead of 'Day' (e.g. Activity, Dejavnost, etc.)">
|
||
<p class="description">This label will be displayed before each day number (e.g. "<?php echo esc_html($day_type_label); ?> 1", "<?php echo esc_html($day_type_label); ?> 2", etc.)</p>
|
||
|
||
<div id="daily-program-list" class="daily-program-list">
|
||
<?php foreach ($daily_program as $index => $day) : ?>
|
||
<div class="program-day">
|
||
<input type="text" name="daily_program[<?php echo $index; ?>][title]"
|
||
placeholder="Day Title"
|
||
value="<?php echo esc_attr($day['title']); ?>">
|
||
<textarea name="daily_program[<?php echo $index; ?>][description]"
|
||
rows="3"
|
||
placeholder="Day Description"><?php echo esc_textarea($day['description']); ?></textarea>
|
||
<button type="button" class="btn-remove" onclick="removeDay(this)">Remove Day</button>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<button type="button" class="btn-add" onclick="addDay()">Add Day</button>
|
||
</div>
|
||
|
||
<!-- Included Items -->
|
||
<h3 class="section-title">Included in Price</h3>
|
||
<div class="form-group">
|
||
<div id="included-items-list" class="items-list">
|
||
<?php foreach ($included_items as $index => $item) : ?>
|
||
<div class="item-row">
|
||
<input type="text" name="included_items[]" value="<?php echo esc_attr($item); ?>" placeholder="Enter included item">
|
||
<button type="button" class="btn-remove" onclick="removeItem(this)">Remove</button>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<button type="button" class="btn-add" onclick="addItem('included-items-list', 'included_items[]')">Add Item</button>
|
||
</div>
|
||
|
||
<!-- Not Included Items -->
|
||
<h3 class="section-title">Not Included in Price</h3>
|
||
<div class="form-group">
|
||
<div id="not-included-items-list" class="items-list">
|
||
<?php foreach ($not_included_items as $index => $item) : ?>
|
||
<div class="item-row">
|
||
<input type="text" name="not_included_items[]" value="<?php echo esc_attr($item); ?>" placeholder="Enter not included item">
|
||
<button type="button" class="btn-remove" onclick="removeItem(this)">Remove</button>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<button type="button" class="btn-add" onclick="addItem('not-included-items-list', 'not_included_items[]')">Add Item</button>
|
||
</div>
|
||
|
||
<!-- Available Extras -->
|
||
<h3 class="section-title">Available Extras</h3>
|
||
<div class="form-group">
|
||
<div id="available-extras-list" class="items-list">
|
||
<?php foreach ($available_extras as $index => $extra) : ?>
|
||
<div class="item-row">
|
||
<input type="text" name="available_extras[<?php echo $index; ?>][name]" value="<?php echo esc_attr($extra['name']); ?>" placeholder="Enter extra name" style="flex: 2;">
|
||
<input type="number" name="available_extras[<?php echo $index; ?>][price]" value="<?php echo esc_attr($extra['price']); ?>" placeholder="Price" step="0.01" style="flex: 1;">
|
||
<label style="margin-left: 10px; display: flex; align-items: center; white-space: nowrap;">
|
||
<input type="checkbox" name="available_extras[<?php echo $index; ?>][per_day_per_person]" <?php checked(!empty($extra['per_day_per_person']), true); ?>>
|
||
<span style="margin-left: 5px;">Per day per person</span>
|
||
</label>
|
||
<button type="button" class="btn-remove" onclick="removeExtra(this)">Remove</button>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<button type="button" class="btn-add" onclick="addExtra()">Add Extra</button>
|
||
<p class="description" style="margin-top: 10px;">
|
||
Check "Per day per person" for extras where the price should be multiplied by both the number of days and participants (e.g. bike rental at €20/day/person for an 8-day tour with 3 participants would cost €480).
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Guide Information -->
|
||
<h3 class="section-title">Guide Information</h3>
|
||
<div class="guide-section">
|
||
<div class="guide-image-container">
|
||
<div class="image-preview-wrapper">
|
||
<?php if ($guide_image) : ?>
|
||
<img src="<?php echo esc_url($guide_image); ?>" alt="Guide" class="guide-image-preview">
|
||
<?php endif; ?>
|
||
</div>
|
||
<input type="hidden" name="guide_image" id="guide_image" value="<?php echo esc_attr($guide_image); ?>">
|
||
<button type="button" class="button guide-image-upload">Select Guide Image</button>
|
||
<button type="button" class="button guide-image-remove" <?php echo empty($guide_image) ? 'style="display:none;"' : ''; ?>>Remove Image</button>
|
||
</div>
|
||
|
||
<div class="guide-details">
|
||
<label for="guide_name">Guide Name</label>
|
||
<input type="text" id="guide_name" name="guide_name" value="<?php echo esc_attr($guide_name); ?>" placeholder="Enter guide's name">
|
||
|
||
<label for="guide_title">Guide Title/Role</label>
|
||
<input type="text" id="guide_title" name="guide_title" value="<?php echo esc_attr($guide_title); ?>" placeholder="e.g. Travel Expert">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- FAQ Section -->
|
||
<h3 class="section-title">FAQ - Frequently Asked Questions</h3>
|
||
<div class="form-group">
|
||
<div id="faq-list" class="items-list">
|
||
<?php
|
||
$faqs = get_post_meta($post->ID, '_tour_faqs', true);
|
||
if (!is_array($faqs)) $faqs = array();
|
||
foreach ($faqs as $index => $faq) :
|
||
?>
|
||
<div class="faq-item" style="background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 15px;">
|
||
<input type="text"
|
||
name="tour_faqs[<?php echo $index; ?>][question]"
|
||
value="<?php echo esc_attr($faq['question']); ?>"
|
||
placeholder="Question"
|
||
style="margin-bottom: 10px;">
|
||
<textarea name="tour_faqs[<?php echo $index; ?>][answer]"
|
||
rows="3"
|
||
placeholder="Answer"
|
||
style="width: 100%; margin-bottom: 10px;"><?php echo esc_textarea($faq['answer']); ?></textarea>
|
||
<button type="button" class="btn-remove" onclick="removeFaq(this)">Remove Question</button>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<button type="button" class="btn-add" onclick="addFaq()">Add New Question</button>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// Experience Journey Dropdown
|
||
const experienceJourney = document.getElementById('experience_journey');
|
||
if (experienceJourney) {
|
||
let isOpen = false;
|
||
|
||
experienceJourney.addEventListener('mousedown', function(e) {
|
||
if (!isOpen) {
|
||
isOpen = true;
|
||
} else {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
this.blur();
|
||
isOpen = false;
|
||
}
|
||
});
|
||
|
||
experienceJourney.addEventListener('change', function(e) {
|
||
isOpen = false;
|
||
this.blur();
|
||
});
|
||
|
||
experienceJourney.addEventListener('blur', function(e) {
|
||
isOpen = false;
|
||
});
|
||
|
||
// Prepreči odpiranje ob kliku izven dropdown-a
|
||
document.addEventListener('click', function(e) {
|
||
if (!experienceJourney.contains(e.target)) {
|
||
isOpen = false;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Hero Image Upload
|
||
const heroImageUpload = document.querySelector('.upload-hero-image');
|
||
const heroImageRemove = document.querySelector('.remove-hero-image');
|
||
const heroImageInput = document.getElementById('hero_image');
|
||
const heroPreviewContainer = document.querySelector('.hero-image-preview');
|
||
|
||
if (heroImageUpload) {
|
||
heroImageUpload.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
|
||
const frame = wp.media({
|
||
title: 'Select or Upload Hero Image',
|
||
button: {
|
||
text: 'Use this image'
|
||
},
|
||
multiple: false
|
||
});
|
||
|
||
frame.on('select', function() {
|
||
const attachment = frame.state().get('selection').first().toJSON();
|
||
heroImageInput.value = attachment.id;
|
||
|
||
// Update preview
|
||
heroPreviewContainer.innerHTML = `
|
||
<img src="${attachment.url}"
|
||
style="max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"
|
||
class="hero-preview-img">
|
||
`;
|
||
|
||
// Show remove button if it doesn't exist
|
||
if (!document.querySelector('.remove-hero-image')) {
|
||
const removeButton = document.createElement('button');
|
||
removeButton.type = 'button';
|
||
removeButton.className = 'button remove-hero-image';
|
||
removeButton.style.marginLeft = '10px';
|
||
removeButton.innerHTML = '<i class="dashicons dashicons-no" style="margin-top: 3px;"></i> Remove Image';
|
||
document.querySelector('.hero-image-buttons').appendChild(removeButton);
|
||
|
||
// Add event listener to new remove button
|
||
removeButton.addEventListener('click', removeHeroImage);
|
||
}
|
||
|
||
// Update upload button text
|
||
heroImageUpload.innerHTML = '<i class="dashicons dashicons-upload" style="margin-top: 3px;"></i> Change Hero Image';
|
||
});
|
||
|
||
frame.open();
|
||
});
|
||
}
|
||
|
||
function removeHeroImage() {
|
||
heroImageInput.value = '';
|
||
heroPreviewContainer.innerHTML = '';
|
||
this.remove();
|
||
heroImageUpload.innerHTML = '<i class="dashicons dashicons-upload" style="margin-top: 3px;"></i> Upload Hero Image';
|
||
}
|
||
|
||
if (heroImageRemove) {
|
||
heroImageRemove.addEventListener('click', removeHeroImage);
|
||
}
|
||
|
||
// Gallery Images Upload
|
||
const galleryUpload = document.querySelector('.upload-gallery-images');
|
||
const galleryInput = document.getElementById('tour_gallery');
|
||
const galleryPreview = document.querySelector('.gallery-preview');
|
||
|
||
if (galleryUpload) {
|
||
galleryUpload.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
|
||
const frame = wp.media({
|
||
title: 'Select Gallery Images',
|
||
button: {
|
||
text: 'Add to gallery'
|
||
},
|
||
multiple: true
|
||
});
|
||
|
||
frame.on('select', function() {
|
||
const attachments = frame.state().get('selection').toJSON();
|
||
const currentImages = galleryInput.value ? galleryInput.value.split(',') : [];
|
||
|
||
attachments.forEach(attachment => {
|
||
if (!currentImages.includes(attachment.id.toString())) {
|
||
currentImages.push(attachment.id);
|
||
|
||
const galleryItem = document.createElement('div');
|
||
galleryItem.className = 'gallery-item';
|
||
galleryItem.dataset.id = attachment.id;
|
||
galleryItem.style.position = 'relative';
|
||
|
||
galleryItem.innerHTML = `
|
||
<img src="${attachment.url}" style="width: 100%; height: 150px; object-fit: cover; border-radius: 4px;">
|
||
<button type="button" class="remove-gallery-image" style="position: absolute; top: 5px; right: 5px; background: #dc3232; color: white; border: none; border-radius: 50%; width: 25px; height: 25px; cursor: pointer;">×</button>
|
||
`;
|
||
|
||
galleryPreview.appendChild(galleryItem);
|
||
}
|
||
});
|
||
|
||
galleryInput.value = currentImages.join(',');
|
||
});
|
||
|
||
frame.open();
|
||
});
|
||
}
|
||
|
||
// Remove gallery image
|
||
document.addEventListener('click', function(e) {
|
||
if (e.target.classList.contains('remove-gallery-image')) {
|
||
const galleryItem = e.target.closest('.gallery-item');
|
||
const imageId = galleryItem.dataset.id;
|
||
const currentImages = galleryInput.value.split(',');
|
||
const updatedImages = currentImages.filter(id => id !== imageId);
|
||
|
||
galleryInput.value = updatedImages.join(',');
|
||
galleryItem.remove();
|
||
}
|
||
});
|
||
|
||
// Guide Image Upload
|
||
jQuery(document).ready(function($) {
|
||
$('.guide-image-upload').click(function(e) {
|
||
e.preventDefault();
|
||
|
||
var button = $(this);
|
||
var imageField = $('#guide_image');
|
||
var previewWrapper = $('.guide-image-container .image-preview-wrapper');
|
||
var removeButton = $('.guide-image-remove');
|
||
|
||
var frame = wp.media({
|
||
title: 'Select Guide Image',
|
||
button: {
|
||
text: 'Use this image'
|
||
},
|
||
library: {
|
||
type: 'image'
|
||
},
|
||
multiple: false
|
||
});
|
||
|
||
frame.on('select', function() {
|
||
var attachment = frame.state().get('selection').first().toJSON();
|
||
imageField.val(attachment.url);
|
||
previewWrapper.html('<img src="' + attachment.url + '" alt="Guide" class="guide-image-preview">');
|
||
removeButton.show();
|
||
});
|
||
|
||
frame.open();
|
||
});
|
||
|
||
// Remove Guide Image
|
||
$('.guide-image-remove').click(function() {
|
||
$('#guide_image').val('');
|
||
$('.guide-image-container .image-preview-wrapper').empty();
|
||
$(this).hide();
|
||
});
|
||
});
|
||
});
|
||
|
||
function addDay() {
|
||
const list = document.getElementById('daily-program-list');
|
||
const index = list.children.length;
|
||
const day = document.createElement('div');
|
||
day.className = 'program-day';
|
||
day.innerHTML = `
|
||
<input type="text" name="daily_program[${index}][title]" placeholder="Day Title">
|
||
<textarea name="daily_program[${index}][description]" rows="3" placeholder="Day Description"></textarea>
|
||
<button type="button" class="btn-remove" onclick="removeDay(this)">Remove Day</button>
|
||
`;
|
||
list.appendChild(day);
|
||
}
|
||
|
||
function removeDay(button) {
|
||
button.parentElement.remove();
|
||
reindexDays();
|
||
}
|
||
|
||
function reindexDays() {
|
||
const days = document.querySelectorAll('#daily-program-list .program-day');
|
||
days.forEach((day, index) => {
|
||
day.querySelector('input').name = `daily_program[${index}][title]`;
|
||
day.querySelector('textarea').name = `daily_program[${index}][description]`;
|
||
});
|
||
}
|
||
|
||
function addItem(listId, inputName) {
|
||
const list = document.getElementById(listId);
|
||
const row = document.createElement('div');
|
||
row.className = 'item-row';
|
||
row.innerHTML = `
|
||
<input type="text" name="${inputName}" placeholder="Enter item">
|
||
<button type="button" class="btn-remove" onclick="removeItem(this)">Remove</button>
|
||
`;
|
||
list.appendChild(row);
|
||
}
|
||
|
||
function removeItem(button) {
|
||
button.parentElement.remove();
|
||
}
|
||
|
||
function addExtra() {
|
||
const list = document.getElementById('available-extras-list');
|
||
const index = list.children.length;
|
||
const row = document.createElement('div');
|
||
row.className = 'item-row';
|
||
row.innerHTML = `
|
||
<input type="text" name="available_extras[${index}][name]" placeholder="Enter extra name" style="flex: 2;">
|
||
<input type="number" name="available_extras[${index}][price]" placeholder="Price" step="0.01" style="flex: 1;">
|
||
<label style="margin-left: 10px; display: flex; align-items: center; white-space: nowrap;">
|
||
<input type="checkbox" name="available_extras[${index}][per_day_per_person]">
|
||
<span style="margin-left: 5px;">Per day per person</span>
|
||
</label>
|
||
<button type="button" class="btn-remove" onclick="removeExtra(this)">Remove</button>
|
||
`;
|
||
list.appendChild(row);
|
||
}
|
||
|
||
function removeExtra(button) {
|
||
button.parentElement.remove();
|
||
reindexExtras();
|
||
}
|
||
|
||
function reindexExtras() {
|
||
const extras = document.querySelectorAll('#available-extras-list .item-row');
|
||
extras.forEach((extra, index) => {
|
||
const inputs = extra.querySelectorAll('input');
|
||
inputs[0].name = `available_extras[${index}][name]`;
|
||
inputs[1].name = `available_extras[${index}][price]`;
|
||
// Update the checkbox name as well if it exists
|
||
if (inputs[2] && inputs[2].type === 'checkbox') {
|
||
inputs[2].name = `available_extras[${index}][per_day_per_person]`;
|
||
}
|
||
});
|
||
}
|
||
|
||
function addFaq() {
|
||
const list = document.getElementById('faq-list');
|
||
const index = list.children.length;
|
||
const faq = document.createElement('div');
|
||
faq.className = 'faq-item';
|
||
faq.style = 'background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 15px;';
|
||
faq.innerHTML = `
|
||
<input type="text"
|
||
name="tour_faqs[${index}][question]"
|
||
placeholder="Question"
|
||
style="margin-bottom: 10px;">
|
||
<textarea name="tour_faqs[${index}][answer]"
|
||
rows="3"
|
||
placeholder="Answer"
|
||
style="width: 100%; margin-bottom: 10px;"></textarea>
|
||
<button type="button" class="btn-remove" onclick="removeFaq(this)">Remove Question</button>
|
||
`;
|
||
list.appendChild(faq);
|
||
}
|
||
|
||
function removeFaq(button) {
|
||
button.parentElement.remove();
|
||
reindexFaqs();
|
||
}
|
||
|
||
function reindexFaqs() {
|
||
const faqs = document.querySelectorAll('#faq-list .faq-item');
|
||
faqs.forEach((faq, index) => {
|
||
const inputs = faq.querySelectorAll('input, textarea');
|
||
inputs[0].name = `tour_faqs[${index}][question]`;
|
||
inputs[1].name = `tour_faqs[${index}][answer]`;
|
||
});
|
||
}
|
||
</script>
|
||
<?php
|
||
}
|
||
|
||
// Shrani meta podatke za Individual Tour
|
||
function save_individual_tour_meta($post_id) {
|
||
if (!isset($_POST['individual_tour_nonce']) || !wp_verify_nonce($_POST['individual_tour_nonce'], 'individual_tour_nonce')) {
|
||
return;
|
||
}
|
||
|
||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||
return;
|
||
}
|
||
|
||
if (!current_user_can('edit_post', $post_id)) {
|
||
return;
|
||
}
|
||
|
||
// Shrani osnovne podatke
|
||
$fields = array(
|
||
'tour_price' => 'sanitize_text_field',
|
||
'tour_duration' => 'sanitize_text_field',
|
||
'tour_location' => 'sanitize_text_field',
|
||
'experience_journey' => 'absint',
|
||
'hero_image' => 'absint',
|
||
'guide_image' => 'absint',
|
||
'guide_name' => 'sanitize_text_field',
|
||
'guide_title' => 'sanitize_text_field',
|
||
'day_type_label' => 'sanitize_text_field'
|
||
);
|
||
|
||
// Debug izpis za administratorje
|
||
if (current_user_can('administrator')) {
|
||
error_log('Saving tour meta data:');
|
||
error_log('POST data: ' . print_r($_POST, true));
|
||
}
|
||
|
||
foreach ($fields as $field => $sanitize_callback) {
|
||
if (isset($_POST[$field])) {
|
||
$value = call_user_func($sanitize_callback, $_POST[$field]);
|
||
update_post_meta($post_id, '_' . $field, $value);
|
||
|
||
// Debug izpis za administratorje
|
||
if (current_user_can('administrator')) {
|
||
error_log("Saving field {$field} with value: {$value}");
|
||
}
|
||
}
|
||
}
|
||
|
||
// Shrani galerijo
|
||
if (isset($_POST['tour_gallery'])) {
|
||
$gallery_images = array_filter(explode(',', sanitize_text_field($_POST['tour_gallery'])));
|
||
update_post_meta($post_id, '_tour_gallery', $gallery_images);
|
||
}
|
||
|
||
// Shrani dnevni program
|
||
if (isset($_POST['daily_program'])) {
|
||
$daily_program = array();
|
||
foreach ($_POST['daily_program'] as $index => $day) {
|
||
if (!empty($day['title']) || !empty($day['description'])) {
|
||
$daily_program[] = array(
|
||
'title' => sanitize_text_field($day['title']),
|
||
'description' => wp_kses_post($day['description'])
|
||
);
|
||
}
|
||
}
|
||
update_post_meta($post_id, '_daily_program', $daily_program);
|
||
}
|
||
|
||
// Shrani vključene elemente
|
||
if (isset($_POST['included_items'])) {
|
||
$included_items = array_filter(array_map('sanitize_text_field', $_POST['included_items']));
|
||
update_post_meta($post_id, '_included_items', $included_items);
|
||
}
|
||
|
||
// Shrani nevključene elemente
|
||
if (isset($_POST['not_included_items'])) {
|
||
$not_included_items = array_filter(array_map('sanitize_text_field', $_POST['not_included_items']));
|
||
update_post_meta($post_id, '_not_included_items', $not_included_items);
|
||
}
|
||
|
||
// Shrani available extras
|
||
if (isset($_POST['available_extras'])) {
|
||
$available_extras = array();
|
||
foreach ($_POST['available_extras'] as $extra) {
|
||
if (!empty($extra['name'])) {
|
||
$available_extras[] = array(
|
||
'name' => sanitize_text_field($extra['name']),
|
||
'price' => floatval($extra['price']),
|
||
'per_day_per_person' => isset($extra['per_day_per_person']) ? true : false
|
||
);
|
||
}
|
||
}
|
||
update_post_meta($post_id, '_available_extras', $available_extras);
|
||
}
|
||
|
||
// Shrani FAQ vprašanja in odgovore
|
||
if (isset($_POST['tour_faqs'])) {
|
||
$faqs = array();
|
||
foreach ($_POST['tour_faqs'] as $faq) {
|
||
if (!empty($faq['question']) || !empty($faq['answer'])) {
|
||
$faqs[] = array(
|
||
'question' => sanitize_text_field($faq['question']),
|
||
'answer' => wp_kses_post($faq['answer'])
|
||
);
|
||
}
|
||
}
|
||
update_post_meta($post_id, '_tour_faqs', $faqs);
|
||
}
|
||
}
|
||
add_action('save_post_individual_tour', 'save_individual_tour_meta');
|
||
|
||
// Dodaj podporo za naslovno sliko
|
||
add_theme_support('post-thumbnails');
|
||
|
||
// Registriraj meta polja za REST API
|
||
function register_tour_meta_fields() {
|
||
// Registracija meta polj za Individual Tour
|
||
register_post_meta('individual_tour', '_daily_program', array(
|
||
'type' => 'array',
|
||
'single' => true,
|
||
'show_in_rest' => array(
|
||
'schema' => array(
|
||
'type' => 'array',
|
||
'items' => array(
|
||
'type' => 'object',
|
||
'properties' => array(
|
||
'title' => array('type' => 'string'),
|
||
'description' => array('type' => 'string')
|
||
)
|
||
)
|
||
)
|
||
)
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_included_items', array(
|
||
'type' => 'array',
|
||
'single' => true,
|
||
'show_in_rest' => array(
|
||
'schema' => array(
|
||
'type' => 'array',
|
||
'items' => array('type' => 'string')
|
||
)
|
||
)
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_not_included_items', array(
|
||
'type' => 'array',
|
||
'single' => true,
|
||
'show_in_rest' => array(
|
||
'schema' => array(
|
||
'type' => 'array',
|
||
'items' => array('type' => 'string')
|
||
)
|
||
)
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_available_extras', array(
|
||
'type' => 'array',
|
||
'single' => true,
|
||
'show_in_rest' => array(
|
||
'schema' => array(
|
||
'type' => 'array',
|
||
'items' => array(
|
||
'type' => 'object',
|
||
'properties' => array(
|
||
'title' => array('type' => 'string'),
|
||
'price' => array('type' => 'number')
|
||
)
|
||
)
|
||
)
|
||
)
|
||
));
|
||
|
||
// Registracija ostalih meta polj
|
||
register_post_meta('individual_tour', '_tour_price', array(
|
||
'type' => 'number',
|
||
'single' => true,
|
||
'show_in_rest' => true
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_tour_duration', array(
|
||
'type' => 'number',
|
||
'single' => true,
|
||
'show_in_rest' => true
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_tour_location', array(
|
||
'type' => 'string',
|
||
'single' => true,
|
||
'show_in_rest' => true
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_experience_journey', array(
|
||
'type' => 'number',
|
||
'single' => true,
|
||
'show_in_rest' => true
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_hero_image', array(
|
||
'type' => 'number',
|
||
'single' => true,
|
||
'show_in_rest' => true
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_tour_gallery', array(
|
||
'type' => 'array',
|
||
'single' => true,
|
||
'show_in_rest' => array(
|
||
'schema' => array(
|
||
'type' => 'array',
|
||
'items' => array('type' => 'number')
|
||
)
|
||
)
|
||
));
|
||
|
||
register_post_meta('individual_tour', '_tour_faqs', array(
|
||
'type' => 'array',
|
||
'single' => true,
|
||
'show_in_rest' => array(
|
||
'schema' => array(
|
||
'type' => 'array',
|
||
'items' => array(
|
||
'type' => 'object',
|
||
'properties' => array(
|
||
'question' => array('type' => 'string'),
|
||
'answer' => array('type' => 'string')
|
||
)
|
||
)
|
||
)
|
||
)
|
||
));
|
||
}
|
||
add_action('init', 'register_tour_meta_fields');
|