src/Core/Checkout/Cart/Address/AddressValidator.php line 100

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Checkout\Cart\Address;
  3. use Shopware\Core\Checkout\Cart\Address\Error\BillingAddressSalutationMissingError;
  4. use Shopware\Core\Checkout\Cart\Address\Error\ProfileSalutationMissingError;
  5. use Shopware\Core\Checkout\Cart\Address\Error\ShippingAddressBlockedError;
  6. use Shopware\Core\Checkout\Cart\Address\Error\ShippingAddressSalutationMissingError;
  7. use Shopware\Core\Checkout\Cart\Cart;
  8. use Shopware\Core\Checkout\Cart\CartValidatorInterface;
  9. use Shopware\Core\Checkout\Cart\Error\ErrorCollection;
  10. use Shopware\Core\Content\Product\State;
  11. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Shopware\Core\Framework\Log\Package;
  15. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  16. use Symfony\Contracts\Service\ResetInterface;
  17. #[Package('checkout')]
  18. class AddressValidator implements CartValidatorInterfaceResetInterface
  19. {
  20.     /**
  21.      * @var array<string, bool>
  22.      */
  23.     private array $available = [];
  24.     /**
  25.      * @internal
  26.      */
  27.     public function __construct(private readonly EntityRepository $repository)
  28.     {
  29.     }
  30.     public function validate(Cart $cartErrorCollection $errorsSalesChannelContext $context): void
  31.     {
  32.         $country $context->getShippingLocation()->getCountry();
  33.         $customer $context->getCustomer();
  34.         $validateShipping $cart->getLineItems()->count() === 0
  35.             || $cart->getLineItems()->hasLineItemWithState(State::IS_PHYSICAL);
  36.         if (!$country->getActive() && $validateShipping) {
  37.             $errors->add(new ShippingAddressBlockedError((string) $country->getTranslation('name')));
  38.             return;
  39.         }
  40.         if (!$country->getShippingAvailable() && $validateShipping) {
  41.             $errors->add(new ShippingAddressBlockedError((string) $country->getTranslation('name')));
  42.             return;
  43.         }
  44.         if (!$this->isSalesChannelCountry($country->getId(), $context) && $validateShipping) {
  45.             $errors->add(new ShippingAddressBlockedError((string) $country->getTranslation('name')));
  46.             return;
  47.         }
  48.         if ($customer === null) {
  49.             return;
  50.         }
  51.         if (!$customer->getSalutationId()) {
  52.             $errors->add(new ProfileSalutationMissingError($customer));
  53.             return;
  54.         }
  55.         if ($customer->getActiveBillingAddress() === null || $customer->getActiveShippingAddress() === null) {
  56.             // No need to add salutation-specific errors in this case
  57.             return;
  58.         }
  59.         if (!$customer->getActiveBillingAddress()->getSalutationId()) {
  60.             $errors->add(new BillingAddressSalutationMissingError($customer->getActiveBillingAddress()));
  61.             return;
  62.         }
  63.         if (!$customer->getActiveShippingAddress()->getSalutationId() && $validateShipping) {
  64.             $errors->add(new ShippingAddressSalutationMissingError($customer->getActiveShippingAddress()));
  65.         }
  66.     }
  67.     public function reset(): void
  68.     {
  69.         $this->available = [];
  70.     }
  71.     private function isSalesChannelCountry(string $countryIdSalesChannelContext $context): bool
  72.     {
  73.         if (isset($this->available[$countryId])) {
  74.             return $this->available[$countryId];
  75.         }
  76.         $criteria = new Criteria([$countryId]);
  77.         $criteria->addFilter(new EqualsFilter('salesChannels.id'$context->getSalesChannelId()));
  78.         $salesChannelCountryIds $this->repository->searchIds($criteria$context->getContext());
  79.         return $this->available[$countryId] = $salesChannelCountryIds->has($countryId);
  80.     }
  81. }