/** * Removes add to cart buttons from single product page if: * - the product is sold-individually, * - has a voucher attached, and * - the product is already in the cart * to prevent multiple purchases of a voucher in an order. */ function sv_wc_pdf_product_vouchers_disable_multiple_quantities() { // Bail if PDF Product vouchers isn't active if (!function_exists('wc_pdf_product_vouchers')) { return; } // Get the ID for the current product global $product; $product_id = $product->is_type('variation') ? $product->variation_id : $product->id; // bail unless there's a voucher and the product is sold individually if (!($product->is_sold_individually() && WC_PDF_Product_Vouchers_Product::has_voucher($product))) { return; } // check if the item is already in the cart foreach (WC()->cart->get_cart() as $cart_key => $cart_item) { $cart_product = $cart_item['data']; // if our product ID matches an item in the cart, disable purchasing if ($product->id === $cart_product->id) { // remove add to cart button remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30); // add a notice that you can only purchase one function no_purchase_message() { echo '<div class="woocommerce-info">Looks like this product is already in your cart! You can only purchase one per order.</div>'; } add_action('woocommerce_single_product_summary', 'no_purchase_message', 30); } } }
/** * Pluggable function to render the frontend product page voucher fields * * @since 1.2 * @param WC_Product $product the voucher product */ function wc_pdf_product_vouchers_render_product_voucher_fields($product) { if ($product->is_type('variable')) { foreach ($product->get_children() as $variation_product_id) { $products[] = wc_get_product($variation_product_id); } } else { $products[] = $product; } foreach ($products as $product) { $voucher = WC_PDF_Product_Vouchers_Product::get_voucher($product); if ($voucher) { $fields = $voucher->get_user_input_voucher_fields(); $images = $voucher->get_image_urls(); if ($fields || $images) { // load the template file wc_get_template('single-product/product-voucher.php', array('product' => $product, 'product_id' => isset($product->variation_id) ? $product->variation_id : $product->id, 'voucher' => $voucher, 'fields' => $fields, 'images' => $images), '', wc_pdf_product_vouchers()->get_plugin_path() . '/templates/'); } } } }
/** * Called from the customer account page, this adds the date to the * voucher links so they are a little bit easier to distinguish from one * another. Also filter out links for voucher files that don't exist for * whatever reason. * * @since 1.2 * @param array $downloads available downloads * * @return array available downloads */ public function customer_get_downloadable_products($downloads) { $new_downloads = array(); foreach ($downloads as $download) { $product = wc_get_product($download['product_id']); // is the product a voucher product? if (false !== strpos($download['download_id'], 'wc_vouchers_') && WC_PDF_Product_Vouchers_Product::has_voucher($product)) { $order = wc_get_order($download['order_id']); // download id looks like "wc_vouchers_{voucher number}" $voucher = WC_PDF_Product_Vouchers_Order::get_voucher_by_voucher_number($order, str_replace('wc_vouchers_', '', $download['download_id'])); if ($voucher && $voucher->file_exists(WC_PDF_Product_Vouchers::get_uploads_path())) { $download['download_name'] .= ' (' . sprintf(_x('Voucher %s %s', 'Voucher number and date', WC_PDF_Product_Vouchers::TEXT_DOMAIN), $voucher->get_voucher_number(), date_i18n(get_option('date_format'), strtotime($order->order_date))) . ')'; $new_downloads[] = $download; } } else { // regular file $new_downloads[] = $download; } } return $new_downloads; }
/** * Add any user-supplied voucher field data to the cart item data, to * set in the session * * @since 1.2 * @param array $cart_item_data associative-array of name/value pairs of cart item data * @param int $product_id the product identifier * @param int $variation_id optional product variation identifer * * @return array associative array of name/value pairs of cart item * data to set in the session */ public function add_cart_item_voucher_data($cart_item_data, $product_id, $variation_id) { $_product_id = $variation_id ? $variation_id : $product_id; $product = wc_get_product($_product_id); // is this a voucher product? if (WC_PDF_Product_Vouchers_Product::has_voucher($product)) { $voucher = WC_PDF_Product_Vouchers_Product::get_voucher($product); // record the voucher id $cart_item_data['voucher_id'] = $voucher->id; // set the selected voucher image id, or default to the main one if the voucher was added from the catalog $cart_item_data['voucher_image_id'] = isset($_POST['voucher_image'][$_product_id]) ? $_POST['voucher_image'][$_product_id] : $voucher->image_id; // set any user-input fields, which will end up in the order item meta data (which can be displayed on the frontend) $fields = $voucher->get_user_input_voucher_fields(); foreach ($fields as $field) { if (isset($_POST[$field['name']][$_product_id])) { $cart_item_data['voucher_item_meta_data'][$field['name']] = $_POST[$field['name']][$_product_id]; } } // add a random so that multiple of the same product can be added to the cart when "sold individually" is enabled $cart_item_data['voucher_random'] = uniqid('voucher_'); } return $cart_item_data; }
/** * Called when an order is updated from the admin, creates a new voucher if * a voucher item was added, and updates the voucher expiration and redeem * item meta. * * @since 1.2 * @param int $post_id the post identifier * @param object $post the order post object * * @return array order item data to persist */ public function process_shop_order_meta($post_id, $post) { // get the order $order = wc_get_order($post_id); $order_items = $order->get_items(); // loop through any order items by id if (isset($_POST['order_item_id'])) { foreach ($_POST['order_item_id'] as $item_id) { $item_id = absint($item_id); if (!isset($order_items[$item_id]) || !$order_items[$item_id]) { continue; } $order_item = $order_items[$item_id]; $product_id = $order_item['variation_id'] ? $order_item['variation_id'] : $order_item['product_id']; $product = wc_get_product($product_id); // if we have a voucher product, but no voucher set for the order item, this is likely an item newly added from the admin, so create a default voucher if ($product && $product->is_downloadable() && WC_PDF_Product_Vouchers_Product::has_voucher($product) && (!isset($order_item['voucher_id']) || !$order_item['voucher_id'])) { $voucher = WC_PDF_Product_Vouchers_Product::get_voucher($product); $voucher_number = WC_PDF_Product_Vouchers_Voucher::generate_voucher_number(); wc_add_order_item_meta($item_id, '_voucher_image_id', $voucher->get_image_id()); wc_add_order_item_meta($item_id, '_voucher_id', $voucher->id); wc_add_order_item_meta($item_id, '_voucher_redeem', array_pad(array(), $order_item['qty'], null)); // TODO: need to handle the order item quantity being changed from the admin wc_add_order_item_meta($item_id, '_voucher_number', $voucher_number); // if download permissions have already been granted, grant permission to the newly created voucher if (isset($order->download_permissions_granted[0]) && 1 == $order->download_permissions_granted[0]) { wc_downloadable_file_permission('wc_vouchers_' . $voucher_number, $product_id, $order); } } if (isset($_POST['voucher_expiration'][$item_id])) { wc_update_order_item_meta($item_id, '_voucher_expiration', $_POST['voucher_expiration'][$item_id]); } if (isset($_POST['voucher_redeem'][$item_id])) { wc_update_order_item_meta($item_id, '_voucher_redeem', $_POST['voucher_redeem'][$item_id]); } } } }
/** * Return our voucher file path as the download file * * @since 1.2 * @param string $download_file_path the download file path * @param int $product the product * @param int $download_id downloadable file identifier * * @return string the download file path */ public function voucher_file_download_path($download_file_path, $product, $download_id) { global $wpdb, $post; // if there is no download file path set, it means this might be an item voucher being requested if (!$download_file_path) { $order_id = null; if ($post && 'shop_order' == $post->post_type && $post->ID) { $order_id = $post->ID; } // are we being called from the context of the has_file() checks? if (!$order_id && (!isset($_GET['download_file']) || !isset($_GET['order']) || !isset($_GET['email']) || !isset($_GET['key']))) { if (WC_PDF_Product_Vouchers_Product::has_voucher($product)) { return $download_id; } else { // otherwise, non-voucher product, return the passed-in value return $download_file_path; } } if (!$order_id) { // get the order id from the GET parameters when needed $order_key = urldecode($_GET['order']); $email = str_replace(' ', '+', urldecode($_GET['email'])); $order_id = $wpdb->get_var($wpdb->prepare("\n\t\t\t\t\tSELECT order_id\n\t\t\t\t\tFROM {$wpdb->prefix}woocommerce_downloadable_product_permissions\n\t\t\t\t\tWHERE user_email = %s\n\t\t\t\t\tAND order_key = %s\n\t\t\t\t\tAND product_id = %s\n\t\t\t\t\tAND download_id = %s", $email, $order_key, isset($product->variation_id) ? $product->variation_id : $product->id, $download_id)); } // get and return the path to the requested voucher file if ($order_id) { $order = wc_get_order($order_id); $voucher = WC_PDF_Product_Vouchers_Order::get_voucher_by_voucher_number($order, str_replace('wc_vouchers_', '', $download_id)); if ($voucher && $voucher->file_exists($this->plugin->get_uploads_path())) { $download_file_path = $voucher->get_voucher_full_filename($this->plugin->get_uploads_path()); if ('redirect' === get_option('woocommerce_file_download_method')) { $download_file_path = $voucher->convert_path_to_url($file_path); } } } } return $download_file_path; }