diff --git a/plugins/OpenBeautyFactsBarcodeLookupPlugin.php b/plugins/OpenBeautyFactsBarcodeLookupPlugin.php new file mode 100644 index 00000000..e3c86dd6 --- /dev/null +++ b/plugins/OpenBeautyFactsBarcodeLookupPlugin.php @@ -0,0 +1,67 @@ + false]); + $response = $webClient->request('GET', 'https://world.openbeautyfacts.org/api/v2/product/' . preg_replace('/[^0-9]/', '', $barcode) . '?fields=product_name,image_url,' . $productNameFieldLocalized, ['headers' => ['User-Agent' => 'GrocyOpenFoodFactsBarcodeLookupPlugin/1.0 (https://grocy.info)']]); + $statusCode = $response->getStatusCode(); + + // Guzzle throws exceptions for connection errors, so nothing to do on that here + + $data = json_decode($response->getBody()); + if ($statusCode == 404 || $data->status != 1) { + // Nothing found for the given barcode + return null; + } else { + $imageUrl = ''; + if (isset($data->product->image_url) && !empty($data->product->image_url)) { + $imageUrl = $data->product->image_url; + } + + // Take the preset user setting or otherwise simply the first existing location + $locationId = $this->Locations[0]->id; + if ($this->UserSettings['product_presets_location_id'] != -1) { + $locationId = $this->UserSettings['product_presets_location_id']; + } + + // Take the preset user setting or otherwise simply the first existing quantity unit + $quId = $this->QuantityUnits[0]->id; + if ($this->UserSettings['product_presets_qu_id'] != -1) { + $quId = $this->UserSettings['product_presets_qu_id']; + } + + // Use the localized product name, if provided + $name = $data->product->product_name; + if (isset($data->product->$productNameFieldLocalized) && !empty($data->product->$productNameFieldLocalized)) { + $name = $data->product->$productNameFieldLocalized; + } + + // Remove non-ASCII characters in product name (whyever a product name should have them at all) + $name = preg_replace('/[^a-zA-Z0-9äöüÄÖÜß ]/', '', $name); + + return [ + 'name' => $name, + 'location_id' => $locationId, + 'qu_id_purchase' => $quId, + 'qu_id_stock' => $quId, + '__qu_factor_purchase_to_stock' => 1, + '__barcode' => $barcode, + '__image_url' => $imageUrl + ]; + } + } +} diff --git a/plugins/OpenFoodAndBeautyFactsBarcodeLookupPlugin.php b/plugins/OpenFoodAndBeautyFactsBarcodeLookupPlugin.php new file mode 100644 index 00000000..3c2bda0f --- /dev/null +++ b/plugins/OpenFoodAndBeautyFactsBarcodeLookupPlugin.php @@ -0,0 +1,100 @@ +request( + 'GET', + $apiUrl . preg_replace('/[^0-9]/', '', $barcode) . '?fields=product_name,image_url,' . $productNameFieldLocalized, + ['headers' => ['User-Agent' => 'GrocyOpenFoodFactsBarcodeLookupPlugin/1.0 (https://grocy.info)']] + ); + + // Parse the response + $statusCode = $response->getStatusCode(); + $data = json_decode($response->getBody()); + + // Check if the product was not found + if ($statusCode == 404 || $data->status != 1) + { + return null; + } + + // Return the response data + return $data; + } + + $productNameFieldLocalized = 'product_name_' . substr(GROCY_LOCALE, 0, 2); + $webClient = new Client(['http_errors' => false]); + + // First lookup on Open Food Facts + $data = performLookup('https://world.openfoodfacts.org/api/v2/product/', $barcode, $productNameFieldLocalized, $webClient); + + // If the first lookup fails, try the Open Beauty Facts + if ($data === null) + { + $data = performLookup('https://world.openbeautyfacts.org/api/v2/product/', $barcode, $productNameFieldLocalized, $webClient); + + // If the second lookup fails too, return null + if ($data === null) + { + return null; + } + } + + // Initialize an empty image URL + $imageUrl = ''; + if (isset($data->product->image_url) && !empty($data->product->image_url)) + { + $imageUrl = $data->product->image_url; + } + + // Retrieve the location ID from user settings or set to the first location in the list + $locationId = $this->Locations[0]->id; + if ($this->UserSettings['product_presets_location_id'] != -1) + { + $locationId = $this->UserSettings['product_presets_location_id']; + } + + // Retrieve the quantity unit ID from user settings or set to the first quantity unit in the list + $quId = $this->QuantityUnits[0]->id; + if ($this->UserSettings['product_presets_qu_id'] != -1) + { + $quId = $this->UserSettings['product_presets_qu_id']; + } + + // Use the localized product name if provided + $name = $data->product->product_name; + if (isset($data->product->$productNameFieldLocalized) && !empty($data->product->$productNameFieldLocalized)) + { + $name = $data->product->$productNameFieldLocalized; + } + + // Remove non-ASCII characters from the product name + $name = preg_replace('/[^a-zA-Z0-9äöüÄÖÜß ]/', '', $name); + + // Return the structured product data + return [ + 'name' => $name, + 'location_id' => $locationId, + 'qu_id_purchase' => $quId, + 'qu_id_stock' => $quId, + '__qu_factor_purchase_to_stock' => 1, + '__barcode' => $barcode, + '__image_url' => $imageUrl + ]; + } +} \ No newline at end of file