-
Notifications
You must be signed in to change notification settings - Fork 44
/
AdminSearchService.php
108 lines (82 loc) · 3.87 KB
/
AdminSearchService.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php declare(strict_types=1);
namespace Vin\ShopwareSdk\Service;
use GuzzleHttp\Exception\BadResponseException;
use Vin\ShopwareSdk\Data\Context;
use Vin\ShopwareSdk\Data\Criteria;
use Vin\ShopwareSdk\Exception\ShopwareResponseException;
use Vin\ShopwareSdk\Factory\HydratorFactory;
use Vin\ShopwareSdk\Hydrate\HydratorInterface;
use Vin\ShopwareSdk\Repository\Struct\AggregationResultCollection;
use Vin\ShopwareSdk\Repository\Struct\EntitySearchResult;
use Vin\ShopwareSdk\Repository\Struct\SearchResultMeta;
use Vin\ShopwareSdk\Service\Struct\KeyValuePair;
use Vin\ShopwareSdk\Service\Struct\KeyValuePairs;
class AdminSearchService extends ApiService
{
private const ADMIN_SEARCH_ENDPOINT = '/api/_admin/search';
private HydratorInterface $hydrator;
public function __construct(
?Context $context = null,
string $contentType = 'application/vnd.api+json',
?HydratorInterface $hydrator = null
) {
$this->hydrator = $hydrator ?: HydratorFactory::create();
parent::__construct($context, $contentType);
}
/**
* @param KeyValuePairs $criteriaCollection
* @param array $additionalHeaders
* @throws ShopwareResponseException
* @return KeyValuePairs
*/
public function search(KeyValuePairs $criteriaCollection, array $additionalHeaders = []): KeyValuePairs
{
$parsed = [];
foreach ($criteriaCollection as $part) {
$partCriteria = $part->getValue();
if (!$partCriteria instanceof Criteria) {
throw new \InvalidArgumentException('Parameter $criteria must be array of Criteria');
}
$parsed[$part->getKey()] = $partCriteria->parse();
}
/** @var Context|null $context */
$context = $this->context;
if ($context === null) {
throw new \Exception('Please call setContext method before sending the request');
}
try {
$response = $this->httpClient->post($this->getFullUrl(self::ADMIN_SEARCH_ENDPOINT), [
'headers' => $this->getBasicHeaders($additionalHeaders),
'json' => $parsed,
]);
$contents = self::handleResponse($response->getBody()->getContents(), $response->getHeaders());
$pairs = new KeyValuePairs();
$data = $contents['data'] ?? [];
foreach ($criteriaCollection as $entityName => $partCriteria) {
$itemResponse = $data[$entityName] ?? [];
$rawData = $itemResponse['data'] ?? [];
$rawData = array_map(function ($item) use ($entityName, $itemResponse) {
return [
'type' => $entityName,
'id' => $item['id'],
'attributes' => $item,
'meta' => [
'total' => $itemResponse['total'],
'totalCountMode' => Criteria::TOTAL_COUNT_MODE_EXACT
],
];
}, $rawData);
$itemResponse['data'] = $rawData;
$aggregations = new AggregationResultCollection($itemResponse['aggregations'] ?? []);
$entities = $this->hydrator->hydrateSearchResult($itemResponse, $context, $entityName);
$meta = new SearchResultMeta($itemResponse['total'] ?? 0, Criteria::TOTAL_COUNT_MODE_EXACT);
$result = new EntitySearchResult($entityName, $meta, $entities, $aggregations, $partCriteria->getValue(), $context);
$pairs->add(KeyValuePair::create($entityName, $result));
}
return $pairs;
} catch (BadResponseException $exception) {
$message = $exception->getResponse()->getBody()->getContents();
throw new ShopwareResponseException($message, $exception->getResponse()->getStatusCode(), $exception);
}
}
}