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

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