Passed
Push — trunk ( 9c6f44...b568e5 )
by Christian
09:43 queued 12s
created

AdminSearchController::buildSearchEntities()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 2
dl 0
loc 21
rs 9.9332
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Administration\Controller;
4
5
use Shopware\Administration\Framework\Search\CriteriaCollection;
6
use Shopware\Administration\Service\AdminSearcher;
7
use Shopware\Core\Framework\Api\Acl\AclCriteriaValidator;
8
use Shopware\Core\Framework\Api\Exception\MissingPrivilegeException;
9
use Shopware\Core\Framework\Api\Serializer\JsonEntityEncoder;
10
use Shopware\Core\Framework\Context;
11
use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry;
12
use Shopware\Core\Framework\DataAbstractionLayer\Entity;
13
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
14
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
15
use Shopware\Core\Framework\DataAbstractionLayer\Search\RequestCriteriaBuilder;
16
use Shopware\Core\Framework\Routing\Annotation\Since;
17
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Routing\Annotation\Route;
22
use Symfony\Component\Serializer\Encoder\DecoderInterface;
23
24
/**
25
 * @package administration
26
 */
27
class AdminSearchController extends AbstractController
28
{
29
    /**
30
     * @internal
31
     */
32
    public function __construct(private readonly RequestCriteriaBuilder $requestCriteriaBuilder, private readonly DefinitionInstanceRegistry $definitionInstanceRegistry, private readonly AdminSearcher $searcher, private readonly DecoderInterface $serializer, private readonly AclCriteriaValidator $criteriaValidator, private readonly DefinitionInstanceRegistry $definitionRegistry, private readonly JsonEntityEncoder $entityEncoder)
33
    {
34
    }
35
36
    /**
37
     * @Since("6.4.5.0")
38
     */
39
    #[Route(path: '/api/_admin/search', name: 'api.admin.search', defaults: ['_routeScope' => ['administration']], methods: ['POST'])]
40
    public function search(Request $request, Context $context): Response
41
    {
42
        $criteriaCollection = $this->buildSearchEntities($request, $context);
43
44
        $violations = [];
45
46
        foreach ($criteriaCollection as $entity => $criteria) {
47
            $missing = $this->criteriaValidator->validate($entity, $criteria, $context);
0 ignored issues
show
Bug introduced by
$criteria of type array is incompatible with the type Shopware\Core\Framework\...onLayer\Search\Criteria expected by parameter $criteria of Shopware\Core\Framework\...iaValidator::validate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

47
            $missing = $this->criteriaValidator->validate($entity, /** @scrutinizer ignore-type */ $criteria, $context);
Loading history...
48
49
            if (!empty($missing)) {
50
                $violations[$entity] = (new MissingPrivilegeException($missing))->getErrors()->current();
51
                $criteriaCollection->remove($entity);
52
            }
53
        }
54
55
        $results = $this->searcher->search($criteriaCollection, $context);
56
57
        foreach ($results as $entityName => $result) {
58
            if (!$criteriaCollection->has($entityName)) {
59
                continue;
60
            }
61
62
            /** @var Criteria $criteria */
63
            $criteria = $criteriaCollection->get($entityName);
64
            $definition = $this->definitionRegistry->getByEntityName($entityName);
65
66
            /** @var EntityCollection<Entity> $entityCollection */
67
            $entityCollection = $result['data'];
68
            $entities = [];
69
70
            foreach ($entityCollection->getElements() as $key => $entity) {
71
                $entities[$key] = $this->entityEncoder->encode($criteria, $definition, $entity, '/api');
72
            }
73
74
            $results[$entityName]['data'] = $entities;
75
        }
76
77
        return new JsonResponse(['data' => array_merge($results, $violations)]);
78
    }
79
80
    private function buildSearchEntities(Request $request, Context $context): CriteriaCollection
81
    {
82
        $collection = new CriteriaCollection();
83
84
        $queries = $this->serializer->decode($request->getContent(), 'json');
85
86
        foreach ($queries as $entityName => $query) {
87
            if (!$this->definitionInstanceRegistry->has($entityName)) {
88
                continue;
89
            }
90
91
            $definition = $this->definitionInstanceRegistry->getByEntityName($entityName);
92
93
            $criteriaRequest = $request->duplicate($request->query->all(), $query);
94
95
            $criteria = $this->requestCriteriaBuilder->handleRequest($criteriaRequest, new Criteria(), $definition, $context);
96
97
            $collection->set($entityName, $criteria);
98
        }
99
100
        return $collection;
101
    }
102
}
103