Plugin Directory

Changeset 3454430


Ignore:
Timestamp:
02/05/2026 09:47:04 AM (7 weeks ago)
Author:
codemenschen
Message:

Version 4.6.4 - Released: February 05, 2026

  • Fix: Prevent WooCommerce email preview fatal. Ensure payment-complete filter returns original status for empty $order_id and validate WC_Order before calling methods to avoid preview crashes. (Files: include/redeem-voucher.php)
  • Fix: Do not force Stripe-paid orders to 'processing' for digital/download-only orders. Only set 'processing' when incoming status is 'completed' and the order requires shipping. (Files: include/redeem-voucher.php)
  • Fix/Improvement: Add diagnostics and robustness for Stripe order status and email handling — added temporary logs (WPGV_STATUS_DEBUG, wpgv_log_order_status_change), input guards and fallback for admin mail helper to prevent undefined function errors and PHP warnings. (Files: include/redeem-voucher.php, classes/wpgv-gift-voucher-cart-process.php, gift-voucher.php)
  • Fix: Load plugin translations on init and defer plugin file includes to prevent WordPress 6.7+ _load_textdomain_just_in_time notice. (Files: gift-voucher.php, admin.php, front.php)
  • Fix: Ensure post types/taxonomies are registered immediately if voucher_posttype.php is included late to avoid "Invalid post type." in admin. (Files: gift-voucher.php, include/voucher_posttype.php)
  • Fix: Remove unnecessary wpdb->prepare() usage without placeholders to prevent wpdb::prepare() notices. (Files: classes/template.php)
  • Fix: Add missing _wpgv_nonce hidden input to the Gift Voucher product tab so product updates without price no longer trigger "Invalid request." (Files: include/wpgv-product-settings.php, admin/wpgv-gift-voucher-admin.php)
  • Fix: Avoid warnings in [wpgv_giftcard] shortcode when taxonomy terms are returned as arrays; handle both term objects and arrays and escape output. (Files: giftcard.php)
Location:
gift-voucher
Files:
975 added
9 edited

Legend:

