/**
  * Locate the voucher preview template file, in this plugin's templates directory
  *
  * @since 1.0
  * @param string $locate locate path
  *
  * @return string the location path for the voucher preview file
  */
 function wc_vouchers_locate_voucher_preview_template($locate)
 {
     $post_type = get_query_var('post_type');
     $preview = get_query_var('preview');
     if ('wc_voucher' == $post_type && 'true' == $preview) {
         $locate = wc_pdf_product_vouchers()->get_plugin_path() . '/templates/single-wc_voucher.php';
     }
     return $locate;
 }
    /**
     * Display the voucher select box in the product variation meta box for
     * downloadable variable products
     *
     * @since 1.2
     * @param int $loop loop counter
     * @param array $variation_data associative array of variation data
     */
    public function product_after_variable_attributes($loop, $variation_data, $variation)
    {
        // WooCommerce 2.3 removed meta data from the $variation_data array, let's add it back
        if (SV_WC_Plugin_Compatibility::is_wc_version_gte_2_3()) {
            $variation_data = array_merge(get_post_meta($variation->ID), $variation_data);
        }
        $options = array('' => '');
        // get all the published vouchers
        foreach (wc_pdf_product_vouchers()->get_voucher_handler()->get_vouchers() as $voucher) {
            $options[$voucher->ID] = $voucher->post_title;
        }
        if (SV_WC_Plugin_Compatibility::is_wc_version_gte_2_3()) {
            ?>
			<div class="show_if_variation_downloadable" style="display:none;">
				<p class="form-row form-row-first">
					<label><?php 
            _e('Voucher:', WC_PDF_Product_Vouchers::TEXT_DOMAIN);
            ?>
 <a class="tips" data-tip="<?php 
            _e('Select a voucher rather than providing a file path', WC_PDF_Product_Vouchers::TEXT_DOMAIN);
            ?>
" href="#">[?]</a></label><select class="variable_voucher" name="variable_voucher_id[<?php 
            echo $loop;
            ?>
]"><?php 
            foreach ($options as $voucher_id => $name) {
                echo '<option value="' . $voucher_id . '" ';
                if (isset($variation_data['_voucher_id'][0])) {
                    selected($voucher_id, $variation_data['_voucher_id'][0]);
                }
                echo '>' . $name . '</option>';
            }
            ?>
</select>
				</p>
			</div>
		<?php 
        } else {
            ?>
			<tr class="show_if_variation_downloadable" style="display:none;">
				<td>
					<label><?php 
            _e('Voucher:', WC_PDF_Product_Vouchers::TEXT_DOMAIN);
            ?>
 <a class="tips" data-tip="<?php 
            _e('Select a voucher rather than providing a file path', WC_PDF_Product_Vouchers::TEXT_DOMAIN);
            ?>
" href="#">[?]</a></label><select class="variable_voucher" name="variable_voucher_id[<?php 
            echo $loop;
            ?>
]"><?php 
            foreach ($options as $voucher_id => $name) {
                echo '<option value="' . $voucher_id . '" ';
                if (isset($variation_data['_voucher_id'][0])) {
                    selected($voucher_id, $variation_data['_voucher_id'][0]);
                }
                echo '>' . $name . '</option>';
            }
            ?>
