Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
91.46% |
75 / 82 |
|
66.67% |
14 / 21 |
|
62.50% |
10 / 16 |
|
45.45% |
5 / 11 |
CRAP | |
0.00% |
0 / 1 |
| RebrickableDataLoader | |
91.46% |
75 / 82 |
|
66.67% |
14 / 21 |
|
62.50% |
10 / 16 |
|
45.45% |
5 / 11 |
32.24 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| fetchFromExternalApi | |
84.62% |
11 / 13 |
|
33.33% |
1 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
2.50 | |||
| fetchSetsFromExternalApi | |
93.75% |
15 / 16 |
|
66.67% |
2 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
2.50 | |||
| fetchPartsFromExternalApi | |
92.86% |
13 / 14 |
|
66.67% |
2 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
4.12 | |||
| fetchPartElementsFromExternalApi | |
93.75% |
15 / 16 |
|
66.67% |
2 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
2.50 | |||
| fetchSetElementsFromExternalApi | |
94.12% |
16 / 17 |
|
66.67% |
2 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
2.50 | |||
| findSets | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| findParts | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getSetParts | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getPartElements | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getSetElements | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\CollectionManagement\Infrastructure\Service; |
| 4 | |
| 5 | use App\CollectionManagement\Domain\Model\External\ExternalElement; |
| 6 | use App\CollectionManagement\Domain\Model\External\ExternalElementCollection; |
| 7 | use App\CollectionManagement\Domain\Model\External\ExternalPart; |
| 8 | use App\CollectionManagement\Domain\Model\External\ExternalSet; |
| 9 | use App\CollectionManagement\Domain\Model\External\ExternalSetElement; |
| 10 | use App\CollectionManagement\Domain\Model\External\ExternalSetElementCollection; |
| 11 | use App\CollectionManagement\Domain\Model\PartCollection; |
| 12 | use App\CollectionManagement\Domain\Model\SetCollection; |
| 13 | use App\CollectionManagement\Domain\Service\LegoDataLoader; |
| 14 | use Override; |
| 15 | use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; |
| 16 | use Symfony\Contracts\HttpClient\HttpClientInterface; |
| 17 | |
| 18 | /** |
| 19 | * @author Wilhelm Zwertvaegher |
| 20 | * Lego data loader ; this will be our only loader at the moment. |
| 21 | * This loader uses a cache to avoid external requests when possible |
| 22 | * |
| 23 | */ |
| 24 | |
| 25 | #[Autoconfigure] |
| 26 | class RebrickableDataLoader implements LegoDataLoader |
| 27 | { |
| 28 | private const API_BASE_URL = 'https://rebrickable.com/api/v3/lego/'; |
| 29 | |
| 30 | public function __construct( |
| 31 | private readonly ExternalDataCacheManager $cacheManager, |
| 32 | private readonly HttpClientInterface $httpClient, |
| 33 | private readonly string $apiKey |
| 34 | ) { |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * @param string $endpointUri |
| 39 | * @return array<mixed>|null |
| 40 | * |
| 41 | * */ |
| 42 | private function fetchFromExternalApi($endpointUri): ?array |
| 43 | { |
| 44 | try { |
| 45 | $response = $this->httpClient->request( |
| 46 | 'GET', |
| 47 | sprintf('%s%s', self::API_BASE_URL, $endpointUri), |
| 48 | array( |
| 49 | 'headers' => [ |
| 50 | 'Authorization' => sprintf('key %s', $this->apiKey), |
| 51 | ] |
| 52 | ) |
| 53 | ); |
| 54 | // return raw data fetched from external API |
| 55 | $data = $response->toArray(); |
| 56 | return $data['results'] ?? []; |
| 57 | } |
| 58 | // TODO : properly handle this throwable |
| 59 | catch (\Throwable $e) { |
| 60 | return null; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | /** |
| 65 | * @param string $search |
| 66 | * @return SetCollection|null |
| 67 | */ |
| 68 | private function fetchSetsFromExternalApi(string $search): ?SetCollection |
| 69 | { |
| 70 | $results = $this->fetchFromExternalApi(sprintf('sets/?search=%s', $search)); |
| 71 | if ($results === null) { |
| 72 | return null; |
| 73 | } |
| 74 | |
| 75 | return new SetCollection( |
| 76 | array_map( |
| 77 | fn ($item) => new ExternalSet( |
| 78 | $item['set_num'], |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 80 | $item['name'], |
| 81 | $item['num_parts'], |
| 82 | $item['set_img_url'] ?? '', |
| 83 | $item['year'] |
| 84 | ), |
| 85 | $results |
| 86 | ) |
| 87 | ); |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * @param string $search |
| 92 | * @return PartCollection|null |
| 93 | */ |
| 94 | private function fetchPartsFromExternalApi(string $search): ?PartCollection |
| 95 | { |
| 96 | $results = $this->fetchFromExternalApi(sprintf('parts/?search=%s', $search)); |
| 97 | if ($results === null) { |
| 98 | return null; |
| 99 | } |
| 100 | |
| 101 | return new PartCollection( |
| 102 | array_map( |
| 103 | fn ($item) => new ExternalPart( |
| 104 | $item['part_num'], |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 106 | $item['name'], |
| 107 | $item['part_img_url'] ?? '' |
| 108 | ), |
| 109 | $results |
| 110 | ) |
| 111 | ); |
| 112 | } |
| 113 | |
| 114 | /** |
| 115 | * @param string $partExternalId |
| 116 | * @return ExternalElementCollection|null |
| 117 | */ |
| 118 | private function fetchPartElementsFromExternalApi(string $partExternalId): ?ExternalElementCollection |
| 119 | { |
| 120 | $results = $this->fetchFromExternalApi(sprintf('parts/%s/colors/', $partExternalId)); |
| 121 | if ($results === null) { |
| 122 | return null; |
| 123 | } |
| 124 | |
| 125 | return new ExternalElementCollection( |
| 126 | array_map( |
| 127 | fn ($item) => new ExternalElement( |
| 128 | $item['elements'][0], |
| 129 | $item['elements'][0], |
| 130 | $partExternalId, |
| 131 | $item['part_img_url'] ?? '', |
| 132 | $item['color_id'], |
| 133 | $item['color_name'] |
| 134 | ), |
| 135 | $results |
| 136 | ) |
| 137 | ); |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * @param string $setExternalId |
| 142 | * @return ExternalSetElementCollection|null |
| 143 | */ |
| 144 | private function fetchSetElementsFromExternalApi(string $setExternalId): ?ExternalSetElementCollection |
| 145 | { |
| 146 | $results = $this->fetchFromExternalApi(sprintf('sets/%s/parts/?inc_part_details=1', $setExternalId)); |
| 147 | if ($results === null) { |
| 148 | return null; |
| 149 | } |
| 150 | |
| 151 | return new ExternalSetElementCollection( |
| 152 | array_map( |
| 153 | fn ($item) => new ExternalSetElement( |
| 154 | $item['element_id'], |
| 155 | $setExternalId, |
| 156 | $item['part']['part_num'], |
| 157 | $item['quantity'] |
| 158 | ), |
| 159 | array_filter( |
| 160 | $results, |
| 161 | fn ($item) => $item['is_spare'] === false |
| 162 | ) |
| 163 | ) |
| 164 | ); |
| 165 | } |
| 166 | |
| 167 | #[Override] |
| 168 | public function findSets(string $search): ?SetCollection |
| 169 | { |
| 170 | return $this->cacheManager->getSets($search, fn ($s) => $this->fetchSetsFromExternalApi($s)); |
| 171 | } |
| 172 | |
| 173 | #[Override] |
| 174 | public function findParts(string $search): ?PartCollection |
| 175 | { |
| 176 | return $this->cacheManager->getParts($search, fn ($s) => $this->fetchPartsFromExternalApi($s)); |
| 177 | } |
| 178 | |
| 179 | #[Override] |
| 180 | public function getSetParts(string $setExternalId): ?ExternalSetElementCollection |
| 181 | { |
| 182 | return new ExternalSetElementCollection([]); |
| 183 | } |
| 184 | |
| 185 | #[Override] |
| 186 | public function getPartElements(string $partExternalId): ?ExternalElementCollection |
| 187 | { |
| 188 | return $this->cacheManager->getPartElements($partExternalId, fn ($s) => $this->fetchPartElementsFromExternalApi($partExternalId)); |
| 189 | } |
| 190 | |
| 191 | #[Override] |
| 192 | public function getSetElements(string $setExternalId): ?ExternalSetElementCollection |
| 193 | { |
| 194 | return $this->cacheManager->getSetElements($setExternalId, fn ($s) => $this->fetchSetElementsFromExternalApi($setExternalId)); |
| 195 | } |
| 196 | } |
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 30 | public function __construct( |
| 31 | private readonly ExternalDataCacheManager $cacheManager, |
| 32 | private readonly HttpClientInterface $httpClient, |
| 33 | private readonly string $apiKey |
| 34 | ) { |
| 35 | } |
| 42 | private function fetchFromExternalApi($endpointUri): ?array |
| 43 | { |
| 44 | try { |
| 45 | $response = $this->httpClient->request( |
| 46 | 'GET', |
| 47 | sprintf('%s%s', self::API_BASE_URL, $endpointUri), |
| 48 | array( |
| 49 | 'headers' => [ |
| 50 | 'Authorization' => sprintf('key %s', $this->apiKey), |
| 51 | ] |
| 52 | ) |
| 53 | ); |
| 54 | // return raw data fetched from external API |
| 55 | $data = $response->toArray(); |
| 56 | return $data['results'] ?? []; |
| 59 | catch (\Throwable $e) { |
| 60 | return null; |
| 61 | } |
| 62 | } |
| 118 | private function fetchPartElementsFromExternalApi(string $partExternalId): ?ExternalElementCollection |
| 119 | { |
| 120 | $results = $this->fetchFromExternalApi(sprintf('parts/%s/colors/', $partExternalId)); |
| 121 | if ($results === null) { |
| 122 | return null; |
| 125 | return new ExternalElementCollection( |
| 126 | array_map( |
| 127 | fn ($item) => new ExternalElement( |
| 128 | $item['elements'][0], |
| 129 | $item['elements'][0], |
| 130 | $partExternalId, |
| 131 | $item['part_img_url'] ?? '', |
| 132 | $item['color_id'], |
| 133 | $item['color_name'] |
| 134 | ), |
| 135 | $results |
| 136 | ) |
| 137 | ); |
| 138 | } |
| 94 | private function fetchPartsFromExternalApi(string $search): ?PartCollection |
| 95 | { |
| 96 | $results = $this->fetchFromExternalApi(sprintf('parts/?search=%s', $search)); |
| 97 | if ($results === null) { |
| 98 | return null; |
| 101 | return new PartCollection( |
| 102 | array_map( |
| 103 | fn ($item) => new ExternalPart( |
| 104 | $item['part_num'], |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 106 | $item['name'], |
| 107 | $item['part_img_url'] ?? '' |
| 108 | ), |
| 109 | $results |
| 110 | ) |
| 111 | ); |
| 112 | } |
| 144 | private function fetchSetElementsFromExternalApi(string $setExternalId): ?ExternalSetElementCollection |
| 145 | { |
| 146 | $results = $this->fetchFromExternalApi(sprintf('sets/%s/parts/?inc_part_details=1', $setExternalId)); |
| 147 | if ($results === null) { |
| 148 | return null; |
| 151 | return new ExternalSetElementCollection( |
| 152 | array_map( |
| 153 | fn ($item) => new ExternalSetElement( |
| 154 | $item['element_id'], |
| 155 | $setExternalId, |
| 156 | $item['part']['part_num'], |
| 157 | $item['quantity'] |
| 158 | ), |
| 159 | array_filter( |
| 160 | $results, |
| 161 | fn ($item) => $item['is_spare'] === false |
| 162 | ) |
| 163 | ) |
| 164 | ); |
| 165 | } |
| 68 | private function fetchSetsFromExternalApi(string $search): ?SetCollection |
| 69 | { |
| 70 | $results = $this->fetchFromExternalApi(sprintf('sets/?search=%s', $search)); |
| 71 | if ($results === null) { |
| 72 | return null; |
| 75 | return new SetCollection( |
| 76 | array_map( |
| 77 | fn ($item) => new ExternalSet( |
| 78 | $item['set_num'], |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 80 | $item['name'], |
| 81 | $item['num_parts'], |
| 82 | $item['set_img_url'] ?? '', |
| 83 | $item['year'] |
| 84 | ), |
| 85 | $results |
| 86 | ) |
| 87 | ); |
| 88 | } |
| 174 | public function findParts(string $search): ?PartCollection |
| 175 | { |
| 176 | return $this->cacheManager->getParts($search, fn ($s) => $this->fetchPartsFromExternalApi($s)); |
| 177 | } |
| 168 | public function findSets(string $search): ?SetCollection |
| 169 | { |
| 170 | return $this->cacheManager->getSets($search, fn ($s) => $this->fetchSetsFromExternalApi($s)); |
| 171 | } |
| 186 | public function getPartElements(string $partExternalId): ?ExternalElementCollection |
| 187 | { |
| 188 | return $this->cacheManager->getPartElements($partExternalId, fn ($s) => $this->fetchPartElementsFromExternalApi($partExternalId)); |
| 189 | } |
| 192 | public function getSetElements(string $setExternalId): ?ExternalSetElementCollection |
| 193 | { |
| 194 | return $this->cacheManager->getSetElements($setExternalId, fn ($s) => $this->fetchSetElementsFromExternalApi($setExternalId)); |
| 195 | } |
| 180 | public function getSetParts(string $setExternalId): ?ExternalSetElementCollection |
| 181 | { |
| 182 | return new ExternalSetElementCollection([]); |
| 183 | } |
| 103 | fn ($item) => new ExternalPart( |
| 104 | $item['part_num'], |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 106 | $item['name'], |
| 107 | $item['part_img_url'] ?? '' |
| 108 | ), |
| 127 | fn ($item) => new ExternalElement( |
| 128 | $item['elements'][0], |
| 129 | $item['elements'][0], |
| 130 | $partExternalId, |
| 131 | $item['part_img_url'] ?? '', |
| 132 | $item['color_id'], |
| 133 | $item['color_name'] |
| 134 | ), |
| 153 | fn ($item) => new ExternalSetElement( |
| 154 | $item['element_id'], |
| 155 | $setExternalId, |
| 156 | $item['part']['part_num'], |
| 157 | $item['quantity'] |
| 158 | ), |
| 161 | fn ($item) => $item['is_spare'] === false |
| 162 | ) |
| 170 | return $this->cacheManager->getSets($search, fn ($s) => $this->fetchSetsFromExternalApi($s)); |
| 176 | return $this->cacheManager->getParts($search, fn ($s) => $this->fetchPartsFromExternalApi($s)); |
| 188 | return $this->cacheManager->getPartElements($partExternalId, fn ($s) => $this->fetchPartElementsFromExternalApi($partExternalId)); |
| 194 | return $this->cacheManager->getSetElements($setExternalId, fn ($s) => $this->fetchSetElementsFromExternalApi($setExternalId)); |
| 77 | fn ($item) => new ExternalSet( |
| 78 | $item['set_num'], |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 80 | $item['name'], |
| 81 | $item['num_parts'], |
| 82 | $item['set_img_url'] ?? '', |
| 83 | $item['year'] |
| 84 | ), |
| 3 | namespace App\CollectionManagement\Infrastructure\Service; |
| 4 | |
| 5 | use App\CollectionManagement\Domain\Model\External\ExternalElement; |
| 6 | use App\CollectionManagement\Domain\Model\External\ExternalElementCollection; |
| 7 | use App\CollectionManagement\Domain\Model\External\ExternalPart; |
| 8 | use App\CollectionManagement\Domain\Model\External\ExternalSet; |
| 9 | use App\CollectionManagement\Domain\Model\External\ExternalSetElement; |
| 10 | use App\CollectionManagement\Domain\Model\External\ExternalSetElementCollection; |
| 11 | use App\CollectionManagement\Domain\Model\PartCollection; |
| 12 | use App\CollectionManagement\Domain\Model\SetCollection; |
| 13 | use App\CollectionManagement\Domain\Service\LegoDataLoader; |
| 14 | use Override; |
| 15 | use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; |
| 16 | use Symfony\Contracts\HttpClient\HttpClientInterface; |
| 17 | |
| 18 | /** |
| 19 | * @author Wilhelm Zwertvaegher |
| 20 | * Lego data loader ; this will be our only loader at the moment. |
| 21 | * This loader uses a cache to avoid external requests when possible |
| 22 | * |
| 23 | */ |
| 24 | |
| 25 | #[Autoconfigure] |
| 26 | class RebrickableDataLoader implements LegoDataLoader |
| 27 | { |
| 28 | private const API_BASE_URL = 'https://rebrickable.com/api/v3/lego/'; |
| 29 | |
| 30 | public function __construct( |
| 31 | private readonly ExternalDataCacheManager $cacheManager, |
| 32 | private readonly HttpClientInterface $httpClient, |
| 33 | private readonly string $apiKey |
| 34 | ) { |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * @param string $endpointUri |
| 39 | * @return array<mixed>|null |
| 40 | * |
| 41 | * */ |
| 42 | private function fetchFromExternalApi($endpointUri): ?array |
| 43 | { |
| 44 | try { |
| 45 | $response = $this->httpClient->request( |
| 46 | 'GET', |
| 47 | sprintf('%s%s', self::API_BASE_URL, $endpointUri), |
| 48 | array( |
| 49 | 'headers' => [ |
| 50 | 'Authorization' => sprintf('key %s', $this->apiKey), |
| 51 | ] |
| 52 | ) |
| 53 | ); |
| 54 | // return raw data fetched from external API |
| 55 | $data = $response->toArray(); |
| 56 | return $data['results'] ?? []; |
| 57 | } |
| 58 | // TODO : properly handle this throwable |
| 59 | catch (\Throwable $e) { |
| 60 | return null; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | /** |
| 65 | * @param string $search |
| 66 | * @return SetCollection|null |
| 67 | */ |
| 68 | private function fetchSetsFromExternalApi(string $search): ?SetCollection |
| 69 | { |
| 70 | $results = $this->fetchFromExternalApi(sprintf('sets/?search=%s', $search)); |
| 71 | if ($results === null) { |
| 72 | return null; |
| 73 | } |
| 74 | |
| 75 | return new SetCollection( |
| 76 | array_map( |
| 77 | fn ($item) => new ExternalSet( |
| 78 | $item['set_num'], |
| 79 | preg_replace('/-.*$/', '', $item['set_num']), |
| 80 | $item['name'], |
| 81 | $item['num_parts'], |
| 82 | $item['set_img_url'] ?? '', |
| 83 | $item['year'] |
| 84 | ), |
| 85 | $results |
| 86 | ) |
| 87 | ); |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * @param string $search |
| 92 | * @return PartCollection|null |
| 93 | */ |
| 94 | private function fetchPartsFromExternalApi(string $search): ?PartCollection |
| 95 | { |
| 96 | $results = $this->fetchFromExternalApi(sprintf('parts/?search=%s', $search)); |
| 97 | if ($results === null) { |
| 98 | return null; |
| 99 | } |
| 100 | |
| 101 | return new PartCollection( |
| 102 | array_map( |
| 103 | fn ($item) => new ExternalPart( |
| 104 | $item['part_num'], |
| 105 | isset($item['external_ids']['LEGO']) ? $item['external_ids']['LEGO'][0] : '', |
| 106 | $item['name'], |
| 107 | $item['part_img_url'] ?? '' |
| 108 | ), |
| 109 | $results |
| 110 | ) |
| 111 | ); |
| 112 | } |
| 113 | |
| 114 | /** |
| 115 | * @param string $partExternalId |
| 116 | * @return ExternalElementCollection|null |
| 117 | */ |
| 118 | private function fetchPartElementsFromExternalApi(string $partExternalId): ?ExternalElementCollection |
| 119 | { |
| 120 | $results = $this->fetchFromExternalApi(sprintf('parts/%s/colors/', $partExternalId)); |
| 121 | if ($results === null) { |
| 122 | return null; |
| 123 | } |
| 124 | |
| 125 | return new ExternalElementCollection( |
| 126 | array_map( |
| 127 | fn ($item) => new ExternalElement( |
| 128 | $item['elements'][0], |
| 129 | $item['elements'][0], |
| 130 | $partExternalId, |
| 131 | $item['part_img_url'] ?? '', |
| 132 | $item['color_id'], |
| 133 | $item['color_name'] |
| 134 | ), |
| 135 | $results |
| 136 | ) |
| 137 | ); |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * @param string $setExternalId |
| 142 | * @return ExternalSetElementCollection|null |
| 143 | */ |
| 144 | private function fetchSetElementsFromExternalApi(string $setExternalId): ?ExternalSetElementCollection |
| 145 | { |
| 146 | $results = $this->fetchFromExternalApi(sprintf('sets/%s/parts/?inc_part_details=1', $setExternalId)); |
| 147 | if ($results === null) { |
| 148 | return null; |
| 149 | } |
| 150 | |
| 151 | return new ExternalSetElementCollection( |
| 152 | array_map( |
| 153 | fn ($item) => new ExternalSetElement( |
| 154 | $item['element_id'], |
| 155 | $setExternalId, |
| 156 | $item['part']['part_num'], |
| 157 | $item['quantity'] |
| 158 | ), |
| 159 | array_filter( |
| 160 | $results, |
| 161 | fn ($item) => $item['is_spare'] === false |
| 162 | ) |
| 163 | ) |
| 164 | ); |
| 165 | } |
| 166 | |
| 167 | #[Override] |
| 168 | public function findSets(string $search): ?SetCollection |
| 169 | { |
| 170 | return $this->cacheManager->getSets($search, fn ($s) => $this->fetchSetsFromExternalApi($s)); |
| 171 | } |
| 172 | |
| 173 | #[Override] |
| 174 | public function findParts(string $search): ?PartCollection |
| 175 | { |
| 176 | return $this->cacheManager->getParts($search, fn ($s) => $this->fetchPartsFromExternalApi($s)); |
| 177 | } |
| 178 | |
| 179 | #[Override] |
| 180 | public function getSetParts(string $setExternalId): ?ExternalSetElementCollection |
| 181 | { |
| 182 | return new ExternalSetElementCollection([]); |
| 183 | } |
| 184 | |
| 185 | #[Override] |
| 186 | public function getPartElements(string $partExternalId): ?ExternalElementCollection |
| 187 | { |
| 188 | return $this->cacheManager->getPartElements($partExternalId, fn ($s) => $this->fetchPartElementsFromExternalApi($partExternalId)); |
| 189 | } |
| 190 | |
| 191 | #[Override] |
| 192 | public function getSetElements(string $setExternalId): ?ExternalSetElementCollection |
| 193 | { |
| 194 | return $this->cacheManager->getSetElements($setExternalId, fn ($s) => $this->fetchSetElementsFromExternalApi($setExternalId)); |
| 195 | } |