custom/plugins/NetiNextStoreLocator/src/Decorator/EntityRepositoryDecorator.php line 117

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace NetInventors\NetiNextStoreLocator\Decorator;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition;
  5. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\AggregationResultCollection;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\IdSearchResult;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Write\CloneBehavior;
  13. use Shopware\Core\Framework\Uuid\Uuid;
  14. class EntityRepositoryDecorator implements EntityRepositoryInterface
  15. {
  16.     private const COUNTRY_ISOS = [
  17.         '2'  => 'DE',
  18.         '3'  => 'AE',
  19.         '4'  => 'AU',
  20.         '5'  => 'BE',
  21.         '7'  => 'DK',
  22.         '8'  => 'FI',
  23.         '9'  => 'FR',
  24.         '10' => 'GR',
  25.         '11' => 'GB',
  26.         '12' => 'IE',
  27.         '13' => 'IS',
  28.         '14' => 'IT',
  29.         '15' => 'JP',
  30.         '16' => 'CA',
  31.         '18' => 'LU',
  32.         '20' => 'NA',
  33.         '21' => 'NL',
  34.         '22' => 'NO',
  35.         '23' => 'AT',
  36.         '24' => 'PT',
  37.         '25' => 'SE',
  38.         '26' => 'CH',
  39.         '27' => 'ES',
  40.         '28' => 'US',
  41.         '29' => 'LI',
  42.         '30' => 'PL',
  43.         '31' => 'HU',
  44.         '32' => 'TR',
  45.         '33' => 'CZ',
  46.         '34' => 'SK',
  47.         '35' => 'RO',
  48.         '36' => 'BR',
  49.         '37' => 'IL',
  50.     ];
  51.     /**
  52.      * @var EntityRepositoryInterface
  53.      */
  54.     private $repository;
  55.     /**
  56.      * @var EntityRepositoryInterface
  57.      */
  58.     private $salesChannelRepository;
  59.     /**
  60.      * @var EntityRepositoryInterface
  61.      */
  62.     private $countryRepository;
  63.     /**
  64.      * @var EntityRepositoryInterface
  65.      */
  66.     private $countryStateRepository;
  67.     /**
  68.      * EntityRepositoryDecorator constructor.
  69.      *
  70.      * @param EntityRepositoryInterface $repository
  71.      * @param EntityRepositoryInterface $salesChannelRepository
  72.      * @param EntityRepositoryInterface $countryRepository
  73.      * @param EntityRepositoryInterface $countryStateRepository
  74.      */
  75.     public function __construct(
  76.         EntityRepositoryInterface $repository,
  77.         EntityRepositoryInterface $salesChannelRepository,
  78.         EntityRepositoryInterface $countryRepository,
  79.         EntityRepositoryInterface $countryStateRepository
  80.     ) {
  81.         $this->repository             = $repository;
  82.         $this->salesChannelRepository = $salesChannelRepository;
  83.         $this->countryRepository      = $countryRepository;
  84.         $this->countryStateRepository = $countryStateRepository;
  85.     }
  86.     public function getDefinition(): EntityDefinition
  87.     {
  88.         return $this->repository->getDefinition();
  89.     }
  90.     public function aggregate(Criteria $criteria, Context $context): AggregationResultCollection
  91.     {
  92.         return $this->repository->aggregate($criteria, $context);
  93.     }
  94.     public function searchIds(Criteria $criteria, Context $context): IdSearchResult
  95.     {
  96.         return $this->repository->searchIds($criteria, $context);
  97.     }
  98.     public function clone(string $id, Context $context, ?string $newId = null, ?CloneBehavior $behavior = null): EntityWrittenContainerEvent
  99.     {
  100.         return $this->repository->clone($id, $context, $newId, $behavior);
  101.     }
  102.     public function search(Criteria $criteria, Context $context): EntitySearchResult
  103.     {
  104.         return $this->repository->search($criteria, $context);
  105.     }
  106.     public function update(array $data, Context $context): EntityWrittenContainerEvent
  107.     {
  108.         return $this->repository->update($data, $context);
  109.     }
  110.     public function upsert(array $data, Context $context): EntityWrittenContainerEvent
  111.     {
  112.         if (!array_key_exists('excludeFromSync', $data[0]) && array_key_exists('label', $data[0])) {
  113.             $data[0]['countryId'] = $this->getCountryId($data[0]['countryId'], $context);
  114.             $data[0]['id']        = $this->createStoreId($data[0], $context);
  115.             /**
  116.              * Due to the condition above data must be an array
  117.              *
  118.              * @psalm-suppress MixedArgument
  119.              */
  120.             $data[0]['showAlways'] = $this->setShowAlways($data[0]);
  121.             $salesChannelIds = $this->getSalesChannelsIds($context);
  122.             unset($data[0]['salesChannels']);
  123.             foreach ($salesChannelIds as $channelId) {
  124.                 $data[0]['salesChannels'][] = [ 'id' => $channelId ];
  125.             }
  126.         }
  127.         if (isset($data[0]['salesChannels'])) {
  128.             $data[0]['salesChannels'] = $this->assignSalesChannel($data[0]['salesChannels'], $context);
  129.         }
  130.         if (isset($data[0]['countryId'])) {
  131.             $data[0]['countryId'] = $this->assignCountryIdByIso($data[0], $context);
  132.             if (isset($data[0]['country'])) {
  133.                 unset($data[0]['country']);
  134.             }
  135.             if (isset($data[0]['countryState'])) {
  136.                 $data[0]['countryStateId'] = $this->assignCountryStateByShortCode($data[0], $context);
  137.                 unset($data[0]['countryState']);
  138.             }
  139.         }
  140.         return $this->repository->upsert($data, $context);
  141.     }
  142.     public function create(array $data, Context $context): EntityWrittenContainerEvent
  143.     {
  144.         return $this->repository->create($data, $context);
  145.     }
  146.     public function delete(array $data, Context $context): EntityWrittenContainerEvent
  147.     {
  148.         return $this->repository->delete($data, $context);
  149.     }
  150.     public function createVersion(string $id, Context $context, ?string $name = null, ?string $versionId = null): string
  151.     {
  152.         return $this->repository->createVersion($id, $context, $name, $versionId);
  153.     }
  154.     public function merge(string $versionId, Context $context): void
  155.     {
  156.         $this->repository->merge($versionId, $context);
  157.     }
  158.     private function getSalesChannelsIds(Context $context): array
  159.     {
  160.         $criteria = new Criteria();
  161.         return $this->salesChannelRepository->searchIds($criteria, $context)->getIds();
  162.     }
  163.     /**
  164.      * @param string  $id
  165.      * @param Context $context
  166.      *
  167.      * @return string
  168.      */
  169.     private function getCountryId(string $id, Context $context): string
  170.     {
  171.         $criteria = new Criteria();
  172.         $criteria->addFilter(new EqualsFilter('iso', self::COUNTRY_ISOS[$id] ?? 'DE'));
  173.         return $this->countryRepository->searchIds($criteria, $context)->firstId();
  174.     }
  175.     /**
  176.      * @param array   $data
  177.      * @param Context $context
  178.      *
  179.      * @return string
  180.      */
  181.     private function createStoreId(array $data, Context $context): string
  182.     {
  183.         unset($data['salesChannels'], $data['id']);
  184.         $criteria = new Criteria();
  185.         foreach ($data as $key => $value) {
  186.             if ($key !== 'country' && !empty($value)) {
  187.                 $criteria->addFilter(new EqualsFilter($key, $value));
  188.             }
  189.         }
  190.         $result = $this->repository->searchIds($criteria, $context)->firstId();
  191.         if (null === $result) {
  192.             $result = Uuid::randomHex();
  193.         }
  194.         return $result;
  195.     }
  196.     /**
  197.      * @param array $data
  198.      *
  199.      * @return string
  200.      */
  201.     private function setShowAlways(array $data): string
  202.     {
  203.         $newDisplay = 'no';
  204.         if (!isset($data['showAlways'])) {
  205.             return $newDisplay;
  206.         }
  207.         $showAlways = (string) $data['showAlways'];
  208.         switch ($showAlways) {
  209.             case '0':
  210.                 break;
  211.             case '1':
  212.                 $newDisplay = 'top';
  213.                 break;
  214.             case '2':
  215.                 $newDisplay = 'bottom';
  216.                 break;
  217.         }
  218.         return $newDisplay;
  219.     }
  220.     /**
  221.      * @param string  $salesChannelId
  222.      * @param Context $context
  223.      *
  224.      * @return bool
  225.      */
  226.     private function isMatchingSalesChannel(string $salesChannelId, Context $context): bool
  227.     {
  228.         $criteria = new Criteria([ $salesChannelId ]);
  229.         $result   = $this->salesChannelRepository->searchIds($criteria, $context)->getIds();
  230.         return !empty($result);
  231.     }
  232.     /**
  233.      * @param array   $salesChannels
  234.      * @param Context $context
  235.      *
  236.      * @return array
  237.      */
  238.     private function assignSalesChannel(array $salesChannels, Context $context): array
  239.     {
  240.         foreach ($salesChannels as $key => $salesChannel) {
  241.             if (!$this->isMatchingSalesChannel($salesChannel['id'], $context)) {
  242.                 unset($salesChannels[$key]);
  243.             }
  244.         }
  245.         if (empty($salesChannels)) {
  246.             $defaultSalesChannelIds = $this->getSalesChannelsIds($context);
  247.             foreach ($defaultSalesChannelIds as $defaultSalesChannelId) {
  248.                 $salesChannels[] = [ 'id' => $defaultSalesChannelId ];
  249.             }
  250.         }
  251.         return $salesChannels;
  252.     }
  253.     /**
  254.      * @param array   $data
  255.      * @param Context $context
  256.      *
  257.      * @return string
  258.      */
  259.     private function assignCountryIdByIso(array $data, Context $context): string
  260.     {
  261.         if (isset($data['countryId'], $data['country']['iso']) && !$this->isMatchingCountryId($data['countryId'], $context)) {
  262.             $data['countryId'] = $this->getCountryByIso($data['country']['iso'], $context);
  263.         }
  264.         if (!isset($data['countryId']) || null === $data['countryId']) {
  265.             $data['countryId'] = $this->getCountryId('deutsch', $context);
  266.         }
  267.         return $data['countryId'];
  268.     }
  269.     /**
  270.      * @param array   $data
  271.      * @param Context $context
  272.      *
  273.      * @return string
  274.      */
  275.     private function assignCountryStateByShortCode(array $data, Context $context): string
  276.     {
  277.         if (isset($data['countryStateId'], $data['countryState']['shortCode']) && !$this->isMatchingCountryStateId($data['countryStateId'], $context)) {
  278.             $data['countryStateId'] = $this->getCountryStateByShortCode($data['countryState']['shortCode'], $context);
  279.         }
  280.         return $data['countryStateId'];
  281.     }
  282.     /**
  283.      * @param string  $countryId
  284.      * @param Context $context
  285.      *
  286.      * @return bool
  287.      */
  288.     private function isMatchingCountryId(string $countryId, Context $context): bool
  289.     {
  290.         $criteria = new Criteria([ $countryId ]);
  291.         $result   = $this->countryRepository->searchIds($criteria, $context)->getIds();
  292.         return !empty($result);
  293.     }
  294.     /**
  295.      * @param string  $iso
  296.      * @param Context $context
  297.      *
  298.      * @return string|null
  299.      */
  300.     private function getCountryByIso(string $iso, Context $context): ?string
  301.     {
  302.         $criteria = new Criteria();
  303.         $criteria->addFilter(new EqualsFilter('iso', $iso));
  304.         return $this->countryRepository->searchIds($criteria, $context)->firstId();
  305.     }
  306.     /**
  307.      * @param string  $countryStateId
  308.      * @param Context $context
  309.      *
  310.      * @return bool
  311.      */
  312.     private function isMatchingCountryStateId(string $countryStateId, Context $context): bool
  313.     {
  314.         $criteria = new Criteria([ $countryStateId]);
  315.         $result   = $this->countryStateRepository->searchIds($criteria, $context)->getIds();
  316.         return !empty($result);
  317.     }
  318.     /**
  319.      * @param string  $shortCode
  320.      * @param Context $context
  321.      *
  322.      * @return string|null
  323.      */
  324.     private function getCountryStateByShortCode(string $shortCode, Context $context): ?string
  325.     {
  326.         $criteria = new Criteria();
  327.         $criteria->addFilter(new EqualsFilter('shortCode', $shortCode));
  328.         return $this->countryStateRepository->searchIds($criteria, $context)->firstId();
  329.     }
  330. }