</select>
				</td>
				<td>&nbsp;</td>
			</tr>
		<?php 
        }
    }
 /**
  * Generate and save or stream a PDF file for this product voucher
  *
  * @since 1.0
  * @param string $path optional absolute path to the voucher directory, if
  *        not supplied the PDF will be streamed as a downloadable file (used
  *        for admin previewing of the PDF)
  *
  * @return mixed nothing if a $path is supplied, otherwise a PDF download
  * @throws Exception if the voucher image is not available
  */
 public function generate_pdf($path = '')
 {
     // include the pdf library
     define('FPDF_FONTPATH', wc_pdf_product_vouchers()->get_plugin_path() . '/lib/fpdf/font');
     require_once wc_pdf_product_vouchers()->get_plugin_path() . '/lib/fpdf/fpdf.php';
     $upload_dir = wp_upload_dir();
     $image = wp_get_attachment_metadata($this->get_image_id());
     // make sure the image hasn't been deleted through the media editor
     if (!$image) {
         throw new Exception(__("Voucher image not found", WC_PDF_Product_Vouchers::TEXT_DOMAIN));
     }
     // make sure the file exists and is readable
     if (!is_readable($upload_dir['basedir'] . '/' . $image['file'])) {
         throw new Exception(sprintf(__("Voucher image file missing or not readable: %s", WC_PDF_Product_Vouchers::TEXT_DOMAIN), $upload_dir['basedir'] . '/' . $image['file']));
     }
     // determine orientation: landscape or portrait
     if ($image['width'] > $image['height']) {
         $orientation = 'L';
     } else {
         $orientation = "P";
     }
     // get the width and height in points
     $width_pt = $this->convert_pixels_to_points($image['width']);
     $height_pt = $this->convert_pixels_to_points($image['height']);
     // Create the pdf
     // When writing text to a Cell, the text is vertically-aligned in the middle
     $fpdf = new FPDF($orientation, 'pt', array($width_pt, $height_pt));
     $fpdf->AddPage();
     $fpdf->SetAutoPageBreak(false);
     // set the voucher image
     $fpdf->Image($upload_dir['basedir'] . '/' . $image['file'], 0, 0, $width_pt, $height_pt);
     // this is useful for displaying the text cell borders when debugging the PDF layout,
     //  though keep in mind that we translate the box position to align the text to bottom
     //  edge of what the user selected, so if you want to see the originally selected box,
     //  display that prior to the translation
     $show_border = 0;
     foreach ($this->voucher_fields as $field_name => $field) {
         switch ($field_name) {
             case 'message':
                 // voucher message text, this is multi-line, so it's handled specially
                 $this->textarea_field($fpdf, 'message', $this->get_message(), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'product_name':
                 // product name (allow optional wrapping)
                 if (apply_filters('wc_pdf_product_vouchers_product_name_multi_line', false, $this)) {
                     $this->textarea_field($fpdf, 'product_name', strtoupper($this->get_product_name()), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 } else {
                     $this->text_field($fpdf, 'product_name', strtoupper($this->get_product_name()), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 }
                 break;
             case 'product_sku':
                 // product sku
                 $this->text_field($fpdf, 'product_sku', $this->get_product_sku(), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'recipient_name':
                 // recepient name
                 $this->text_field($fpdf, 'recipient_name', $this->get_recipient_name(), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'recipient_email':
                 // recepient email
                 $this->text_field($fpdf, 'recipient_email', $this->get_recipient_email(), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'expiration_date':
                 // expiry date
                 $this->text_field($fpdf, 'expiration_date', $this->get_formatted_expiration_date(), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'voucher_number':
                 // voucher number
                 $this->text_field($fpdf, 'voucher_number', $this->get_voucher_number(), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'voucher_product_price':
                 // voucher number
                 $this->text_field($fpdf, 'voucher_product_price', $this->wc_price($this->get_product_price()), $show_border, isset($field['text_align']) && $field['text_align'] ? $field['text_align'] : $this->voucher_text_align);
                 break;
             case 'qr-code':
             case 'qrcode':
             case 'qr':
                 // Voucher QR-code
                 require_once wc_pdf_product_vouchers()->get_plugin_path() . '/lib/fpdf/qrcode/qrcode.class.php';
                 $qrcode = new QRcode(str_replace("{X}", $this->get_voucher_number(), $this->voucher_fields[strtolower($this->{$field_name})]["label"]), 'L');
                 // error level : L, M, Q, H
                 $qrcode->disableBorder();
                 //header("Content-type: text/plain");
                 //print_r($this->voucher_fields[strtolower($this->$field_name)]["position"]["color"]);
                 //exit();
                 //$qrcode->displayPNG();
                 //exit();
                 $qrcode->displayFPDF($fpdf, $this->voucher_fields[strtolower($this->{$field_name})]["position"]["x"], $this->voucher_fields[strtolower($this->{$field_name})]["position"]["y"], $this->voucher_fields[strtolower($this->{$field_name})]["position"]["width"], $this->voucher_fields[strtolower($this->{$field_name})]["position"]["background"], $this->voucher_fields[strtolower($this->{$field_name})]["position"]["color"]);
                 break;
             default:
                 //header("Content-type: text/plain");
                 //print $this->$field_name . ":\n";
                 //print_r($this->voucher_fields);
                 //print "\n\n";
                 //exit();
                 // TODO: allowing custom fields in this manner could lead to name clashes if they use a reserved field name.  have to deal with that later
                 if (isset($field['multiline']) && $field['multiline']) {
                     $this->textarea_field($fpdf, $field_name, apply_filters('wc_pdf_product_vouchers_voucher_field_value', $this->voucher_fields[strtolower($this->{$field_name})]["label"], $this, $field_name, $field), $show_border, isset($field['text_align']) ? $field['text_align'] : $this->voucher_text_align);
                 } else {
                     $this->text_field($fpdf, $field_name, apply_filters('wc_pdf_product_vouchers_voucher_field_value', $this->voucher_fields[strtolower($this->{$field_name})]["label"], $this, $field_name, $field), $show_border, isset($field['text_align']) ? $field['text_align'] : $this->voucher_text_align);
                 }
                 break;
         }
     }
     // has additional pages?
     foreach ($this->additional_image_ids as $additional_image_id) {
         $fpdf->AddPage();
         $additional_image = wp_get_attachment_metadata($additional_image_id);
         $fpdf->Image($upload_dir['basedir'] . '/' . $additional_image['file'], 0, 0, $this->convert_pixels_to_points($additional_image['width'] < $image['width'] ? $additional_image['width'] : $image['width']), $this->convert_pixels_to_points($additional_image['height'] < $image['height'] ? $additional_image['height'] : $image['height']));
     }
     if ($path) {
         // save the pdf as a file
         $fpdf->Output($this->get_voucher_full_filename($path), 'F');
     } else {
         // download file
         $fpdf->Output('voucher-preview-' . $this->id . '.pdf', 'I');
     }
 }
function init_woocommerce_pdf_product_vouchers()
{
    /**
     * <h2>WooCommerce PDF Product Vouchers main plugin class</h2>
     *
     * <h3>Plugin Overview</h3>
     *
     * This plugin allows an admin to create and customize "Voucher Templates"
     * which can be assigned to Simple/Variable Downloadable products and purchased
     * by customers.  Once purchased the Voucher will be created when it's
     * available for download (order completed or processing with "Grant access to
     * downloadable products after payment" enabled) and can be downloaded like any
     * standard downloadable product.
     *
     * <h3>Terminology</h3>
     *
     * **Voucher Template** - the Voucher custom post type which is configured
     *  by the admin
     *
     * **Product Voucher** - a realization of a Voucher Template when attached to a
     *   product and purchased by a customer
     *
     * <h3>Admin Considerations</h3>
     *
     * This plugin adds a "Vouchers" menu item to the "WooCommerce" top level menu
     * where the Voucher Custom Post Type items are listed and created/edited.
     * Various images and fields can be added to a Voucher template and configured.
     *
     * Within the Order Admin a new admin panel named "Vouchers" is added and contains
     * any associated vouchers, displaying the voucher image, name, other identifying
     * fields, as well as an optional "Expires" datepicker field, and a redemption date
     * datepicker field.
     *
     * Any generated/available voucher files are displayed in the Downloadable
     * Product Permissions table.
     *
     * <h3>Frontend Considerations</h3>
     *
     * This plugin adds to the product page zoomable thumbnails of the primary
     * image(s) as well as Recipient Name/Recipient Message input fields (if
     * configured).  After adding to the cart, the product Voucher is available
     * like any other product download.
     *
     * <h3>Database</h3>
     *
     * <h4>Options table</h4>
     *
     * **wc_vouchers_db_version** - the current plugin version, set on install/upgrade
     *
     * **wc_vouchers_number_start** - the current voucher number, set to '0' on install.
     * This is used to generate a unique, sequential voucher number
     *
     * <h4>Voucher Custom Post Type</h4>
     *
     * **wc_voucher** - A Custom Post Type which represents a voucher layout/options
     *
     * <h4>Voucher CPT Postmeta</h4>
     *
     * **thumbnail_id** - (int) identifies the voucher default primary image
     *
     * **_image_ids** - (array) of voucher primary image options.  This should
     * have at least one member, equal to the _thumbnail_id
     *
     * **_additional_image_ids** - (array) optional array of additional (page 2)
     * images.  For now this can only contain one member
     *
     * **_voucher_font_color** - (string) default voucher font color hex value.
     * This can be overridden by an individual voucher field
     *
     * **_voucher_font_size** - (int) default voucher font size.  This can be
     * overridden by an individual voucher field
     *
     * **_voucher_font_family** - (string) default voucher font family.  This can be
     * overridden by an individual voucher field.
     *
     * **_voucher_font_style** - (string) default voucher font style (bold/italic).
     * This can be overridden by an individual voucher field.
     *
     * **_voucher_fields** - (array) voucher field definitions.  Consists of a field
     * identifier (one of 'product_name', 'product_sku', 'voucher_number',
     * 'expiration_date', 'recipient_name', or 'message') to the following datastructure:
     *
     * <pre>
     * Array(
     *   type => 'property'|'user_input',
     *   order => int admin ordering,
     *   font => Array(
     *     family => optional font family override,
     *     size => optional font size override,
     *     style => optional font style override,
     *     color => optional font color override,
     *   ),
     *   position => Array(
     *     x1 => field x position,
     *     y1 => field y position,
     *     width => field width,
     *     height => field height,
     *   ),
     *   days_to_expiry => int days to expiration available for the 'expiration_date' field,
     *   label => user_input type field name which is displayed on the frontend,
     *   input_type => 'text'|'textarea' available for the user_input type fields,
     *   max_length => maximum allowable user input length for the field and available for the user_input type fields,
     *   is_required => boolean whether the user_input type field is required,
     *   is_enabled => boolean whether the user_input type field is enabled though not necessarily printed to the voucher,
     *   multiline => boolean true if the field should be rendered as a text area on the voucher, false for single line
     * )
     * </pre>
     *
     * <h4>Product Postmeta</h4>
     *
     * **_voucher_id** - (int) identifies a voucher when a product is configured
     *  as a downloadable voucher product
     *
     * <h4>Order Postmeta</h4>
     *
     * **_voucher_redeemed** - (int) set to '1' when an order contains only vouchers
     * and all have been redeemed
     *
     * <h4>Order Item Meta Data</h4>
     *
     * **_voucher_id** - (int)  Identifies the voucher post
     *
     * **_voucher_number** - (int)  Unique, incrementing voucher number
     *
     * **_voucher_image_id** - (int)  Identifies the image media selected by the
     * customer during purchase
     *
     * **_voucher_expiration** - (date)  Optional voucher expiration date, based
     * off of the voucher being generated and available to customer, and the
     * Voucher days to expiry, if set.
     *
     * **_voucher_redeem** - (array)  Array of dates for which this voucher has
     * been redeemed.  Products can be purchased with multiple quantities, so a
     * single voucher could be redeemed twice, on different dates for instance.
     *
     * **Voucher Message** (string)  Optional visible voucher message for Vouchers
     * which have a configured voucher message option, and a customer who supplies a message
     *
     * **Voucher Recipient** (string)  Optional visible voucher recipient for Vouchers
     * which have a configured voucher recipient option, and a customer who supplies
     * a recipient name (this does not default to the purchasing customer)
     *
     * <h4>woocommerce_downloadable_product_permissions Table</h4>
     *
     * The download_id column for the downloadable product permissions table is used
     * to identify the particular product voucher, and is in the format
     * wc_vouchers{voucher_id} where {voucher_id} is the uniquely generated product
     * voucher identifier.
     */
    class WC_PDF_Product_Vouchers extends SV_WC_Plugin
    {
        /** version number */
        const VERSION = '2.4.0';
        /** @var WC_PDF_Product_Vouchers single instance of this plugin */
        protected static $instance;
        /** string the plugin id */
        const PLUGIN_ID = 'pdf_product_vouchers';
        /** string plugin text domain */
        const TEXT_DOMAIN = 'woocommerce-pdf-product-vouchers';
        /** Voucher image thumbnail width */
        const VOUCHER_IMAGE_THUMB_WIDTH = 100;
        /** @var WC_PDF_Product_Vouchers_Product product class */
        private $product;
        /** @var WC_PDF_Product_Vouchers_Cart cart class */
        private $cart;
        /** @var WC_PDF_Product_Vouchers_My_Account My Account handler/helper */
        private $my_account;
        /** @var WC_PDF_Product_Vouchers_Taxonomy taxonomy helper class */
        private $taxonomy;
        /** @var WC_PDF_Product_Vouchers_Voucher voucher handler/helper */
        private $voucher_handler;
        /** @var WC_PDF_Product_Vouchers_Admin PDF product vouchers admin */
        private $admin;
        /**
         * Setup main plugin class
         *
         * @since 1.0
         * @see SV_WC_Plugin::__construct()
         */
        public function __construct()
        {
            parent::__construct(self::PLUGIN_ID, self::VERSION, self::TEXT_DOMAIN);
            // include required files
            $this->includes();
            add_action('init', array($this, 'include_template_functions'), 25);
            // generate voucher pdf, attach to emails, handle downloads
            add_filter('woocommerce_email_classes', array($this, 'add_email_classes'));
        }
        /**
         * Files required by both the admin and frontend
         *
         * @since 1.0
         */
        private function includes()
        {
            if (is_admin()) {
                $this->admin_includes();
            }
            require_once $this->get_plugin_path() . '/includes/class-wc-voucher.php';
            require_once $this->get_plugin_path() . '/includes/class-wc-pdf-product-vouchers-product.php';
            $this->product = new WC_PDF_Product_Vouchers_Product($this);
            require_once $this->get_plugin_path() . '/includes/class-wc-pdf-product-vouchers-cart.php';
            $this->cart = new WC_PDF_Product_Vouchers_Cart();
            require_once $this->get_plugin_path() . '/includes/class-wc-pdf-product-vouchers-my-account.php';
            $this->my_account = new WC_PDF_Product_Vouchers_My_Account();
            require_once $this->get_plugin_path() . '/includes/class-wc-pdf-product-vouchers-taxonomy.php';
            $this->taxonomy = new WC_PDF_Product_Vouchers_Taxonomy();
            require_once $this->get_plugin_path() . '/includes/class-wc-pdf-product-vouchers-voucher.php';
            $this->voucher_handler = new WC_PDF_Product_Vouchers_Voucher($this);
            require_once $this->get_plugin_path() . '/includes/class-wc-pdf-product-vouchers-order.php';
        }
        /**
         * Include required voucher admin files
         *
         * @since 1.0
         */
        private function admin_includes()
        {
            require_once $this->get_plugin_path() . '/includes/admin/class-wc-pdf-product-vouchers-admin.php';
            $this->admin = new WC_PDF_Product_Vouchers_Admin($this);
        }
        /**
         * Include WooCommerce PDF Product Vouchers template functions
         *
         * @since 1.0
         */
        public function include_template_functions()
        {
            require_once $this->get_plugin_path() . '/includes/wc-pdf-product-vouchers-template.php';
        }
        /**
         * Load plugin text domain.
         *
         * @since 1.0
         * @see SV_WC_Plugin::load_translation()
         */
        public function load_translation()
        {
            load_plugin_textdomain('woocommerce-pdf-product-vouchers', false, dirname(plugin_basename($this->get_file())) . '/i18n/languages');
        }
        /**
         * Adds PDF Product Vouchers email class
         *
         * @since 1.2
         */
        public function add_email_classes($email_classes)
        {
            require_once $this->get_plugin_path() . '/includes/emails/class-wc-pdf-product-vouchers-email-voucher-recipient.php';
            $email_classes['WC_PDF_Product_Vouchers_Email_Voucher_Recipient'] = new WC_PDF_Product_Vouchers_Email_Voucher_Recipient();
            return $email_classes;
        }
        /** Admin methods ******************************************************/
        /**
         * Gets the plugin configuration URL
         *
         * @since 1.0-1
         * @see SV_WC_Plugin::get_settings_url()
         * @param string $plugin_id the plugin identifier.  Note that this can be a
         *        sub-identifier for plugins with multiple parallel settings pages
         *        (ie a gateway that supports both credit cards and echecks)
         * @return string plugin settings URL
         */
        public function get_settings_url($plugin_id = null)
        {
            // link to the wc_voucher list table
            return admin_url('edit.php?post_type=wc_voucher');
        }
        /**
         * Returns true if on the Vouchers List Table/Edit screens
         *
         * @since 1.0-1
         * @see SV_WC_Plugin::is_plugin_settings()
         * @return boolean true if on the admin gateway settings page
         */
        public function is_plugin_settings()
        {
            return isset($_GET['post_type']) && 'wc_voucher' == $_GET['post_type'];
        }
        /**
         * Checks if required PHP extensions are loaded and adds an admin notice
         * for any missing extensions.  Also plugin settings can be checked
         * as well.
         *
         * @since 2.1.1
         * @see SV_WC_Plugin::add_admin_notices()
         */
        public function add_admin_notices()
        {
            parent::add_admin_notices();
            $this->add_file_permissions_notices();
        }
        /**
         * Render an admin error if there's a directory permission that will prevent
         * voucher files from being written
         *
         * @since 2.1.1
         */
        private function add_file_permissions_notices()
        {
            // check for file permission errors
            $message = __('%s: non-writable path %s%s%s detected, please fix directory permissions or voucher files may not be able to be generated.', self::TEXT_DOMAIN);
            $message_id = null;
            $upload_dir = wp_upload_dir();
            if (!is_writable($upload_dir['basedir'])) {
                $message = sprintf($message, $this->get_plugin_name(), $upload_dir['basedir']);
                $message_id = 'bad-perms-1';
            } elseif (!is_writable(self::get_woocommerce_uploads_path())) {
                $message = sprintf($message, $this->get_plugin_name(), '<code>', self::get_woocommerce_uploads_path(), '</code>');
                $message_id = 'bad-perms-2';
            } elseif (file_exists(self::get_uploads_path()) && !is_writable(self::get_uploads_path())) {
                $message = sprintf($message, $this->get_plugin_name(), self::get_uploads_path());
                $message_id = 'bad-perms-3';
            }
            if ($message_id) {
                $this->get_admin_notice_handler()->add_admin_notice($message, $message_id);
            }
        }
        /** Helper methods ******************************************************/
        /**
         * Main PDF Product Vouchers Instance, ensures only one instance is/can be loaded
         *
         * @since 2.2.0
         * @see wc_pdf_product_vouchers()
         * @return WC_PDF_Product_Vouchers
         */
        public static function instance()
        {
            if (is_null(self::$instance)) {
                self::$instance = new self();
            }
            return self::$instance;
        }
        /**
         * Returns the plugin name, localized
         *
         * @since 1.0
         * @see SV_WC_Plugin::get_plugin_name()
         * @return string the plugin name
         */
        public function get_plugin_name()
        {
            return __('WooCommerce PDF Product Vouchers', self::TEXT_DOMAIN);
        }
        /**
         * Returns __FILE__
         *
         * @since 1.0
         * @see SV_WC_Plugin::get_file()
         * @return string the full path and filename of the plugin file
         */
        protected function get_file()
        {
            return __FILE__;
        }
        /**
         * Returns the uploads path, which is used to store the generated PDF
         * product voucher files
         *
         * @since 1.0
         * @return string upload path for this plugin
         */
        public static function get_uploads_path()
        {
            return self::get_woocommerce_uploads_path() . '/woocommerce_pdf_product_vouchers';
        }
        /**
         * Returns the voucher helper/handler class
         *
         * @since 1.2
         * @return WC_PDF_Product_Vouchers_Voucher voucher helper/handler class
         */
        public function get_voucher_handler()
        {
            return $this->voucher_handler;
        }
        /**
         * Gets the plugin documentation url
         *
         * @since 2.4.0
         * @see SV_WC_Plugin::get_documentation_url()
         * @return string documentation URL
         */
        public function get_documentation_url()
        {
            return 'http://docs.woothemes.com/document/woocommerce-pdf-product-vouchers/';
        }
        /**
         * Gets the plugin support URL
         *
         * @since 2.4.0
         * @see SV_WC_Plugin::get_support_url()
         * @return string
         */
        public function get_support_url()
        {
            return 'http://support.woothemes.com/';
        }
        /** Lifecycle methods ******************************************************/
        /**
         * Plugin install method
         *
         * @since 1.0
         * @see SV_WC_Plugin::install()
         */
        protected function install()
        {
            add_option('wc_vouchers_number_start', '0');
        }
        /**
         * Plugin upgrade method
         *
         * @since 2.0.3-2
         * @see SV_WC_Plugin::upgrade()
         * @param string $installed version the currently installed version we are upgrading from
         */
        protected function upgrade($installed_version)
        {
            global $wpdb;
            if (version_compare($installed_version, '2.0.3-2', '<')) {
                // Actually in version 2.0 a field name changed 'display_name' -> 'label' that we forgot to update for existing shops
                $results = $wpdb->get_results("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key='_voucher_fields'");
                if (is_array($results)) {
                    foreach ($results as $row) {
                        $fixed = false;
                        $voucher_fields = maybe_unserialize($row->meta_value);
                        if (is_array($voucher_fields)) {
                            foreach ($voucher_fields as $name => $field) {
                                if (isset($field['display_name']) && (!isset($field['label']) || !$field['label'])) {
                                    // old-style
                                    if ('recipient_name' == $name) {
                                        $voucher_fields[$name]['label'] = 'Recipient Name';
                                        unset($voucher_fields[$name]['display_name']);
                                    } elseif ('message' == $name) {
                                        $voucher_fields[$name]['label'] = 'Message to recipient';
                                        unset($voucher_fields[$name]['display_name']);
                                    }
                                    $fixed = true;
                                }
                            }
                        }
                        if ($fixed) {
                            update_post_meta($row->post_id, '_voucher_fields', $voucher_fields);
                        }
                    }
                }
                unset($results);
            }
        }
    }
    /**
     * Returns the One True Instance of PDF Product Vouchers
     *
     * @since 2.2.0
     * @return WC_PDF_Product_Vouchers
     */
    function wc_pdf_product_vouchers()
    {
        return WC_PDF_Product_Vouchers::instance();
    }
    /**
     * The WC_PDF_Product_Vouchers global object
     *
     * @deprecated 2.2.0
     * @name $wc_pdf_product_vouchers
     * @global WC_PDF_Product_Vouchers $GLOBALS['wc_pdf_product_vouchers']
     */
    $GLOBALS['wc_pdf_product_vouchers'] = wc_pdf_product_vouchers();
}
 /**
  * Dispatch the email(s)
  *
  * @since 1.2
  * @param int $order_id order identifier
  */
 public function trigger($order_id)
 {
     // nothingtodohere
     if (!$order_id || !$this->is_enabled()) {
         return;
     }
     // only dispatch the voucher recipient email once, unless we're being called from the Voucher Recipient email order action
     if (get_post_meta($order_id, '_wc_pdf_product_vouchers_voucher_recipient_email_sent', true) && !(isset($_POST['wc_order_action']) && 'send_email_wc_pdf_product_vouchers_voucher_recipient' == $_POST['wc_order_action'])) {
         return;
     }
     $order = wc_get_order($order_id);
     $this->find[] = '{billing_first_name}';
     $this->replace[] = $order->billing_first_name;
     $this->find[] = '{billing_last_name}';
     $this->replace[] = $order->billing_last_name;
     // foreach voucher item in this order, if it contains a recipient email,
     //  add the voucher to those being sent to that recipient.
     // foreach voucher recipient, send an email with any and all vouchers
     $recipient_emails = array();
     $order_items = $order->get_items();
     if (count($order_items) > 0) {
         foreach ($order_items as $order_item_id => $item) {
             if ($item['product_id'] > 0 && isset($item['voucher_id']) && $item['voucher_id']) {
                 $voucher = new WC_Voucher($item['voucher_id'], $order->id, $item, $order_item_id);
                 if ($voucher->get_recipient_email() && $voucher->file_exists(wc_pdf_product_vouchers()->get_uploads_path())) {
                     if (!isset($recipient_emails[$voucher->get_recipient_email()])) {
                         $recipient_emails[$voucher->get_recipient_email()] = array('count' => 0, 'message' => '', 'recipient_name' => $voucher->get_recipient_name());
                     }
                     $recipient_emails[$voucher->get_recipient_email()]['count']++;
                     // message to the recipient?
                     if ($voucher->get_message()) {
                         if ('' === $recipient_emails[$voucher->get_recipient_email()]['message']) {
                             $recipient_emails[$voucher->get_recipient_email()]['message'] = $voucher->get_message();
                         } elseif ($recipient_emails[$voucher->get_recipient_email()]['message'] != $voucher->get_message()) {
                             // guard against the admitedly edge case of multiple vouchers with different messages
                             //  being sent to the same recipient, by just not displaying a message.  Cause it would
                             //  probably look odd to have a bunch of different messages in the same email
                             $recipient_emails[$voucher->get_recipient_email()]['message'] = null;
                         }
                     }
                 }
             }
         }
     }
     foreach ($recipient_emails as $recipient_email => $data) {
         $this->object = array('order' => $order, 'recipient_email' => $recipient_email, 'voucher_count' => $data['count']);
         $this->message = $data['message'];
         $this->recipient_name = $data['recipient_name'];
         $this->recipient = $recipient_email;
         $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
     }
     // record the fact that the vouchers have been sent
     update_post_meta($order_id, '_wc_pdf_product_vouchers_voucher_recipient_email_sent', true);
 }
 /**
  * Mark the entire order as being redeemed if it contains all redeemed vouchers.
  * Also, generate any voucher pdfs for items newly added from the admin
  *
  * @since 1.2
  * @param int $post_id the order id
  * @param object $post the order
  */
 public function maybe_complete_order($post_id, $post)
 {
     // generate any vouchers as needed
     wc_pdf_product_vouchers()->get_voucher_handler()->generate_voucher_pdf($post_id);
     $order = wc_get_order($post_id);
     $voucher_count = 0;
     // if the order status is not completed, and the entire order has not already been marked as 'voucher redeemed'
     if (!WC_PDF_Product_Vouchers_Order::vouchers_redeemed($order)) {
         foreach (WC_PDF_Product_Vouchers_Order::get_vouchers($order) as $voucher) {
             $voucher_count++;
             // an unredeemed voucher, bail
             if (!$voucher->is_redeemed()) {
                 return;
             }
         }
         if ($voucher_count) {
             // if we made it here, it means this order contains only voucher items, and they are all redeemed
             WC_PDF_Product_Vouchers_Order::mark_vouchers_redeemed($order, $voucher_count);
         }
     }
 }