custom/plugins/AcrisShopSwitchCS/src/Components/ShopSwitchRuleService.php line 229

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\ShopSwitch\Components;
  3. use Acris\ShopSwitch\Components\Struct\PossibleCountryCollection;
  4. use Acris\ShopSwitch\Components\Struct\PossibleCountryStruct;
  5. use Acris\ShopSwitch\Components\Struct\PossibleLanguageCollection;
  6. use Acris\ShopSwitch\Components\Struct\PossibleLanguageStruct;
  7. use Acris\ShopSwitch\Custom\ShopSwitchRuleDefinition;
  8. use Acris\ShopSwitch\Custom\ShopSwitchRuleDomainEntity;
  9. use Acris\ShopSwitch\Custom\ShopSwitchRuleEntity;
  10. use Shopware\Core\Framework\Context;
  11. use Shopware\Core\System\Locale\LocaleEntity;
  12. use Shopware\Core\System\SalesChannel\Aggregate\SalesChannelDomain\SalesChannelDomainEntity;
  13. use Symfony\Component\HttpFoundation\Request;
  14. class ShopSwitchRuleService
  15. {
  16.     /**
  17.      * @var ShopSwitchRedirectUrlService
  18.      */
  19.     private $redirectUrlService;
  20.     /**
  21.      * @var SalesChannelCountryLanguageService
  22.      */
  23.     private $salesChannelCountryLanguageService;
  24.     public function __construct(
  25.         ShopSwitchRedirectUrlService $redirectUrlService,
  26.         SalesChannelCountryLanguageService $salesChannelCountryLanguageService
  27.     )
  28.     {
  29.         $this->redirectUrlService $redirectUrlService;
  30.         $this->salesChannelCountryLanguageService $salesChannelCountryLanguageService;
  31.     }
  32.     public function getPossibleCountriesOfRule(ShopSwitchRuleEntity $ruleEntitystring $activeDomainUrlContext $contextRequest $request): PossibleCountryCollection
  33.     {
  34.         $possibleCountryCollection = new PossibleCountryCollection();
  35.         if($ruleEntity->getRuleDefinitionType() !== ShopSwitchRuleDefinition::RULE_DEFINITION_TYPE_COUNTRY_LANGUAGE && $ruleEntity->getRuleDefinitionType() !== ShopSwitchRuleDefinition::RULE_DEFINITION_TYPE_COUNTRY) {
  36.             return $possibleCountryCollection;
  37.         }
  38.         $salesChannelIds $this->getSalesChannelIdsFromRuleEntity($ruleEntity);
  39.         $this->sortRuleEntityDomains($ruleEntity);
  40.         foreach ($ruleEntity->getDomains()->getElements() as $domainEntity) {
  41.             if($domainEntity->isActive() === false) {
  42.                 continue;
  43.             }
  44.             $domainUrl = (!empty($domainEntity->getRedirectTo()) && $domainEntity->getRedirectTo() === 'external') ? $domainEntity->getExternalUrl() : $this->redirectUrlService->getUrlByRequestAndDomainUrl($domainEntity->getDomain(), $activeDomainUrl$ruleEntity$request);
  45.             $prioritizeDomainUrl $domainEntity->getDomain() instanceof SalesChannelDomainEntity && $context->getLanguageId() === $domainEntity->getDomain()->getLanguageId();
  46.             // Do blacklist first, because whitelist should override
  47.             if($domainEntity->getCountryBlacklist() && $domainEntity->getCountryBlacklist()->count() !== 0) {
  48.                 foreach ($this->salesChannelCountryLanguageService->getCountriesFromSalesChannelIds($salesChannelIds$context)->getElements() as $countryEntityFromSalesChannel) {
  49.                     foreach ($domainEntity->getCountryBlacklist()->getElements() as $countryEntity) {
  50.                         if($countryEntityFromSalesChannel->getId() === $countryEntity->getId()) {
  51.                             continue 2;
  52.                         }
  53.                     }
  54.                     if($possibleCountryCollection->has($countryEntityFromSalesChannel->getId()) === true) {
  55.                         $domainUrls $this->mergeDomainUrls($domainUrl$possibleCountryCollection->get($countryEntityFromSalesChannel->getId())->getDomainUrls(), $prioritizeDomainUrl);
  56.                     } else {
  57.                         $domainUrls = [$domainUrl];
  58.                     }
  59.                     $possibleCountryCollection->set($countryEntityFromSalesChannel->getId(), new PossibleCountryStruct(
  60.                         $countryEntityFromSalesChannel->getTranslation('name'),
  61.                         $countryEntityFromSalesChannel->getIso(),
  62.                         $domainUrl,
  63.                         $domainUrls,
  64.                         $countryEntityFromSalesChannel->getId(),
  65.                         $countryEntityFromSalesChannel->getPosition(),
  66.                         $domainEntity
  67.                     ));
  68.                 }
  69.             }
  70.             if($domainEntity->getCountryWhitelist()) {
  71.                 foreach ($domainEntity->getCountryWhitelist()->getElements() as $countryEntity) {
  72.                     if($possibleCountryCollection->has($countryEntity->getId()) === true) {
  73.                         $domainUrls $this->mergeDomainUrls($domainUrl$possibleCountryCollection->get($countryEntity->getId())->getDomainUrls(), $prioritizeDomainUrl);
  74.                     } else {
  75.                         $domainUrls = [$domainUrl];
  76.                     }
  77.                     $possibleCountryCollection->set($countryEntity->getId(), new PossibleCountryStruct(
  78.                         $countryEntity->getTranslation('name'),
  79.                         $countryEntity->getIso(),
  80.                         $domainUrl,
  81.                         $domainUrls,
  82.                         $countryEntity->getId(),
  83.                         $countryEntity->getPosition(),
  84.                         $domainEntity
  85.                     ));
  86.                 }
  87.             }
  88.         }
  89.         return $this->sortCountriesByNameAndPosition($possibleCountryCollection);
  90.     }
  91.     public function getPossibleCountriesOnlySetCountries(ShopSwitchRuleEntity $ruleEntityContext $context): PossibleCountryCollection
  92.     {
  93.         $possibleCountryCollection = new PossibleCountryCollection();
  94.         foreach ($ruleEntity->getDomains()->getElements() as $domainEntity) {
  95.             if($domainEntity->isActive() === false) {
  96.                 continue;
  97.             }
  98.             foreach ($this->salesChannelCountryLanguageService->getCountriesFromSalesChannel($domainEntity->getDomain()->getSalesChannelId(), $context)->getElements() as $countryEntityFromSalesChannel) {
  99.                 $possibleCountryCollection->set($countryEntityFromSalesChannel->getId(), new PossibleCountryStruct(
  100.                     $countryEntityFromSalesChannel->getTranslated()['name'],
  101.                     $countryEntityFromSalesChannel->getIso(),
  102.                     '',
  103.                     [],
  104.                     $countryEntityFromSalesChannel->getId(),
  105.                     $countryEntityFromSalesChannel->getPosition(),
  106.                     $domainEntity
  107.                 ));
  108.             }
  109.         }
  110.         return $this->sortCountriesByNameAndPosition($possibleCountryCollection);
  111.     }
  112.     public function getPossibleLanguagesOfRule(ShopSwitchRuleEntity $ruleEntitystring $activeDomainUrlContext $contextRequest $request): PossibleLanguageCollection
  113.     {
  114.         $possibleLanguageCollection = new PossibleLanguageCollection();
  115.         if($ruleEntity->getRuleDefinitionType() !== ShopSwitchRuleDefinition::RULE_DEFINITION_TYPE_COUNTRY_LANGUAGE && $ruleEntity->getRuleDefinitionType() !== ShopSwitchRuleDefinition::RULE_DEFINITION_TYPE_LANGUAGE) {
  116.             return $possibleLanguageCollection;
  117.         }
  118.         $salesChannelIds $this->getSalesChannelIdsFromRuleEntity($ruleEntity);
  119.         foreach ($ruleEntity->getDomains()->getElements() as $domainEntity) {
  120.             if($domainEntity->isActive() === false) {
  121.                 continue;
  122.             }
  123.             $domainUrl = (!empty($domainEntity->getRedirectTo()) && $domainEntity->getRedirectTo() === 'external') ? $domainEntity->getExternalUrl() : $this->redirectUrlService->getUrlByRequestAndDomainUrl($domainEntity->getDomain(), $activeDomainUrl$ruleEntity$request);
  124.             $prioritizeDomainUrl $domainEntity->getDomain() instanceof SalesChannelDomainEntity && $context->getLanguageId() === $domainEntity->getDomain()->getLanguageId();
  125.             // Do blacklist first, because whitelist should override
  126.             if($domainEntity->getLanguageBlacklist() && $domainEntity->getLanguageBlacklist()->count() !== 0) {
  127.                 foreach ($this->salesChannelCountryLanguageService->getLanguagesFromSalesChannelIds($salesChannelIds$context)->getElements() as $languageEntityFromSalesChannel) {
  128.                     $localeEntityFromSalesChannel $languageEntityFromSalesChannel->getLocale();
  129.                     if(empty($localeEntityFromSalesChannel)) {
  130.                         continue;
  131.                     }
  132.                     foreach ($domainEntity->getLanguageBlacklist()->getElements() as $languageEntity) {
  133.                         if($languageEntityFromSalesChannel->getId() === $languageEntity->getId()) {
  134.                             continue 2;
  135.                         }
  136.                     }
  137.                     if($possibleLanguageCollection->has($languageEntityFromSalesChannel->getId()) === true) {
  138.                         $domainUrls $this->mergeDomainUrls($domainUrl$possibleLanguageCollection->get($languageEntityFromSalesChannel->getId())->getDomainUrls(), $prioritizeDomainUrl);
  139.                     } else {
  140.                         $domainUrls = [$domainUrl];
  141.                     }
  142.                     $possibleLanguageCollection->set($languageEntityFromSalesChannel->getId(), new PossibleLanguageStruct(
  143.                         $this->getNameOfLanguageAndLocale($localeEntityFromSalesChannel),
  144.                         $localeEntityFromSalesChannel->getCode(),
  145.                         $domainUrl,
  146.                         $domainUrls,
  147.                         $localeEntityFromSalesChannel->getId(),
  148.                         $languageEntityFromSalesChannel->getId(),
  149.                         $domainEntity
  150.                     ));
  151.                 }
  152.             }
  153.             if($domainEntity->getLanguageWhitelist()) {
  154.                 foreach ($domainEntity->getLanguageWhitelist()->getElements() as $languageEntity) {
  155.                     $localeEntity $languageEntity->getLocale();
  156.                     if(empty($localeEntity)) {
  157.                         continue;
  158.                     }
  159.                     if($possibleLanguageCollection->has($languageEntity->getId()) === true) {
  160.                         $domainUrls $this->mergeDomainUrls($domainUrl$possibleLanguageCollection->get($languageEntity->getId())->getDomainUrls(), $prioritizeDomainUrl);
  161.                     } else {
  162.                         $domainUrls = [$domainUrl];
  163.                     }
  164.                     $possibleLanguageCollection->set($languageEntity->getId(), new PossibleLanguageStruct(
  165.                         $this->getNameOfLanguageAndLocale($localeEntity),
  166.                         $localeEntity->getCode(),
  167.                         $domainUrl,
  168.                         $domainUrls,
  169.                         $localeEntity->getId(),
  170.                         $languageEntity->getId(),
  171.                         $domainEntity
  172.                     ));
  173.                 }
  174.             }
  175.         }
  176.         return $this->sortLanguagesByName($possibleLanguageCollection);
  177.     }
  178.     public function getActiveRuleDomain(string $activeDomainIdShopSwitchRuleEntity $activeRule): ?ShopSwitchRuleDomainEntity
  179.     {
  180.         foreach ($activeRule->getDomains()->getElements() as $ruleDomainEntity) {
  181.             if((!empty($ruleDomainEntity->getDomain()) && $ruleDomainEntity->getDomain()->getId() === $activeDomainId) || $ruleDomainEntity->getRedirectTo() === 'external') {
  182.                 return $ruleDomainEntity;
  183.             }
  184.         }
  185.         return null;
  186.     }
  187.     private function mergeDomainUrls($domainId$domainUrls = [], $insertBefore false): array
  188.     {
  189.         if(in_array($domainId$domainUrls) === false) {
  190.             if($insertBefore === true) {
  191.                 array_unshift($domainUrls$domainId);
  192.             } else {
  193.                 array_push($domainUrls$domainId);
  194.             }
  195.         }
  196.         return $domainUrls;
  197.     }
  198.     private function sortCountriesByNameAndPosition(PossibleCountryCollection $possibleCountryCollection): PossibleCountryCollection
  199.     {
  200.         $possibleCountryCollection->sort(function (PossibleCountryStruct $aPossibleCountryStruct $b) {
  201.             if($a->getPosition() !== $b->getPosition()) {
  202.                 return $a->getPosition() > $b->getPosition();
  203.             }
  204.             return $a->getName() > $b->getName();
  205.         });
  206.         return $possibleCountryCollection;
  207.     }
  208.     private function sortLanguagesByName(PossibleLanguageCollection $possibleLanguageCollection): PossibleLanguageCollection
  209.     {
  210.         $possibleLanguageCollection->sort(function (PossibleLanguageStruct $aPossibleLanguageStruct $b) {
  211.             return $a->getName() > $b->getName();
  212.         });
  213.         return $possibleLanguageCollection;
  214.     }
  215.     private function getNameOfLanguageAndLocale(LocaleEntity $localeEntityFromSalesChannel): string
  216.     {
  217.         if(!empty($localeEntityFromSalesChannel->getTranslation('name'))) {
  218.             return $localeEntityFromSalesChannel->getTranslation('name');
  219.         }
  220.         return $localeEntityFromSalesChannel->getName();
  221.     }
  222.     private function getSalesChannelIdsFromRuleEntity(ShopSwitchRuleEntity $ruleEntity): array
  223.     {
  224.         $salesChannelIds = [];
  225.         foreach ($ruleEntity->getDomains() as $domain) {
  226.             if($domain->getDomain() instanceof SalesChannelDomainEntity) {
  227.                 $salesChannelIds[] = $domain->getDomain()->getSalesChannelId();
  228.             }
  229.         }
  230.         return $salesChannelIds;
  231.     }
  232.     private function sortRuleEntityDomains(ShopSwitchRuleEntity $ruleEntity): void
  233.     {
  234.         if(empty($ruleEntity->getDomains())) return;
  235.         $ruleEntity->getDomains()->sort(function (ShopSwitchRuleDomainEntity $aShopSwitchRuleDomainEntity $b) {
  236.             $aHasCountryBlacklist = !empty($a->getCountryBlacklist()) && $a->getCountryBlacklist()->count() > 0;
  237.             $aHasLanguageBlacklist = !empty($a->getLanguageBlacklist()) && $a->getLanguageBlacklist()->count() > 0;
  238.             $bHasCountryBlacklist = !empty($b->getCountryBlacklist()) && $b->getCountryBlacklist()->count() > 0;
  239.             $bHasLanguageBlacklist = !empty($b->getLanguageBlacklist()) && $b->getLanguageBlacklist()->count() > 0;
  240.             // first check if both exists
  241.             if($aHasCountryBlacklist && $aHasLanguageBlacklist) return -1;
  242.             if($bHasCountryBlacklist && $bHasLanguageBlacklist) return 1;
  243.             if($aHasCountryBlacklist || $aHasLanguageBlacklist) return -1;
  244.             if($bHasCountryBlacklist || $bHasLanguageBlacklist) return 1;
  245.             return 0;
  246.         });
  247.     }
  248. }