public function validate_add_cart_item($passed, $product_id, $quantity, $variation_id = '', $variations = '')
 {
     if ($variation_id) {
         $product_id = $variation_id;
     }
     // skip if not a nyp product - send original status back
     if (!WC_Name_Your_Price_Helpers::is_nyp($product_id)) {
         return $passed;
     }
     $prefix = apply_filters('nyp_field_prefix', '', $product_id);
     // get the posted price (can be null string)
     $input = WC_Name_Your_Price_Helpers::get_posted_price($product_id, $prefix);
     // get minimum price
     $minimum = WC_Name_Your_Price_Helpers::get_minimum_price($product_id);
     // null error message
     $error_message = '';
     // the product title
     $the_product = wc_nyp_get_product($product_id);
     $product_title = $the_product->get_title();
     // check that it is a positive numeric value
     if (!is_numeric($input) || is_infinite($input) || floatval($input) < 0) {
         $passed = false;
         $error_message = WC_Name_Your_Price_Helpers::error_message('invalid', array('%%TITLE%%' => $product_title));
         // check that it is greater than minimum price for variable billing subscriptions
     } elseif ($minimum && WC_Name_Your_Price_Helpers::is_subscription($product_id) && WC_Name_Your_Price_Helpers::is_billing_period_variable($product_id)) {
         // get the posted billing period, defaults to 'month'
         $period = WC_Name_Your_Price_Helpers::get_posted_period($product_id, $prefix);
         // minimum billing period
         $minimum_period = WC_Name_Your_Price_Helpers::get_minimum_billing_period($product_id);
         // annual minimum
         $minimum_annual = WC_Name_Your_Price_Helpers::annualize_price($minimum, $minimum_period);
         // annual input
         $input_annual = WC_Name_Your_Price_Helpers::annualize_price($input, $period);
         // by standardizing the prices over the course of a year we can safely compare them
         if ($input_annual < $minimum_annual) {
             $passed = false;
             $factors = WC_Name_Your_Price_Helpers::annual_price_factors();
             // If set period is in the $factors array we can calc the min price shown in the error according to entered period
             if (isset($factors[$period])) {
                 $error_price = $minimum_annual / $factors[$period];
                 $error_period = $period;
                 // otherwise, just show the saved minimum price and period
             } else {
                 $error_price = $minimum;
                 $error_period = $minimum_period;
             }
             // the minimum is a combo of price and period
             $minimum_error = wc_price($error_price) . ' / ' . $error_period;
             $error_message = WC_Name_Your_Price_Helpers::error_message('minimum', array('%%TITLE%%' => $product_title, '%%MINIMUM%%' => $minimum_error), $the_product);
         }
         // check that it is greater than minimum price
     } elseif ($minimum && floatval(WC_Name_Your_Price_Helpers::standardize_number($input)) < floatval($minimum)) {
         $passed = false;
         $minimum_error = wc_price($minimum);
         $error_message = WC_Name_Your_Price_Helpers::error_message('minimum', array('%%TITLE%%' => $product_title, '%%MINIMUM%%' => $minimum_error), $the_product);
     }
     // show the error message
     if ($error_message) {
         wc_add_notice($error_message, 'error');
     }
     return $passed;
 }
 /**
  * Generate Markup for Subscription Periods
  * 
  * @param	string $input
  * @param	obj $product
  * @return	string
  * @access	public
  * @since	2.0
  */
 public static function get_subscription_terms($input = '', $product)
 {
     $terms = '&nbsp;';
     if (!is_object($product)) {
         $product = wc_nyp_get_product($product);
     }
     // parent variable subscriptions don't have a billing period, so we get a array to string notice. therefore only apply to simple subs and sub variations
     if ($product->is_type('subscription') || $product->is_type('subscription_variation')) {
         if (self::is_billing_period_variable($product)) {
             // don't display the subscription price, period or length
             $include = array('price' => '', 'subscription_price' => false, 'subscription_period' => false);
         } else {
             $include = array('price' => '', 'subscription_price' => false);
             // if we don't show the price we don't get the "per" backslash so add it back
             if (WC_Subscriptions_Product::get_interval($product) == 1) {
                 $terms .= '<span class="per">/ </span>';
             }
         }
         $terms .= WC_Subscriptions_Product::get_price_string($product, $include);
     }
     // piece it all together - JS needs a span with this class to change terms on variation found event
     // use details class to mimic Subscriptions plugin, leave terms class for backcompat
     if ('woocommerce_get_price_input' == current_filter()) {
         $terms = '<span class="subscription-details subscription-terms">' . $terms . '</span>';
     }
     return $input . $terms;
 }