src/validators/WCCartSubscriptionLimiter.php
<?php
namespace VindiPaymentGateways;
use WC_Subscriptions_Product;
class WCCartSubscriptionLimiter
{
public function __construct()
{
$this->init_hooks();
}
private function init_hooks()
{
add_filter('woocommerce_add_to_cart_validation', [$this, 'limit_same_subscriptions'], 10, 3);
add_filter('woocommerce_update_cart_validation', [$this, 'limit_duplicate_subscriptions_cart_update'], 10, 4);
add_filter('woocommerce_add_to_cart_validation', [$this, 'disallow_subscription_single_product_cart'], 10, 2);
add_filter('woocommerce_checkout_fields', [$this, 'customize_billing_neighborhood_field']);
}
public function limit_same_subscriptions($passed, $product_id, $quantity)
{
$subscriptions_product = new WC_Subscriptions_Product();
$product = wc_get_product($product_id);
if ($product->is_virtual()) {
return $passed;
}
if ($subscriptions_product->is_subscription($product_id)) {
$subscription_count = $this->get_subscription_count($product_id);
if ($subscription_count + $quantity > 1) {
wc_add_notice('Você só pode ter até 1 assinatura do mesmo produto no seu carrinho.', 'error');
return false;
}
}
return $passed;
}
public function get_subscription_count($product_id)
{
$cart = WC()->cart->get_cart();
$subscription_count = 0;
foreach ($cart as $cart_item) {
if ($cart_item['data']->get_id() === $product_id) {
$subscription_count += $cart_item['quantity'];
}
}
return $subscription_count;
}
public function limit_duplicate_subscriptions_cart_update($passed, $_cart_item_key, $values, $quantity)
{
unset($_cart_item_key);
$product_id = $values['product_id'];
$product = wc_get_product($product_id);
if ($this->is_virtual_product($product)) {
return $passed;
}
if ($this->subscription_exceeds_limit($product_id, $quantity)) {
return false;
}
return $passed;
}
public function is_virtual_product($product)
{
return $product->is_virtual();
}
public function subscription_exceeds_limit($product_id, $quantity)
{
$subscriptions_product = new WC_Subscriptions_Product();
if ($subscriptions_product->is_subscription($product_id)) {
$subscription_count = $this->count_subscriptions_in_cart($product_id);
if ($subscription_count >= 1 && $quantity > 1) {
$message = 'Você só pode ter até 1 assinatura do mesmo produto no seu carrinho.';
wc_add_notice(__($message, 'vindi-payment-gateway'), 'error');
return true;
}
}
return false;
}
public function count_subscriptions_in_cart($product_id)
{
$subscription_count = 0;
foreach (WC()->cart->get_cart() as $cart_item) {
if ($cart_item['data']->get_id() === $product_id) {
$subscription_count++;
}
}
return $subscription_count;
}
public function disallow_subscription_single_product_cart($passed, $product_id)
{
$product = wc_get_product($product_id);
if ($this->is_virtual_product($product)) {
return $passed;
}
if ($this->is_cart_mixed_with_subscription($product_id)) {
wc_add_notice(__('Olá! Finalize a compra da assinatura adicionada
ao carrinho antes de adicionar outra assinatura ou produto.', 'vindi-payment-gateway'), 'error');
return false;
}
return $passed;
}
public function is_cart_mixed_with_subscription($product_id)
{
$cart = WC()->cart->get_cart();
$subscriptions_product = new WC_Subscriptions_Product();
if (empty($cart)) {
return false;
}
$is_subscription = false;
$new_product_subscription = $subscriptions_product->is_subscription($product_id);
foreach ($cart as $cart_item) {
if ($subscriptions_product->is_subscription($cart_item['data']->get_id())) {
$is_subscription = true;
break;
}
}
return $is_subscription !== $new_product_subscription;
}
public function customize_billing_neighborhood_field($fields)
{
$fields['billing']['billing_neighborhood']['required'] = true;
return $fields;
}
}