Skip to content

Commit d3b2257

Browse files
Danixujbtronics
andauthored
Modified the DigiKey Provider to works with the V4 API (#875)
* Modified the DigiKey Provider to works with the V4 API * Correclty apply the MarketPlaceFilter option to digikey v4 API * Show the packe type (Tape&Reel, Box, etc.) as footprint in digikey provider search --------- Co-authored-by: Jan Böhmer <[email protected]>
1 parent 7275db2 commit d3b2257

File tree

1 file changed

+73
-44
lines changed

1 file changed

+73
-44
lines changed

src/Services/InfoProviderSystem/Providers/DigikeyProvider.php

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,15 @@ public function searchByKeyword(string $keyword): array
108108
{
109109
$request = [
110110
'Keywords' => $keyword,
111-
'RecordCount' => 50,
112-
'RecordStartPosition' => 0,
113-
'ExcludeMarketPlaceProducts' => 'true',
111+
'Limit' => 50,
112+
'Offset' => 0,
113+
'FilterOptionsRequest' => [
114+
'MarketPlaceFilter' => 'ExcludeMarketPlace',
115+
],
114116
];
115117

116-
$response = $this->digikeyClient->request('POST', '/Search/v3/Products/Keyword', [
118+
//$response = $this->digikeyClient->request('POST', '/Search/v3/Products/Keyword', [
119+
$response = $this->digikeyClient->request('POST', '/products/v4/search/keyword', [
117120
'json' => $request,
118121
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
119122
]);
@@ -124,51 +127,64 @@ public function searchByKeyword(string $keyword): array
124127
$result = [];
125128
$products = $response_array['Products'];
126129
foreach ($products as $product) {
127-
$result[] = new SearchResultDTO(
128-
provider_key: $this->getProviderKey(),
129-
provider_id: $product['DigiKeyPartNumber'],
130-
name: $product['ManufacturerPartNumber'],
131-
description: $product['DetailedDescription'] ?? $product['ProductDescription'],
132-
category: $this->getCategoryString($product),
133-
manufacturer: $product['Manufacturer']['Value'] ?? null,
134-
mpn: $product['ManufacturerPartNumber'],
135-
preview_image_url: $product['PrimaryPhoto'] ?? null,
136-
manufacturing_status: $this->productStatusToManufacturingStatus($product['ProductStatus']),
137-
provider_url: $product['ProductUrl'],
138-
);
130+
foreach ($product['ProductVariations'] as $variation) {
131+
$result[] = new SearchResultDTO(
132+
provider_key: $this->getProviderKey(),
133+
provider_id: $variation['DigiKeyProductNumber'],
134+
name: $product['ManufacturerProductNumber'],
135+
description: $product['Description']['DetailedDescription'] ?? $product['Description']['ProductDescription'],
136+
category: $this->getCategoryString($product),
137+
manufacturer: $product['Manufacturer']['Name'] ?? null,
138+
mpn: $product['ManufacturerProductNumber'],
139+
preview_image_url: $product['PhotoUrl'] ?? null,
140+
manufacturing_status: $this->productStatusToManufacturingStatus($product['ProductStatus']['Id']),
141+
provider_url: $product['ProductUrl'],
142+
footprint: $variation['PackageType']['Name'], //Use the footprint field, to show the user the package type (Tape & Reel, etc., as digikey has many different package types)
143+
);
144+
}
139145
}
140146

141147
return $result;
142148
}
143149

144150
public function getDetails(string $id): PartDetailDTO
145151
{
146-
$response = $this->digikeyClient->request('GET', '/Search/v3/Products/' . urlencode($id), [
152+
$response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/productdetails', [
147153
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
148154
]);
149155

150-
$product = $response->toArray();
156+
$response_array = $response->toArray();
157+
$product = $response_array['Product'];
151158

152159
$footprint = null;
153160
$parameters = $this->parametersToDTOs($product['Parameters'] ?? [], $footprint);
154-
$media = $this->mediaToDTOs($product['MediaLinks']);
161+
$media = $this->mediaToDTOs($id);
162+
163+
// Get the price_breaks of the selected variation
164+
$price_breaks = [];
165+
foreach ($product['ProductVariations'] as $variation) {
166+
if ($variation['DigiKeyProductNumber'] == $id) {
167+
$price_breaks = $variation['StandardPricing'] ?? [];
168+
break;
169+
}
170+
}
155171

156172
return new PartDetailDTO(
157173
provider_key: $this->getProviderKey(),
158-
provider_id: $product['DigiKeyPartNumber'],
159-
name: $product['ManufacturerPartNumber'],
160-
description: $product['DetailedDescription'] ?? $product['ProductDescription'],
174+
provider_id: $id,
175+
name: $product['ManufacturerProductNumber'],
176+
description: $product['Description']['DetailedDescription'] ?? $product['Description']['ProductDescription'],
161177
category: $this->getCategoryString($product),
162-
manufacturer: $product['Manufacturer']['Value'] ?? null,
163-
mpn: $product['ManufacturerPartNumber'],
164-
preview_image_url: $product['PrimaryPhoto'] ?? null,
165-
manufacturing_status: $this->productStatusToManufacturingStatus($product['ProductStatus']),
178+
manufacturer: $product['Manufacturer']['Name'] ?? null,
179+
mpn: $product['ManufacturerProductNumber'],
180+
preview_image_url: $product['PhotoUrl'] ?? null,
181+
manufacturing_status: $this->productStatusToManufacturingStatus($product['ProductStatus']['Id']),
166182
provider_url: $product['ProductUrl'],
167183
footprint: $footprint,
168184
datasheets: $media['datasheets'],
169185
images: $media['images'],
170186
parameters: $parameters,
171-
vendor_infos: $this->pricingToDTOs($product['StandardPricing'] ?? [], $product['DigiKeyPartNumber'], $product['ProductUrl']),
187+
vendor_infos: $this->pricingToDTOs($price_breaks, $id, $product['ProductUrl']),
172188
);
173189
}
174190

@@ -177,28 +193,35 @@ public function getDetails(string $id): PartDetailDTO
177193
* @param string|null $dk_status
178194
* @return ManufacturingStatus|null
179195
*/
180-
private function productStatusToManufacturingStatus(?string $dk_status): ?ManufacturingStatus
196+
private function productStatusToManufacturingStatus(?int $dk_status): ?ManufacturingStatus
181197
{
198+
// The V4 can use strings to get the status, but if you have changed the PROVIDER_DIGIKEY_LANGUAGE it will not match.
199+
// Using the Id instead which should be fixed.
200+
//
201+
// The API is not well documented and the ID are not there yet, so were extracted using "trial and error".
202+
// The 'Preliminary' id was not found in several categories so I was unable to extract it. Disabled for now.
182203
return match ($dk_status) {
183204
null => null,
184-
'Active' => ManufacturingStatus::ACTIVE,
185-
'Obsolete' => ManufacturingStatus::DISCONTINUED,
186-
'Discontinued at Digi-Key', 'Last Time Buy' => ManufacturingStatus::EOL,
187-
'Not For New Designs' => ManufacturingStatus::NRFND,
188-
'Preliminary' => ManufacturingStatus::ANNOUNCED,
205+
0 => ManufacturingStatus::ACTIVE,
206+
1 => ManufacturingStatus::DISCONTINUED,
207+
2, 4 => ManufacturingStatus::EOL,
208+
7 => ManufacturingStatus::NRFND,
209+
//'Preliminary' => ManufacturingStatus::ANNOUNCED,
189210
default => ManufacturingStatus::NOT_SET,
190211
};
191212
}
192213

193214
private function getCategoryString(array $product): string
194215
{
195-
$category = $product['Category']['Value'];
196-
$sub_category = $product['Family']['Value'];
216+
$category = $product['Category']['Name'];
217+
$sub_category = current($product['Category']['ChildCategories']);
197218

198-
//Replace the ' - ' category separator with ' -> '
199-
$sub_category = str_replace(' - ', ' -> ', $sub_category);
219+
if ($sub_category) {
220+
//Replace the ' - ' category separator with ' -> '
221+
$category = $category . ' -> ' . str_replace(' - ', ' -> ', $sub_category["Name"]);
222+
}
200223

201-
return $category . ' -> ' . $sub_category;
224+
return $category;
202225
}
203226

204227
/**
@@ -215,18 +238,18 @@ private function parametersToDTOs(array $parameters, string|null &$footprint_nam
215238

216239
foreach ($parameters as $parameter) {
217240
if ($parameter['ParameterId'] === 1291) { //Meaning "Manufacturer given footprint"
218-
$footprint_name = $parameter['Value'];
241+
$footprint_name = $parameter['ValueText'];
219242
}
220243

221-
if (in_array(trim((string) $parameter['Value']), ['', '-'], true)) {
244+
if (in_array(trim((string) $parameter['ValueText']), ['', '-'], true)) {
222245
continue;
223246
}
224247

225248
//If the parameter was marked as text only, then we do not try to parse it as a numerical value
226249
if (in_array($parameter['ParameterId'], self::TEXT_ONLY_PARAMETERS, true)) {
227-
$results[] = new ParameterDTO(name: $parameter['Parameter'], value_text: $parameter['Value']);
250+
$results[] = new ParameterDTO(name: $parameter['ParameterText'], value_text: $parameter['ValueText']);
228251
} else { //Otherwise try to parse it as a numerical value
229-
$results[] = ParameterDTO::parseValueIncludingUnit($parameter['Parameter'], $parameter['Value']);
252+
$results[] = ParameterDTO::parseValueIncludingUnit($parameter['ParameterText'], $parameter['ValueText']);
230253
}
231254
}
232255

@@ -258,12 +281,18 @@ private function pricingToDTOs(array $price_breaks, string $order_number, string
258281
* @return FileDTO[][]
259282
* @phpstan-return array<string, FileDTO[]>
260283
*/
261-
private function mediaToDTOs(array $media_links): array
284+
private function mediaToDTOs(string $id): array
262285
{
263286
$datasheets = [];
264287
$images = [];
265288

266-
foreach ($media_links as $media_link) {
289+
$response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/media', [
290+
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
291+
]);
292+
293+
$media_array = $response->toArray();
294+
295+
foreach ($media_array['MediaLinks'] as $media_link) {
267296
$file = new FileDTO(url: $media_link['Url'], name: $media_link['Title']);
268297

269298
switch ($media_link['MediaType']) {

0 commit comments

Comments
 (0)