Advertisement
zumixosan

Min Max Qty

Oct 23rd, 2019
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 30.90 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Plugin Name: WooCommerce Min/Max Quantities
  4.  * Plugin URI: https://woocommerce.com/products/minmax-quantities/
  5.  * Description: Lets you define minimum/maximum allowed quantities for products, variations and orders. Requires 2.0+
  6.  * Version: 2.4.10
  7.  * Author: WooCommerce
  8.  * Author URI: https://woocommerce.com
  9.  * Requires at least: 4.0
  10.  * Tested up to: 5.0
  11.  * WC tested up to: 3.7
  12.  * WC requires at least: 2.6
  13.  *
  14.  * Text Domain: woocommerce-min-max-quantities
  15.  * Domain Path: /languages
  16.  *
  17.  * Copyright: © 2019 WooCommerce.
  18.  * License: GNU General Public License v3.0
  19.  * License URI: http://www.gnu.org/licenses/gpl-3.0.html
  20.  * Woo: 18616:2b5188d90baecfb781a5aa2d6abb900a
  21.  */
  22.  
  23. /**
  24.  * Required functions
  25.  */
  26. if ( ! function_exists( 'woothemes_queue_update' ) ) {
  27.     require_once( 'woo-includes/woo-functions.php' );
  28. }
  29.  
  30. /**
  31.  * Plugin updates
  32.  */
  33. woothemes_queue_update( plugin_basename( __FILE__ ), '2b5188d90baecfb781a5aa2d6abb900a', '18616' );
  34.  
  35. /**
  36.  * woocommerce_min_max_quantities class
  37.  **/
  38. if ( ! class_exists( 'WC_Min_Max_Quantities' ) ) :
  39.  
  40. define( 'WC_MIN_MAX_QUANTITIES', '2.4.10' );
  41.  
  42. class WC_Min_Max_Quantities {
  43.  
  44.     public $minimum_order_quantity;
  45.     public $maximum_order_quantity;
  46.     public $minimum_order_value;
  47.     public $maximum_order_value;
  48.     public $excludes = array();
  49.     public $addons;
  50.  
  51.     /** @var object Class Instance */
  52.     private static $instance;
  53.  
  54.     /**
  55.      * Get the class instance
  56.      */
  57.     public static function get_instance() {
  58.         return null === self::$instance ? ( self::$instance = new self ) : self::$instance;
  59.     }
  60.  
  61.     /**
  62.      * Constructor
  63.      */
  64.     public function __construct() {
  65.         if ( ! is_woocommerce_active() ) {
  66.             return;
  67.         }
  68.  
  69.         /**
  70.          * Localisation
  71.          **/
  72.         $this->load_plugin_textdomain();
  73.  
  74.         if ( is_admin() ) {
  75.             include_once( dirname( __FILE__ ) . '/includes/class-wc-min-max-quantities-admin.php' );
  76.         }
  77.  
  78.         include_once( dirname( __FILE__ ) . '/includes/class-wc-min-max-quantities-addons.php' );
  79.  
  80.         $this->addons = new WC_Min_Max_Quantities_Addons();
  81.  
  82.         $this->minimum_order_quantity = absint( get_option( 'woocommerce_minimum_order_quantity' ) );
  83.         $this->maximum_order_quantity = absint( get_option( 'woocommerce_maximum_order_quantity' ) );
  84.         $this->minimum_order_value    = absint( get_option( 'woocommerce_minimum_order_value' ) );
  85.         $this->maximum_order_value    = absint( get_option( 'woocommerce_maximum_order_value' ) );
  86.  
  87.         // Check items
  88.         add_action( 'woocommerce_check_cart_items', array( $this, 'check_cart_items' ) );
  89.        
  90.         add_action('woocommerce_after_add_to_cart_button',array($this,'minimum_info_qty'));
  91.         // quantity selelectors (2.0+)
  92.         add_filter( 'woocommerce_quantity_input_args', array( $this, 'update_quantity_args' ), 10, 2 );
  93.         add_filter( 'woocommerce_available_variation',  array( $this, 'available_variation' ), 10, 3 );
  94.  
  95.         // Prevent add to cart
  96.         add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'add_to_cart' ), 10, 4 );
  97.  
  98.         // Min add to cart ajax
  99.         add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_link' ), 10, 2 );
  100.  
  101.         // Show a notice when items would have to be on back order because of min/max
  102.         add_filter( 'woocommerce_get_availability', array( $this, 'maybe_show_backorder_message' ), 10, 2 );
  103.  
  104.         add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ) );
  105.     }
  106.  
  107.     public function load_scripts() {
  108.         // only load on single product page and cart page
  109.         if ( is_product() || is_cart() ) {
  110.             wc_enqueue_js( "
  111.                 jQuery( 'body' ).on( 'show_variation', function( event, variation ) {
  112.                     jQuery( 'form.variations_form' ).find( 'input[name=quantity]' ).prop( 'step', variation.step ).val( variation.input_value );
  113.                 });
  114.             " );
  115.         }
  116.     }
  117.  
  118.     /**
  119.      * Load Localisation files.
  120.      *
  121.      * Note: the first-loaded translation file overrides any following ones if the same translation is present.
  122.      *
  123.      * Frontend/global Locales found in:
  124.      *      - WP_LANG_DIR/woocommerce-min-max-quantities/woocommerce-min-max-quantities-LOCALE.mo
  125.      *      - woocommerce-min-max-quantities/woocommerce-min-max-quantities-LOCALE.mo (which if not found falls back to:)
  126.      *      - WP_LANG_DIR/plugins/woocommerce-min-max-quantities-LOCALE.mo
  127.      */
  128.     public function load_plugin_textdomain() {
  129.         $locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce-min-max-quantities' );
  130.  
  131.         load_textdomain( 'woocommerce-min-max-quantities', WP_LANG_DIR . '/woocommerce-min-max-quantities/woocommerce-min-max-quantities-' . $locale . '.mo' );
  132.         load_plugin_textdomain( 'woocommerce-min-max-quantities', false, plugin_basename( dirname( __FILE__ ) ) . '/' );
  133.     }
  134.  
  135.     /**
  136.      * Add an error.
  137.      *
  138.      * @since 1.0.0
  139.      * @version 2.3.18
  140.      * @param string $error
  141.      */
  142.     public function add_error( $error = '' ) {
  143.         wc_add_notice( $error, 'error' );
  144.     }
  145.  
  146.     /**
  147.      * Add quantity property to add to cart button on shop loop for simple products.
  148.      *
  149.      * @access public
  150.      * @return void
  151.      */
  152.     public function add_to_cart_link( $html, $product ) {
  153.  
  154.         if ( 'variable' !== $product->get_type() ) {
  155.             $quantity_attribute = 1;
  156.             $minimum_quantity   = absint( get_post_meta( $product->get_id(), 'minimum_allowed_quantity', true ) );
  157.             $group_of_quantity  = absint( get_post_meta( $product->get_id(), 'group_of_quantity', true ) );
  158.  
  159.             if ( $minimum_quantity || $group_of_quantity ) {
  160.  
  161.                 $quantity_attribute = $minimum_quantity;
  162.  
  163.                 if ( $group_of_quantity > 0 && $minimum_quantity < $group_of_quantity ) {
  164.                     $quantity_attribute = $group_of_quantity;
  165.                 }
  166.  
  167.                 $html = str_replace( '<a ', '<a data-quantity="' . $quantity_attribute . '" ', $html );
  168.             }
  169.         }
  170.  
  171.         return $html;
  172.     }
  173.  
  174.     /**
  175.      * Get product or variation ID to check
  176.      * @return int
  177.      */
  178.     public function get_id_to_check( $values ) {
  179.         if ( $values['variation_id'] ) {
  180.             $min_max_rules = get_post_meta( $values['variation_id'], 'min_max_rules', true );
  181.  
  182.             if ( 'yes' === $min_max_rules ) {
  183.                 $checking_id = $values['variation_id'];
  184.             } else {
  185.                 $checking_id = $values['product_id'];
  186.             }
  187.         } else {
  188.             $checking_id = $values['product_id'];
  189.         }
  190.  
  191.         return $checking_id;
  192.     }
  193.  
  194.     /**
  195.      * Validate cart items against set rules
  196.      *
  197.      */
  198.     public function check_cart_items() {
  199.         $checked_ids      = $product_quantities = $category_quantities = array();
  200.         $total_quantity   = $total_cost = 0;
  201.         $apply_cart_rules = false;
  202.  
  203.         // Count items + variations first
  204.         foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
  205.             $product     = $values['data'];
  206.             $checking_id = $this->get_id_to_check( $values );
  207.  
  208.             if ( ! isset( $product_quantities[ $checking_id ] ) ) {
  209.                 $product_quantities[ $checking_id ] = $values['quantity'];
  210.             } else {
  211.                 $product_quantities[ $checking_id ] += $values['quantity'];
  212.             }
  213.  
  214.             // do_not_count and cart_exclude from variation or product
  215.             $minmax_do_not_count = apply_filters( 'wc_min_max_quantity_minmax_do_not_count', ( 'yes' === get_post_meta( $checking_id, 'variation_minmax_do_not_count', true ) ? 'yes' : get_post_meta( $values['product_id'], 'minmax_do_not_count', true ) ), $checking_id, $cart_item_key, $values );
  216.  
  217.             $minmax_cart_exclude = apply_filters( 'wc_min_max_quantity_minmax_cart_exclude', ( 'yes' === get_post_meta( $checking_id, 'variation_minmax_cart_exclude', true ) ? 'yes' : get_post_meta( $values['product_id'], 'minmax_cart_exclude', true ) ), $checking_id, $cart_item_key, $values );
  218.  
  219.             if ( 'yes' !== $minmax_do_not_count && 'yes' !== $minmax_cart_exclude ) {
  220.                 $total_cost += $product->get_price() * $values['quantity'];
  221.             }
  222.         }
  223.  
  224.         // Check cart items
  225.         foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
  226.             $checking_id    = $this->get_id_to_check( $values );
  227.             $terms          = get_the_terms( $values['product_id'], 'product_cat' );
  228.             $found_term_ids = array();
  229.  
  230.             if ( $terms ) {
  231.  
  232.                 foreach ( $terms as $term ) {
  233.  
  234.                     if ( 'yes' === get_post_meta( $checking_id, 'minmax_category_group_of_exclude', true ) ) {
  235.                         continue;
  236.                     }
  237.  
  238.                     if ( 'yes' === get_post_meta( $checking_id, 'variation_minmax_category_group_of_exclude', true ) ) {
  239.                         continue;
  240.                     }
  241.  
  242.                     if ( in_array( $term->term_id, $found_term_ids ) ) {
  243.                         continue;
  244.                     }
  245.  
  246.                     $found_term_ids[] = $term->term_id;
  247.                     $category_quantities[ $term->term_id ] = isset( $category_quantities[ $term->term_id ] ) ? $category_quantities[ $term->term_id ] + $values['quantity'] : $values['quantity'];
  248.  
  249.                     // Record count in parents of this category too
  250.                     $parents = get_ancestors( $term->term_id, 'product_cat' );
  251.  
  252.                     foreach ( $parents as $parent ) {
  253.                         if ( in_array( $parent, $found_term_ids ) ) {
  254.                             continue;
  255.                         }
  256.  
  257.                         $found_term_ids[] = $parent;
  258.                         $category_quantities[ $parent ] = isset( $category_quantities[ $parent ] ) ? $category_quantities[ $parent ] + $values['quantity'] : $values['quantity'];
  259.                     }
  260.                 }
  261.             }
  262.  
  263.             // Check item rules once per product ID
  264.             if ( in_array( $checking_id, $checked_ids ) ) {
  265.                 continue;
  266.             }
  267.  
  268.             $product = $values['data'];
  269.  
  270.             // do_not_count and cart_exclude from variation or product
  271.             $minmax_do_not_count = apply_filters( 'wc_min_max_quantity_minmax_do_not_count', ( 'yes' === get_post_meta( $checking_id, 'variation_minmax_do_not_count', true ) ? 'yes' : get_post_meta( $values['product_id'], 'minmax_do_not_count', true ) ), $checking_id, $cart_item_key, $values );
  272.  
  273.             $minmax_cart_exclude = apply_filters( 'wc_min_max_quantity_minmax_cart_exclude', ( 'yes' === get_post_meta( $checking_id, 'variation_minmax_cart_exclude', true ) ? 'yes' : get_post_meta( $values['product_id'], 'minmax_cart_exclude', true ) ), $checking_id, $cart_item_key, $values );
  274.  
  275.             if ( 'yes' === $minmax_do_not_count || 'yes' === $minmax_cart_exclude ) {
  276.                 // Do not count
  277.                 $this->excludes[] = $product->get_title();
  278.  
  279.             } else {
  280.                 $total_quantity += $product_quantities[ $checking_id ];
  281.             }
  282.  
  283.             if ( 'yes' !== $minmax_cart_exclude ) {
  284.                 $apply_cart_rules = true;
  285.             }
  286.  
  287.             $checked_ids[] = $checking_id;
  288.  
  289.             if ( $values['variation_id'] ) {
  290.                 $min_max_rules = get_post_meta( $values['variation_id'], 'min_max_rules', true );
  291.  
  292.                 // variation level min max rules enabled
  293.                 if ( 'yes' === $min_max_rules ) {
  294.                     $minimum_quantity  = absint( apply_filters( 'wc_min_max_quantity_minimum_allowed_quantity', get_post_meta( $values['variation_id'], 'variation_minimum_allowed_quantity', true ), $values['variation_id'], $cart_item_key, $values ) );
  295.  
  296.                     $maximum_quantity  = absint( apply_filters( 'wc_min_max_quantity_maximum_allowed_quantity', get_post_meta( $values['variation_id'], 'variation_maximum_allowed_quantity', true ), $values['variation_id'], $cart_item_key, $values ) );
  297.  
  298.                     $group_of_quantity = absint( apply_filters( 'wc_min_max_quantity_group_of_quantity', get_post_meta( $values['variation_id'], 'variation_group_of_quantity', true ), $values['variation_id'], $cart_item_key, $values ) );
  299.                 } else {
  300.                     $minimum_quantity  = absint( apply_filters( 'wc_min_max_quantity_minimum_allowed_quantity', get_post_meta( $values['product_id'], 'minimum_allowed_quantity', true ), $values['product_id'], $cart_item_key, $values ) );
  301.  
  302.                     $maximum_quantity  = absint( apply_filters( 'wc_min_max_quantity_maximum_allowed_quantity', get_post_meta( $values['product_id'], 'maximum_allowed_quantity', true ), $values['product_id'], $cart_item_key, $values ) );
  303.  
  304.                     $group_of_quantity = absint( apply_filters( 'wc_min_max_quantity_group_of_quantity', get_post_meta( $values['product_id'], 'group_of_quantity', true ), $values['product_id'], $cart_item_key, $values ) );
  305.                 }
  306.             } else {
  307.                 $minimum_quantity  = absint( apply_filters( 'wc_min_max_quantity_minimum_allowed_quantity', get_post_meta( $checking_id, 'minimum_allowed_quantity', true ), $checking_id, $cart_item_key, $values ) );
  308.  
  309.                 $maximum_quantity  = absint( apply_filters( 'wc_min_max_quantity_maximum_allowed_quantity', get_post_meta( $checking_id, 'maximum_allowed_quantity', true ), $checking_id, $cart_item_key, $values ) );
  310.  
  311.                 $group_of_quantity = absint( apply_filters( 'wc_min_max_quantity_group_of_quantity', get_post_meta( $checking_id, 'group_of_quantity', true ), $checking_id, $cart_item_key, $values ) );
  312.             }
  313.  
  314.             $this->check_rules( $product, $product_quantities[ $checking_id ], $minimum_quantity, $maximum_quantity, $group_of_quantity );
  315.            
  316.         }
  317.  
  318.         // Cart rules
  319.         if ( $apply_cart_rules ) {
  320.  
  321.             $excludes = '';
  322.  
  323.             if ( sizeof( $this->excludes ) > 0 ) {
  324.                 $excludes = ' (' . __( 'excludes ', 'woocommerce-min-max-quantities' ) . implode( ', ', $this->excludes ) . ')';
  325.             }
  326.  
  327.             if ( $this->minimum_order_quantity > 0 && $total_quantity < $this->minimum_order_quantity ) {
  328.  
  329.                 $this->add_error( sprintf( __( 'The minimum required items in cart is %d. Please add more items to your cart', 'woocommerce-min-max-quantities' ), $this->minimum_order_quantity ) . $excludes );
  330.  
  331.                 return;
  332.  
  333.             }
  334.  
  335.             if ( $this->maximum_order_quantity > 0 && $total_quantity > $this->maximum_order_quantity ) {
  336.  
  337.                 $this->add_error( sprintf( __( 'The maximum allowed order quantity is %d. Please remove some items from your cart.', 'woocommerce-min-max-quantities' ), $this->maximum_order_quantity ) );
  338.  
  339.                 return;
  340.  
  341.             }
  342.  
  343.             // Check cart value
  344.             if ( $this->minimum_order_value && $total_cost && $total_cost < $this->minimum_order_value ) {
  345.  
  346.                 $this->add_error( sprintf( __( 'The minimum required order value is %s. Please add more items to your cart', 'woocommerce-min-max-quantities' ), wc_price( $this->minimum_order_value ) ) . $excludes );
  347.  
  348.                 return;
  349.             }
  350.  
  351.             if ( $this->maximum_order_value && $total_cost && $total_cost > $this->maximum_order_value ) {
  352.  
  353.                 $this->add_error( sprintf( __( 'The maximum allowed order value is %s. Please remove some items from your cart.', 'woocommerce-min-max-quantities' ), wc_price( $this->maximum_order_value ) ) );
  354.  
  355.                 return;
  356.             }
  357.         }
  358.  
  359.         // Check category rules
  360.         foreach ( $category_quantities as $category => $quantity ) {
  361.  
  362.             $group_of_quantity = intval( version_compare( WC_VERSION, '3.6', 'ge' ) ? get_term_meta( $category, 'group_of_quantity', true ) : get_woocommerce_term_meta( $category, 'group_of_quantity', true ) );
  363.  
  364.             if ( $group_of_quantity > 0 && ( intval( $quantity ) % intval( $group_of_quantity ) > 0 ) ) {
  365.  
  366.                 $term          = get_term_by( 'id', $category, 'product_cat' );
  367.                 $product_names = array();
  368.  
  369.                 foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
  370.  
  371.                     // if exclude is enable, skip
  372.                     if ( 'yes' === get_post_meta( $values['product_id'], 'minmax_category_group_of_exclude', true ) || 'yes' === get_post_meta( $values['variation_id'], 'variation_minmax_category_group_of_exclude', true ) ) {
  373.                         continue;
  374.                     }
  375.  
  376.                     if ( has_term( $category, 'product_cat', $values['product_id'] ) ) {
  377.                         $product_names[] = $values['data']->get_title();
  378.                     }
  379.                 }
  380.  
  381.                 if ( $product_names ) {
  382.                     $this->add_error( sprintf( __( 'Items in the <strong>%s</strong> category (<em>%s</em>) must be bought in groups of %d. Please add or remove the items to continue.', 'woocommerce-min-max-quantities' ), $term->name, implode( ', ', $product_names ), $group_of_quantity, $group_of_quantity - ( $quantity % $group_of_quantity ) ) );
  383.                     return;
  384.                 }
  385.             }
  386.         }
  387.     }
  388.  
  389.     /**
  390.      * If the minimum allowed quantity for purchase is lower then the current stock, we need to
  391.      * let the user know that they are on backorder, or out of stock.
  392.      */
  393.     public function maybe_show_backorder_message( $args, $product ) {
  394.         if ( ! $product->managing_stock() ) {
  395.             return $args;
  396.         }
  397.  
  398.         // Figure out what our minimum_quantity is
  399.         $product_id = $product->get_id();
  400.         if ( 'WC_Product_Variation' === get_class( $product ) ) {
  401.             $variation_id = ( version_compare( WC_VERSION, '3.0', '<' ) && isset( $product->variation_id ) ) ? $product->variation_id : $product->get_id();
  402.             $min_max_rules = get_post_meta( $variation_id, 'min_max_rules', true );
  403.             if ( 'yes' === $min_max_rules ) {
  404.                 $minimum_quantity = absint( get_post_meta( $variation_id, 'variation_minimum_allowed_quantity', true ) );
  405.             } else {
  406.                 $minimum_quantity = absint( get_post_meta( $product_id, 'minimum_allowed_quantity', true ) );
  407.             }
  408.         } else {
  409.             $minimum_quantity = absint( get_post_meta( $product_id, 'minimum_allowed_quantity', true ) );
  410.         }
  411.  
  412.         // If the minimum quantity allowed for purchase is smaller then the amount in stock, we need
  413.         // clearer messaging
  414.         if ( $minimum_quantity > 0 && $product->get_stock_quantity() < $minimum_quantity ) {
  415.             if ( $product->backorders_allowed() ) {
  416.                 return array(
  417.                     'availability' =>  __( 'Available on backorder', 'woocommerce-min-max-quantities' ),
  418.                     'class'        => 'available-on-backorder',
  419.                 );
  420.             } else {
  421.                 return array(
  422.                     'availability' => __( 'Out of stock', 'woocommerce-min-max-quantities' ),
  423.                     'class'        => 'out-of-stock',
  424.                 );
  425.             }
  426.         }
  427.  
  428.         return $args;
  429.     }
  430.  
  431.     /**
  432.      * Add respective error message depending on rules checked
  433.      *
  434.      * @access public
  435.      * @return void
  436.      */
  437.     public function check_rules( $product, $quantity, $minimum_quantity, $maximum_quantity, $group_of_quantity ) {
  438.         $parent_id = $product->is_type( 'variation' ) ? ( version_compare( WC_VERSION, '3.0', '<' ) ? $product->parent_id : $product->get_parent_id() ) : $product->get_id();
  439.  
  440.         $allow_combination = 'yes' === get_post_meta( $parent_id, 'allow_combination', true );
  441.  
  442.         if ( $minimum_quantity > 0 && $quantity < $minimum_quantity ) {
  443.  
  444.             if ( $allow_combination && ( $product->is_type( 'variation' ) || $product->is_type( 'variable' ) ) ) {
  445.                 $this->add_error( sprintf( __( 'The minimum order quantity for %s is %s - please increase the quantity in your cart or add additional variation of this product.', 'woocommerce-min-max-quantities' ), $product->get_title(), $minimum_quantity ) );
  446.             } else {
  447.                 $this->add_error( sprintf( __( 'The minimum order quantity for %s is %s - please increase the quantity in your cart.', 'woocommerce-min-max-quantities' ), $product->get_title(), $minimum_quantity ) );
  448.             }
  449.  
  450.         } elseif ( $maximum_quantity > 0 && $quantity > $maximum_quantity ) {
  451.             if ( $allow_combination && ( $product->is_type( 'variation' ) || $product->is_type( 'variable' ) ) ) {
  452.                 $this->add_error( sprintf( __( 'The maximum allowed quantity for %s is %s - please decrease the quantity in your cart or remove additional variation of this product.', 'woocommerce-min-max-quantities' ), $product->get_title(), $maximum_quantity ) );
  453.             } else {
  454.                 $this->add_error( sprintf( __( 'The maximum allowed quantity for %s is %s - please decrease the quantity in your cart.', 'woocommerce-min-max-quantities' ), $product->get_title(), $maximum_quantity ) );
  455.             }
  456.  
  457.         }
  458.  
  459.         if ( $group_of_quantity > 0 && ( intval( $quantity ) % intval( $group_of_quantity ) > 0 ) ) {
  460.             $this->add_error( sprintf( __( '%s must be bought in groups of %d. Please add or decrease items to continue.', 'woocommerce-min-max-quantities' ), $product->get_title(), $group_of_quantity, $group_of_quantity - ( $quantity % $group_of_quantity ) ) );
  461.         }
  462.     }
  463.  
  464.     /**
  465.      * Add to cart validation
  466.      *
  467.      * @access public
  468.      * @param mixed $pass
  469.      * @param mixed $product_id
  470.      * @param mixed $quantity
  471.      * @return void
  472.      */
  473.     public function add_to_cart( $pass, $product_id, $quantity, $variation_id = 0 ) {
  474.         $rule_for_variaton = false;
  475.  
  476.         $allow_combination = 'yes' === get_post_meta( $product_id, 'allow_combination', true );
  477.  
  478.         if ( 0 < $variation_id && $allow_combination ) {
  479.             return $pass;
  480.         }
  481.  
  482.         // Product level.
  483.         if ( $variation_id ) {
  484.  
  485.             $min_max_rules = get_post_meta( $variation_id, 'min_max_rules', true );
  486.  
  487.             if ( 'yes' === $min_max_rules ) {
  488.  
  489.                 $maximum_quantity  = absint( get_post_meta( $variation_id, 'variation_maximum_allowed_quantity', true ) );
  490.                 $minimum_quantity  = absint( get_post_meta( $variation_id, 'variation_minimum_allowed_quantity', true ) );
  491.                 $rule_for_variaton = true;
  492.  
  493.             } else {
  494.  
  495.                 $maximum_quantity = absint( get_post_meta( $product_id, 'maximum_allowed_quantity', true ) );
  496.                 $minimum_quantity = absint( get_post_meta( $product_id, 'minimum_allowed_quantity', true ) );
  497.  
  498.             }
  499.  
  500.         } else {
  501.  
  502.             $maximum_quantity = absint( get_post_meta( $product_id, 'maximum_allowed_quantity', true ) );
  503.             $minimum_quantity = absint( get_post_meta( $product_id, 'minimum_allowed_quantity', true ) );
  504.  
  505.         }
  506.  
  507.         $total_quantity = $quantity;
  508.  
  509.         // Count items
  510.         foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
  511.  
  512.             if ( $rule_for_variaton ) {
  513.  
  514.                 if ( $values['variation_id'] == $variation_id ) {
  515.  
  516.                     $total_quantity += $values['quantity'];
  517.                 }
  518.  
  519.             } else {
  520.  
  521.                 if ( $values['product_id'] == $product_id ) {
  522.  
  523.                     $total_quantity += $values['quantity'];
  524.                 }
  525.             }
  526.         }
  527.  
  528.         if ( isset( $maximum_quantity ) && $maximum_quantity > 0 ) {
  529.             if ( $total_quantity > 0 && $total_quantity > $maximum_quantity ) {
  530.  
  531.                 $_product = wc_get_product( $product_id );
  532.  
  533.                 $this->add_error( sprintf( __( 'The maximum allowed quantity for %s is %d (you currently have %s in your cart).', 'woocommerce-min-max-quantities' ), $_product->get_title(), $maximum_quantity, $total_quantity - $quantity ) );
  534.  
  535.                 $pass = false;
  536.             }
  537.         }
  538.  
  539.         if ( isset( $minimum_quantity ) && $minimum_quantity > 0 ) {
  540.             if ( $total_quantity < $minimum_quantity ) {
  541.  
  542.                 $_product = wc_get_product( $product_id );
  543.  
  544.                 $this->add_error( sprintf( __( 'The minimum allowed quantity for %s is %d (you currently have %s in your cart).', 'woocommerce-min-max-quantities' ), $_product->get_title(), $minimum_quantity, $total_quantity - $quantity ) );
  545.  
  546.                 $pass = true;
  547.             }
  548.         }
  549.  
  550.         // If product level quantity are not set then check global order quantity.
  551.         if ( empty( $maximum_quantity ) && empty( $minimum_quantity ) ) {
  552.             $total_quantity = intval( WC()->cart->get_cart_contents_count() + $quantity );
  553.  
  554.             if ( $this->maximum_order_quantity && $this->maximum_order_quantity > 0 ) {
  555.                 if ( $total_quantity > $this->maximum_order_quantity ) {
  556.                     if ( 0 === $total_quantity - $quantity ) {
  557.                         $this->add_error( sprintf( __( 'The maximum allowed items in cart is %d.', 'woocommerce-min-max-quantities' ), $this->maximum_order_quantity ) );
  558.                     } else {
  559.                         $this->add_error( sprintf( __( 'The maximum allowed items in cart is %d (you currently have %d in your cart).', 'woocommerce-min-max-quantities' ), $this->maximum_order_quantity, $total_quantity - $quantity ) );
  560.                     }
  561.  
  562.                     $pass = false;
  563.                 }
  564.             }
  565.         }
  566.  
  567.         return $pass;
  568.     }
  569.  
  570.     /**
  571.      * Updates the quantity arguments
  572.      *
  573.      * @return array
  574.      */
  575.     function update_quantity_args( $data, $product ) {
  576.         // multiple shipping address product plugin compat
  577.         // don't update the quantity args when on set multiple address page
  578.         if ( $this->addons->is_multiple_shipping_address_page() ) {
  579.             return $data;
  580.         }
  581.  
  582.         $group_of_quantity = get_post_meta( $product->get_id(), 'group_of_quantity', true );
  583.         $minimum_quantity  = get_post_meta( $product->get_id(), 'minimum_allowed_quantity', true );
  584.         $maximum_quantity  = get_post_meta( $product->get_id(), 'maximum_allowed_quantity', true );
  585.         $allow_combination = 'yes' === get_post_meta( version_compare( WC_VERSION, '3.0', '<' ) ? $product->get_id() : $product->get_parent_id(), 'allow_combination', true );
  586.  
  587.         /*
  588.          * If its a variable product and allow combination is enabled,
  589.          * we don't need to set the quantity to default minimum.
  590.          */
  591.         if ( $allow_combination && $product->is_type( 'variation' ) ) {
  592.             return $data;
  593.         }
  594.  
  595.         // if variable product, only apply in cart
  596.         $variation_id = ( version_compare( WC_VERSION, '3.0', '<' ) && isset( $product->variation_id ) ) ? $product->variation_id : $product->get_id();
  597.  
  598.         if ( is_cart() && $product->is_type( 'variation' ) ) {
  599.             $parent_variable_id = version_compare( WC_VERSION, '3.0', '<' ) ? $product->get_id() : $product->get_parent_id();
  600.  
  601.             $group_of_quantity = get_post_meta( $parent_variable_id, 'group_of_quantity', true );
  602.             $minimum_quantity  = get_post_meta( $parent_variable_id, 'minimum_allowed_quantity', true );
  603.             $maximum_quantity  = get_post_meta( $parent_variable_id, 'maximum_allowed_quantity', true );
  604.             $allow_combination = 'yes' === get_post_meta( $parent_variable_id, 'allow_combination', true );
  605.  
  606.             $min_max_rules = get_post_meta( $variation_id, 'min_max_rules', true );
  607.  
  608.             if ( 'no' === $min_max_rules || empty( $min_max_rules ) ) {
  609.                 $min_max_rules = false;
  610.  
  611.             } else {
  612.                 $min_max_rules = true;
  613.  
  614.             }
  615.  
  616.             $variation_minimum_quantity  = get_post_meta( $variation_id, 'variation_minimum_allowed_quantity', true );
  617.             $variation_maximum_quantity  = get_post_meta( $variation_id, 'variation_maximum_allowed_quantity', true );
  618.             $variation_group_of_quantity = get_post_meta( $variation_id, 'variation_group_of_quantity', true );
  619.  
  620.             // override product level
  621.             if ( $min_max_rules && $variation_minimum_quantity ) {
  622.                 $minimum_quantity = $variation_minimum_quantity;
  623.  
  624.             }
  625.  
  626.             // override product level
  627.             if ( $min_max_rules && $variation_maximum_quantity ) {
  628.                 $maximum_quantity = $variation_maximum_quantity;
  629.             }
  630.  
  631.             // override product level
  632.             if ( $min_max_rules && $variation_group_of_quantity ) {
  633.                 $group_of_quantity = $variation_group_of_quantity;
  634.  
  635.             }
  636.  
  637.         }
  638.  
  639.         if ( $minimum_quantity ) {
  640.  
  641.             if ( $product->managing_stock() && ! $product->backorders_allowed() && absint( $minimum_quantity ) > $product->get_stock_quantity() ) {
  642.                 $data['min_value'] = $product->get_stock_quantity();
  643.  
  644.             } else {
  645.                 $data['min_value'] = $minimum_quantity;
  646.             }
  647.         }
  648.  
  649.         if ( $maximum_quantity ) {
  650.  
  651.             if ( $product->managing_stock() && $product->backorders_allowed() ) {
  652.                 $data['max_value'] = $maximum_quantity;
  653.  
  654.             } elseif ( $product->managing_stock() && absint( $maximum_quantity ) > $product->get_stock_quantity() ) {
  655.                 $data['max_value'] = $product->get_stock_quantity();
  656.  
  657.             } else {
  658.                 $data['max_value'] = $maximum_quantity;
  659.             }
  660.         }
  661.  
  662.         if ( $group_of_quantity ) {
  663.             $data['step'] = 1;
  664.  
  665.             // if both minimum and maximum quantity are set, make sure both are equally divisble by qroup of quantity
  666.             if ( $maximum_quantity && $minimum_quantity ) {
  667.  
  668.                 if ( absint( $maximum_quantity ) % absint( $group_of_quantity ) === 0 && absint( $minimum_quantity ) % absint( $group_of_quantity ) === 0 ) {
  669.                     $data['step'] = $group_of_quantity;
  670.  
  671.                 }
  672.  
  673.             } elseif ( ! $maximum_quantity || absint( $maximum_quantity ) % absint( $group_of_quantity ) === 0 ) {
  674.  
  675.                 $data['step'] = $group_of_quantity;
  676.             }
  677.  
  678.             // set a new minimum if group of is set but not minimum
  679.             if ( ! $minimum_quantity ) {
  680.                 $data['min_value'] = $group_of_quantity;
  681.             }
  682.         }
  683.  
  684.         // don't apply for cart or checkout as cart/checkout form has qty already pre-filled
  685.         if ( ! is_cart() && ! is_checkout() ) {
  686.             $data['input_value'] = ! empty( $minimum_quantity ) ? $minimum_quantity : $data['input_value'];
  687.         }
  688.  
  689.         return $data;
  690.     }
  691.  
  692.     /**
  693.      * Adds variation min max settings to the localized variation parameters to be used by JS
  694.      *
  695.      * @access public
  696.      * @param array $data
  697.      * @param obhect $product
  698.      * @param object $variation
  699.      * @return array $data
  700.      */
  701.     function available_variation( $data, $product, $variation ) {
  702.         $variation_id = ( version_compare( WC_VERSION, '3.0', '<' ) && isset( $variation->variation_id ) ) ? $variation->variation_id : $variation->get_id();
  703.  
  704.         $min_max_rules = get_post_meta( $variation_id, 'min_max_rules', true );
  705.  
  706.         if ( 'no' === $min_max_rules || empty( $min_max_rules ) ) {
  707.             $min_max_rules = false;
  708.  
  709.         } else {
  710.             $min_max_rules = true;
  711.  
  712.         }
  713.  
  714.         $minimum_quantity  = get_post_meta( $product->get_id(), 'minimum_allowed_quantity', true );
  715.         $maximum_quantity  = get_post_meta( $product->get_id(), 'maximum_allowed_quantity', true );
  716.         $group_of_quantity = get_post_meta( $product->get_id(), 'group_of_quantity', true );
  717.         $allow_combination = 'yes' === get_post_meta( $product->get_id(), 'allow_combination', true );
  718.  
  719.         $variation_minimum_quantity  = get_post_meta( $variation_id, 'variation_minimum_allowed_quantity', true );
  720.         $variation_maximum_quantity  = get_post_meta( $variation_id, 'variation_maximum_allowed_quantity', true );
  721.         $variation_group_of_quantity = get_post_meta( $variation_id, 'variation_group_of_quantity', true );
  722.  
  723.         // override product level
  724.         if ( $variation->managing_stock() ) {
  725.             $product = $variation;
  726.  
  727.         }
  728.  
  729.         // override product level
  730.         if ( $min_max_rules && $variation_minimum_quantity ) {
  731.             $minimum_quantity = $variation_minimum_quantity;
  732.  
  733.         }
  734.  
  735.         // override product level
  736.         if ( $min_max_rules && $variation_maximum_quantity ) {
  737.             $maximum_quantity = $variation_maximum_quantity;
  738.         }
  739.  
  740.         // override product level
  741.         if ( $min_max_rules && $variation_group_of_quantity ) {
  742.             $group_of_quantity = $variation_group_of_quantity;
  743.  
  744.         }
  745.  
  746.         if ( $minimum_quantity ) {
  747.  
  748.             if ( $product->managing_stock() && $product->backorders_allowed() && absint( $minimum_quantity ) > $product->get_stock_quantity() ) {
  749.                 $data['min_qty'] = $product->get_stock_quantity();
  750.  
  751.             } else {
  752.                 $data['min_qty'] = $minimum_quantity;
  753.             }
  754.         }
  755.  
  756.         if ( $maximum_quantity ) {
  757.  
  758.             if ( $product->managing_stock() && $product->backorders_allowed() ) {
  759.                 $data['max_qty'] = $maximum_quantity;
  760.  
  761.             } elseif ( $product->managing_stock() && absint( $maximum_quantity ) > $product->get_stock_quantity() ) {
  762.                 $data['max_qty'] = $product->get_stock_quantity();
  763.  
  764.             } else {
  765.                 $data['max_qty'] = $maximum_quantity;
  766.             }
  767.         }
  768.  
  769.         if ( $group_of_quantity ) {
  770.             $data['step'] = 1;
  771.  
  772.             // if both minimum and maximum quantity are set, make sure both are equally divisible by qroup of quantity
  773.             if ( $maximum_quantity && $minimum_quantity ) {
  774.  
  775.                 if ( absint( $maximum_quantity ) % absint( $group_of_quantity ) === 0 && absint( $minimum_quantity ) % absint( $group_of_quantity ) === 0 ) {
  776.                     $data['step'] = $group_of_quantity;
  777.  
  778.                 }
  779.  
  780.             } elseif ( ! $maximum_quantity || absint( $maximum_quantity ) % absint( $group_of_quantity ) === 0 ) {
  781.  
  782.                 $data['step'] = $group_of_quantity;
  783.             }
  784.  
  785.             // set the minimum only when minimum is not set
  786.             if ( ! $minimum_quantity ) {
  787.                 $data['min_qty'] = $group_of_quantity;
  788.             }
  789.         }
  790.  
  791.         // don't apply for cart as cart has qty already pre-filled
  792.         if ( ! is_cart() ) {
  793.             if ( ! $minimum_quantity && $group_of_quantity ) {
  794.                 $data['input_value'] = $group_of_quantity;
  795.             } else {
  796.                 $data['input_value'] = ! empty( $minimum_quantity ) ? $minimum_quantity : 1;
  797.             }
  798.  
  799.             if ( $allow_combination ) {
  800.                 $data['input_value'] = 1;
  801.                 $data['min_qty']     = 1;
  802.                 $data['max_qty']     = '';
  803.                 $data['step']        = 1;
  804.             }
  805.         }
  806.  
  807.         return $data;
  808.     }
  809.  
  810.     function minimum_info_qty(){
  811.         global $post;
  812.         global $product;
  813.         $product = new WC_Product($post->ID);
  814.         $minimum_quantity   = absint( get_post_meta( $product->get_id(), 'minimum_allowed_quantity', true ) );
  815.         if($minimum_quantity > 0){
  816.             echo "Minimum Qty : ".$minimum_quantity;
  817.         }
  818.         //echo "Minimum Qty : ".$minimum_quantity;
  819.     }
  820.    
  821. }
  822.  
  823. add_action( 'plugins_loaded', array( 'WC_Min_Max_Quantities', 'get_instance' ) );
  824.  
  825. endif;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement