/** * 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> </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); } } }