533 lines
21 KiB
Plaintext
533 lines
21 KiB
Plaintext
<?php
|
|
/**
|
|
* Grilc Tours functions and definitions
|
|
*/
|
|
|
|
function grilctours_setup() {
|
|
// Add default posts and comments RSS feed links to head.
|
|
add_theme_support('automatic-feed-links');
|
|
|
|
// Let WordPress manage the document title.
|
|
add_theme_support('title-tag');
|
|
|
|
// Enable support for Post Thumbnails on posts and pages.
|
|
add_theme_support('post-thumbnails');
|
|
|
|
// Add support for custom logo
|
|
add_theme_support('custom-logo');
|
|
|
|
// Register navigation menus
|
|
register_nav_menus(array(
|
|
'primary' => esc_html__('Primary Menu', 'grilctours'),
|
|
'footer' => esc_html__('Footer Menu', 'grilctours'),
|
|
));
|
|
}
|
|
add_action('after_setup_theme', 'grilctours_setup');
|
|
|
|
// Enqueue scripts and styles
|
|
function grilctours_scripts() {
|
|
wp_enqueue_style('grilctours-style', get_stylesheet_uri());
|
|
|
|
// Dodaj Font Awesome
|
|
wp_enqueue_style('font-awesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css');
|
|
|
|
wp_enqueue_script('grilctours-script', get_template_directory_uri() . '/js/script.js', array(), '1.0.0', true);
|
|
}
|
|
add_action('wp_enqueue_scripts', 'grilctours_scripts');
|
|
|
|
// Dodaj podporo za media uploader v admin
|
|
function grilctours_admin_scripts() {
|
|
global $post_type;
|
|
if ('individual_tour' == $post_type) {
|
|
wp_enqueue_media();
|
|
}
|
|
}
|
|
add_action('admin_enqueue_scripts', 'grilctours_admin_scripts');
|
|
|
|
// Registracija Experience Journey post type
|
|
function register_experience_journey_post_type() {
|
|
$labels = array(
|
|
'name' => 'Experience Journeys',
|
|
'singular_name' => 'Experience Journey',
|
|
'menu_name' => 'Experience Journeys',
|
|
'add_new' => 'Add New',
|
|
'add_new_item' => 'Add New Experience Journey',
|
|
'edit_item' => 'Edit Experience Journey',
|
|
'new_item' => 'New Experience Journey',
|
|
'view_item' => 'View Experience Journey',
|
|
'search_items' => 'Search Experience Journeys',
|
|
'not_found' => 'No experience journeys found',
|
|
'not_found_in_trash' => 'No experience journeys found in Trash',
|
|
);
|
|
|
|
$args = array(
|
|
'labels' => $labels,
|
|
'public' => true,
|
|
'publicly_queryable' => true,
|
|
'show_ui' => true,
|
|
'show_in_menu' => true,
|
|
'query_var' => true,
|
|
'rewrite' => array('slug' => 'journeys'),
|
|
'capability_type' => 'post',
|
|
'has_archive' => true,
|
|
'hierarchical' => false,
|
|
'menu_position' => null,
|
|
'supports' => array('title', 'editor', 'thumbnail'),
|
|
'menu_icon' => 'dashicons-groups',
|
|
);
|
|
|
|
register_post_type('experience_journey', $args);
|
|
}
|
|
add_action('init', 'register_experience_journey_post_type');
|
|
|
|
// Registracija Individual Tour post type
|
|
function register_individual_tour_post_type() {
|
|
$labels = array(
|
|
'name' => 'Individual Tours',
|
|
'singular_name' => 'Individual Tour',
|
|
'menu_name' => 'Individual Tours',
|
|
'add_new' => 'Add New',
|
|
'add_new_item' => 'Add New Individual Tour',
|
|
'edit_item' => 'Edit Individual Tour',
|
|
'new_item' => 'New Individual Tour',
|
|
'view_item' => 'View Individual Tour',
|
|
'search_items' => 'Search Individual Tours',
|
|
'not_found' => 'No individual tours found',
|
|
'not_found_in_trash' => 'No individual tours found in Trash',
|
|
);
|
|
|
|
$args = array(
|
|
'labels' => $labels,
|
|
'public' => true,
|
|
'publicly_queryable' => true,
|
|
'show_ui' => true,
|
|
'show_in_menu' => true,
|
|
'query_var' => true,
|
|
'rewrite' => array('slug' => 'tours'),
|
|
'capability_type' => 'post',
|
|
'has_archive' => true,
|
|
'hierarchical' => false,
|
|
'menu_position' => null,
|
|
'supports' => array('title', 'editor', 'thumbnail'),
|
|
'menu_icon' => 'dashicons-location-alt',
|
|
);
|
|
|
|
register_post_type('individual_tour', $args);
|
|
}
|
|
add_action('init', 'register_individual_tour_post_type');
|
|
|
|
// Registracija meta boxov za Experience Journey
|
|
function register_experience_journey_meta_boxes() {
|
|
add_meta_box(
|
|
'experience_journey_details',
|
|
'Journey Details',
|
|
'render_experience_journey_meta_box',
|
|
'experience_journey',
|
|
'normal',
|
|
'high'
|
|
);
|
|
}
|
|
add_action('add_meta_boxes', 'register_experience_journey_meta_boxes');
|
|
|
|
// Render meta box za Experience Journey
|
|
function render_experience_journey_meta_box($post) {
|
|
$target_audience = get_post_meta($post->ID, '_target_audience', true);
|
|
|
|
wp_nonce_field('experience_journey_nonce', 'experience_journey_nonce');
|
|
?>
|
|
<div class="journey-meta-box">
|
|
<p>
|
|
<label for="target_audience"><strong>Target Audience</strong></label>
|
|
<textarea id="target_audience" name="target_audience" class="widefat" rows="5"><?php echo esc_textarea($target_audience); ?></textarea>
|
|
<span class="description">Describe who this journey is designed for.</span>
|
|
</p>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
// 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_meta_box(
|
|
'individual_tour_journey',
|
|
'Experience Journey',
|
|
'render_individual_tour_journey_meta_box',
|
|
'individual_tour',
|
|
'side',
|
|
'default'
|
|
);
|
|
}
|
|
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, '_price', true);
|
|
$duration = get_post_meta($post->ID, '_duration', true);
|
|
$distance = get_post_meta($post->ID, '_distance', true);
|
|
$fitness_level = get_post_meta($post->ID, '_fitness_level', true);
|
|
$hero_image = get_post_meta($post->ID, '_hero_image', true);
|
|
$highlights = get_post_meta($post->ID, '_highlights', true) ?: array('');
|
|
$inclusions = get_post_meta($post->ID, '_inclusions', true) ?: array('');
|
|
$optional_extras = get_post_meta($post->ID, '_optional_extras', true) ?: array('');
|
|
$itinerary = get_post_meta($post->ID, '_itinerary', true) ?: array(array('title' => '', 'description' => '', 'image' => ''));
|
|
|
|
wp_nonce_field('individual_tour_nonce', 'individual_tour_nonce');
|
|
?>
|
|
<div class="tour-meta-box">
|
|
<p>
|
|
<label for="price"><strong>Price (€)</strong></label>
|
|
<input type="number" id="price" name="price" value="<?php echo esc_attr($price); ?>" class="widefat" min="0" step="0.01">
|
|
</p>
|
|
<p>
|
|
<label for="duration"><strong>Duration</strong></label>
|
|
<input type="text" id="duration" name="duration" value="<?php echo esc_attr($duration); ?>" class="widefat" placeholder="e.g., 7 days / 6 nights">
|
|
</p>
|
|
<p>
|
|
<label for="distance"><strong>Distance</strong></label>
|
|
<input type="text" id="distance" name="distance" value="<?php echo esc_attr($distance); ?>" class="widefat" placeholder="e.g., 60 - 100 km/day">
|
|
</p>
|
|
<p>
|
|
<label for="fitness_level"><strong>Fitness Level</strong></label>
|
|
<select id="fitness_level" name="fitness_level" class="widefat">
|
|
<option value="">Select fitness level</option>
|
|
<option value="Beginner" <?php selected($fitness_level, 'Beginner'); ?>>Beginner</option>
|
|
<option value="Intermediate" <?php selected($fitness_level, 'Intermediate'); ?>>Intermediate</option>
|
|
<option value="Advanced" <?php selected($fitness_level, 'Advanced'); ?>>Advanced</option>
|
|
<option value="Expert" <?php selected($fitness_level, 'Expert'); ?>>Expert</option>
|
|
</select>
|
|
</p>
|
|
|
|
<div class="hero-image-field">
|
|
<h4>Hero Image</h4>
|
|
<p>This image will be displayed at the top of the tour page. If not set, the featured image will be used.</p>
|
|
<div class="image-preview-wrapper">
|
|
<?php if (!empty($hero_image)) : ?>
|
|
<img src="<?php echo esc_url($hero_image); ?>" alt="Hero Image" class="image-preview" style="max-width: 300px; height: auto;">
|
|
<?php endif; ?>
|
|
</div>
|
|
<input type="text" name="hero_image" id="hero_image" value="<?php echo esc_attr($hero_image); ?>" class="widefat">
|
|
<button type="button" class="button hero-image-upload">Upload/Select Image</button>
|
|
<button type="button" class="button hero-image-remove" <?php echo empty($hero_image) ? 'style="display:none;"' : ''; ?>>Remove Image</button>
|
|
</div>
|
|
|
|
<div class="repeatable-fields">
|
|
<h4>Highlights</h4>
|
|
<div id="highlights-container">
|
|
<?php foreach ($highlights as $highlight) : ?>
|
|
<div class="repeatable-field">
|
|
<input type="text" name="highlights[]" value="<?php echo esc_attr($highlight); ?>" class="widefat">
|
|
<button type="button" class="remove-field">Remove</button>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<button type="button" class="add-field" data-container="highlights-container">Add Highlight</button>
|
|
</div>
|
|
|
|
<div class="repeatable-fields">
|
|
<h4>Inclusions</h4>
|
|
<div id="inclusions-container">
|
|
<?php foreach ($inclusions as $inclusion) : ?>
|
|
<div class="repeatable-field">
|
|
<input type="text" name="inclusions[]" value="<?php echo esc_attr($inclusion); ?>" class="widefat">
|
|
<button type="button" class="remove-field">Remove</button>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<button type="button" class="add-field" data-container="inclusions-container">Add Inclusion</button>
|
|
</div>
|
|
|
|
<div class="repeatable-fields">
|
|
<h4>Optional Extras</h4>
|
|
<div id="optional-extras-container">
|
|
<?php foreach ($optional_extras as $extra) : ?>
|
|
<div class="repeatable-field">
|
|
<input type="text" name="optional_extras[]" value="<?php echo esc_attr($extra); ?>" class="widefat">
|
|
<button type="button" class="remove-field">Remove</button>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<button type="button" class="add-field" data-container="optional-extras-container">Add Optional Extra</button>
|
|
</div>
|
|
|
|
<div class="repeatable-fields">
|
|
<h4>Itinerary</h4>
|
|
<div id="itinerary-container">
|
|
<?php foreach ($itinerary as $index => $day) : ?>
|
|
<div class="repeatable-field itinerary-day">
|
|
<input type="text" name="itinerary[<?php echo $index; ?>][title]" value="<?php echo esc_attr($day['title']); ?>" class="widefat" placeholder="Day Title">
|
|
<textarea name="itinerary[<?php echo $index; ?>][description]" class="widefat" rows="3" placeholder="Day Description"><?php echo esc_textarea($day['description']); ?></textarea>
|
|
|
|
<div class="itinerary-image-field">
|
|
<label><strong>Day Image</strong></label>
|
|
<div class="image-preview-wrapper">
|
|
<?php if (!empty($day['image'])) : ?>
|
|
<img src="<?php echo esc_url($day['image']); ?>" alt="Day Image" class="image-preview" style="max-width: 200px; height: auto;">
|
|
<?php endif; ?>
|
|
</div>
|
|
<input type="text" name="itinerary[<?php echo $index; ?>][image]" value="<?php echo esc_attr($day['image'] ?? ''); ?>" class="widefat itinerary-image-url">
|
|
<button type="button" class="button itinerary-image-upload">Upload/Select Image</button>
|
|
<button type="button" class="button itinerary-image-remove" <?php echo empty($day['image']) ? 'style="display:none;"' : ''; ?>>Remove Image</button>
|
|
</div>
|
|
|
|
<button type="button" class="remove-field">Remove Day</button>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<button type="button" class="add-field" data-container="itinerary-container">Add Day</button>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.repeatable-fields {
|
|
margin: 20px 0;
|
|
padding: 15px;
|
|
background: #f9f9f9;
|
|
border: 1px solid #e5e5e5;
|
|
}
|
|
.repeatable-field {
|
|
margin-bottom: 10px;
|
|
padding: 10px;
|
|
background: #fff;
|
|
border: 1px solid #e5e5e5;
|
|
}
|
|
.remove-field {
|
|
margin-top: 5px;
|
|
color: #a00;
|
|
}
|
|
.itinerary-day {
|
|
padding: 15px;
|
|
}
|
|
.itinerary-day textarea {
|
|
margin-top: 5px;
|
|
}
|
|
.hero-image-field, .itinerary-image-field {
|
|
margin: 15px 0;
|
|
padding: 10px;
|
|
background: #f0f0f0;
|
|
border: 1px solid #ddd;
|
|
}
|
|
.image-preview-wrapper {
|
|
margin: 10px 0;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
jQuery(document).ready(function($) {
|
|
// Obstoječa koda za ponavljajoča se polja
|
|
$('.add-field').click(function() {
|
|
var container = $('#' + $(this).data('container'));
|
|
var field = container.children().first().clone();
|
|
field.find('input, textarea').val('');
|
|
field.find('.image-preview-wrapper img').remove();
|
|
field.find('.itinerary-image-remove').hide();
|
|
|
|
// Posodobi indekse za itinerary
|
|
if (container.attr('id') === 'itinerary-container') {
|
|
var newIndex = container.children().length;
|
|
field.find('input, textarea').each(function() {
|
|
var name = $(this).attr('name');
|
|
if (name) {
|
|
name = name.replace(/\[\d+\]/, '[' + newIndex + ']');
|
|
$(this).attr('name', name);
|
|
}
|
|
});
|
|
}
|
|
|
|
container.append(field);
|
|
});
|
|
|
|
$(document).on('click', '.remove-field', function() {
|
|
var container = $(this).closest('.repeatable-fields').find('.repeatable-field');
|
|
if (container.length > 1) {
|
|
$(this).closest('.repeatable-field').remove();
|
|
}
|
|
});
|
|
|
|
// Media uploader za hero sliko
|
|
$('.hero-image-upload').click(function(e) {
|
|
e.preventDefault();
|
|
var button = $(this);
|
|
var imageField = $('#hero_image');
|
|
var previewWrapper = button.siblings('.image-preview-wrapper');
|
|
var removeButton = button.siblings('.hero-image-remove');
|
|
|
|
var frame = wp.media({
|
|
title: 'Select or Upload Hero Image',
|
|
button: {
|
|
text: 'Use this image'
|
|
},
|
|
multiple: false
|
|
});
|
|
|
|
frame.on('select', function() {
|
|
var attachment = frame.state().get('selection').first().toJSON();
|
|
imageField.val(attachment.url);
|
|
|
|
// Posodobi preview
|
|
previewWrapper.html('<img src="' + attachment.url + '" alt="Hero Image" class="image-preview" style="max-width: 300px; height: auto;">');
|
|
removeButton.show();
|
|
});
|
|
|
|
frame.open();
|
|
});
|
|
|
|
// Odstrani hero sliko
|
|
$('.hero-image-remove').click(function() {
|
|
$('#hero_image').val('');
|
|
$(this).siblings('.image-preview-wrapper').empty();
|
|
$(this).hide();
|
|
});
|
|
|
|
// Media uploader za itinerary slike
|
|
$(document).on('click', '.itinerary-image-upload', function(e) {
|
|
e.preventDefault();
|
|
var button = $(this);
|
|
var imageField = button.siblings('.itinerary-image-url');
|
|
var previewWrapper = button.siblings('.image-preview-wrapper');
|
|
var removeButton = button.siblings('.itinerary-image-remove');
|
|
|
|
var frame = wp.media({
|
|
title: 'Select or Upload Day Image',
|
|
button: {
|
|
text: 'Use this image'
|
|
},
|
|
multiple: false
|
|
});
|
|
|
|
frame.on('select', function() {
|
|
var attachment = frame.state().get('selection').first().toJSON();
|
|
imageField.val(attachment.url);
|
|
|
|
// Posodobi preview
|
|
previewWrapper.html('<img src="' + attachment.url + '" alt="Day Image" class="image-preview" style="max-width: 200px; height: auto;">');
|
|
removeButton.show();
|
|
});
|
|
|
|
frame.open();
|
|
});
|
|
|
|
// Odstrani itinerary sliko
|
|
$(document).on('click', '.itinerary-image-remove', function() {
|
|
$(this).siblings('.itinerary-image-url').val('');
|
|
$(this).siblings('.image-preview-wrapper').empty();
|
|
$(this).hide();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
// Render meta box za povezavo Individual Tour z Experience Journey
|
|
function render_individual_tour_journey_meta_box($post) {
|
|
$current_journey = get_post_meta($post->ID, '_experience_journey', true);
|
|
|
|
$journeys = get_posts(array(
|
|
'post_type' => 'experience_journey',
|
|
'posts_per_page' => -1,
|
|
'orderby' => 'title',
|
|
'order' => 'ASC'
|
|
));
|
|
|
|
if (empty($journeys)) {
|
|
echo '<p>No experience journeys found. Please create one first.</p>';
|
|
return;
|
|
}
|
|
|
|
echo '<select name="experience_journey" class="widefat">';
|
|
echo '<option value="">Select Experience Journey</option>';
|
|
|
|
foreach ($journeys as $journey) {
|
|
printf(
|
|
'<option value="%s" %s>%s</option>',
|
|
esc_attr($journey->ID),
|
|
selected($current_journey, $journey->ID, false),
|
|
esc_html($journey->post_title)
|
|
);
|
|
}
|
|
|
|
echo '</select>';
|
|
}
|
|
|
|
// Shrani meta podatke za Experience Journey
|
|
function save_experience_journey_meta($post_id) {
|
|
if (!isset($_POST['experience_journey_nonce']) || !wp_verify_nonce($_POST['experience_journey_nonce'], 'experience_journey_nonce')) {
|
|
return;
|
|
}
|
|
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
|
return;
|
|
}
|
|
|
|
if (!current_user_can('edit_post', $post_id)) {
|
|
return;
|
|
}
|
|
|
|
if (isset($_POST['target_audience'])) {
|
|
update_post_meta($post_id, '_target_audience', sanitize_textarea_field($_POST['target_audience']));
|
|
}
|
|
}
|
|
add_action('save_post_experience_journey', 'save_experience_journey_meta');
|
|
|
|
// 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(
|
|
'price' => 'sanitize_text_field',
|
|
'duration' => 'sanitize_text_field',
|
|
'distance' => 'sanitize_text_field',
|
|
'fitness_level' => 'sanitize_text_field',
|
|
'hero_image' => 'esc_url_raw',
|
|
'experience_journey' => 'absint'
|
|
);
|
|
|
|
foreach ($fields as $field => $sanitize_callback) {
|
|
if (isset($_POST[$field])) {
|
|
update_post_meta($post_id, '_' . $field, $sanitize_callback($_POST[$field]));
|
|
}
|
|
}
|
|
|
|
// Shrani array podatke
|
|
$array_fields = array('highlights', 'inclusions', 'optional_extras');
|
|
foreach ($array_fields as $field) {
|
|
if (isset($_POST[$field]) && is_array($_POST[$field])) {
|
|
$sanitized = array_map('sanitize_text_field', array_filter($_POST[$field]));
|
|
update_post_meta($post_id, '_' . $field, $sanitized);
|
|
}
|
|
}
|
|
|
|
// Shrani itinerary
|
|
if (isset($_POST['itinerary']) && is_array($_POST['itinerary'])) {
|
|
$itinerary = array();
|
|
foreach ($_POST['itinerary'] as $day) {
|
|
if (!empty($day['title']) || !empty($day['description'])) {
|
|
$itinerary[] = array(
|
|
'title' => sanitize_text_field($day['title']),
|
|
'description' => sanitize_textarea_field($day['description']),
|
|
'image' => isset($day['image']) ? esc_url_raw($day['image']) : ''
|
|
);
|
|
}
|
|
}
|
|
update_post_meta($post_id, '_itinerary', $itinerary);
|
|
}
|
|
}
|
|
add_action('save_post_individual_tour', 'save_individual_tour_meta'); |