/**
  * Get all product cats for a product by ID, including hierarchy.
  *
  * @since  4.13.1
  * @param  int $product_id
  * @return array
  */
 public static function wc_get_product_cat_ids($product_id)
 {
     if (self::is_wc_version_gte_2_5()) {
         $product_cats = wc_get_product_cat_ids($product_id);
     } else {
         $product_cats = wp_get_post_terms($product_id, 'product_cat', array("fields" => "ids"));
         foreach ($product_cats as $product_cat) {
             $product_cats = array_merge($product_cats, get_ancestors($product_cat, 'product_cat'));
         }
     }
     return $product_cats;
 }
 /**
  * Map one of the WC_Coupon error codes to a message string.
  *
  * @param int $err_code Message/error code.
  * @return string| Message/error string
  */
 public function get_coupon_error($err_code)
 {
     switch ($err_code) {
         case self::E_WC_COUPON_INVALID_FILTERED:
             $err = __('Coupon is not valid.', 'woocommerce');
             break;
         case self::E_WC_COUPON_NOT_EXIST:
             $err = sprintf(__('Coupon "%s" does not exist!', 'woocommerce'), $this->code);
             break;
         case self::E_WC_COUPON_INVALID_REMOVED:
             $err = sprintf(__('Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce'), $this->code);
             break;
         case self::E_WC_COUPON_NOT_YOURS_REMOVED:
             $err = sprintf(__('Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce'), $this->code);
             break;
         case self::E_WC_COUPON_ALREADY_APPLIED:
             $err = __('Coupon code already applied!', 'woocommerce');
             break;
         case self::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY:
             $err = sprintf(__('Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce'), $this->code);
             break;
         case self::E_WC_COUPON_USAGE_LIMIT_REACHED:
             $err = __('Coupon usage limit has been reached.', 'woocommerce');
             break;
         case self::E_WC_COUPON_EXPIRED:
             $err = __('This coupon has expired.', 'woocommerce');
             break;
         case self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET:
             $err = sprintf(__('The minimum spend for this coupon is %s.', 'woocommerce'), wc_price($this->minimum_amount));
             break;
         case self::E_WC_COUPON_MAX_SPEND_LIMIT_MET:
             $err = sprintf(__('The maximum spend for this coupon is %s.', 'woocommerce'), wc_price($this->maximum_amount));
             break;
         case self::E_WC_COUPON_NOT_APPLICABLE:
             $err = __('Sorry, this coupon is not applicable to your cart contents.', 'woocommerce');
             break;
         case self::E_WC_COUPON_EXCLUDED_PRODUCTS:
             // Store excluded products that are in cart in $products
             $products = array();
             if (!WC()->cart->is_empty()) {
                 foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
                     if (in_array($cart_item['product_id'], $this->exclude_product_ids) || in_array($cart_item['variation_id'], $this->exclude_product_ids) || in_array($cart_item['data']->get_parent(), $this->exclude_product_ids)) {
                         $products[] = $cart_item['data']->get_title();
                     }
                 }
             }
             $err = sprintf(__('Sorry, this coupon is not applicable to the products: %s.', 'woocommerce'), implode(', ', $products));
             break;
         case self::E_WC_COUPON_EXCLUDED_CATEGORIES:
             // Store excluded categories that are in cart in $categories
             $categories = array();
             if (!WC()->cart->is_empty()) {
                 foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
                     $product_cats = wc_get_product_cat_ids($cart_item['product_id']);
                     if (sizeof($intersect = array_intersect($product_cats, $this->exclude_product_categories)) > 0) {
                         foreach ($intersect as $cat_id) {
                             $cat = get_term($cat_id, 'product_cat');
                             $categories[] = $cat->name;
                         }
                     }
                 }
             }
             $err = sprintf(__('Sorry, this coupon is not applicable to the categories: %s.', 'woocommerce'), implode(', ', array_unique($categories)));
             break;
         case self::E_WC_COUPON_NOT_VALID_SALE_ITEMS:
             $err = __('Sorry, this coupon is not valid for sale items.', 'woocommerce');
             break;
         default:
             $err = '';
             break;
     }
     return apply_filters('woocommerce_coupon_error', $err, $err_code, $this);
 }