Plugin Directory

Changeset 3489592


Ignore:
Timestamp:
03/24/2026 03:43:22 AM (4 days ago)
Author:
codemenschen
Message:

Version 4.6.5 - Released: March 24, 2026

  • Feature: Add admin PDF regeneration support in Free plugin for both modern (Konva) and standard (style1) vouchers.
  • fix: address deprecated warnings in gift-voucher admin menu (View Voucher Details) while keeping view-detail action functional on WP 6.9.4.
Location:
gift-voucher
Files:
985 added
6 edited

Legend:

Unmodified
Added
Removed
  • gift-voucher/trunk/admin.php

    r3248177 r3489592  
    1818        add_filter('set-screen-option', array(__CLASS__, 'set_screen'), 10, 3);
    1919        add_action('admin_menu', array($this, 'plugin_menu'));
     20        add_action('admin_enqueue_scripts', array($this, 'hide_voucher_details_menu'));
    2021        add_action('admin_enqueue_scripts', array($this, 'admin_register_assets'));
    2122    }
     
    2425    {
    2526        return $value;
     27    }
     28
     29    /**
     30     * Hide View Voucher Details from sidebar menu but keep functionality
     31     */
     32    public function hide_voucher_details_menu()
     33    {
     34        echo '<style>
     35            #adminmenu a[href*="page=view-voucher-details"],
     36            .wp-submenu a[href*="page=view-voucher-details"],
     37            .wp-submenu a[href*="page=new-voucher-template"] {
     38                display: none !important;
     39            }
     40        </style>';
    2641    }
    2742
     
    3348        wp_enqueue_style('wp-color-picker');
    3449        wp_enqueue_style('voucher-style', WPGIFT__PLUGIN_URL . '/assets/css/admin-style.css');
    35         wp_enqueue_script('voucher-script', WPGIFT__PLUGIN_URL  . '/assets/js/admin-script.js', array('wp-color-picker'), '1.0.0', true);
     50        wp_enqueue_script('konva-js', WPGIFT__PLUGIN_URL . '/assets/js/konva.min.js', array('jquery'), 'v8.0.4', true);
     51        wp_enqueue_script('voucher-script', WPGIFT__PLUGIN_URL  . '/assets/js/admin-script.js', array('wp-color-picker', 'konva-js'), '1.0.0', true);
    3652        wp_localize_script('voucher-script', 'WPGiftAjax', array('ajaxurl' => admin_url('admin-ajax.php')));
    3753    }
     
    4359    {
    4460        add_menu_page('Gift Vouchers', 'Gift Vouchers', 'read', 'wpgv-gift-cards', '', 'dashicons-tickets-alt', 25);
    45         add_submenu_page('wpgv-gift-cards', 'Item Categories', 'Item Categories', 'edit_posts', 'edit-tags.php?taxonomy=wpgv_voucher_category&post_type=wpgv_voucher_product', false);
    46         add_submenu_page('wpgv-gift-cards', 'Voucher Categories', 'Gift Cards Categories', 'edit_posts', 'edit-tags.php?taxonomy=category_voucher_template&post_type=voucher_template', false);
     61        add_submenu_page('wpgv-gift-cards', 'Item Categories', 'Item Categories', 'edit_posts', 'edit-tags.php?taxonomy=wpgv_voucher_category&post_type=wpgv_voucher_product', '');
     62        add_submenu_page('wpgv-gift-cards', 'Voucher Categories', 'Gift Cards Categories', 'edit_posts', 'edit-tags.php?taxonomy=category_voucher_template&post_type=voucher_template', '');
    4763        $templatehook = add_submenu_page('wpgv-gift-cards', __('Voucher Templates', 'gift-voucher'), __('Voucher Templates', 'gift-voucher'), 'manage_options', 'voucher-templates', array($this, 'voucher_template'));
    48         add_submenu_page(NULL, __('Add New Template', 'gift-voucher'), __('Add New Template', 'gift-voucher'), 'manage_options', 'new-voucher-template', array($this, 'new_voucher_template'));
    49 
    50         add_submenu_page(NULL, __('View Voucher Details', 'gift-voucher'), __('View Voucher Details', 'gift-voucher'), 'manage_options', 'view-voucher-details', array($this, 'view_voucher_details'));
     64        add_submenu_page('wpgv-gift-cards', __('Add New Template', 'gift-voucher'), __('Add New Template', 'gift-voucher'), 'manage_options', 'new-voucher-template', array($this, 'new_voucher_template'));
     65
     66        // Create page for viewing voucher details (will be hidden from sidebar but accessible via URL/action buttons)
     67        add_submenu_page('wpgv-gift-cards', __('View Voucher Details', 'gift-voucher'), __('View Voucher Details', 'gift-voucher'), 'manage_options', 'view-voucher-details', array($this, 'view_voucher_details'));
    5168
    5269        add_submenu_page('wpgv-gift-cards', __('Settings', 'gift-voucher'), __('Settings', 'gift-voucher'), 'manage_options', 'voucher-setting', array($this, 'voucher_settings'));
  • gift-voucher/trunk/assets/css/admin-style.css

    r3179739 r3489592  
    113113
    114114.voucher-page .vpaid {
    115     background-color: #ddd;
     115    background-color: green;
    116116    padding: 5px 10px;
    117117    display: inline-block;
  • gift-voucher/trunk/assets/js/admin-script.js

    r3375423 r3489592  
    4747    });
    4848})();
     49
     50// Regenerate Modern Giftcard PDF — Purchase History admin page
     51// Full Konva canvas render → PNG capture → server PDF write
     52jQuery(document).on('click', '.wpgv-regen-pdf-btn', function () {
     53    var $btn = jQuery(this);
     54    var $msg = $btn.siblings('.wpgv-regen-pdf-msg');
     55    var voucherId = $btn.data('voucher-id');
     56    var nonce = $btn.data('nonce');
     57
     58    $btn.prop('disabled', true).text('Loading...');
     59    $msg.hide().text('');
     60
     61    // Step 1: fetch all order + template data from server
     62    jQuery.ajax({
     63        url: ajaxurl,
     64        type: 'POST',
     65        data: { action: 'wpgv_admin_get_voucher_regen_data', voucher_id: voucherId, nonce: nonce },
     66        success: function (resp) {
     67            if (!resp || !resp.success) {
     68                var errMsg = (resp && resp.data && resp.data.message) ? resp.data.message : 'Failed to load order data.';
     69                $msg.css('color', 'red').text(errMsg).show();
     70                $btn.prop('disabled', false).text('Regenerate PDF');
     71                return;
     72            }
     73            $btn.text('Rendering...');
     74            wpgv_regen_render_canvas(resp.data, voucherId, nonce, $btn, $msg);
     75        },
     76        error: function () {
     77            $msg.css('color', 'red').text('Request failed. Please try again.').show();
     78            $btn.prop('disabled', false).text('Regenerate PDF');
     79        }
     80    });
     81});
     82
     83// Regenerate Standard Giftcard PDF (admin-only)
     84jQuery(document).on('click', '.wpgv-regen-standard-pdf-btn', function () {
     85    var $btn = jQuery(this);
     86    var $msg = $btn.siblings('.wpgv-regen-standard-pdf-msg');
     87    var voucherId = $btn.data('voucher-id');
     88    var nonce = $btn.data('nonce');
     89
     90    $btn.prop('disabled', true).text('Working...');
     91    $msg.hide().text('');
     92
     93    jQuery.ajax({
     94        url: ajaxurl,
     95        type: 'POST',
     96        data: {
     97            action: 'wpgv_admin_regenerate_standard_pdf',
     98            voucher_id: voucherId,
     99            nonce: nonce
     100        },
     101        success: function (resp) {
     102            if (resp && resp.success) {
     103                $msg.css('color', 'green').text(resp.data.message || 'PDF regenerated successfully.').show();
     104                setTimeout(function () { location.reload(); }, 1000);
     105            } else {
     106                var errMsg = (resp && resp.data && resp.data.message) ? resp.data.message : 'Standard PDF regeneration failed.';
     107                $msg.css('color', 'red').text(errMsg).show();
     108            }
     109        },
     110        error: function () {
     111            $msg.css('color', 'red').text('Request failed. Please try again.').show();
     112        },
     113        complete: function () {
     114            $btn.prop('disabled', false).text('Regenerate PDF');
     115        }
     116    });
     117});
     118
     119/**
     120 * Render the Konva canvas with order data, capture PNG, send to server.
     121 */
     122function wpgv_regen_render_canvas(data, voucherId, nonce, $btn, $msg) {
     123    if (typeof Konva === 'undefined') {
     124        $msg.css('color', 'red').text('Konva.js not loaded.').show();
     125        $btn.prop('disabled', false).text('Regenerate PDF');
     126        return;
     127    }
     128
     129    var json = data.json;
     130    if (!json || json === '') {
     131        $msg.css('color', 'red').text('No template JSON found for this order.').show();
     132        $btn.prop('disabled', false).text('Regenerate PDF');
     133        return;
     134    }
     135
     136    // Parse JSON
     137    var jsonData;
     138    try {
     139        jsonData = (typeof json === 'string') ? JSON.parse(json) : json;
     140    } catch (e) {
     141        $msg.css('color', 'red').text('Invalid template JSON.').show();
     142        $btn.prop('disabled', false).text('Regenerate PDF');
     143        return;
     144    }
     145
     146    // Create off-screen container (positioned way off-screen, not display:none, so Konva can render)
     147    var containerId = 'wpgv-regen-offscreen-' + voucherId;
     148    jQuery('#' + containerId).remove();
     149    jQuery('body').append(
     150        '<div id="wpgv-regen-wrap-' + voucherId + '" style="position:fixed;top:-99999px;left:-99999px;pointer-events:none;visibility:hidden;" aria-hidden="true">' +
     151        '<div id="' + containerId + '"></div>' +
     152        '</div>'
     153    );
     154
     155    var stage;
     156    try {
     157        stage = Konva.Node.create(jsonData, containerId);
     158    } catch (e) {
     159        $msg.css('color', 'red').text('Konva stage creation failed: ' + e.message).show();
     160        $btn.prop('disabled', false).text('Regenerate PDF');
     161        jQuery('#wpgv-regen-wrap-' + voucherId).remove();
     162        return;
     163    }
     164
     165    // Update text layers with real order data
     166    var stage_json = stage.toJSON();
     167    var shapes = stage.find('Text');
     168    for (var i = 0; i < shapes.length; i++) {
     169        var shape = shapes[i];
     170        var shapeId = shape.getAttribute ? shape.getAttribute('id') : (shape.attrs && shape.attrs.id ? shape.attrs.id : '');
     171        if (shapeId === 'giftto_name' && data.to_name) {
     172            shape.text(data.to_name);
     173        } else if (shapeId === 'giftfrom_name' && data.from_name) {
     174            shape.text(data.from_name);
     175        } else if (shapeId === 'gift_amount' && data.amount) {
     176            shape.text(data.currency || data.amount);
     177        } else if (shapeId === 'expiry_date' && data.expiry) {
     178            shape.text(data.expiry);
     179        } else if (shapeId === 'giftcard_coupon' && data.couponcode) {
     180            shape.text(data.couponcode);
     181        } else if (shapeId === 'personal_message' && data.message) {
     182            shape.text(data.message);
     183        }
     184    }
     185
     186    // Ask browser to render.
     187    stage.batchDraw();
     188
     189    // Capture as PNG base64
     190    setTimeout(function () {
     191        var canvas = stage.toCanvas();
     192        var imageData = canvas.toDataURL('image/png');
     193
     194        // Send to server for PDF generation
     195        jQuery.ajax({
     196            url: ajaxurl,
     197            type: 'POST',
     198            data: {
     199                action: 'wpgv_admin_regenerate_modern_pdf',
     200                voucher_id: voucherId,
     201                nonce: nonce,
     202                canvas_data: imageData
     203            },
     204            success: function (resp) {
     205                if (resp && resp.success) {
     206                    $msg.css('color', 'green').text(resp.data.message || 'PDF regenerated successfully.').show();
     207                    setTimeout(function () { location.reload(); }, 1000);
     208                } else {
     209                    var errMsg = (resp && resp.data && resp.data.message) ? resp.data.message : 'PDF regeneration failed.';
     210                    $msg.css('color', 'red').text(errMsg).show();
     211                }
     212            },
     213            error: function () {
     214                $msg.css('color', 'red').text('PDF generation request failed. Try again.').show();
     215            },
     216            complete: function () {
     217                $btn.prop('disabled', false).text('Regenerate PDF');
     218                jQuery('#wpgv-regen-wrap-' + voucherId).remove();
     219            }
     220        });
     221    }, 100);
     222}
  • gift-voucher/trunk/classes/voucher.php

    r3444528 r3489592  
    533533                $send_mail = $this->row_actions($actions, true);
    534534            }
     535
     536            // Regenerate PDF button (modern and standard orders)
     537            $regenerate_pdf_btn = '';
     538            $template_info = array('kind' => 'unknown', 'template_id' => 0);
     539            if (function_exists('wpgv_get_voucher_template_kind')) {
     540                $template_info = wpgv_get_voucher_template_kind((object) $item);
     541            }
     542            $is_modern_order = ($template_info['kind'] === 'modern');
     543            $is_standard_order = in_array($template_info['kind'], array('standard_list', 'standard_grid'), true);
     544
     545            if ($item['payment_status'] === 'Paid' && $is_modern_order) {
     546                $regen_nonce = wp_create_nonce('wpgv_regen_modern_pdf_' . $item['id']);
     547                $regenerate_pdf_btn = '<div style="margin-top:4px;">'
     548                    . '<button type="button" class="button button-small wpgv-regen-pdf-btn" '
     549                    . 'data-voucher-id="' . absint($item['id']) . '" '
     550                    . 'data-nonce="' . esc_attr($regen_nonce) . '" '
     551                    . 'style="background:#f7b600;color:#000;border-radius:unset;border:none;">'
     552                    . esc_html__('Regenerate PDF', 'gift-voucher')
     553                    . '</button>'
     554                    . '<span class="wpgv-regen-pdf-msg" style="display:none;margin-left:6px;font-size:12px;"></span>'
     555                    . '</div>';
     556            } elseif ($item['payment_status'] === 'Paid' && $is_standard_order) {
     557                $regen_nonce = wp_create_nonce('wpgv_regen_standard_pdf_' . $item['id']);
     558                $regenerate_pdf_btn = '<div style="margin-top:4px;">'
     559                    . '<button type="button" class="button button-small wpgv-regen-standard-pdf-btn" '
     560                    . 'data-voucher-id="' . absint($item['id']) . '" '
     561                    . 'data-nonce="' . esc_attr($regen_nonce) . '" '
     562                    . 'style="background:#f7b600;color:#000;border-radius:unset;border:none;">'
     563                    . esc_html__('Regenerate PDF', 'gift-voucher')
     564                    . '</button>'
     565                    . '<span class="wpgv-regen-standard-pdf-msg" style="display:none;margin-left:6px;font-size:12px;"></span>'
     566                    . '</div>';
     567            }
     568
    535569            $arr = array(
    536570                'div' => array(
    537571                    'class' => array(),
     572                    'style' => array(),
    538573                ),
    539574                'span' => array(
    540575                    'class' => array(),
     576                    'style' => array(),
    541577                ),
    542578                'a' => array(
     
    544580                    'class' => array(),
    545581                ),
     582                'button' => array(
     583                    'type' => array(),
     584                    'class' => array(),
     585                    'data-voucher-id' => array(),
     586                    'data-nonce' => array(),
     587                    'style' => array(),
     588                ),
    546589                'strong' => array(),
    547590            );
    548             return wp_kses_post($mark_used, $arr) . wp_kses_post($send_mail, $arr) . wp_kses_post($mark_paid, $arr);
     591            return wp_kses_post($mark_used, $arr) . wp_kses_post($send_mail, $arr) . wp_kses_post($mark_paid, $arr) . wp_kses_post($regenerate_pdf_btn, $arr);
    549592        }
    550593
  • gift-voucher/trunk/gift-voucher.php

    r3454430 r3489592  
    77 * Author: Codemenschen GmbH
    88 * Author URI: https://www.codemenschen.at/
    9  * Version: 4.6.4
     9 * Version: 4.6.5
    1010 * Text Domain: gift-voucher
    1111 * Domain Path: /languages
     
    3939}
    4040
    41 define('WPGIFT_VERSION', '4.6.4');
     41define('WPGIFT_VERSION', '4.6.5');
    4242define('WPGIFT__MINIMUM_WP_VERSION', '4.0');
    4343define('WPGIFT__PLUGIN_DIR', untrailingslashit(plugin_dir_path(__FILE__)));
     
    125125  require_once(WPGIFT__PLUGIN_DIR . '/include/wpgv_giftcard_pdf.php');
    126126  require_once(WPGIFT__PLUGIN_DIR . '/include/edit-order-voucher.php');
     127  require_once(WPGIFT__PLUGIN_DIR . '/include/receipt-functions.php');
     128  require_once(WPGIFT__PLUGIN_DIR . '/include/admin_regenerate_modern_pdf.php');
     129  require_once(WPGIFT__PLUGIN_DIR . '/include/admin_regenerate_standard_pdf.php');
    127130
    128131  if (wpgv_is_woocommerce_enable()) {
  • gift-voucher/trunk/readme.txt

    r3454430 r3489592  
    33Tags: gift cards, gift certificates, gift voucher, premium vouchers, generate gift cards
    44Requires at least: 4.0
    5 Tested up to: 6.9.1
    6 Stable tag: 4.6.4
     5Tested up to: 6.9.4
     6Stable tag: 4.6.5
    77Requires PHP: 5.6
    88License: GPLv2 or later
     
    226226== Changelog ==
    227227
     228= Version 4.6.5 - Released: March 24, 2026 =
     229* Feature: Add admin PDF regeneration support in Free plugin for both modern (Konva) and standard (style1) vouchers.
     230* fix: address deprecated warnings in gift-voucher admin menu (View Voucher Details) while keeping view-detail action functional on WP 6.9.4.
     231
    228232= Version 4.6.4 - Released: February 05, 2026 =
    229233* 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)
Note: See TracChangeset for help on using the changeset viewer.