custom/plugins/SwagB2bPlatform/components/OrderNumber/BridgePlatform/SalesChannelProductRepositoryDecorator.php line 52

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\B2B\OrderNumber\BridgePlatform;
  3. use Shopware\B2B\Shop\BridgePlatform\SalesChannelProductExtension;
  4. use Shopware\B2B\StoreFrontAuthentication\Framework\AuthenticationService;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\AggregationResultCollection;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\AntiJoinFilter;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\Filter;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\IdSearchResult;
  16. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  17. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  18. use function end;
  19. use function explode;
  20. use function get_class;
  21. use function in_array;
  22. class SalesChannelProductRepositoryDecorator implements SalesChannelRepositoryInterface
  23. {
  24.     private const ORDER_NUMBER_CONTEXT_OWNER_ID_FIELD 'contextOwnerId';
  25.     private const ORDER_NUMBER_CUSTOM_ORDER_NUMBER_FIELD 'customOrderNumber';
  26.     private const PRODUCT_DEFINITION_PRODUCT_NUMBER_FIELD 'productNumber';
  27.     private const PRODUCT_ORDER_NUMBER_ID_FIELD 'product.b2bOrderNumber.id';
  28.     private const PRODUCT_ORDER_NUMBER_CUSTOM_ORDER_NUMBER_FIELD 'product.b2bOrderNumber.customOrderNumber';
  29.     private const PRODUCT_ORDER_NUMBER_CONTEXT_OWNER_ID_FIELD 'product.b2bOrderNumber.contextOwnerId';
  30.     /**
  31.      * @var AuthenticationService
  32.      */
  33.     private $authenticationService;
  34.     /**
  35.      * @var SalesChannelRepositoryInterface
  36.      */
  37.     private $decorated;
  38.     public function __construct(
  39.         AuthenticationService $authenticationService,
  40.         SalesChannelRepositoryInterface $decorated
  41.     ) {
  42.         $this->authenticationService $authenticationService;
  43.         $this->decorated $decorated;
  44.     }
  45.     public function search(Criteria $criteriaSalesChannelContext $salesChannelContext): EntitySearchResult
  46.     {
  47.         if (!$this->authenticationService->isB2b()) {
  48.             return $this->decorated->search($criteria$salesChannelContext);
  49.         }
  50.         $this->prepareCriteriaForB2bOrderNumber($criteria);
  51.         return $this->decorated->search($criteria$salesChannelContext);
  52.     }
  53.     public function aggregate(Criteria $criteriaSalesChannelContext $salesChannelContext): AggregationResultCollection
  54.     {
  55.         return $this->decorated->aggregate($criteria$salesChannelContext);
  56.     }
  57.     public function searchIds(Criteria $criteriaSalesChannelContext $salesChannelContext): IdSearchResult
  58.     {
  59.         if (!$this->authenticationService->isB2b()) {
  60.             return $this->decorated->searchIds($criteria$salesChannelContext);
  61.         }
  62.         $this->prepareCriteriaForB2bOrderNumber($criteria);
  63.         return $this->decorated->searchIds($criteria$salesChannelContext);
  64.     }
  65.     /**
  66.      * @internal
  67.      */
  68.     protected function prepareCriteriaForB2bOrderNumber(Criteria $criteria): void
  69.     {
  70.         $filters $criteria->getFilters();
  71.         $criteria->addAssociation(SalesChannelProductExtension::B2B_ORDER_NUMBER_EXTENSION_NAME);
  72.         $associationCriteria $criteria->getAssociation(SalesChannelProductExtension::B2B_ORDER_NUMBER_EXTENSION_NAME);
  73.         $associationCriteria->addFilter(new EqualsFilter(
  74.             self::ORDER_NUMBER_CONTEXT_OWNER_ID_FIELD,
  75.             $this->authenticationService->getIdentity()->getContextAuthId()->getValue()
  76.         ));
  77.         $criteria->resetFilters();
  78.         foreach ($filters as $filter) {
  79.             $criteria->addFilter($this->mapFilter($filter));
  80.         }
  81.     }
  82.     /**
  83.      * @internal
  84.      */
  85.     protected function mapFilter(Filter $filter): Filter
  86.     {
  87.         // ignore inherited MultiFilter
  88.         if (in_array(
  89.             $class get_class($filter),
  90.             [MultiFilter::class, NotFilter::class, AntiJoinFilter::class],
  91.             true
  92.         )) {
  93.             $queries = [];
  94.             foreach ($filter->getQueries() as $query) {
  95.                 $queries[] = $this->mapFilter($query);
  96.             }
  97.             return new $class($filter->getOperator(), $queries);
  98.         }
  99.         if (!$this->isOrderNumberFilter($filter)) {
  100.             return $filter;
  101.         }
  102.         return $this->buildOrderNumberFilter($filter);
  103.     }
  104.     /**
  105.      * @internal
  106.      */
  107.     protected function isOrderNumberFilter(Filter $filter): bool
  108.     {
  109.         return ($filter instanceof EqualsFilter || $filter instanceof EqualsAnyFilter || $filter instanceof ContainsFilter)
  110.             && $this->getNecessaryFieldValue($filter->getField()) === self::PRODUCT_DEFINITION_PRODUCT_NUMBER_FIELD;
  111.     }
  112.     /**
  113.      * @internal
  114.      */
  115.     protected function buildOrderNumberFilter(Filter $filter): Filter
  116.     {
  117.         return new MultiFilter(
  118.             MultiFilter::CONNECTION_OR,
  119.             [
  120.                 $filter,
  121.                 new MultiFilter(MultiFilter::CONNECTION_AND, [
  122.                     $this->mapOrderNumberFilter(self::PRODUCT_ORDER_NUMBER_CUSTOM_ORDER_NUMBER_FIELD$filter),
  123.                     new NotFilter(NotFilter::CONNECTION_AND, [new EqualsFilter(self::PRODUCT_ORDER_NUMBER_ID_FIELDnull)]),
  124.                     new EqualsFilter(self::PRODUCT_ORDER_NUMBER_CONTEXT_OWNER_ID_FIELD$this->authenticationService->getIdentity()->getContextAuthId()->getValue()),
  125.                 ]),
  126.             ]
  127.         );
  128.     }
  129.     /**
  130.      * @internal
  131.      */
  132.     protected function mapOrderNumberFilter(string $fieldNameFilter $filter): Filter
  133.     {
  134.         if ($filter instanceof EqualsFilter) {
  135.             return new EqualsFilter($fieldName$filter->getValue());
  136.         }
  137.         if ($filter instanceof EqualsAnyFilter) {
  138.             return new EqualsAnyFilter($fieldName$filter->getValue());
  139.         }
  140.         if ($filter instanceof ContainsFilter) {
  141.             return new ContainsFilter($fieldName$filter->getValue());
  142.         }
  143.         return $filter;
  144.     }
  145.     /**
  146.      * @internal
  147.      */
  148.     protected function getNecessaryFieldValue(string $field): string
  149.     {
  150.         $explodedField explode('.'$field);
  151.         return end($explodedField);
  152.     }
  153. }