100, 'width' => 300, 'flex-height' => true, 'flex-width' => true, )); // Registriraj navigacijske menije register_nav_menus(array( 'primary' => esc_html__('Primary Menu', 'grilctours'), 'footer' => esc_html__('Footer Menu', 'grilctours'), )); } add_action('after_setup_theme', 'grilctours_setup'); /** * Registracija stilov in skript */ function grilctours_scripts() { // Glavni CSS wp_enqueue_style('grilctours-style', get_stylesheet_uri()); // Google Fonts wp_enqueue_style('google-fonts', 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); // Glavni JavaScript wp_enqueue_script('grilctours-script', get_template_directory_uri() . '/js/script.js', array('jquery'), '1.0.0', true); } add_action('wp_enqueue_scripts', 'grilctours_scripts'); // Dodaj podporo za media uploader v admin function grilctours_admin_scripts($hook) { global $post_type; // Naloži skripte za edit in add new strani za individual_tour in experience_journey if (($hook == 'post.php' || $hook == 'post-new.php') && ($post_type == 'individual_tour' || $post_type == 'experience_journey')) { wp_enqueue_media(); wp_enqueue_script('grilctours-admin-script', get_template_directory_uri() . '/admin-scripts.js', array('jquery'), '1.0.0', true); } } add_action('admin_enqueue_scripts', 'grilctours_admin_scripts'); // Registracija Custom Post Type za Experience Journey function register_experience_journey_post_type() { $labels = array( 'name' => 'Experience Journeys', 'singular_name' => 'Experience Journey', 'menu_name' => 'Experience Journeys', 'add_new' => 'Add New Journey', 'add_new_item' => 'Add New Journey', 'edit_item' => 'Edit Journey', 'new_item' => 'New Journey', 'view_item' => 'View Journey', 'search_items' => 'Search Journeys', 'not_found' => 'No journeys found', 'not_found_in_trash' => 'No journeys found in Trash' ); $args = array( 'labels' => $labels, 'public' => true, 'has_archive' => true, 'menu_icon' => 'dashicons-palmtree', 'supports' => array('title', 'editor', 'thumbnail', 'excerpt'), 'rewrite' => array('slug' => 'journeys'), 'show_in_rest' => true, 'menu_position' => 5 ); register_post_type('experience_journey', $args); } add_action('init', 'register_experience_journey_post_type'); // Registracija Custom Post Type za Individual Tour function register_individual_tour_post_type() { $labels = array( 'name' => 'Individual Tours', 'singular_name' => 'Individual Tour', 'menu_name' => 'Individual Tours', 'add_new' => 'Add New Tour', 'add_new_item' => 'Add New Tour', 'edit_item' => 'Edit Tour', 'new_item' => 'New Tour', 'view_item' => 'View Tour', 'search_items' => 'Search Tours', 'not_found' => 'No tours found', 'not_found_in_trash' => 'No tours found in Trash' ); $args = array( 'labels' => $labels, 'public' => true, 'has_archive' => true, 'menu_icon' => 'dashicons-location', 'supports' => array('title', 'editor', 'thumbnail'), 'rewrite' => array('slug' => 'tours'), 'show_in_rest' => true, 'menu_position' => 6 ); register_post_type('individual_tour', $args); } add_action('init', 'register_individual_tour_post_type'); // Vključi datoteko za meta polja tur require_once get_template_directory() . '/tour-meta-fields.php'; // 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); $journey_image = get_post_meta($post->ID, '_journey_image', true); $short_title = get_post_meta($post->ID, '_short_title', true); $page_title = get_post_meta($post->ID, '_page_title', true); wp_nonce_field('experience_journey_nonce', 'experience_journey_nonce'); ?>

Enter a short title that will be displayed on the homepage (e.g. "One Day Experience")

Enter the title that will be displayed when viewing this experience journey (e.g. "One Day Tours")



Upload an image that will be displayed as the journey's main image.

Describe who this journey is designed for.

