Skip to content

Commit 99b3f73

Browse files
authored
When failing to find products by SKU, Meta will try to find Products by Retailer ID (#550)
* When failing to find products by SKU, Meta will try to find Products by Retailer ID * Adding helpful comment * Class instance also updates when identifier is incorrect
1 parent a1412c8 commit 99b3f73

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

app/code/Meta/BusinessExtension/Model/System/Config.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use Magento\Store\Model\ScopeInterface;
3131
use Magento\Store\Model\StoreManagerInterface;
3232
use Meta\BusinessExtension\Model\ResourceModel\FacebookInstalledFeature;
33+
use Meta\Catalog\Model\Config\Source\Product\Identifier as IdentifierConfig;
3334

3435
/**
3536
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
@@ -182,7 +183,8 @@ public function __construct(
182183
CacheInterface $cache,
183184
ComposerInformation $composerInformation,
184185
FacebookInstalledFeature $fbeInstalledFeatureResource
185-
) {
186+
)
187+
{
186188
$this->storeManager = $storeManager;
187189
$this->scopeConfig = $scopeConfig;
188190
$this->resourceConfig = $resourceConfig;
@@ -906,6 +908,20 @@ public function getProductIdentifierAttr($scopeId = null, $scope = null)
906908
return $this->getConfig(self::XML_PATH_FACEBOOK_PRODUCT_IDENTIFIER, $scopeId, $scope);
907909
}
908910

911+
/**
912+
* Set product identifier attr
913+
*
914+
* @param string $attr
915+
* @return void
916+
*/
917+
public function setProductIdentifierAttr(string $attr)
918+
{
919+
if ($attr !== IdentifierConfig::PRODUCT_IDENTIFIER_ID && $attr !== IdentifierConfig::PRODUCT_IDENTIFIER_SKU) {
920+
throw new \InvalidArgumentException('Invalid product identifier attribute');
921+
}
922+
$this->saveConfig(self::XML_PATH_FACEBOOK_PRODUCT_IDENTIFIER, $attr);
923+
}
924+
909925
/**
910926
* Is all categories sync enabled or not
911927
*

app/code/Meta/Catalog/Helper/Product/Identifier.php

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,26 @@ class Identifier
3232
/**
3333
* @var ProductRepository
3434
*/
35-
private $productRepository;
35+
private ProductRepository $productRepository;
3636

3737
/**
3838
* @var string
3939
*/
4040
private $identifierAttr;
4141

42+
/**
43+
* @var SystemConfig
44+
*/
45+
private $systemConfig;
46+
4247
/**
4348
* @param SystemConfig $systemConfig
4449
* @param ProductRepository $productRepository
4550
*/
4651
public function __construct(SystemConfig $systemConfig, ProductRepository $productRepository)
4752
{
4853
$this->identifierAttr = $systemConfig->getProductIdentifierAttr();
54+
$this->systemConfig = $systemConfig;
4955
$this->productRepository = $productRepository;
5056
}
5157

@@ -128,20 +134,56 @@ public function getProductIDOtherThanRetailerId(ProductInterface $product)
128134
* @throws LocalizedException
129135
*/
130136
public function getProductByFacebookRetailerId($retailerId)
137+
{
138+
// Sometimes (without realizing), seller catalogs will be set up so that the Retailer ID they pass to Meta is
139+
// the entity ID of their magento product, not the SKU. There are legitimate reasons for sellers to do this,
140+
// but if they don't update their extension settings, calls to fetch magento products will fail.
141+
// This logic catches the product load failure, and makes an attempt to load by the inverted identifier instead
142+
// (Sku -> Entity Id, Entity Id -> Sku). If the config was misset, it will gracefully flip to the correct value.
143+
$product = $this->fetchProduct($retailerId, $this->identifierAttr);
144+
145+
if (!$product) {
146+
// Switch identifier attribute
147+
$newIdentifierAttr = $this->identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_SKU
148+
? IdentifierConfig::PRODUCT_IDENTIFIER_ID
149+
: IdentifierConfig::PRODUCT_IDENTIFIER_SKU;
150+
151+
$product = $this->fetchProduct($retailerId, $newIdentifierAttr);
152+
153+
if ($product) {
154+
$this->systemConfig->setProductIdentifierAttr($newIdentifierAttr);
155+
$this->identifierAttr = $newIdentifierAttr;
156+
} else {
157+
throw new LocalizedException(__(sprintf(
158+
'Product with %s %s does not exist in Magento catalog',
159+
strtoupper($this->identifierAttr),
160+
$retailerId
161+
)));
162+
}
163+
}
164+
165+
return $product;
166+
}
167+
168+
/**
169+
* Fetch product by retailer id and identifier attribute
170+
*
171+
* @param string|int $retailerId
172+
* @param string $identifierAttr
173+
* @return ProductInterface|bool
174+
*/
175+
private function fetchProduct($retailerId, string $identifierAttr)
131176
{
132177
try {
133-
if ($this->identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_SKU) {
178+
if ($identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_SKU) {
134179
return $this->productRepository->get($retailerId);
135-
} elseif ($this->identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_ID) {
180+
} elseif ($identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_ID) {
136181
return $this->productRepository->getById($retailerId);
137182
}
138-
throw new LocalizedException(__('Invalid FB product identifier configuration'));
139183
} catch (NoSuchEntityException $e) {
140-
throw new LocalizedException(__(sprintf(
141-
'Product with %s %s does not exist in Magento catalog',
142-
strtoupper($this->identifierAttr),
143-
$retailerId
144-
)));
184+
// Product not found
185+
return false;
145186
}
187+
return false;
146188
}
147189
}

0 commit comments

Comments
 (0)