Unmodified
Added
Removed
  • gift-voucher/trunk/classes/template.php

    r3248177 r3454430  
    7171            global $wpdb;
    7272
    73             return $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}giftvouchers_template"));
     73            // No placeholders needed — use a plain query for row count to avoid prepare() notices
     74            return $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}giftvouchers_template");
    7475        }
    7576
  • gift-voucher/trunk/classes/wpgv-gift-voucher-cart-process.php

    r3258145 r3454430  
    377377        function add_gift_vouchers_to_order($order_id, $order, $note)
    378378        {
     379            // Initialize commonly used variables to avoid undefined warnings
     380            $return = '';
     381            if (! $order || ! ( $order instanceof WC_Order ) ) {
     382                $order = wc_get_order($order_id);
     383            }
     384            $billing_email = '';
     385            if ( $order && $order instanceof WC_Order ) {
     386                $billing_email = $order->get_billing_email();
     387            }
    379388
    380389            // translators: 1: Order ID, 2: Customer's first name, 3: Customer's last name.
     
    515524                        $recipientto = $voucher_options->from_name . '<' . $buy_email . '>';
    516525                    }
    517                     if ($voucher_options->email_send_date_time == 'send_instantly') {
     526                    $email_send_time = isset($voucher_options->email_send_date_time) ? $voucher_options->email_send_date_time : 'send_instantly';
     527                    if ($email_send_time === 'send_instantly' || empty($email_send_time)) {
    518528                        $checkmail1 = wp_mail($recipientto, $recipientsub, $recipientmsg, $headers, $attachments_user);
    519529                    } else {
    520                         $timezone = wp_timezone();
    521                         $datetime = new DateTime($voucher_options->email_send_date_time, $timezone);
    522                         $send_gift_voucher_email_event_date_time = $datetime->getTimestamp();
    523 
    524                         $send_gift_voucher_email_event_args = array($recipientto, $recipientsub, $recipientmsg, $headers, $attachments_user);
    525                         wp_schedule_single_event($send_gift_voucher_email_event_date_time, 'send_gift_voucher_email_event', $send_gift_voucher_email_event_args);
     530                        // Safely parse provided datetime; if parsing fails fallback to sending instantly.
     531                        try {
     532                            $timezone = wp_timezone();
     533                            $datetime = new DateTime($email_send_time, $timezone);
     534                            $send_gift_voucher_email_event_date_time = $datetime->getTimestamp();
     535
     536                            $send_gift_voucher_email_event_args = array($recipientto, $recipientsub, $recipientmsg, $headers, $attachments_user);
     537                            wp_schedule_single_event($send_gift_voucher_email_event_date_time, 'send_gift_voucher_email_event', $send_gift_voucher_email_event_args);
     538                        } catch (Exception $e) {
     539                            // On error, send immediately and log the issue for debugging.
     540                            error_log('WPGV: Failed to schedule voucher email: ' . $e->getMessage());
     541                            $checkmail1 = wp_mail($recipientto, $recipientsub, $recipientmsg, $headers, $attachments_user);
     542                        }
    526543                    }
    527544                }
     
    571588                }
    572589
    573                 $subadmin = wpgv_mailvarstr_multiple_admin($adminemailsubject, $setting_options, $voucher_options_results);
    574                 $bodyadmin = wpgv_mailvarstr_multiple_admin($adminemailbody, $setting_options, $voucher_options_results);
     590                if ( function_exists('wpgv_mailvarstr_multiple_admin') ) {
     591                    $subadmin = wpgv_mailvarstr_multiple_admin($adminemailsubject, $setting_options, $voucher_options_results);
     592                    $bodyadmin = wpgv_mailvarstr_multiple_admin($adminemailbody, $setting_options, $voucher_options_results);
     593                } else {
     594                    // Fallback to non-admin variant
     595                    $first = !empty($voucher_options_results) && is_array($voucher_options_results) ? reset($voucher_options_results) : $voucher_options_results;
     596                    $voucherpdf_link = isset($first->voucherpdf_link) ? $first->voucherpdf_link : '';
     597                    $subadmin = wpgv_mailvarstr_multiple($adminemailsubject, $setting_options, $voucher_options_results, $voucherpdf_link);
     598                    $bodyadmin = wpgv_mailvarstr_multiple($adminemailbody, $setting_options, $voucher_options_results, $voucherpdf_link);
     599                }
    575600                $headersadmin = 'Content-type: text/html;charset=utf-8' . "\r\n";
    576601                $headersadmin .= 'From: ' . $setting_options->sender_name . ' <' . $setting_options->sender_email . '>' . "\r\n";
  • gift-voucher/trunk/gift-voucher.php

    r3444528 r3454430  
    77 * Author: Codemenschen GmbH
    88 * Author URI: https://www.codemenschen.at/
    9  * Version: 4.6.3
     9 * Version: 4.6.4
    1010 * Text Domain: gift-voucher
    1111 * Domain Path: /languages
     
    3939}
    4040
    41 define('WPGIFT_VERSION', '4.6.3');
     41define('WPGIFT_VERSION', '4.6.4');
    4242define('WPGIFT__MINIMUM_WP_VERSION', '4.0');
    4343define('WPGIFT__PLUGIN_DIR', untrailingslashit(plugin_dir_path(__FILE__)));
     
    8484  return !empty($options->is_woocommerce_enable);
    8585}
    86 function wpgiftv_plugin_init()
    87 {
    88   $langOK = load_plugin_textdomain('gift-voucher', false, dirname(plugin_basename(__FILE__)) . '/languages');
    89 }
    90 
    91 // Load textdomain at the right time to avoid WordPress 6.7+ warnings
    92 add_action('init', 'wpgiftv_plugin_init');
    93 add_action('after_setup_theme', 'wpgiftv_plugin_init');
    94 add_action('admin_init', 'wpgiftv_plugin_init');
    95 
    96 require_once(WPGIFT__PLUGIN_DIR . '/vendor/autoload.php');
    97 require_once(WPGIFT__PLUGIN_DIR . '/vendor/sofort/payment/sofortLibSofortueberweisung.inc.php');
    98 require_once(WPGIFT__PLUGIN_DIR . '/classes/rotation.php');
    99 require_once(WPGIFT__PLUGIN_DIR . '/admin.php');
    100 require_once(WPGIFT__PLUGIN_DIR . '/front.php');
    101 require_once(WPGIFT__PLUGIN_DIR . '/giftitems.php');
    102 require_once(WPGIFT__PLUGIN_DIR . '/classes/fpdf.php');
    103 require_once(WPGIFT__PLUGIN_DIR . '/classes/voucher.php');
    104 require_once(WPGIFT__PLUGIN_DIR . '/classes/template.php');
    105 require_once(WPGIFT__PLUGIN_DIR . '/classes/page_template.php');
    106 require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_voucher_pdf.php');
    107 require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_item_pdf.php');
    108 require_once(WPGIFT__PLUGIN_DIR . '/include/voucher_posttype.php');
    109 require_once(WPGIFT__PLUGIN_DIR . '/include/voucher_metabox.php');
    110 require_once(WPGIFT__PLUGIN_DIR . '/include/voucher-shortcodes.php');
    111 require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-gift-voucher.php');
    112 require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-gift-voucher-activity.php');
    113 require_once(WPGIFT__PLUGIN_DIR . '/giftcard.php');
    114 require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_giftcard_pdf.php');
    115 require_once(WPGIFT__PLUGIN_DIR . '/include/edit-order-voucher.php');
    116 
    117 
    118 if (wpgv_is_woocommerce_enable()) {
    119   require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-voucher-product-list.php');
    120   require_once(WPGIFT__PLUGIN_DIR . '/include/wc_wpgv_voucher_pdf.php');
    121   require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-check-plugin-active.php');
    122 }
     86
     87// Load translations and plugin files on init to avoid early translation notice (WP 6.7+)
     88add_action('init', function() {
     89  load_plugin_textdomain('gift-voucher', false, dirname(plugin_basename(__FILE__)) . '/languages');
     90
     91  require_once(WPGIFT__PLUGIN_DIR . '/vendor/autoload.php');
     92  require_once(WPGIFT__PLUGIN_DIR . '/vendor/sofort/payment/sofortLibSofortueberweisung.inc.php');
     93  require_once(WPGIFT__PLUGIN_DIR . '/classes/rotation.php');
     94  require_once(WPGIFT__PLUGIN_DIR . '/admin.php');
     95  require_once(WPGIFT__PLUGIN_DIR . '/front.php');
     96  require_once(WPGIFT__PLUGIN_DIR . '/giftitems.php');
     97  require_once(WPGIFT__PLUGIN_DIR . '/classes/fpdf.php');
     98  require_once(WPGIFT__PLUGIN_DIR . '/classes/voucher.php');
     99  require_once(WPGIFT__PLUGIN_DIR . '/classes/template.php');
     100  require_once(WPGIFT__PLUGIN_DIR . '/classes/page_template.php');
     101  require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_voucher_pdf.php');
     102  require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_item_pdf.php');
     103  require_once(WPGIFT__PLUGIN_DIR . '/include/voucher_posttype.php');
     104  // If we are including this file during 'init' after priority 0 executed, the
     105  // post type registration hooks added in voucher_posttype.php won't have run
     106  // on this request. Register them immediately if needed so admin pages work.
     107  if (!post_type_exists('wpgv_voucher_product') && function_exists('wpgv_voucher_product_function')) {
     108    wpgv_voucher_product_function();
     109  }
     110  if (!taxonomy_exists('wpgv_voucher_category') && function_exists('wpgv_voucher_category_function')) {
     111    wpgv_voucher_category_function();
     112  }
     113  if (!post_type_exists('voucher_template') && function_exists('codemenschen_voucher_template')) {
     114    codemenschen_voucher_template();
     115  }
     116  if (!taxonomy_exists('category_voucher_template') && function_exists('codemenschen_voucher_template_category')) {
     117    codemenschen_voucher_template_category();
     118  }
     119
     120  require_once(WPGIFT__PLUGIN_DIR . '/include/voucher_metabox.php');
     121  require_once(WPGIFT__PLUGIN_DIR . '/include/voucher-shortcodes.php');
     122  require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-gift-voucher.php');
     123  require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-gift-voucher-activity.php');
     124  require_once(WPGIFT__PLUGIN_DIR . '/giftcard.php');
     125  require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_giftcard_pdf.php');
     126  require_once(WPGIFT__PLUGIN_DIR . '/include/edit-order-voucher.php');
     127
     128  if (wpgv_is_woocommerce_enable()) {
     129    require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-voucher-product-list.php');
     130    require_once(WPGIFT__PLUGIN_DIR . '/include/wc_wpgv_voucher_pdf.php');
     131    require_once(WPGIFT__PLUGIN_DIR . '/classes/wpgv-check-plugin-active.php');
     132  }
     133}, 1);
    123134
    124135add_action('init', function () {
     
    826837  $email = null;
    827838  $amount = null;
     839
     840  // Normalize input: ensure we can iterate and access an example item safely.
     841  if (empty($voucher_options_results)) {
     842    return $string;
     843  }
     844
    828845  foreach ($voucher_options_results as $get_value) {
    829     $get_link_pdf[] = get_home_url() . '/wp-content/uploads/voucherpdfuploads/' . $get_value->voucherpdf_link . '.pdf';
    830     $get_order_number[] = $get_value->id;
    831     $from_name = $get_value->from_name;
    832     $to_name = $get_value->to_name;
    833     if ($get_value->email) {
     846    $get_link_pdf[] = get_home_url() . '/wp-content/uploads/voucherpdfuploads/' . (isset($get_value->voucherpdf_link) ? $get_value->voucherpdf_link : '') . '.pdf';
     847    $get_order_number[] = isset($get_value->id) ? $get_value->id : '';
     848    $from_name = isset($get_value->from_name) ? $get_value->from_name : '';
     849    $to_name = isset($get_value->to_name) ? $get_value->to_name : '';
     850    if (!empty($get_value->email)) {
    834851      $email = $get_value->email;
    835852    } else {
    836       $email = $get_value->shipping_email;
     853      $email = isset($get_value->shipping_email) ? $get_value->shipping_email : '';
    837854    }
    838     $amount = $get_value->amount;
    839   }
    840 
     855    $amount = isset($get_value->amount) ? $get_value->amount : '';
     856  }
     857
     858  // Use the first record as a representative for order-level fields if necessary.
     859  $first = is_array($voucher_options_results) ? reset($voucher_options_results) : $voucher_options_results;
    841860
    842861  $vars = array(
    843     '{order_type}'        => ($voucher_options_results->order_type) ? $voucher_options_results->order_type : 'vouchers',
    844     '{company_name}'      => ($setting_options->company_name) ? stripslashes($setting_options->company_name) : '',
     862    '{order_type}'        => (!empty($first->order_type)) ? $first->order_type : 'vouchers',
     863    '{company_name}'      => (!empty($setting_options->company_name)) ? stripslashes($setting_options->company_name) : '',
    845864    '{website_url}'       => get_site_url(),
    846     '{sender_email}'      => $setting_options->sender_email,
    847     '{sender_name}'       => stripslashes($setting_options->sender_name),
    848     '{order_number}'      => $voucher_options_results->id,
     865    '{sender_email}'      => isset($setting_options->sender_email) ? $setting_options->sender_email : '',
     866    '{sender_name}'       => isset($setting_options->sender_name) ? stripslashes($setting_options->sender_name) : '',
     867    '{order_number}'      => isset($first->id) ? $first->id : '',
    849868    '{amount}'            => $amount,
    850869    '{customer_name}'     => stripslashes($from_name),
    851870    '{recipient_name}'    => stripslashes($to_name),
    852871    '{customer_email}'    => $email,
    853     '{customer_address}'  => $voucher_options_results->address,
    854     '{customer_postcode}' => $voucher_options_results->postcode,
    855     '{coupon_code}'       => $voucher_options_results->couponcode,
    856     '{payment_method}'    => $voucher_options_results->pay_method,
    857     '{payment_status}'    => $voucher_options_results->payment_status,
     872    '{customer_address}'  => isset($first->address) ? $first->address : '',
     873    '{customer_postcode}' => isset($first->postcode) ? $first->postcode : '',
     874    '{coupon_code}'       => isset($first->couponcode) ? $first->couponcode : '',
     875    '{payment_method}'    => isset($first->pay_method) ? $first->pay_method : '',
     876    '{payment_status}'    => isset($first->payment_status) ? $first->payment_status : '',
    858877    '{pdf_link}'          => get_home_url() . '/wp-content/uploads/voucherpdfuploads/' . $voucherpdf_link . '.pdf',
    859     '{receipt_link}'      => get_home_url() . '/wp-content/uploads/voucherpdfuploads/' . $voucher_options_results->voucherpdf_link . '-receipt.pdf',
     878    '{receipt_link}'      => get_home_url() . '/wp-content/uploads/voucherpdfuploads/' . (isset($first->voucherpdf_link) ? $first->voucherpdf_link : '') . '-receipt.pdf',
    860879  );
    861880  return strtr($string, $vars);
     881}
     882
     883// Provide admin variant fallback if not defined elsewhere. This keeps backward compatibility
     884if (! function_exists('wpgv_mailvarstr_multiple_admin')) {
     885  function wpgv_mailvarstr_multiple_admin($string, $setting_options, $voucher_options_results)
     886  {
     887    // Try to use the same logic as wpgv_mailvarstr_multiple; admin templates typically do not need a specific pdf link.
     888    $first = !empty($voucher_options_results) && is_array($voucher_options_results) ? reset($voucher_options_results) : $voucher_options_results;
     889    $voucherpdf_link = isset($first->voucherpdf_link) ? $first->voucherpdf_link : '';
     890    return wpgv_mailvarstr_multiple($string, $setting_options, $voucher_options_results, $voucherpdf_link);
     891  }
    862892}
    863893function wpgv_mailvarstr($string, $setting_options, $voucher_options)
  • gift-voucher/trunk/giftcard.php

    r3394006 r3454430  
    673673    if (!empty($category_voucher)) {
    674674        foreach ($category_voucher as $key => $category) {
    675             $html .= '<li class="category-nav-item"><a class="category-voucher-item" data-category-id=' . $category->term_id . '>' . $category->name . '</a></li>';
     675            // Support both WP_Term objects and term arrays
     676            if (is_object($category)) {
     677                $cat_id = isset($category->term_id) ? $category->term_id : '';
     678                $cat_name = isset($category->name) ? $category->name : '';
     679            } else {
     680                $cat_id = isset($category['term_id']) ? $category['term_id'] : '';
     681                $cat_name = isset($category['name']) ? $category['name'] : '';
     682            }
     683            $html .= '<li class="category-nav-item"><a class="category-voucher-item" data-category-id="' . esc_attr($cat_id) . '">' . esc_html($cat_name) . '</a></li>';
    676684        }
    677685    }
  • gift-voucher/trunk/include/redeem-voucher.php

    r3179739 r3454430  
    3333                add_filter('woocommerce_paypal_args', array($this, 'woocommerce_paypal_args'), 10, 2);
    3434                add_filter('woocommerce_payment_complete_order_status', array($this, 'filter_woocommerce_payment_complete_order_status_gift_voucher'), 10, 3);
     35
     36                // Temporary: log status changes for Stripe orders to trace who sets order status
     37                add_action('woocommerce_order_status_changed', array($this, 'wpgv_log_order_status_change'), 10, 4);
     38
    3539                add_action('wp_ajax_nopriv_wpgv-gift-voucher-redeem', array($this, 'wpgv_ajax_redeem'));
    3640                add_action('wp_ajax_wpgv-gift-voucher-redeem', array($this, 'wpgv_ajax_redeem'));
     
    140144        }
    141145        // checking status order payment  stripe
    142         function filter_woocommerce_payment_complete_order_status_gift_voucher($var, $order_id, $instance)
    143         {
    144             if (! $order_id) {
    145                 return;
    146             }
    147             $order = wc_get_order($order_id);
    148             if ($order->get_payment_method() == 'stripe') {
     146        function filter_woocommerce_payment_complete_order_status_gift_voucher($status, $order_id, $instance)
     147        {
     148            // Keep the original status if no order ID is provided (e.g., email previews)
     149            if ( empty( $order_id ) ) {
     150                return $status;
     151            }
     152
     153            $order = wc_get_order( $order_id );
     154
     155            // Ensure we have a valid order object before calling methods on it
     156            if ( ! $order || ! $order instanceof WC_Order ) {
     157                return $status;
     158            }
     159
     160            // Debug logging when WP_DEBUG enabled
     161            if ( defined('WP_DEBUG') && WP_DEBUG ) {
     162                $items = array();
     163                foreach ( $order->get_items() as $item ) {
     164                    $p = $item->get_product();
     165                    $items[] = array(
     166                        'product_id' => $item->get_product_id(),
     167                        'is_virtual' => $p ? ( method_exists( $p, 'is_virtual' ) ? $p->is_virtual() : null ) : null,
     168                        'is_downloadable' => $p ? ( method_exists( $p, 'is_downloadable' ) ? $p->is_downloadable() : null ) : null,
     169                        'quantity' => $item->get_quantity(),
     170                    );
     171                }
     172                error_log('WPGV_STATUS_DEBUG: order_id=' . $order_id . ', status_in=' . $status . ', payment_method=' . $order->get_payment_method() . ', needs_shipping=' . ( $order->needs_shipping() ? '1' : '0' ) . ', items=' . json_encode( $items ));
     173            }
     174
     175            // Only adjust for Stripe payments
     176            if ( $order->get_payment_method() !== 'stripe' ) {
     177                return $status;
     178            }
     179
     180            // Only override when WooCommerce intends to mark as 'completed'.
     181            // This avoids forcing 'processing' in contexts like preview or for digital-only orders.
     182            if ( $status !== 'completed' ) {
     183                return $status;
     184            }
     185
     186            // Determine whether the order requires shipping (i.e., has any non-virtual, non-downloadable product)
     187            $needs_processing = false;
     188            foreach ( $order->get_items() as $item ) {
     189                $product = $item->get_product();
     190                if ( $product && ! $product->is_virtual() && ! $product->is_downloadable() ) {
     191                    $needs_processing = true;
     192                    break;
     193                }
     194            }
     195
     196            if ( $needs_processing ) {
    149197                return 'processing';
    150             } else {
    151                 return $var;
    152             }
    153         }
     198            }
     199
     200            return $status;
     201        }
     202
     203        // Temporary logger to capture who/what sets order status for Stripe orders
     204        function wpgv_log_order_status_change($order_id, $old_status, $new_status, $order)
     205        {
     206            if (! $order || ! $order instanceof WC_Order) {
     207                return;
     208            }
     209
     210            $pm = $order->get_payment_method();
     211            if ( strpos( $pm, 'stripe' ) === false ) {
     212                return;
     213            }
     214
     215            $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
     216            $callers = array();
     217            foreach ( $bt as $b ) {
     218                $callers[] = (isset($b['function']) ? $b['function'] : '') . (isset($b['class']) ? ' in ' . $b['class'] : '');
     219            }
     220
     221            error_log('WPGV_STATUS_CHANGE: order=' . $order_id . ', old=' . $old_status . ', new=' . $new_status . ', pm=' . $pm . ', callers=' . json_encode($callers));
     222        }
     223
    154224        // Ensure we have the right total, even after recalculations and such.
    155225        function woocommerce_update_order($order_id)
  • gift-voucher/trunk/include/wpgv-product-settings.php

    r3262503 r3454430  
    132132
    133133                ?>
     134                <!-- Nonce for saving Gift Voucher product meta -->
     135                <input type="hidden" name="_wpgv_nonce" id="_wpgv_nonce" value="<?php echo esc_attr(wp_create_nonce('wpgv_save_product_meta')); ?>">
    134136                <input type="hidden" name="wpgv_product_id" id="wpgv_product_id" value="<?php echo esc_attr($post_id); ?>">
    135137                <input type="button" value="Add" name="wpgv-add-price-button" id="wpgv-add-price-button" class="button button-primary">
  • gift-voucher/trunk/include/wpgv_item_pdf.php

    r3299113 r3454430  
    5252    $wpgv_expiry_date_format = get_option('wpgv_expiry_date_format') ? get_option('wpgv_expiry_date_format') : 'd.m.Y';
    5353    $wpgv_enable_pdf_saving = get_option('wpgv_enable_pdf_saving') ? get_option('wpgv_enable_pdf_saving') : 0;
     54
     55    // Optional settings with safe defaults
     56    $wpgv_add_extra_charges = get_option('wpgv_add_extra_charges_item') ? get_option('wpgv_add_extra_charges_item') : 0;
     57    $is_stripe_ideal_enable = get_option('wpgv_stripe_ideal') ? get_option('wpgv_stripe_ideal') : 0;
     58    $wpgv_barcode_on_voucher = isset($setting_options->wpgv_barcode_on_voucher) ? $setting_options->wpgv_barcode_on_voucher : 0;
    5459
    5560    if ($wpgv_hide_expiry == 'no') {
  • gift-voucher/trunk/readme.txt

    r3444528 r3454430  
    33Tags: gift cards, gift certificates, gift voucher, premium vouchers, generate gift cards
    44Requires at least: 4.0
    5 Tested up to: 6.9
    6 Stable tag: 4.6.3
     5Tested up to: 6.9.1
     6Stable tag: 4.6.4
    77Requires PHP: 5.6
    88License: GPLv2 or later
     
    226226== Changelog ==
    227227
    228 = Version 4.6.3 - Released: January 22, 2026 =
     228= Version 4.6.4 - Released: February 05, 2026 =
     229* Fix: Prevent WooCommerce email preview fatal. Ensure payment-complete filter returns original status for empty $order_id and validate WC_Order before calling methods to avoid preview crashes. (Files: include/redeem-voucher.php)
     230* Fix: Do not force Stripe-paid orders to 'processing' for digital/download-only orders. Only set 'processing' when incoming status is 'completed' and the order requires shipping. (Files: include/redeem-voucher.php)
     231* Fix/Improvement: Add diagnostics and robustness for Stripe order status and email handling — added temporary logs (WPGV_STATUS_DEBUG, wpgv_log_order_status_change), input guards and fallback for admin mail helper to prevent undefined function errors and PHP warnings. (Files: include/redeem-voucher.php, classes/wpgv-gift-voucher-cart-process.php, gift-voucher.php)
     232* Fix: Load plugin translations on `init` and defer plugin file includes to prevent WordPress 6.7+ `_load_textdomain_just_in_time` notice. (Files: gift-voucher.php, admin.php, front.php)
     233* Fix: Ensure post types/taxonomies are registered immediately if `voucher_posttype.php` is included late to avoid "Invalid post type." in admin. (Files: gift-voucher.php, include/voucher_posttype.php)
     234* Fix: Remove unnecessary `wpdb->prepare()` usage without placeholders to prevent `wpdb::prepare()` notices. (Files: classes/template.php)
     235* Fix: Add missing `_wpgv_nonce` hidden input to the Gift Voucher product tab so product updates without price no longer trigger "Invalid request." (Files: include/wpgv-product-settings.php, admin/wpgv-gift-voucher-admin.php)
     236* Fix: Avoid warnings in `[wpgv_giftcard]` shortcode when taxonomy terms are returned as arrays; handle both term objects and arrays and escape output. (Files: giftcard.php)
     237
     238= Version 4.6.3 - Released: January 02, 2026 =
    229239* Fix: Secure database query in `classes/voucher.php::record_count()` by building the full SQL and using `$wpdb->prepare()` with bound parameters to avoid unescaped DB parameters.
    230240* Fix: Add direct file access protection to `templates/wpgv_item_pdf.php`, `templates/wpgv_voucher_pdf.php`, and `templates/pdfstyles/receipt.php`, `templates/pdfstyles/style1.php`, `templates/pdfstyles/style2.php`, `templates/pdfstyles/style3.php` by checking `if ( ! defined( 'ABSPATH' ) ) exit;` to prevent direct access.
  • gift-voucher/trunk/templates/pdfstyles/style1.php

    r3444528 r3454430  
    1414
    1515$wpgv_leftside_notice = (get_option('wpgv_leftside_notice') != '') ? get_option('wpgv_leftside_notice') : __('Cash payment is not possible. The terms and conditions apply.', 'gift-voucher' );
     16
     17// Ensure optional settings exist to avoid undefined variable warnings
     18$wpgv_barcode_on_voucher = isset($wpgv_barcode_on_voucher) ? $wpgv_barcode_on_voucher : (isset($setting_options->wpgv_barcode_on_voucher) ? $setting_options->wpgv_barcode_on_voucher : 0);
    1619
    1720$pdf = new WPGV_PDF('P','pt',array(595,900));
Note: See TracChangeset for help on using the changeset viewer.