"; foreach ($extras as $extra) { $extras_list .= "
  • " . sanitize_text_field($extra) . "
  • "; } $extras_list .= ""; } else { $extras_list = "None"; } // Pripravi vsebino e-pošte $to = 'dincija@gmail.com'; $subject = 'New Tour Inquiry: ' . $tour_title; $body = " New Tour Inquiry

    New Inquiry for: $tour_title

    Name: $name

    Email: $email

    Phone: " . ($phone ? $phone : "Not provided") . "

    Date: $date

    Number of participants: $participants

    Country: " . ($country ? $country : "Not provided") . "

    Selected extras: $extras_list

    Message:

    " . nl2br($message) . "

    "; // Nastavi glave za HTML e-pošto $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: ' . $name . ' <' . $email . '>', 'Reply-To: ' . $email ); // Pošlji e-pošto $sent = wp_mail($to, $subject, $body, $headers); // Pošlji odgovor if ($sent) { wp_send_json_success(array('message' => 'Inquiry sent successfully!')); } else { wp_send_json_error(array('message' => 'Failed to send inquiry. Please try again later.')); } wp_die(); } // Registriraj AJAX akcije add_action('wp_ajax_send_inquiry', 'handle_inquiry_form'); add_action('wp_ajax_nopriv_send_inquiry', 'handle_inquiry_form'); // Funkcija za testiranje pošiljanja e-pošte function test_email_sending() { $to = 'dincija@gmail.com'; $subject = 'Test Email from Slovenia Bike Tours'; $body = ' Test Email

    Test Email

    This is a test email from Slovenia Bike Tours website.

    If you are receiving this, the email functionality is working correctly.

    Time of sending: ' . current_time('mysql') . '

    '; $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: Slovenia Bike Tours ', ); $sent = wp_mail($to, $subject, $body, $headers); return $sent ? 'Email sent successfully!' : 'Failed to send email.'; } // Dodaj REST API endpoint za testiranje e-pošte function register_test_email_endpoint() { register_rest_route('slovenia-bike-tours/v1', '/test-email', array( 'methods' => 'GET', 'callback' => 'test_email_sending', 'permission_callback' => function() { return current_user_can('manage_options'); } )); } add_action('rest_api_init', 'register_test_email_endpoint'); /** * Dodaj nastavitve za footer v WordPress Customizer */ function grilctours_customize_register($wp_customize) { // Sekcija za footer $wp_customize->add_section('footer_settings', array( 'title' => __('Footer Settings', 'grilctours'), 'priority' => 120, )); // Footer opis $wp_customize->add_setting('footer_description', array( 'default' => 'We\'re a travel agency and tour operator for holidays, activities, and other unforgettable experiences in every corner of the Europe, and for every sort of traveler.', 'sanitize_callback' => 'wp_kses_post', 'transport' => 'refresh', )); $wp_customize->add_control('footer_description', array( 'label' => __('Footer Description', 'grilctours'), 'section' => 'footer_settings', 'type' => 'textarea', )); // Kontaktni podatki $wp_customize->add_setting('footer_email', array( 'default' => 'info@europewonder.com', 'sanitize_callback' => 'sanitize_email', 'transport' => 'refresh', )); $wp_customize->add_control('footer_email', array( 'label' => __('Email Address', 'grilctours'), 'section' => 'footer_settings', 'type' => 'email', )); $wp_customize->add_setting('footer_phone', array( 'default' => '+386 (0) 31 332 823', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('footer_phone', array( 'label' => __('Phone Number', 'grilctours'), 'section' => 'footer_settings', 'type' => 'text', )); $wp_customize->add_setting('footer_whatsapp', array( 'default' => '38631332823', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('footer_whatsapp', array( 'label' => __('WhatsApp Number', 'grilctours'), 'section' => 'footer_settings', 'type' => 'text', 'description' => __('Enter your WhatsApp number (numbers only, no spaces or special characters)', 'grilctours'), )); // Calendly link $wp_customize->add_setting('calendly_link', array( 'default' => '', 'sanitize_callback' => 'esc_url_raw', 'transport' => 'refresh', )); $wp_customize->add_control('calendly_link', array( 'label' => __('Calendly Link', 'grilctours'), 'section' => 'footer_settings', 'type' => 'url', 'description' => __('Enter your Calendly link for booking consultations in the footer', 'grilctours'), )); } add_action('customize_register', 'grilctours_customize_register'); /** * Dodaj nastavitve za front page v WordPress Customizer */ function grilctours_customize_front_page($wp_customize) { // Hero sekcija $wp_customize->add_section('hero_settings', array( 'title' => __('Hero Section Settings', 'grilctours'), 'priority' => 110, )); // Hero naslov $wp_customize->add_setting('hero_title', array( 'default' => 'Europe Wonder', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('hero_title', array( 'label' => __('Hero Title', 'grilctours'), 'section' => 'hero_settings', 'type' => 'text', )); // Hero podnaslov $wp_customize->add_setting('hero_subtitle', array( 'default' => 'Your path to unforgettable experiences', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('hero_subtitle', array( 'label' => __('Hero Subtitle', 'grilctours'), 'section' => 'hero_settings', 'type' => 'text', )); // Hero ozadje $wp_customize->add_setting('hero_background', array( 'default' => get_theme_file_uri('images/hero.jpg'), 'sanitize_callback' => 'esc_url_raw', 'transport' => 'refresh', )); $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'hero_background', array( 'label' => __('Hero Background Image', 'grilctours'), 'section' => 'hero_settings', ))); // Tours sekcija $wp_customize->add_section('tours_settings', array( 'title' => __('Tours Section Settings', 'grilctours'), 'priority' => 115, )); // Tours naslov $wp_customize->add_setting('tours_title', array( 'default' => 'Experience Journeys', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('tours_title', array( 'label' => __('Tours Section Title', 'grilctours'), 'section' => 'tours_settings', 'type' => 'text', )); // Video sekcija $wp_customize->add_section('video_settings', array( 'title' => __('Video Section Settings', 'grilctours'), 'priority' => 116, )); // Video URL $wp_customize->add_setting('video_url', array( 'default' => 'https://player.vimeo.com/video/1061260497?h=7fb6d020c3', 'sanitize_callback' => 'esc_url_raw', 'transport' => 'refresh', )); $wp_customize->add_control('video_url', array( 'label' => __('Video URL (Vimeo)', 'grilctours'), 'section' => 'video_settings', 'type' => 'url', 'description' => __('Enter the Vimeo video URL', 'grilctours'), )); } add_action('customize_register', 'grilctours_customize_front_page'); /** * Dodaj nastavitve za logotipe v WordPress Customizer */ function grilctours_customize_logos($wp_customize) { // Sekcija za logotipe $wp_customize->add_section('logo_settings', array( 'title' => __('Logo Settings', 'grilctours'), 'priority' => 105, )); // Header logo $wp_customize->add_setting('header_logo', array( 'default' => get_theme_file_uri('images/logo.png'), 'sanitize_callback' => 'esc_url_raw', 'transport' => 'refresh', )); $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'header_logo', array( 'label' => __('Header Logo', 'grilctours'), 'section' => 'logo_settings', 'description' => __('Upload logo for the header (recommended size: 40px height)', 'grilctours'), ))); // Footer logo $wp_customize->add_setting('footer_logo', array( 'default' => get_theme_file_uri('images/logo-footer.png'), 'sanitize_callback' => 'esc_url_raw', 'transport' => 'refresh', )); $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'footer_logo', array( 'label' => __('Footer Logo', 'grilctours'), 'section' => 'logo_settings', 'description' => __('Upload logo for the footer (recommended size: 40px height)', 'grilctours'), ))); } add_action('customize_register', 'grilctours_customize_logos'); /** * Customizer funkcije za razporejanje Experience Journeys */ function grilctours_customize_journey_order($wp_customize) { $wp_customize->add_section('experience_journey_order_section', array( 'title' => 'Razporeditev Experience Journeys', 'priority' => 30, )); // Get all experience journeys $args = array( 'post_type' => 'experience_journey', 'posts_per_page' => -1, 'post_status' => 'publish', ); $journeys = get_posts($args); $journey_choices = array(); if (!empty($journeys)) { foreach ($journeys as $journey) { $journey_choices[$journey->ID] = $journey->post_title; } } // Add setting for journey order $wp_customize->add_setting('experience_journey_order', array( 'default' => '', 'type' => 'option', 'capability' => 'edit_theme_options', 'transport' => 'refresh', 'sanitize_callback' => 'sanitize_text_field', )); // Definiraj razred znotraj funkcije, samo ko je potreben class Journey_Order_Control extends WP_Customize_Control { public $type = 'journey_order'; public $journeys = array(); public function render_content() { // Edinstveni ID za ta kontrolnik $list_id = 'sortable-journey-list'; ?> journeys)): ?> link(); ?> />

    Ni najdenih Experience Journeys za razporejanje.

    add_control(new Journey_Order_Control( $wp_customize, 'experience_journey_order_control', array( 'label' => 'Razporeditev Experience Journeys', 'section' => 'experience_journey_order_section', 'settings' => 'experience_journey_order', 'journeys' => $journey_choices, ) )); } add_action('customize_register', 'grilctours_customize_journey_order'); /** * Dodaj JavaScript in CSS za Customizer */ function grilctours_customizer_scripts() { wp_enqueue_script('jquery-ui-sortable'); // Dodaj JavaScript za sortiranje $script = " jQuery(document).ready(function($) { // Počakaj, da se DOM naloži, preden inicializiramo sortable setTimeout(function() { console.log('Inicializacija journey sortable seznama...'); // Poišči sortable seznam var sortableList = $('.journey-sortable-list'); if (sortableList.length) { console.log('Sortable seznam najden, inicializam...'); sortableList.sortable({ items: '.sortable-journey-item', handle: '.dashicons-move', placeholder: 'sortable-journey-placeholder', update: function(event, ui) { console.log('Vrstni red posodobljen'); // Zberi ID-je v novem vrstnem redu var ids = []; $('.sortable-journey-item').each(function() { ids.push($(this).data('journey-id')); }); // Posodobi skrito polje var inputField = sortableList.siblings('input[type=\"hidden\"]'); inputField.val(ids.join(',')).trigger('change'); console.log('Nova vrednost:', ids.join(',')); } }); console.log('Sortable inicializiran!'); } else { console.log('Sortable seznam ni bil najden!'); } }, 1000); }); "; wp_add_inline_script('jquery-ui-sortable', $script); // Dodaj CSS stile $style = " .journey-sortable-list { margin: 15px 0; padding: 0; list-style: none; } .sortable-journey-item { background: #fff; border: 1px solid #ddd; padding: 10px; margin-bottom: 10px; display: flex; align-items: center; cursor: move; border-radius: 3px; } .sortable-journey-item .dashicons-move { margin-right: 10px; color: #555; } .sortable-journey-item:hover { background: #f9f9f9; border-color: #999; } .sortable-journey-placeholder { border: 2px dashed #bbb; background: #f7f7f7; height: 40px; margin-bottom: 10px; } "; wp_add_inline_style('customize-controls', $style); } add_action('customize_controls_enqueue_scripts', 'grilctours_customizer_scripts'); /** * Omogoči admin skripte za posamezne tipe objav */ // ... existing code ... // Začasno odstranjeno zaradi napake // require_once get_template_directory() . '/mytheme-customizer.php'; // Preveri če je WooCommerce aktiviran function is_woocommerce_activated() { return class_exists('WooCommerce'); } // Vključi Stripe PHP knjižnico in inicializiraj samo če je WooCommerce aktiviran function init_stripe() { if (!is_woocommerce_activated()) { return; } // Preveri če obstaja composer autoload $autoload_path = get_template_directory() . '/vendor/autoload.php'; if (!file_exists($autoload_path)) { error_log('Stripe PHP library not found. Please run composer require stripe/stripe-php'); return; } // Vključi composer autoload require_once $autoload_path; // Preveri če je Stripe razred na voljo if (!class_exists('\Stripe\Stripe')) { error_log('Stripe PHP class not found after including autoload.php'); return; } try { // Nastavi Stripe API ključ \Stripe\Stripe::setApiKey('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'); } catch (Exception $e) { error_log('Error initializing Stripe: ' . $e->getMessage()); } } // Inicializiraj Stripe po tem, ko je WordPress naložen add_action('init', 'init_stripe', 20); // AJAX handler za obdelavo rezervacije ture function process_tour_booking() { if (!is_woocommerce_activated()) { wp_send_json_error(['message' => 'WooCommerce is not activated']); return; } check_ajax_referer('process_tour_booking', 'security'); try { // Preveri obvezna polja in izpiši natančen razlog napake $required_fields = [ 'name' => 'Full Name', 'email' => 'Email', 'date' => 'Departure Date', 'participants' => 'Number of Participants' ]; $missing_fields = []; foreach ($required_fields as $field => $label) { if (empty($_POST[$field])) { $missing_fields[] = $label; } } if (!empty($missing_fields)) { throw new Exception('The following fields are required: ' . implode(', ', $missing_fields)); } // Dodatno preverjanje veljavnosti e-pošte if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { throw new Exception('Please enter a valid email address.'); } // Preveri, da je število udeležencev najmanj 1 if (intval($_POST['participants']) < 1) { throw new Exception('Number of participants must be at least 1.'); } // Datum mora biti v prihodnosti $departure_date = new DateTime($_POST['date']); $today = new DateTime(); $today->setTime(0, 0, 0); // Nastavi čas na začetek dneva if ($departure_date < $today) { throw new Exception('Departure date must be in the future.'); } // Ustvari WooCommerce naročilo $order = wc_create_order(); // Dodaj podatke o stranki $order->set_billing_first_name($_POST['name']); $order->set_billing_email($_POST['email']); // Dodaj podatke o turi $tour_id = intval($_POST['tour_id']); $tour_name = sanitize_text_field($_POST['tour_name']); $participants = intval($_POST['participants']); $total_price = floatval($_POST['total_price']); // Pridobi WooCommerce produkt preko SKU-ja $product_id = wc_get_product_id_by_sku('tour-' . $tour_id); if (!$product_id) { // Poskusimo pridobiti produkt direktno po ID-ju $product = wc_get_product($tour_id); if (!$product) { throw new Exception('Tour product not found. Please contact administrator.'); } } else { $product = wc_get_product($product_id); if (!$product) { throw new Exception('Failed to load tour product'); } } // Dodaj produkt v naročilo $item_id = $order->add_product($product, $participants); // Dodaj datum odhoda kot meta podatek postavke if ($item_id) { wc_add_order_item_meta($item_id, '_tour_date', sanitize_text_field($_POST['date'])); } // Dodaj dodatke, če obstajajo if (!empty($_POST['extras'])) { $extras = json_decode(stripslashes($_POST['extras']), true); if (!is_array($extras)) { $extras = json_decode($_POST['extras'], true); // Poskusi brez stripslashes } if (is_array($extras)) { foreach ($extras as $extra) { // Preveri, da ima ekstra vse potrebne podatke if (empty($extra['name']) || !isset($extra['price'])) { continue; } // Ustvari nov produkt za dodatek $extra_product = new WC_Product_Simple(); $extra_product->set_name($extra['name']); $extra_product->set_regular_price(strval($extra['price'])); $extra_product->set_status('private'); $extra_product->set_catalog_visibility('hidden'); $extra_product->save(); // Dodaj dodatek v naročilo $order->add_product($extra_product, 1); // Dodaj meta podatke $order->add_meta_data('_extra_' . sanitize_title($extra['name']), true); // Izbriši začasni produkt wp_delete_post($extra_product->get_id(), true); } } } // Dodaj single supplement, če je potrebno if (!empty($_POST['single_supplement']) && ($_POST['single_supplement'] === 'true' || $_POST['single_supplement'] === true)) { $tour_duration = intval(get_post_meta($tour_id, '_tour_duration', true)); $single_supplement = 100 * $tour_duration; // 100€ na dan $order->add_fee('Single Supplement', $single_supplement); } // Nastavi skupno ceno $order->calculate_totals(); $order->set_total($total_price); // Shrani meta podatke $order->update_meta_data('_tour_date', sanitize_text_field($_POST['date'])); $order->update_meta_data('_participants', $participants); // Preračunaj skupno vrednost in določi znesek plačila glede na izbrani tip plačila $payment_type = isset($_POST['payment_type']) ? sanitize_text_field($_POST['payment_type']) : 'full'; $payment_amount = isset($_POST['payment_amount']) ? floatval($_POST['payment_amount']) : $total_price; // Shrani informacije o plačilu $order->update_meta_data('_payment_type', $payment_type); if ($payment_type === 'partial') { // Izračunaj zneske za delno plačilo $deposit_amount = $payment_amount; // že nastavljen na 30% v JavaScript $remaining_amount = $total_price - $deposit_amount; // Shrani podatke o delnem plačilu $order->update_meta_data('_deposit_amount', $deposit_amount); $order->update_meta_data('_remaining_amount', $remaining_amount); $order->update_meta_data('_is_deposit_paid', false); $order->update_meta_data('_is_remaining_paid', false); // Dodaj opombo naročilu o delnem plačilu $order->add_order_note(sprintf( 'Partial payment selected. Deposit: €%.2f, Remaining: €%.2f', $deposit_amount, $remaining_amount )); } // Shrani naročilo $order->save(); // Ustvari Stripe Payment Intent try { // Če je izbrano delno plačilo, uporabi znesek pologa namesto celotnega zneska $payment_amount_cents = intval($payment_amount * 100); // Stripe uporablja cente $payment_intent = \Stripe\PaymentIntent::create([ 'amount' => $payment_amount_cents, 'currency' => 'eur', 'metadata' => [ 'order_id' => $order->get_id(), 'tour_name' => $tour_name, 'tour_date' => $_POST['date'], 'payment_type' => $payment_type, 'total_price' => $total_price ] ]); // Shrani Payment Intent ID v naročilo $order->update_meta_data('_stripe_payment_intent', $payment_intent->id); $order->save(); // Vrni uspeh in client secret wp_send_json_success([ 'client_secret' => $payment_intent->client_secret, 'thank_you_url' => $order->get_checkout_order_received_url(), 'order_id' => $order->get_id(), 'payment_type' => $payment_type, 'payment_amount' => $payment_amount ]); } catch (\Stripe\Exception\ApiErrorException $e) { // Če Stripe vrne napako, izbriši naročilo in vrni napako $order->delete(true); throw new Exception('Payment processing error: ' . $e->getMessage()); } } catch (Exception $e) { error_log('Tour booking error: ' . $e->getMessage()); wp_send_json_error(['message' => $e->getMessage()]); } } add_action('wp_ajax_process_tour_booking', 'process_tour_booking'); add_action('wp_ajax_nopriv_process_tour_booking', 'process_tour_booking'); // Webhook handler za Stripe dogodke function handle_stripe_webhook() { $payload = @file_get_contents('php://input'); $event = null; try { $event = \Stripe\Event::constructFrom( json_decode($payload, true) ); } catch(\UnexpectedValueException $e) { http_response_code(400); exit(); } if ($event->type === 'payment_intent.succeeded') { $payment_intent = $event->data->object; // Najdi WooCommerce naročilo $orders = wc_get_orders([ 'meta_key' => '_stripe_payment_intent', 'meta_value' => $payment_intent->id, 'limit' => 1 ]); if (!empty($orders)) { $order = $orders[0]; // Pridobi podatke o plačilu $payment_type = get_post_meta($order->get_id(), '_payment_type', true); $payment_amount = $payment_intent->amount / 100; // Pretvori iz centov if ($payment_type === 'partial') { // Če gre za delno plačilo $is_deposit_paid = get_post_meta($order->get_id(), '_is_deposit_paid', true); if (!$is_deposit_paid) { // Označi polog kot plačan update_post_meta($order->get_id(), '_is_deposit_paid', true); // Dodaj opombo naročilu $deposit_amount = get_post_meta($order->get_id(), '_deposit_amount', true); $remaining_amount = get_post_meta($order->get_id(), '_remaining_amount', true); $order->add_order_note(sprintf( 'Deposit of €%.2f received. Remaining balance: €%.2f', $deposit_amount, $remaining_amount )); // Posodobi status naročila na "on-hold" ali podobno $order->update_status('on-hold', 'Deposit payment received. Awaiting final payment.'); } else { // Če gre za plačilo preostalega zneska update_post_meta($order->get_id(), '_is_remaining_paid', true); $order->payment_complete($payment_intent->id); $order->add_order_note('Final payment completed via Stripe (Payment Intent ID: ' . $payment_intent->id . ')'); } } else { // Če gre za polno plačilo, označi naročilo kot plačano $order->payment_complete($payment_intent->id); $order->add_order_note('Stripe payment completed (Payment Intent ID: ' . $payment_intent->id . ')'); } $order->save(); } } http_response_code(200); } // Dodaj rewrite pravilo za Stripe webhook function add_stripe_webhook_endpoint() { add_rewrite_rule('^stripe-webhook/?$', 'index.php?stripe-webhook=1', 'top'); } add_action('init', 'add_stripe_webhook_endpoint'); // Registriraj query var za webhook function add_stripe_webhook_query_var($vars) { $vars[] = 'stripe-webhook'; return $vars; } add_filter('query_vars', 'add_stripe_webhook_query_var'); // Poslušaj za webhook zahtevke function listen_for_stripe_webhook() { if (get_query_var('stripe-webhook')) { handle_stripe_webhook(); exit; } } add_action('parse_request', 'listen_for_stripe_webhook'); // Funkcija za kreiranje/posodabljanje WooCommerce produkta ob shranjevanju Individual Tour-a function create_wc_product_from_tour($post_id) { // Preveri če je WooCommerce aktiviran if (!class_exists('WooCommerce')) { return; } // Preveri če je post type Individual Tour if (get_post_type($post_id) !== 'individual_tour') { return; } // Preveri če je to avtomatsko shranjevanje if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // Pridobi podatke o turi $tour_title = get_the_title($post_id); $tour_price = floatval(get_post_meta($post_id, '_tour_price', true)); $tour_description = get_post_field('post_content', $post_id); // Če cena ni nastavljena, nastavi na 0 if (!$tour_price) { $tour_price = 0; } // Preveri če produkt že obstaja (uporabi SKU za povezavo) $product_id = wc_get_product_id_by_sku('tour-' . $post_id); if ($product_id) { // Posodobi obstoječ produkt $product = wc_get_product($product_id); if ($product) { $product->set_name($tour_title); $product->set_regular_price(strval($tour_price)); $product->set_description($tour_description); $product->save(); } } else { // Ustvari nov produkt $product = new WC_Product_Simple(); $product->set_name($tour_title); $product->set_regular_price(strval($tour_price)); $product->set_description($tour_description); $product->set_sku('tour-' . $post_id); $product->set_status('publish'); // Nastavi featured image če obstaja $hero_image_id = get_post_meta($post_id, '_hero_image', true); if ($hero_image_id) { $product->set_image_id($hero_image_id); } $product->save(); } } // Odstrani staro akcijo remove_action('save_post_individual_tour', 'create_wc_product_from_tour'); // Dodaj novo akcijo, ki se sproži po shranjevanju meta podatkov add_action('updated_post_meta', 'update_wc_product_on_meta_update', 10, 4); // Funkcija za posodobitev WooCommerce produkta ob spremembi meta podatkov function update_wc_product_on_meta_update($meta_id, $post_id, $meta_key, $_meta_value) { // Preveri če je pravi meta ključ in post type if ($meta_key === '_tour_price' && get_post_type($post_id) === 'individual_tour') { create_wc_product_from_tour($post_id); } } // Dodaj akcijo za kreiranje produkta ob objavi ture add_action('wp_insert_post', function($post_id, $post) { if ($post->post_type === 'individual_tour' && $post->post_status === 'publish') { create_wc_product_from_tour($post_id); } }, 10, 2); // Izbriši WooCommerce produkt ko se izbriše Individual Tour function delete_wc_product_with_tour($post_id) { if (!class_exists('WooCommerce')) { return; } if (get_post_type($post_id) !== 'individual_tour') { return; } $product_id = wc_get_product_id_by_sku('tour-' . $post_id); if ($product_id) { wp_delete_post($product_id, true); } } add_action('before_delete_post', 'delete_wc_product_with_tour'); // Funkcija za dodajanje ture v košarico function add_tour_to_cart() { try { // Preveri nonce za varnost if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'add_tour_to_cart')) { wp_send_json_error(array('message' => 'Security check failed')); return; } // Preveri če so vsi potrebni podatki prisotni $required_fields = array('tour_id', 'participants', 'date', 'name', 'email'); foreach ($required_fields as $field) { if (!isset($_POST[$field]) || empty($_POST[$field])) { wp_send_json_error(array('message' => "Missing required field: {$field}")); return; } } // Pridobi podatke iz zahtevka $tour_id = intval($_POST['tour_id']); $participants = intval($_POST['participants']); $date = sanitize_text_field($_POST['date']); $name = sanitize_text_field($_POST['name']); $email = sanitize_email($_POST['email']); // Preveri če je WooCommerce aktiviran if (!class_exists('WooCommerce')) { wp_send_json_error(array('message' => 'WooCommerce is not active')); return; } // Pridobi WooCommerce product ID $product_id = wc_get_product_id_by_sku('tour-' . $tour_id); if (!$product_id) { wp_send_json_error(array('message' => 'Product not found')); return; } // Počisti košarico WC()->cart->empty_cart(); // Dodaj produkt v košarico $cart_item_data = array( 'tour_date' => $date, 'participants' => $participants, 'customer_name' => $name, 'customer_email' => $email ); $added = WC()->cart->add_to_cart($product_id, $participants, 0, array(), $cart_item_data); if ($added) { wp_send_json_success(array( 'message' => 'Tour added to cart', 'checkout_url' => wc_get_checkout_url() )); } else { wp_send_json_error(array('message' => 'Failed to add tour to cart')); } } catch (Exception $e) { wp_send_json_error(array( 'message' => 'An error occurred: ' . $e->getMessage(), 'error' => $e->getTraceAsString() )); } } // Registriraj AJAX akcije add_action('wp_ajax_add_tour_to_cart', 'add_tour_to_cart'); add_action('wp_ajax_nopriv_add_tour_to_cart', 'add_tour_to_cart'); // Prikaži dodatne podatke v košarici in na checkout strani function display_cart_item_custom_meta($item_data, $cart_item) { if (isset($cart_item['tour_date'])) { $item_data[] = array( 'key' => 'Departure Date', 'value' => wc_clean($cart_item['tour_date']) ); } if (isset($cart_item['customer_name'])) { $item_data[] = array( 'key' => 'Customer Name', 'value' => wc_clean($cart_item['customer_name']) ); } if (isset($cart_item['customer_email'])) { $item_data[] = array( 'key' => 'Customer Email', 'value' => wc_clean($cart_item['customer_email']) ); } return $item_data; } add_filter('woocommerce_get_item_data', 'display_cart_item_custom_meta', 10, 2); // Shrani dodatne podatke v naročilo function add_custom_meta_to_order_items($item, $cart_item_key, $values, $order) { if (isset($values['tour_date'])) { $item->add_meta_data('Departure Date', $values['tour_date']); } if (isset($values['customer_name'])) { $item->add_meta_data('Customer Name', $values['customer_name']); } if (isset($values['customer_email'])) { $item->add_meta_data('Customer Email', $values['customer_email']); } } add_action('woocommerce_checkout_create_order_line_item', 'add_custom_meta_to_order_items', 10, 4); // Dodaj order bump template na checkout stran function add_order_bump_to_checkout() { include_once get_template_directory() . '/woocommerce/checkout/order-bump.php'; } // Odstrani stari hook remove_action('woocommerce_review_order_before_payment', 'add_order_bump_to_checkout'); // Dodaj nove hooke za različne lokacije add_action('woocommerce_checkout_before_order_review', 'add_order_bump_to_checkout'); add_action('woocommerce_before_checkout_form', 'add_order_bump_to_checkout'); // AJAX handler za posodobitev košarice z extras-i function handle_update_cart_extras() { check_ajax_referer('update_order_review', 'security'); if (!isset($_POST['extras'])) { wp_send_json_error('No extras provided'); return; } $extras = json_decode(stripslashes($_POST['extras']), true); // Odstrani obstoječe extras iz košarice foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) { if (isset($cart_item['is_extra']) && $cart_item['is_extra']) { WC()->cart->remove_cart_item($cart_item_key); } } // Pridobi tour ID iz prvega izdelka v košarici $tour_id = null; foreach (WC()->cart->get_cart() as $cart_item) { if (isset($cart_item['product_id'])) { $product = wc_get_product($cart_item['product_id']); if ($product) { $sku = $product->get_sku(); if (strpos($sku, 'tour-') === 0) { $tour_id = str_replace('tour-', '', $sku); break; } } } } if (!$tour_id) { wp_send_json_error('No tour found in cart'); return; } // Pridobi available extras za tour $available_extras = get_post_meta($tour_id, '_available_extras', true); // Dodaj izbrane extras v košarico foreach ($extras as $extra) { $index = $extra['index']; if (isset($available_extras[$index])) { $extra_data = $available_extras[$index]; // Ustvari nov produkt za extra $extra_product = new WC_Product_Simple(); $extra_product->set_name($extra_data['name']); $extra_product->set_price($extra_data['price']); $extra_product->set_status('private'); $extra_product->save(); // Dodaj extra v košarico WC()->cart->add_to_cart($extra_product->get_id(), 1, 0, array(), array( 'is_extra' => true, 'tour_id' => $tour_id, 'extra_data' => $extra_data )); // Izbriši začasni produkt wp_delete_post($extra_product->get_id(), true); } } WC()->cart->calculate_totals(); wp_send_json_success(); } add_action('wp_ajax_update_cart_extras', 'handle_update_cart_extras'); add_action('wp_ajax_nopriv_update_cart_extras', 'handle_update_cart_extras'); // Prikaži extra podatke v košarici in naročilu function display_cart_item_extra_meta($item_data, $cart_item) { if (isset($cart_item['is_extra']) && $cart_item['is_extra']) { $item_data[] = array( 'key' => 'Type', 'value' => 'Tour Extra' ); } return $item_data; } add_filter('woocommerce_get_item_data', 'display_cart_item_extra_meta', 10, 2); // Shrani extra podatke v naročilo function save_order_item_extra_meta($item, $cart_item_key, $values, $order) { if (isset($values['is_extra']) && $values['is_extra']) { $item->add_meta_data('_is_extra', true); $item->add_meta_data('_tour_id', $values['tour_id']); $item->add_meta_data('_extra_data', $values['extra_data']); } } add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_extra_meta', 10, 4); /** * Prikaži dodatne podatke o turi v košarici */ function display_tour_cart_item_data($item_data, $cart_item) { if (isset($cart_item['tour_date'])) { $item_data[] = array( 'key' => 'Date', 'value' => $cart_item['tour_date'] ); } if (isset($cart_item['participants'])) { $item_data[] = array( 'key' => 'Participants', 'value' => $cart_item['participants'] ); } return $item_data; } add_filter('woocommerce_get_item_data', 'display_tour_cart_item_data', 10, 2); /** * Shrani dodatne podatke o turi v naročilo */ function save_tour_order_item_meta($item, $cart_item_key, $values, $order) { if (isset($values['tour_date'])) { $item->add_meta_data('Date', $values['tour_date']); } if (isset($values['participants'])) { $item->add_meta_data('Participants', $values['participants']); } if (isset($values['is_tour_extra'])) { $item->add_meta_data('_is_tour_extra', true); if (isset($values['tour_id'])) { $item->add_meta_data('_tour_id', $values['tour_id']); } } } add_action('woocommerce_checkout_create_order_line_item', 'save_tour_order_item_meta', 10, 4); // Preusmeri na custom Thank You stran po uspešnem plačilu function redirect_to_custom_thank_you_page($order_received_url, $order) { return home_url('/thank-you/'); } add_filter('woocommerce_get_checkout_order_received_url', 'redirect_to_custom_thank_you_page', 10, 2); /** * Dodaj Customizer kontrolo za "drag & drop" Individual Tours znotraj Experience Journeyev */ function grilctours_customize_individual_tour_order($wp_customize) { // Dodaj sekcijo $wp_customize->add_section('individual_tour_order_section', array( 'title' => __('Individual Tours Order', 'grilctours'), 'priority' => 210, )); // Definiraj razred znotraj funkcije, samo ko je potreben class Individual_Tour_Order_Control extends WP_Customize_Control { public $type = 'individual_tour_order'; public $tours = array(); public $journey_id = 0; public function render_content() { // Edinstveni ID za ta kontrolnik $list_id = 'sortable-tour-list-' . $this->journey_id; ?> 'experience_journey', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', )); // Za vsak Experience Journey dodaj kontrolo za Individual Tours foreach ($journeys as $journey) { $journey_id = $journey->ID; $journey_title = $journey->post_title; // Pridobi vse Individual Tours za ta Experience Journey $tours = get_posts(array( 'post_type' => 'individual_tour', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => '_experience_journey', 'value' => $journey_id, 'compare' => '=' ) ) )); // Če ni Individual Tours za ta Journey, preskoči if (empty($tours)) { continue; } // Ustvari nastavitev za ta Journey $setting_id = 'individual_tour_order_' . $journey_id; $wp_customize->add_setting($setting_id, array( 'default' => '', 'type' => 'option', 'capability' => 'edit_theme_options', 'transport' => 'refresh', )); // Pridobi shranjeni vrstni red $saved_order = get_option($setting_id, ''); $order_array = !empty($saved_order) ? explode(',', $saved_order) : array(); // Sortiraj ture glede na obstoječ vrstni red $ordered_tours = array(); // Najprej dodaj tiste v shranjenem vrstnem redu foreach ($order_array as $id) { foreach ($tours as $index => $tour) { if ($tour->ID == $id) { $ordered_tours[] = $tour; unset($tours[$index]); break; } } } // Dodaj preostale na konec $ordered_tours = array_merge($ordered_tours, $tours); // Dodaj kontrolo $wp_customize->add_control( new Individual_Tour_Order_Control( $wp_customize, $setting_id, array( 'label' => sprintf(__('Tours in %s', 'grilctours'), $journey_title), 'description' => __('Drag and drop tours to change their order.', 'grilctours'), 'section' => 'individual_tour_order_section', 'tours' => $ordered_tours, 'journey_id' => $journey_id, ) ) ); } } add_action('customize_register', 'grilctours_customize_individual_tour_order'); /** * Razširi obstoječe JS in CSS za podporo urejanju Individual Tours */ function grilctours_customize_individual_tour_scripts() { $script = " jQuery(document).ready(function($) { setTimeout(function() { console.log('Začenjam inicializacijo sortable za Individual Tours...'); // Poišči vse sortable sezname Individual Tours var sortableLists = $('.sortable-tours-list'); if (sortableLists.length) { console.log('Najdenih', sortableLists.length, 'sortable seznamov za Individual Tours'); sortableLists.each(function() { var journeyId = $(this).data('journey-id'); var listId = $(this).attr('id'); console.log('Inicializiram seznam:', listId, 'za Journey ID:', journeyId); try { $(this).sortable({ containment: 'parent', cursor: 'move', handle: '.dashicons-menu', items: '.sortable-item', revert: true, tolerance: 'pointer', update: function(event, ui) { var ids = []; $(this).find('.sortable-item').each(function() { ids.push($(this).attr('data-id')); }); // Posodobi vrednost kontrole var settingId = 'individual_tour_order_' + journeyId; var inputField = $('input[data-customize-setting-link=\"' + settingId + '\"]'); console.log('Posodabljam', settingId, 'nova vrednost:', ids.join(',')); inputField.val(ids.join(',')).trigger('change'); } }).disableSelection(); console.log('Sortable uspešno inicializiran za', listId); } catch (e) { console.error('Napaka pri inicializaciji sortable za', listId, ':', e); } }); } else { console.log('Ni najdenih sortable seznamov za Individual Tours'); } }, 1500); }); "; wp_add_inline_script('jquery-ui-sortable', $script); } add_action('customize_controls_enqueue_scripts', 'grilctours_customize_individual_tour_scripts'); /** * Funkcija za urejanje vrstnega reda Experience Journeys glede na nastavitev v Customizer-ju * * @param WP_Query $query Query objekt */ function grilctours_order_experience_journeys($query) { // Izvajaj samo za glavne poizvedbe in experience_journey post type if (!is_admin() && $query->is_main_query() && (is_post_type_archive('experience_journey') || is_home() || is_front_page())) { // Pridobi shranjeni vrstni red $saved_order = get_option('experience_journey_order', ''); // Če je vrstni red definiran if (!empty($saved_order)) { $order_array = explode(',', $saved_order); // Uporabi shranjen vrstni red za poizvedbo if (!empty($order_array)) { $query->set('post_type', 'experience_journey'); $query->set('posts_per_page', -1); $query->set('orderby', 'post__in'); $query->set('post__in', $order_array); } } } } add_action('pre_get_posts', 'grilctours_order_experience_journeys'); /** * Dodaj nastavitve za Custom Inquiry sekcijo v WordPress Customizer */ function grilctours_customize_inquiry_section($wp_customize) { // Sekcija za nastavitve Custom Inquiry $wp_customize->add_section('inquiry_section_settings', array( 'title' => __('Inquiry Section Settings', 'grilctours'), 'priority' => 107, )); // Naslov sekcije $wp_customize->add_setting('inquiry_section_title', array( 'default' => 'Ready to Plan Your Custom Journey?', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('inquiry_section_title', array( 'label' => __('Section Title', 'grilctours'), 'section' => 'inquiry_section_settings', 'type' => 'text', )); // Opis sekcije $wp_customize->add_setting('inquiry_section_description', array( 'default' => 'A world of moonlit forests and twisting turquoise rivers, Slovenia is a fairytale destination. Home to storybook castles, historic towns, and picturesque alpine landscapes; let us create your perfect holiday experience.', 'sanitize_callback' => 'wp_kses_post', 'transport' => 'refresh', )); $wp_customize->add_control('inquiry_section_description', array( 'label' => __('Section Description', 'grilctours'), 'section' => 'inquiry_section_settings', 'type' => 'textarea', )); // Gumb besedilo $wp_customize->add_setting('inquiry_button_text', array( 'default' => 'START PLANNING', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', )); $wp_customize->add_control('inquiry_button_text', array( 'label' => __('Button Text', 'grilctours'), 'section' => 'inquiry_section_settings', 'type' => 'text', )); // Ozadje sekcije $wp_customize->add_setting('inquiry_section_background', array( 'default' => '', 'sanitize_callback' => 'esc_url_raw', 'transport' => 'refresh', )); $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'inquiry_section_background', array( 'label' => __('Section Background Image', 'grilctours'), 'section' => 'inquiry_section_settings', 'settings' => 'inquiry_section_background', ))); } add_action('customize_register', 'grilctours_customize_inquiry_section'); /** * Custom Inquiry Ajax Handler */ function handle_custom_inquiry_form() { // Beležimo začetek funkcije error_log('Custom inquiry form submission started'); // Preveri nonce (varnost) if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'custom_inquiry_nonce')) { error_log('Invalid security token in custom inquiry form'); wp_send_json_error('Invalid security token'); return; } // Pridobi podatke iz obrazca $name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : ''; $email = isset($_POST['email']) ? sanitize_email($_POST['email']) : ''; $travel_date = isset($_POST['travel_date']) ? sanitize_text_field($_POST['travel_date']) : 'Not specified'; $travelers = isset($_POST['travelers']) ? intval($_POST['travelers']) : 0; $destination = isset($_POST['destination']) ? sanitize_text_field($_POST['destination']) : 'Not specified'; $message = isset($_POST['message']) ? sanitize_textarea_field($_POST['message']) : ''; // Beleži prejete podatke error_log('Form data: Name=' . $name . ', Email=' . $email . ', Date=' . $travel_date . ', Travelers=' . $travelers); error_log('Form additional data: Destination=' . $destination . ', Message=' . substr($message, 0, 50) . (strlen($message) > 50 ? '...' : '')); // Preveri obvezna polja if (empty($name) || empty($email)) { error_log('Missing required fields in custom inquiry form'); wp_send_json_error('Please fill in all required fields.'); return; } // Nastavi fiksni e-poštni naslov prejemnika $admin_email = 'info@europewonder.com'; // Fiksni e-poštni naslov $to = $admin_email; error_log('Sending inquiry to admin email: ' . $to); // Nastavi zadevo $subject = 'New Custom Journey Inquiry from ' . $name; // Priprava sporočila $body = " New Custom Journey Inquiry

    New Custom Journey Inquiry

    A new inquiry has been submitted through your website:

    Name: " . esc_html($name) . "
    Email: " . esc_html($email) . "
    Planned Travel Date: " . esc_html($travel_date) . "
    Number of Travelers: " . esc_html($travelers) . "
    Preferred Destination(s): " . esc_html($destination) . "
    Message: " . nl2br(esc_html($message)) . "
    "; // Nastavi glave $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: Europe Wonder ', 'Reply-To: ' . esc_html($name) . ' <' . esc_html($email) . '>' ); // Beleži podrobnosti e-pošte pred pošiljanjem error_log('Attempting to send email with subject: ' . $subject); error_log('Email headers: ' . print_r($headers, true)); // Pošlji e-pošto in zapiši več informacij add_action('wp_mail_failed', function($wp_error) { error_log('WP Mail failed: ' . $wp_error->get_error_message()); }); // Pošlji e-pošto $sent = wp_mail($to, $subject, $body, $headers); // Beleži rezultat pošiljanja if (!$sent) { // Beleži napako pri pošiljanju global $phpmailer; if (isset($phpmailer) && isset($phpmailer->ErrorInfo) && !empty($phpmailer->ErrorInfo)) { error_log('PHPMailer error: ' . $phpmailer->ErrorInfo); } else { error_log('Email sending failed but no PHPMailer error available'); } error_log('WordPress admin email setting: ' . get_option('admin_email')); error_log('Email sending result: FAILED'); } else { error_log('Email sending result: SUCCESS'); } // Pošlji tudi e-pošto stranki if ($sent) { $customer_subject = 'Thank you for your inquiry - Europe Wonder'; $customer_body = " Thank You for Your Inquiry

    Thank You for Your Inquiry

    Dear " . esc_html($name) . ",

    Thank you for your interest in our custom journey services. We have received your inquiry and will get back to you as soon as possible to discuss your travel plans.

    Here's a summary of the information you provided:

    If you have any additional questions or information to add, please feel free to reply to this email.

    Best regards,
    Europe Wonder Team

    "; $customer_headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: Europe Wonder ' ); error_log('Attempting to send customer confirmation email to: ' . $email); error_log('Customer email headers: ' . print_r($customer_headers, true)); $customer_sent = wp_mail($email, $customer_subject, $customer_body, $customer_headers); if (!$customer_sent) { // Beleži napako pri pošiljanju potrditvenega e-sporočila global $phpmailer; if (isset($phpmailer) && isset($phpmailer->ErrorInfo) && !empty($phpmailer->ErrorInfo)) { error_log('Customer email PHPMailer error: ' . $phpmailer->ErrorInfo); } else { error_log('Customer email sending failed but no PHPMailer error available'); } error_log('Customer email sending result: FAILED'); } else { error_log('Customer email sending result: SUCCESS'); } } // Vrni odgovor if ($sent) { error_log('Custom inquiry form submission completed successfully'); wp_send_json_success('Thank you for your inquiry! We will contact you shortly.'); } else { error_log('Custom inquiry form submission failed - email not sent'); wp_send_json_error('There was an error sending your inquiry. Please try again.'); } } add_action('wp_ajax_custom_inquiry_submit', 'handle_custom_inquiry_form'); add_action('wp_ajax_nopriv_custom_inquiry_submit', 'handle_custom_inquiry_form'); // ... existing code ... // Dodatni AJAX handler za potrjevanje plačil function confirm_stripe_payment() { try { check_ajax_referer('confirm_stripe_payment', 'security'); // Preveri obvezne parametre if (empty($_POST['payment_intent_id']) || empty($_POST['order_id'])) { wp_send_json_error(['message' => 'Missing required parameters']); return; } $payment_intent_id = sanitize_text_field($_POST['payment_intent_id']); $order_id = intval($_POST['order_id']); // Preveri, da naročilo obstaja $order = wc_get_order($order_id); if (!$order) { wp_send_json_error(['message' => 'Order not found']); return; } // Preveri status plačilnega namena z API klicem na Stripe try { // Inicializiraj Stripe, če še ni if (!class_exists('\Stripe\Stripe')) { init_stripe(); } $payment_intent = \Stripe\PaymentIntent::retrieve($payment_intent_id); // Beleži podatke za razhroščevanje error_log('Stripe Payment Intent: ' . print_r($payment_intent, true)); // Če je plačilo uspešno if ($payment_intent->status === 'succeeded') { // Označi naročilo kot plačano $order->payment_complete($payment_intent_id); $order->add_order_note('Stripe payment confirmed via AJAX (Payment Intent ID: ' . $payment_intent_id . ')'); $order->save(); // Vrni uspeh wp_send_json_success([ 'message' => 'Payment confirmed', 'order_id' => $order_id, 'payment_intent_id' => $payment_intent_id ]); } else { // Če plačilo ni uspešno $order->update_status('failed', 'Stripe payment intent status: ' . $payment_intent->status); wp_send_json_error([ 'message' => 'Payment not completed. Status: ' . $payment_intent->status, 'payment_status' => $payment_intent->status ]); } } catch (Exception $e) { error_log('Error verifying payment intent: ' . $e->getMessage()); wp_send_json_error(['message' => 'Error verifying payment: ' . $e->getMessage()]); } } catch (Exception $e) { error_log('Payment confirmation error: ' . $e->getMessage()); wp_send_json_error(['message' => $e->getMessage()]); } } add_action('wp_ajax_confirm_stripe_payment', 'confirm_stripe_payment'); add_action('wp_ajax_nopriv_confirm_stripe_payment', 'confirm_stripe_payment'); // AJAX handler za generiranje povezave za plačilo preostalega zneska function generate_remaining_payment_link() { try { // Preveri, da je WooCommerce aktiviran if (!is_woocommerce_activated()) { wp_send_json_error(['message' => 'WooCommerce is not activated']); return; } check_ajax_referer('generate_payment_link', 'security'); // Preveri obvezne parametre if (empty($_POST['order_id'])) { wp_send_json_error(['message' => 'Missing order ID']); return; } $order_id = intval($_POST['order_id']); // Preveri, da naročilo obstaja $order = wc_get_order($order_id); if (!$order) { wp_send_json_error(['message' => 'Order not found']); return; } // Preveri, da gre za delno plačilo in da je prvi obrok že plačan $payment_type = get_post_meta($order_id, '_payment_type', true); $is_deposit_paid = get_post_meta($order_id, '_is_deposit_paid', true); $is_remaining_paid = get_post_meta($order_id, '_is_remaining_paid', true); if ($payment_type !== 'partial') { wp_send_json_error(['message' => 'This is not a partial payment order']); return; } if (!$is_deposit_paid) { wp_send_json_error(['message' => 'Deposit not yet paid']); return; } if ($is_remaining_paid) { wp_send_json_error(['message' => 'Remaining amount already paid']); return; } // Pridobi preostali znesek za plačilo $remaining_amount = floatval(get_post_meta($order_id, '_remaining_amount', true)); if (!$remaining_amount || $remaining_amount <= 0) { wp_send_json_error(['message' => 'Invalid remaining amount']); return; } // Inicializiraj Stripe, če še ni if (!class_exists('\Stripe\Stripe')) { init_stripe(); } // Ustvari nov Payment Intent za preostali znesek $payment_intent = \Stripe\PaymentIntent::create([ 'amount' => intval($remaining_amount * 100), // Stripe uporablja cente 'currency' => 'eur', 'metadata' => [ 'order_id' => $order_id, 'payment_type' => 'remaining', 'tour_name' => $order->get_order_item_name(0), // Ime prve postavke v naročilu 'payment_description' => 'Remaining payment (70%) for tour booking' ] ]); // Shrani nov Payment Intent ID v naročilo update_post_meta($order_id, '_stripe_remaining_payment_intent', $payment_intent->id); // Dodaj opombo naročilu $order->add_order_note(sprintf( 'Generated payment link for remaining balance of €%.2f (Payment Intent ID: %s)', $remaining_amount, $payment_intent->id )); $order->save(); // Vrni podatke za plačilo wp_send_json_success([ 'message' => 'Payment link generated', 'order_id' => $order_id, 'amount' => $remaining_amount, 'payment_intent_id' => $payment_intent->id, 'client_secret' => $payment_intent->client_secret ]); } catch (Exception $e) { error_log('Error generating payment link: ' . $e->getMessage()); wp_send_json_error(['message' => 'Error generating payment link: ' . $e->getMessage()]); } } add_action('wp_ajax_generate_remaining_payment_link', 'generate_remaining_payment_link'); add_action('wp_ajax_nopriv_generate_remaining_payment_link', 'generate_remaining_payment_link'); // ... existing code ... /** * Theme Functions */ // Vključi SMTP konfiguracijo require_once get_template_directory() . '/custom-smtp-config.php'; // ... existing code ... /** * Customizer nastavitve za About Us stran */ function grilctours_customize_about_page($wp_customize) { // Dodaj sekcijo za About stran $wp_customize->add_section('about_page_section', array( 'title' => __('About Page Settings', 'grilctours'), 'description' => __('Customize the About Us page content', 'grilctours'), 'priority' => 160, )); // Podnaslov $wp_customize->add_setting('about_subtitle', array( 'default' => 'Get to know our passionate team', 'sanitize_callback' => 'sanitize_text_field', )); $wp_customize->add_control('about_subtitle', array( 'label' => __('About Page Subtitle', 'grilctours'), 'section' => 'about_page_section', 'type' => 'text', )); // Nastavitve za člane ekipe $team_members = array( 'nejc' => 'Nejc Dovžan Kukič', 'matic' => 'Matic Snoj', 'luka' => 'Luka Dovžan Kukič', 'jernej' => 'Jernej Antloga', 'kevin' => 'Kevin Krajnc' ); foreach ($team_members as $id => $name) { // Naslov $wp_customize->add_setting('team_' . $id . '_name', array( 'default' => $name, 'sanitize_callback' => 'sanitize_text_field', )); $wp_customize->add_control('team_' . $id . '_name', array( 'label' => sprintf(__('%s - Name', 'grilctours'), $name), 'section' => 'about_page_section', 'type' => 'text', )); // Pozicija $default_positions = array( 'nejc' => 'CEO', 'matic' => 'COO', 'luka' => 'CFO', 'jernej' => 'Travel specialist', 'kevin' => 'Travel specialist' ); $wp_customize->add_setting('team_' . $id . '_position', array( 'default' => $default_positions[$id], 'sanitize_callback' => 'sanitize_text_field', )); $wp_customize->add_control('team_' . $id . '_position', array( 'label' => sprintf(__('%s - Position', 'grilctours'), $name), 'section' => 'about_page_section', 'type' => 'text', )); // Bio $default_bios = array( 'nejc' => 'A visionary leader with a passion for innovation and growth. Nejc drives the company\'s strategy with precision and purpose — when not in the office, you\'ll find him exploring mountain trails.', 'matic' => 'As the backbone of daily operations, Matic ensures everything runs smoothly behind the scenes. He\'s careful and detail-oriented and brings the same dedication to cycling in his free time.', 'luka' => 'Luka manages the company\'s financial strategy with focus and discipline. Reliable and analytical, he brings the same energy to both numbers and his love for cycling.', 'jernej' => 'Friendly and knowledgeable, Jernej designs personalized trips with energy and enthusiasm. A history enthusiast, he brings stories to life through travel.', 'kevin' => 'Creative and detail-oriented, Kevin helps clients plan seamless, custom journeys. He\'s a road trip specialist known for his helpful nature and great communication skills.' ); $wp_customize->add_setting('team_' . $id . '_bio', array( 'default' => $default_bios[$id], 'sanitize_callback' => 'wp_kses_post', )); $wp_customize->add_control('team_' . $id . '_bio', array( 'label' => sprintf(__('%s - Bio', 'grilctours'), $name), 'section' => 'about_page_section', 'type' => 'textarea', )); // Slika $wp_customize->add_setting('team_' . $id . '_image', array( 'default' => get_template_directory_uri() . '/images/' . $id . '.webp', 'sanitize_callback' => 'esc_url_raw', )); $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'team_' . $id . '_image', array( 'label' => sprintf(__('%s - Image', 'grilctours'), $name), 'section' => 'about_page_section', 'settings' => 'team_' . $id . '_image', ))); } } add_action('customize_register', 'grilctours_customize_about_page'); // ... existing code ... /** * Funkcija za obdelavo kontaktnega obrazca */ function handle_contact_form() { // Beležimo začetek funkcije error_log('Contact form submission started'); // Preveri nonce (varnost) if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'contact_form_nonce')) { error_log('Invalid security token in contact form'); wp_send_json_error('Invalid security token'); return; } // Pridobi podatke iz obrazca $name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : ''; $email = isset($_POST['email']) ? sanitize_email($_POST['email']) : ''; $subject = isset($_POST['subject']) ? sanitize_text_field($_POST['subject']) : ''; $message = isset($_POST['message']) ? sanitize_textarea_field($_POST['message']) : ''; // Beleži prejete podatke error_log('Contact form data: Name=' . $name . ', Email=' . $email . ', Subject=' . $subject); error_log('Contact form message: ' . substr($message, 0, 50) . (strlen($message) > 50 ? '...' : '')); // Preveri obvezna polja if (empty($name) || empty($email) || empty($subject) || empty($message)) { error_log('Missing required fields in contact form'); wp_send_json_error('Please fill in all required fields.'); return; } // Nastavi fiksni e-poštni naslov prejemnika $admin_email = 'info@europewonder.com'; // Fiksni e-poštni naslov $to = $admin_email; error_log('Sending message to admin email: ' . $to); // Nastavi zadevo $email_subject = 'New Contact Form Message: ' . $subject; // Priprava sporočila za administratorja $admin_body = " New Contact Form Message

    New Contact Form Message

    A new message has been submitted through your website's contact form:

    Name: " . esc_html($name) . "
    Email: " . esc_html($email) . "
    Subject: " . esc_html($subject) . "
    Message: " . nl2br(esc_html($message)) . "
    "; // Nastavi glave $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: Europe Wonder ', 'Reply-To: ' . esc_html($name) . ' <' . esc_html($email) . '>' ); // Beleži podrobnosti e-pošte pred pošiljanjem error_log('Attempting to send email with subject: ' . $email_subject); error_log('Email headers: ' . print_r($headers, true)); // Pošlji e-pošto in zapiši več informacij add_action('wp_mail_failed', function($wp_error) { error_log('WP Mail failed: ' . $wp_error->get_error_message()); }); // Pošlji e-pošto administratorju $sent = wp_mail($to, $email_subject, $admin_body, $headers); // Beleži rezultat pošiljanja if (!$sent) { // Beleži napako pri pošiljanju global $phpmailer; if (isset($phpmailer) && isset($phpmailer->ErrorInfo) && !empty($phpmailer->ErrorInfo)) { error_log('PHPMailer error: ' . $phpmailer->ErrorInfo); } else { error_log('Email sending failed but no PHPMailer error available'); } error_log('WordPress admin email setting: ' . get_option('admin_email')); error_log('Email sending result: FAILED'); } else { error_log('Email sending result: SUCCESS'); } // Pošlji tudi e-pošto stranki if ($sent) { $customer_subject = 'Thank you for contacting Europe Wonder'; $customer_body = " Thank You for Your Message

    Thank You for Your Message

    Dear " . esc_html($name) . ",

    Thank you for contacting Europe Wonder. We have received your message and will get back to you as soon as possible.

    Here's a copy of the message you sent us:

    Subject: " . esc_html($subject) . "

    Message:
    " . nl2br(esc_html($message)) . "

    If you have any additional questions, please feel free to reply to this email.

    Best regards,
    Europe Wonder Team

    "; $customer_headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: Europe Wonder ' ); error_log('Attempting to send customer confirmation email to: ' . $email); error_log('Customer email headers: ' . print_r($customer_headers, true)); $customer_sent = wp_mail($email, $customer_subject, $customer_body, $customer_headers); if (!$customer_sent) { // Beleži napako pri pošiljanju potrditvenega e-sporočila global $phpmailer; if (isset($phpmailer) && isset($phpmailer->ErrorInfo) && !empty($phpmailer->ErrorInfo)) { error_log('Customer email PHPMailer error: ' . $phpmailer->ErrorInfo); } else { error_log('Customer email sending failed but no PHPMailer error available'); } error_log('Customer email sending result: FAILED'); } else { error_log('Customer email sending result: SUCCESS'); } } // Vrni odgovor if ($sent) { error_log('Contact form submission completed successfully'); wp_send_json_success('Thank you for your message! We will contact you shortly.'); } else { error_log('Contact form submission failed - email not sent'); wp_send_json_error('There was an error sending your message. Please try again.'); } } add_action('wp_ajax_contact_form_submit', 'handle_contact_form'); add_action('wp_ajax_nopriv_contact_form_submit', 'handle_contact_form'); /** * Funkcija za pridobivanje nonce vrednosti za obrazec Custom Journey Inquiry */ function get_inquiry_nonce() { wp_send_json_success(wp_create_nonce('custom_inquiry_nonce')); } add_action('wp_ajax_get_inquiry_nonce', 'get_inquiry_nonce'); add_action('wp_ajax_nopriv_get_inquiry_nonce', 'get_inquiry_nonce'); /** * Dodamo AJAX URL v JavaScript za plavajoči gumb obrazca */ function add_inquiry_ajax_object() { wp_localize_script('grilctours-script', 'inquiry_ajax_object', array( 'ajax_url' => admin_url('admin-ajax.php') )); } add_action('wp_enqueue_scripts', 'add_inquiry_ajax_object', 20); /** * Obdelava povpraševanja za ture brez cene */ function send_tour_inquiry() { check_ajax_referer('send_tour_inquiry', 'security'); try { // Preveri obvezna polja $required_fields = [ 'name' => 'Full Name', 'email' => 'Email', 'date' => 'Departure Date', 'participants' => 'Number of Participants', 'tour_name' => 'Tour Name' ]; $missing_fields = []; foreach ($required_fields as $field => $label) { if (empty($_POST[$field])) { $missing_fields[] = $label; } } if (!empty($missing_fields)) { throw new Exception('The following fields are required: ' . implode(', ', $missing_fields)); } // Preveri veljavnost e-pošte if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { throw new Exception('Please enter a valid email address.'); } // Pripravi vsebino e-pošte $to = 'info@europewonder.com'; $subject = 'New Tour Inquiry: ' . sanitize_text_field($_POST['tour_name']); $message = "A new tour inquiry has been received:\n\n"; $message .= "Tour: " . sanitize_text_field($_POST['tour_name']) . "\n"; $message .= "Name: " . sanitize_text_field($_POST['name']) . "\n"; $message .= "Email: " . sanitize_email($_POST['email']) . "\n"; $message .= "Departure Date: " . sanitize_text_field($_POST['date']) . "\n"; $message .= "Number of Participants: " . intval($_POST['participants']) . "\n\n"; // Dodaj sporočilo, če obstaja if (!empty($_POST['message'])) { $message .= "Additional Message:\n" . sanitize_textarea_field($_POST['message']) . "\n\n"; } $message .= "This is an inquiry for a tour without a fixed price."; $headers = array( 'Content-Type: text/plain; charset=UTF-8', 'From: ' . get_bloginfo('name') . ' <' . get_bloginfo('admin_email') . '>', 'Reply-To: ' . sanitize_text_field($_POST['name']) . ' <' . sanitize_email($_POST['email']) . '>' ); // Pošlji e-pošto $sent = wp_mail($to, $subject, $message, $headers); if (!$sent) { throw new Exception('Failed to send inquiry email. Please try again later.'); } // Pošlji potrditveno e-pošto stranki $customer_subject = 'Your Tour Inquiry - ' . get_bloginfo('name'); $customer_message = "Dear " . sanitize_text_field($_POST['name']) . ",\n\n"; $customer_message .= "Thank you for your inquiry about our tour:\n"; $customer_message .= sanitize_text_field($_POST['tour_name']) . "\n\n"; $customer_message .= "We have received your request with the following details:\n"; $customer_message .= "Departure Date: " . sanitize_text_field($_POST['date']) . "\n"; $customer_message .= "Number of Participants: " . intval($_POST['participants']) . "\n"; // Dodaj sporočilo v potrditveno e-pošto if (!empty($_POST['message'])) { $customer_message .= "\nYour Message:\n" . sanitize_textarea_field($_POST['message']) . "\n"; } $customer_message .= "\nWe will review your inquiry and get back to you as soon as possible with pricing and availability information.\n\n"; $customer_message .= "Best regards,\n"; $customer_message .= get_bloginfo('name') . " Team"; wp_mail(sanitize_email($_POST['email']), $customer_subject, $customer_message, $headers); wp_send_json_success(['message' => 'Your inquiry has been sent successfully.']); } catch (Exception $e) { wp_send_json_error(['message' => $e->getMessage()]); } } add_action('wp_ajax_send_tour_inquiry', 'send_tour_inquiry'); add_action('wp_ajax_nopriv_send_tour_inquiry', 'send_tour_inquiry'); // Enqueue popup scripts and styles function enqueue_popup_assets() { if (is_front_page() || is_singular('individual_tour')) { wp_enqueue_style('popup-styles', get_template_directory_uri() . '/css/popup.css'); wp_enqueue_script('popup-script', get_template_directory_uri() . '/js/popup.js', array('jquery'), '', true); } } add_action('wp_enqueue_scripts', 'enqueue_popup_assets'); // Add popup HTML to footer function add_popup_html() { ?> get_error_message()); wp_send_json_error('Failed to create user'); return; } // Nastavi vlogo uporabnika na "subscriber" $user = new WP_User($user_id); $user->set_role('subscriber'); // Dodaj meta podatek, da je bil uporabnik ustvarjen preko popup-a update_user_meta($user_id, 'signup_source', 'popup_subscription'); update_user_meta($user_id, 'signup_date', current_time('mysql')); wp_send_json_success('Subscription successful'); } add_action('wp_ajax_save_popup_email', 'handle_popup_email'); add_action('wp_ajax_nopriv_save_popup_email', 'handle_popup_email');