@@ -32,20 +32,26 @@ class Identifier
32
32
/**
33
33
* @var ProductRepository
34
34
*/
35
- private $ productRepository ;
35
+ private ProductRepository $ productRepository ;
36
36
37
37
/**
38
38
* @var string
39
39
*/
40
40
private $ identifierAttr ;
41
41
42
+ /**
43
+ * @var SystemConfig
44
+ */
45
+ private $ systemConfig ;
46
+
42
47
/**
43
48
* @param SystemConfig $systemConfig
44
49
* @param ProductRepository $productRepository
45
50
*/
46
51
public function __construct (SystemConfig $ systemConfig , ProductRepository $ productRepository )
47
52
{
48
53
$ this ->identifierAttr = $ systemConfig ->getProductIdentifierAttr ();
54
+ $ this ->systemConfig = $ systemConfig ;
49
55
$ this ->productRepository = $ productRepository ;
50
56
}
51
57
@@ -128,20 +134,56 @@ public function getProductIDOtherThanRetailerId(ProductInterface $product)
128
134
* @throws LocalizedException
129
135
*/
130
136
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 )
131
176
{
132
177
try {
133
- if ($ this -> identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_SKU ) {
178
+ if ($ identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_SKU ) {
134
179
return $ this ->productRepository ->get ($ retailerId );
135
- } elseif ($ this -> identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_ID ) {
180
+ } elseif ($ identifierAttr === IdentifierConfig::PRODUCT_IDENTIFIER_ID ) {
136
181
return $ this ->productRepository ->getById ($ retailerId );
137
182
}
138
- throw new LocalizedException (__ ('Invalid FB product identifier configuration ' ));
139
183
} 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 ;
145
186
}
187
+ return false ;
146
188
}
147
189
}
0 commit comments