function product_meta_box_content($post)
        {
            global $product;
            global $woocommerce;
            global $wp_roles;
            // Get the product and see what rules are being applied
            $pro = wc_get_product($post);
            // Get applied rules by user role
            $roles = $wp_roles->get_names();
            $roles['guest'] = "Guest";
            $rules_by_role = array();
            $rule = null;
            // Loop through roles
            foreach ($roles as $slug => $name) {
                $newRule = wcqu_get_applied_rule($pro, $slug);
                // Set the latest $rule if its not null. This will
                // be used later below in the if statements
                $rule = $newRule ? $newRule : $rule;
                if ($newRule == 'inactive' or $newRule == 'override' or $newRule == 'sitewide') {
                    continue;
                }
                $rules_by_role[$name] = $newRule;
            }
            // Display Rule Being Applied
            if ($rule == 'inactive') {
                echo "<div class='inactive-rule rule-message'>No rule is being applied becasue you've deactivated the plugin for this product.</div>";
            } elseif ($rule == 'override') {
                echo "<div class='overide-rule rule-message'>The values below are being used because you've chosen to override any applied rules for this product.</div>";
            } elseif ($rule == 'sitewide') {
                ?>
			<?php 
                $values = wcqu_get_value_from_rule('all', $pro, $rule);
                ?>
			<div class="active-rule">
				<span>Active Rule:</span>
				<a href='<?php 
                echo admin_url('edit.php?post_type=quantity-rule&page=class-wcqu-advanced-rules.php');
                ?>
'>
					Site Wide Rule
				</a>
				<span class='active-toggle'><a>Show/Hide Active Rules by Role &#x25BC;</a></span>
			</div>
	
			<div class="rule-meta">		
				<table>
					<tr>
						<th>Role</th>
						<th>Rule</th>
						<th>Min</th>
						<th>Max</th>
						<th>Min OOS</th>
						<th>Max OOS</th>
						<th>Step</th>
						<th>Priority</th>
					</tr>
					<tr>
						<td>All</td>
						<td><a href='<?php 
                echo admin_url('edit.php?post_type=quantity-rule&page=class-wcqu-advanced-rules.php');
                ?>
'>Site Wide Rule</a></td>
						<td><?php 
                echo $values['min_value'];
                ?>
</td>
						<td><?php 
                echo $values['max_value'];
                ?>
</td>
						<td><?php 
                echo $values['min_oos'];
                ?>
</td>
						<td><?php 
                echo $values['max_oos'];
                ?>
</td>
						<td><?php 
                echo $values['step'];
                ?>
</td>
						<td></td>
					</tr>
				</table>
			</div>
			<?php 
            } elseif (!isset($rule->post_title) or $rule->post_title == null) {
                echo "<div class='no-rule rule-message'>No rule is currently being applied to this product.</div>";
            } else {
                ?>
			<div class="active-rule">
				<span>Active Rule:</span>
				<?php 
                foreach ($rules_by_role as $rule) {
                    ?>
					<?php 
                    if (empty($rule)) {
                        continue;
                    }
                    ?>
					<a href='<?php 
                    echo get_edit_post_link($rule->ID);
                    ?>
'>
						<?php 
                    echo $rule->post_title;
                    ?>
					</a>
				<?php 
                }
                ?>
				<span class='active-toggle'><a>Show/Hide Active Rules by Role &#x25BC;</a></span>
			</div>
	
			<div class="rule-meta">		
				<table>
					<tr>
						<th>Role</th>
						<th>Rule</th>
						<th>Min</th>
						<th>Max</th>
						<th>Min OOS</th>
						<th>Max OOS</th>
						<th>Step</th>
						<th>Priority</th>
					</tr>
				<?php 
                foreach ($rules_by_role as $role => $rule) {
                    ?>
					<?php 
                    if ($rule != null) {
                        $values = wcqu_get_value_from_rule('all', $pro, $rule);
                    }
                    ?>
					<tr>
						<td><?php 
                    echo $role;
                    ?>
</td>
						<?php 
                    if ($rule != null) {
                        ?>
							<td><a href='<?php 
                        echo get_edit_post_link($rule->ID);
                        ?>
' target="_blank"><?php 
                        echo $rule->post_title;
                        ?>
</a></td>
							<td><?php 
                        echo $values['min_value'];
                        ?>
</td>
							<td><?php 
                        echo $values['max_value'];
                        ?>
</td>
							<td><?php 
                        echo $values['min_oos'];
                        ?>
</td>
							<td><?php 
                        echo $values['max_oos'];
                        ?>
</td>							
							<td><?php 
                        echo $values['step'];
                        ?>
</td>
							<td><?php 
                        echo $values['priority'];
                        ?>
</td>
						<?php 
                    } else {
                        ?>
							<td>None</td>
							<td></td>
							<td></td>
							<td></td>
							<td></td>
							<td></td>
							<td></td>
						<?php 
                    }
                    ?>
					</tr>
				<?php 
                }
                ?>
				</table>
			</div>
		<?php 
            }
            // Get the current values if they exist
            $deactive = get_post_meta($post->ID, '_wpbo_deactive', true);
            $step = get_post_meta($post->ID, '_wpbo_step', true);
            $min = get_post_meta($post->ID, '_wpbo_minimum', true);
            $max = get_post_meta($post->ID, '_wpbo_maximum', true);
            $over = get_post_meta($post->ID, '_wpbo_override', true);
            $min_oos = get_post_meta($post->ID, '_wpbo_minimum_oos', true);
            $max_oos = get_post_meta($post->ID, '_wpbo_maximum_oos', true);
            // Create Nonce Field
            wp_nonce_field(plugin_basename(__FILE__), '_wpbo_product_rule_nonce');
            // Print the form
            ?>
	
		<div class="rule-input-boxes">
			<input type="checkbox" name="_wpbo_deactive" <?php 
            if ($deactive == 'on') {
                echo 'checked';
            }
            ?>
 />
			<span>Deactivate Quantity Rules on this Product?</span>
			
			<input type="checkbox" name="_wpbo_override" id='toggle_override' <?php 
            if ($over == 'on') {
                echo 'checked';
            }
            ?>
 />
			<span>Override Quantity Rules with Values Below</span>
			
			<span class='wpbo_product_values' <?php 
            if ($over != 'on') {
                echo "style='display:none'";
            }
            ?>
>
				<label for="_wpbo_step">Step Value</label>
				<input type="number" name="_wpbo_step" value="<?php 
            echo $step;
            ?>
" step="any" />
				
				<label for="_wpbo_minimum">Minimum Quantity</label>
				<input type="number" name="_wpbo_minimum" value="<?php 
            echo $min;
            ?>
" step="any" />
				
				<label for="_wpbo_maximum">Maximum Quantity</label>
				<input type="number" name="_wpbo_maximum" value="<?php 
            echo $max;
            ?>
" step="any" />
				
				<label for="_wpbo_minimum_oos">Out of Stock Minimum</label>
				<input type="number" name="_wpbo_minimum_oos" value="<?php 
            echo $min_oos;
            ?>
" step="any" />
				
				<label for="_wpbo_maximum_oos">Out of Stock Maximum</label>
				<input type="number" name="_wpbo_maximum_oos" value="<?php 
            echo $max_oos;
            ?>
" step="any" />
				
				<span class='clear-left'>Note* Maximum values must be larger then minimums</span>
			</span>

		</div>
		<?php 
        }
 public function input_value_validation()
 {
     global $post, $woocommerce;
     // Only display script if we are on a single product or cart page
     if (is_object($post) and $post->post_type == 'product' or is_cart()) {
         wp_enqueue_script('ipq_validation', plugins_url('/assets/js/ipq_input_value_validation.js', __FILE__), array('jquery'));
         // Only localize parameters for variable products
         if (!is_cart()) {
             // Get the product
             $pro = get_product($post);
             // Check if variable
             if ($pro->product_type == 'variable') {
                 // See what rules are being applied
                 $rule_result = wcqu_get_applied_rule($pro);
                 // If the rule result is inactive, we're done
                 if ($rule_result == 'inactive' or $rule_result == null) {
                     return;
                     // Get values for Override, Sitewide and Rule Controlled Products
                 } else {
                     $values = wcqu_get_value_from_rule('all', $pro, $rule_result);
                 }
                 // Check if the product is out of stock
                 $stock = $pro->get_stock_quantity();
                 // Check if the product is under stock management and out of stock
                 if (strlen($stock) != 0 and $stock <= 0) {
                     if ($values['min_oos'] != '') {
                         $values['min_value'] = $values['min_oos'];
                     }
                     if ($values['max_oos'] != '') {
                         $values['max_value'] = $values['max_oos'];
                     }
                 }
                 // Output admin-ajax.php URL with sma eprotocol as current page
                 $params = array('min' => $values['min_value'], 'max' => $values['max_value'], 'step' => $values['step']);
                 wp_localize_script('ipq_validation', 'ipq_validation', $params);
             }
         }
     }
 }
 public function display_minimum_quantity_note()
 {
     global $product;
     if (!is_product()) {
         return;
     }
     if ($product->product_type == 'grouped') {
         return;
     }
     $settings = get_option('ipq_options');
     extract($settings);
     // Get minimum value for product
     $rule = wcqu_get_applied_rule($product);
     // Return nothing if APQ is deactivated
     if ($rule == 'inactive' or $rule == null) {
         return;
     }
     // Check if the product is out of stock
     $stock = $product->get_stock_quantity();
     // Check if the product is under stock management and out of stock
     if (strlen($stock) != 0 and $stock <= 0) {
         $min = wcqu_get_value_from_rule('min_oos', $product, $rule);
         $max = wcqu_get_value_from_rule('max_oos', $product, $rule);
     } else {
         $min = wcqu_get_value_from_rule('min', $product, $rule);
         $max = wcqu_get_value_from_rule('max', $product, $rule);
     }
     $step = wcqu_get_value_from_rule('step', $product, $rule);
     // If sitewide rule is applied, convert return arrays to values
     if ($rule == 'sitewide' and strlen($stock) != 0 and $stock <= 0) {
         if (is_array($min)) {
             $min = $min['min_oos'];
         }
         if (is_array($max)) {
             $max = $max['max_oos'];
         }
         if (is_array($step)) {
             $step = $step['step'];
         }
     } else {
         if ($rule == 'sitewide') {
             if (is_array($min)) {
                 $min = $min['min'];
             }
             if (is_array($max)) {
                 $max = $max['max'];
             }
             if (is_array($step)) {
                 $step = $step['step'];
             }
         }
     }
     // If the text is set, update and print the output
     if (isset($ipq_qty_text)) {
         $min_pattern = '/\\%MIN\\%/';
         $max_pattern = '/\\%MAX\\%/';
         $step_pattern = '/\\%STEP\\%/';
         $ipq_qty_text = preg_replace($min_pattern, $min, $ipq_qty_text);
         $ipq_qty_text = preg_replace($max_pattern, $max, $ipq_qty_text);
         $ipq_qty_text = preg_replace($step_pattern, $step, $ipq_qty_text);
         // Output result with optional custom class
         echo "<span";
         if (isset($ipq_qty_class) and $ipq_qty_class != '') {
             echo " class='" . $ipq_qty_class . "'";
         }
         echo ">";
         echo $ipq_qty_text;
         echo "</span>";
     }
 }
 public function validate_single_product($passed, $product_id, $quantity, $from_cart, $variation_id = null, $variations = null)
 {
     global $woocommerce, $product, $WC_Quantities_and_Units;
     $product = wc_get_product($product_id);
     $title = $product->get_title();
     // Get the applied rule and values - if they exist
     $rule = wcqu_get_applied_rule($product);
     $values = wcqu_get_value_from_rule('all', $product, $rule);
     if ($values != null) {
         extract($values);
     }
     // $min_value, $max_value, $step, $priority, $min_oos, $max_oos
     // Inactive Products can be ignored
     if ($values == null) {
         return true;
     }
     // Check if the product is out of stock
     $stock = $product->get_stock_quantity();
     // Adjust min value if item is out of stock
     if (strlen($stock) != 0 and $stock <= 0 and isset($min_oos) and $min_oos != null) {
         $min_value = $min_oos;
     }
     // Adjust max value if item is out of stock
     if (strlen($stock) != 0 and $stock <= 0 and isset($max_oos) and $max_oos != null) {
         $max_value = $max_oos;
     }
     // Min Validation
     // added $min_value != 0 since List Items starts all products at 0 quantity.
     if ($min_value != null && $min_value != 0 && $quantity < $min_value) {
         if ($WC_Quantities_and_Units->wc_version >= 2.1) {
             wc_add_notice(sprintf(__("You must add a minimum of %s %s's to your cart.", 'woocommerce'), $min_value, $title), 'error');
             // Old Validation Style Support
         } else {
             $woocommerce->add_error(sprintf(__("You must add a minimum of %s %s's to your cart.", 'woocommerce'), $min_value, $title));
         }
         return false;
     }
     // Max Validation
     if ($max_value != null && $quantity > $max_value) {
         if ($WC_Quantities_and_Units->wc_version >= 2.1) {
             wc_add_notice(sprintf(__("You may only add a maximum of %s %s's to your cart.", 'woocommerce'), $max_value, $title), 'error');
             // Old Validation Style Support
         } else {
             $woocommerce->add_error(sprintf(__("You may only add a maximum of %s %s's to your cart.", 'woocommerce'), $max_value, $title));
         }
         return false;
     }
     // Subtract the min value from quantity to calc remainder if min value exists
     if ($min_value != 0) {
         $rem_qty = $quantity - $min_value;
     } else {
         $rem_qty = $quantity;
     }
     $rem_qty = (double) $rem_qty;
     $step = (double) $step;
     // Step Validation
     if ($step != null && wcqu_fmod_round($rem_qty, $step) != 0) {
         if ($WC_Quantities_and_Units->wc_version >= 2.1) {
             wc_add_notice(sprintf(__("You may only add a %s in multiples of %s to your cart.", 'woocommerce'), $title, $step), 'error');
             // Old Validation Style Support
         } else {
             $woocommerce->add_error(sprintf(__("You may only add a %s in multiples of %s to your cart.", 'woocommerce'), $title, $step));
         }
         return false;
     }
     // Don't run Cart Validations if user is updating the cart
     if ($from_cart != true) {
         // Get Cart Quantity for the product
         foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) {
             $_product = $values['data'];
             if ($product_id == $_product->id) {
                 $cart_qty = $values['quantity'];
             }
         }
         //  If there aren't any items in the cart already, ignore these validations
         if (isset($cart_qty) and $cart_qty != null) {
             // Total Cart Quantity Min Validation
             if ($min_value != null && $quantity + $cart_qty < $min_value) {
                 if ($WC_Quantities_and_Units->wc_version >= 2.1) {
                     wc_add_notice(sprintf(__("Your cart must have a minimum of %s %s's to proceed.", 'woocommerce'), $min_value, $title), 'error');
                     // Old Validation Style Support
                 } else {
                     $woocommerce->add_error(sprintf(__("Your cart must have a minimum of %s %s's to proceed.", 'woocommerce'), $min_value, $title));
                 }
                 return false;
             }
             // Total Cart Quantity Max Validation
             if ($max_value != null && $quantity + $cart_qty > $max_value) {
                 if ($WC_Quantities_and_Units->wc_version >= 2.1) {
                     wc_add_notice(sprintf(__("You can only purchase a maximum of %s %s's at once and your cart has %s %s's in it already.", 'woocommerce'), $max_value, $title, $cart_qty, $title), 'error');
                     // Old Validation Style Support
                 } else {
                     $woocommerce->add_error(sprintf(__("You can only purchase a maximum of %s %s's at once and your cart has %s %s's in it already.", 'woocommerce'), $max_value, $title, $cart_qty, $title));
                 }
                 return false;
             }
             // Subtract the min value from cart quantity to calc remainder if min value exists
             if ($min_value != 0) {
                 $cart_qty_rem = $quantity + $cart_qty - $min_value;
             } else {
                 $cart_qty_rem = $quantity + $cart_qty;
             }
             // Total Cart Quantity Step Validation
             $cart_qty_rem = (double) $cart_qty_rem;
             if ($step != null && $step != 0 && $cart_qty_rem != 0 && wcqu_fmod_round($cart_qty_rem, $step) != 0) {
                 if ($WC_Quantities_and_Units->wc_version >= 2.1) {
                     wc_add_notice(sprintf(__("You may only purchase %s in multiples of %s.", 'woocommerce'), $title, $step), 'error');
                     // Old Validation Style Support
                 } else {
                     $woocommerce->add_error(sprintf(__("You may only purchase %s in multiples of %s.", 'woocommerce'), $title, $step));
                 }
                 return false;
             }
         }
     }
     return true;
 }
 /**
  * Provides backwards compatibility for plugins that tied into this plugin pre-fork
  *
  * @params string    $type Product type
  * @params object    $product Product Object
  * @params object    $rule Quantity Rule post object
  *
  * @return mixed
  *
  * @deprecated
  */
 function wpbo_get_value_from_rule($type, $product, $rule)
 {
     return wcqu_get_value_from_rule($type, $product, $rule);
 }
 public function input_set_all_values($args, $product)
 {
     // Return Defaults if it isn't a simple product
     /* Commented out to allow for grouped and variable products
     		*  on their product pages
     		if( $product->product_type != 'simple' ) {
     			return $args;
     		}
     		*/
     // Get Rule
     $rule = wcqu_get_applied_rule($product);
     // Get Value from Rule
     $values = wcqu_get_value_from_rule('all', $product, $rule);
     if ($values == null) {
         return $args;
     }
     $vals = array();
     $vals['input_name'] = 'quantity';
     // Check if the product is out of stock
     $stock = $product->get_stock_quantity();
     // Check stock status and if Out try Out of Stock value
     if (strlen($stock) != 0 and $stock <= 0 and isset($values['min_oos']) and $values['min_oos'] != '') {
         $args['min_value'] = $values['min_oos'];
         // Otherwise just check normal min
     } elseif ($values['min_value'] != '') {
         $args['min_value'] = $values['min_value'];
         // If no min, try step
     } elseif ($values['min_value'] == '' and $values['step'] != '') {
         $args['min_value'] = $values['step'];
     }
     // Check stock status and if Out try Out of Stock value
     if ($stock <= 0 and isset($values['min_oos']) and $values['max_oos'] != '') {
         $args['max_value'] = $values['max_oos'];
         // Otherwise just check normal max
     } elseif ($values['max_value'] != '') {
         $args['max_value'] = $values['max_value'];
     }
     // Set step value
     if ($values['step'] != '') {
         $args['step'] = $values['step'];
     }
     return $args;
 }