Remove OpenFoodFact client
This commit is contained in:
parent
862b6a4741
commit
384328739e
27 changed files with 0 additions and 1682 deletions
18
openfoodfacts-php-0.2.3/.gitignore
vendored
18
openfoodfacts-php-0.2.3/.gitignore
vendored
|
@ -1,18 +0,0 @@
|
||||||
# Created by .ignore support plugin (hsz.mobi)
|
|
||||||
### Example user template template
|
|
||||||
### Example user template
|
|
||||||
/build/
|
|
||||||
|
|
||||||
# IntelliJ project files
|
|
||||||
.idea
|
|
||||||
*.iml
|
|
||||||
out
|
|
||||||
gen### Composer template
|
|
||||||
composer.phar
|
|
||||||
/vendor/
|
|
||||||
/log/
|
|
||||||
/tests/tmp/*
|
|
||||||
|
|
||||||
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
|
|
||||||
# You may choose to ignore a library lock file https://getcomposer.org/doc/02-libraries.md#lock-file
|
|
||||||
composer.lock
|
|
|
@ -1,5 +0,0 @@
|
||||||
language: php
|
|
||||||
php:
|
|
||||||
- '7.2'
|
|
||||||
before_script: composer install --dev
|
|
||||||
script: vendor/bin/phpunit
|
|
|
@ -1,3 +0,0 @@
|
||||||
## 0.0.1 (June 19, 2016) ##
|
|
||||||
|
|
||||||
* Upload project struct
|
|
|
@ -1,7 +0,0 @@
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Fork it ( https://github.com/openfoodfacts/openfoodfacts-php/fork )
|
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
||||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
||||||
4. Push to the branch (`git push origin my-new-feature`)
|
|
||||||
5. Create a new Pull Request
|
|
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2020 Open Food Facts
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,78 +0,0 @@
|
||||||
# openfoodfacts-php
|
|
||||||

|
|
||||||
|
|
||||||
PHP API Wrapper for [Open Food Facts](https://openfoodfacts.org/), the open database about food.
|
|
||||||
|
|
||||||
[](http://opensource.box.com/badges)
|
|
||||||
[](https://travis-ci.org/openfoodfacts/openfoodfacts-php)
|
|
||||||
[](https://isitmaintained.com/project/openfoodfacts/openfoodfacts-php "Average time to resolve an issue")
|
|
||||||
[](https://isitmaintained.com/project/openfoodfacts/openfoodfacts-php "Percentage of issues still open")
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
With Composer:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
composer require openfoodfacts/openfoodfacts-php
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
This is the most basic way of creating the API:
|
|
||||||
```php
|
|
||||||
$api = new OpenFoodFacts\Api('food','fr');
|
|
||||||
$product = $api->getProduct('3057640385148');
|
|
||||||
```
|
|
||||||
In the example above you access the "food" database, limited to the French language/country scope.
|
|
||||||
The first parameter is either
|
|
||||||
- "food"
|
|
||||||
- "beauty" or
|
|
||||||
- "pet"
|
|
||||||
|
|
||||||
to decide which product database you want to use.
|
|
||||||
|
|
||||||
The second parameter decides the language/country scope of the chosen database: f.e. "world" or "de" or "fr".
|
|
||||||
|
|
||||||
For more details on this topic: see the [API Documentation](https://en.wiki.openfoodfacts.org/API/Read#Countries_and_Language_of_the_Response)
|
|
||||||
|
|
||||||
These are all the parameters you really need for basic usage.
|
|
||||||
|
|
||||||
As return types for ```$api->getProduct``` you get an ```Document::class``` Object.
|
|
||||||
This may also be an Object of Type ```FoodProduct::class```,```PetProduct::class```, ```BeautyProduct::class``` depending on which API you are creating.
|
|
||||||
These objects inherit from the more generic ```Document::class```
|
|
||||||
|
|
||||||
In the example above, we use the 'food' API and there will get a ```FoodProduct::class```
|
|
||||||
|
|
||||||
For getting a first overview the ```Document::class``` has a function to return an array representation(sorted) for a first start.
|
|
||||||
```php
|
|
||||||
$product = $api->getProduct('3057640385148');
|
|
||||||
$productDataAsArray = $product->getData();
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### Optional Parameters
|
|
||||||
The other parameters are optional and for a more sophisticated use of the api (from a software development point of view):
|
|
||||||
|
|
||||||
An example in code is found here: [cached_example.php](examples/01-basic_api_usage/cached_example.php)
|
|
||||||
|
|
||||||
LoggerInterface: A logger which decieds where to log errors to (file, console , etc)
|
|
||||||
|
|
||||||
see: [PSR-3 Loggerinterface](https://www.php-fig.org/psr/psr-3/)
|
|
||||||
|
|
||||||
ClientInterface: The HTTP Client - to adjust the connection configs to your needs and more
|
|
||||||
|
|
||||||
see: [Guzzle HTTP Client](https://packagist.org/packages/guzzlehttp/guzzle)
|
|
||||||
|
|
||||||
CacheInterface: To temporarily save the results of API request to improve the performance and to reduce the load on the API- Server
|
|
||||||
|
|
||||||
see: [PSR-16 Simple Cache](https://www.php-fig.org/psr/psr-16/)
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
|
|
||||||
### Contributing
|
|
||||||
|
|
||||||
1. Fork it ( https://github.com/openfoodfacts/openfoodfacts-php/fork )
|
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
||||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
||||||
4. Push to the branch (`git push origin my-new-feature`)
|
|
||||||
5. Create a new Pull Request
|
|
|
@ -1,41 +0,0 @@
|
||||||
{
|
|
||||||
"name": "openfoodfacts/openfoodfacts-php",
|
|
||||||
"description": "Open Food Facts API Wrapper, the open database about food.",
|
|
||||||
"homepage": "https://world.openfoodfacts.org/",
|
|
||||||
"type": "library",
|
|
||||||
"minimum-stability": "stable",
|
|
||||||
"license": "MIT",
|
|
||||||
"support": {
|
|
||||||
"email": "rmorenp@rampamster.org",
|
|
||||||
"issues": "https://github.com/openfoodfacts/openfoodfacts-php/issues",
|
|
||||||
"chat": "https://slack.openfoodfacts.org/",
|
|
||||||
"source": "https://github.com/openfoodfacts/openfoodfacts-php"
|
|
||||||
},
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Roberto Moreno",
|
|
||||||
"email": "rmorenp@rampmaster.org",
|
|
||||||
"homepage": "http://www.rampmaster.org",
|
|
||||||
"role": "Wrapper Developer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": ">=7.1",
|
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
|
||||||
"psr/log": "^1.0",
|
|
||||||
"psr/simple-cache": "^1.0",
|
|
||||||
"ext-json": "*",
|
|
||||||
"ext-curl": "*"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"OpenFoodFacts\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^7.0",
|
|
||||||
"symfony/cache": "^4.3",
|
|
||||||
"monolog/monolog": "^1.23",
|
|
||||||
"ext-gd": ">=7.2"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
TODO
|
|
|
@ -1,13 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>OFF</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<form action="./request.php" method="get">
|
|
||||||
<input type="text" class="form-control" placeholder="barcode" name="ean13">
|
|
||||||
<input type="submit" name="Ok" value="Find this Barcode !">
|
|
||||||
</form>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,31 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
// Default parameters by case
|
|
||||||
$country = 'fr'; // Country by using OFF
|
|
||||||
$productSlug = 'produit'; // Product by language (producto in spanish or product in english)
|
|
||||||
|
|
||||||
// Format URL
|
|
||||||
$url = 'https://{country}.openfoodfacts.org/api/v0/{product}/{scan}.json';
|
|
||||||
|
|
||||||
// Where we will set the value of the scan
|
|
||||||
$barcode = (int) $_GET['ean13'];
|
|
||||||
|
|
||||||
$url = str_replace(['{country}','{product}','{scan}'],[$country,$productSlug,$barcode],$url);
|
|
||||||
|
|
||||||
// Connection to the API (french version here)
|
|
||||||
$result = file_get_contents($url);
|
|
||||||
|
|
||||||
// Decoding the JSON into an usable array (the value "true" confirms that the return is only an array)
|
|
||||||
$json = json_decode($result, true);
|
|
||||||
|
|
||||||
// Get the datas we want
|
|
||||||
$productName = $json['product']['product_name'];
|
|
||||||
$brand = $json['product']['brands'];
|
|
||||||
$image = $json['product']['image_small_url'];
|
|
||||||
|
|
||||||
$viewData = file_get_contents('response.html');
|
|
||||||
|
|
||||||
echo str_replace(
|
|
||||||
['{productName}','{brand}','{image}','{json}'],
|
|
||||||
[$productName,$brand,$image,print_r($json,true)],
|
|
||||||
$viewData);
|
|
|
@ -1,28 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>OFF</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>Example Output</h2>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Product Name</td>
|
|
||||||
<td>{productName}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Brand</td>
|
|
||||||
<td>{brand}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Image</td>
|
|
||||||
<td><img src="{image}"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h2>Response Struct (Array Format)</h2>
|
|
||||||
<pre>
|
|
||||||
{json}
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,13 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
|
||||||
use Symfony\Component\Cache\Psr16Cache;
|
|
||||||
|
|
||||||
include '../../vendor/autoload.php';
|
|
||||||
$logger = new \Monolog\Logger('test');
|
|
||||||
$httpClient = new \GuzzleHttp\Client();
|
|
||||||
// the PSR-6 cache object that you want to use (you might also use a PSR-16 Interface Object directly)
|
|
||||||
$psr6Cache = new FilesystemAdapter();
|
|
||||||
$psr16Cache = new Psr16Cache($psr6Cache);
|
|
||||||
$api = new \OpenFoodFacts\Api('food', 'world', $logger, $httpClient, $psr16Cache);
|
|
||||||
$product = $api->getProduct(rand(1, 50));
|
|
|
@ -1,36 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<phpunit
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
|
|
||||||
backupGlobals="false"
|
|
||||||
colors="true"
|
|
||||||
bootstrap="vendor/autoload.php"
|
|
||||||
>
|
|
||||||
|
|
||||||
<php>
|
|
||||||
<ini name="error_reporting" value="-1" />
|
|
||||||
<server name="KERNEL_CLASS" value="AppKernel" />
|
|
||||||
</php>
|
|
||||||
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="AllTests">
|
|
||||||
<directory>tests</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
|
|
||||||
<filter>
|
|
||||||
<whitelist>
|
|
||||||
<directory>src</directory>
|
|
||||||
<!--<exclude>
|
|
||||||
<directory>src/*Bundle/Resources</directory>
|
|
||||||
</exclude>-->
|
|
||||||
</whitelist>
|
|
||||||
</filter>
|
|
||||||
|
|
||||||
<logging>
|
|
||||||
<log type="coverage-html" target="./build/coverrage" />
|
|
||||||
<log type="coverage-clover" target="./build/logs/clover.xml" />
|
|
||||||
<log type="junit" target="./build/logs/junit.xml" />
|
|
||||||
<log type="testdox-html" target="./build/logstestdox.html" />
|
|
||||||
</logging>
|
|
||||||
</phpunit>
|
|
|
@ -1,536 +0,0 @@
|
||||||
<?php /** @noinspection ALL */
|
|
||||||
|
|
||||||
namespace OpenFoodFacts;
|
|
||||||
|
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\ClientInterface;
|
|
||||||
use GuzzleHttp\Exception\GuzzleException;
|
|
||||||
use GuzzleHttp\TransferStats;
|
|
||||||
use OpenFoodFacts\Exception\BadRequestException;
|
|
||||||
use OpenFoodFacts\Exception\ProductNotFoundException;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Psr\Log\NullLogger;
|
|
||||||
use Psr\SimpleCache\CacheInterface;
|
|
||||||
use Psr\SimpleCache\InvalidArgumentException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this class provide [...]
|
|
||||||
*
|
|
||||||
* It a fork of the python OpenFoodFact rewrite on PHP 7.2
|
|
||||||
*/
|
|
||||||
class Api
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the httpClient for all http request
|
|
||||||
* @var ClientInterface
|
|
||||||
*/
|
|
||||||
private $httpClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this property store the current base of the url
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $geoUrl = 'https://%s.openfoodfacts.org';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this property store the current API (it could be : food/beauty/pet )
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $currentAPI = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This property store the current location for http call
|
|
||||||
*
|
|
||||||
* This property could be world for all product or you can specify le country code (cc) and
|
|
||||||
* language of the interface (lc). If you want filter on french product you can set fr as country code.
|
|
||||||
* We strongly recommend to use english as language of the interface
|
|
||||||
*
|
|
||||||
* @example fr-en
|
|
||||||
* @link https://en.wiki.openfoodfacts.org/API/Read#Country_code_.28cc.29_and_Language_of_the_interface_.28lc.29
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $geography = 'world';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this property store the auth parameter (username and password)
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $auth = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this property help you to log information
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
private $logger = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this constant defines the environments usable by the API
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private const LIST_API = [
|
|
||||||
'food' => 'https://%s.openfoodfacts.org',
|
|
||||||
'beauty' => 'https://%s.openbeautyfacts.org',
|
|
||||||
'pet' => 'https://%s.openpetfoodfacts.org',
|
|
||||||
'product' => 'https://%s.openproductsfacts.org',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines the facets usable by the API
|
|
||||||
*
|
|
||||||
* This variable is used to create the magic functions like "getIngredients" or "getBrands"
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private const FACETS = [
|
|
||||||
'additives',
|
|
||||||
'allergens',
|
|
||||||
'brands',
|
|
||||||
'categories',
|
|
||||||
'countries',
|
|
||||||
'contributors',
|
|
||||||
'code',
|
|
||||||
'entry_dates',
|
|
||||||
'ingredients',
|
|
||||||
'label',
|
|
||||||
'languages',
|
|
||||||
'nutrition_grade',
|
|
||||||
'packaging',
|
|
||||||
'packaging_codes',
|
|
||||||
'purchase_places',
|
|
||||||
'photographer',
|
|
||||||
'informer',
|
|
||||||
'states',
|
|
||||||
'stores',
|
|
||||||
'traces',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constant defines the extensions authorized for the downloading of the data
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private const FILE_TYPE_MAP = [
|
|
||||||
"mongodb" => "openfoodfacts-mongodbdump.tar.gz",
|
|
||||||
"csv" => "en.openfoodfacts.org.products.csv",
|
|
||||||
"rdf" => "en.openfoodfacts.org.products.rdf"
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the constructor of the function
|
|
||||||
*
|
|
||||||
* @param string $api the environment to search
|
|
||||||
* @param string $geography this parameter represent the the country code and the interface of the language
|
|
||||||
* @param LoggerInterface $logger this parameter define an logger
|
|
||||||
* @param ClientInterface|null $clientInterface
|
|
||||||
* @param CacheInterface|null $cacheInterface
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
string $api = 'food',
|
|
||||||
string $geography = 'world',
|
|
||||||
LoggerInterface $logger = null,
|
|
||||||
ClientInterface $clientInterface = null,
|
|
||||||
CacheInterface $cacheInterface = null
|
|
||||||
)
|
|
||||||
{
|
|
||||||
$this->cache = $cacheInterface;
|
|
||||||
$this->logger = $logger ?? new NullLogger();
|
|
||||||
$this->httpClient = $clientInterface ?? new Client();
|
|
||||||
|
|
||||||
$this->geoUrl = sprintf(self::LIST_API[$api], $geography);
|
|
||||||
$this->geography = $geography;
|
|
||||||
$this->currentAPI = $api;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function allows you to perform tests
|
|
||||||
* The domain is correct and for testing purposes only
|
|
||||||
*/
|
|
||||||
public function activeTestMode() : void
|
|
||||||
{
|
|
||||||
$this->geoUrl = 'https://world.openfoodfacts.net';
|
|
||||||
$this->authentification('off', 'off');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function store the authentication parameter
|
|
||||||
* @param string $username
|
|
||||||
* @param string $password
|
|
||||||
*/
|
|
||||||
public function authentification(string $username, string $password) :void
|
|
||||||
{
|
|
||||||
$this->auth = [
|
|
||||||
'user_id' => $username,
|
|
||||||
'password' => $password
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* It's a magic function, it works only for facets
|
|
||||||
* @param string $name The name of the function
|
|
||||||
* @param void $arguments not use yet (probably needed for ingredients)
|
|
||||||
* @return Collection The list of all documents found
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws BadRequestException
|
|
||||||
* @example getIngredients()
|
|
||||||
*/
|
|
||||||
public function __call(string $name, $arguments) : Collection
|
|
||||||
{
|
|
||||||
//TODO : test with argument for ingredient
|
|
||||||
if (strpos($name, 'get') === 0) {
|
|
||||||
$facet = strtolower(substr($name, 3));
|
|
||||||
//TODO: what about PSR-12, e.g.: getNutritionGrade() ?
|
|
||||||
|
|
||||||
if (!in_array($facet, self::FACETS)) {
|
|
||||||
throw new BadRequestException('Facet "' . $facet . '" not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($facet === "purchase_places") {
|
|
||||||
$facet = "purchase-places";
|
|
||||||
} elseif ($facet === "packaging_codes") {
|
|
||||||
$facet = "packager-codes";
|
|
||||||
} elseif ($facet === "entry_dates") {
|
|
||||||
$facet = "entry-dates";
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = $this->buildUrl(null, $facet, []);
|
|
||||||
$result = $this->fetch($url);
|
|
||||||
if ($facet !== 'ingredients') {
|
|
||||||
$result = [
|
|
||||||
'products' => $result['tags'],
|
|
||||||
'count' => $result['count'],
|
|
||||||
'page' => 1,
|
|
||||||
'skip' => 0,
|
|
||||||
'page_size' => $result['count'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return new Collection($result, $this->currentAPI);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new BadRequestException('Call to undefined method '.__CLASS__.'::'.$name.'()');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function search an Document by barcode
|
|
||||||
* @param string $barcode the barcode [\d]{13}
|
|
||||||
* @return Document A Document if found
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws ProductNotFoundException
|
|
||||||
* @throws BadRequestException
|
|
||||||
*/
|
|
||||||
public function getProduct(string $barcode) : Document
|
|
||||||
{
|
|
||||||
$url = $this->buildUrl('api', 'product', $barcode);
|
|
||||||
|
|
||||||
$rawResult = $this->fetch($url);
|
|
||||||
if ($rawResult['status'] === 0) {
|
|
||||||
//TODO: maybe return null here? (just throw an exception if something really went wrong?
|
|
||||||
throw new ProductNotFoundException("Product not found", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Document::createSpecificDocument($this->currentAPI, $rawResult['product']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function return a Collection of Document search by facets
|
|
||||||
* @param array $query list of facets with value
|
|
||||||
* @param integer $page Number of the page
|
|
||||||
* @return Collection The list of all documents found
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws BadRequestException
|
|
||||||
*/
|
|
||||||
public function getByFacets(array $query = [], int $page = 1) : Collection
|
|
||||||
{
|
|
||||||
if (empty($query)) {
|
|
||||||
return new Collection();
|
|
||||||
}
|
|
||||||
$search = [];
|
|
||||||
ksort($query);
|
|
||||||
foreach ($query as $key => $value) {
|
|
||||||
$search[] = $key;
|
|
||||||
$search[] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = $this->buildUrl(null, $search, $page);
|
|
||||||
$result = $this->fetch($url);
|
|
||||||
return new Collection($result, $this->currentAPI);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function help you to add a new product (or update ??)
|
|
||||||
* @param array $postData The post data
|
|
||||||
* @return bool|string bool if the product has been added or the error message
|
|
||||||
* @throws BadRequestException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function addNewProduct(array $postData)
|
|
||||||
{
|
|
||||||
if (!isset($postData['code']) || !isset($postData['product_name'])) {
|
|
||||||
throw new BadRequestException('code or product_name not found!');
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = $this->buildUrl('cgi', 'product_jqm2.pl', []);
|
|
||||||
$result = $this->fetchPost($url, $postData);
|
|
||||||
|
|
||||||
if ($result['status_verbose'] === 'fields saved' && $result['status'] === 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return $result['status_verbose'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [uploadImage description]
|
|
||||||
* @param string $code the barcode of the product
|
|
||||||
* @param string $imageField th name of the image
|
|
||||||
* @param string $imagePath the path of the image
|
|
||||||
* @return array the http post response (cast in array)
|
|
||||||
* @throws BadRequestException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function uploadImage(string $code, string $imageField, string $imagePath)
|
|
||||||
{
|
|
||||||
//TODO : need test
|
|
||||||
if ($this->currentAPI !== 'food') {
|
|
||||||
throw new BadRequestException('not Available yet');
|
|
||||||
}
|
|
||||||
if (!in_array($imageField, ["front", "ingredients", "nutrition"])) {
|
|
||||||
throw new BadRequestException('ImageField not valid!');
|
|
||||||
}
|
|
||||||
if (!file_exists($imagePath)) {
|
|
||||||
throw new BadRequestException('Image not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$url = $this->buildUrl('cgi', 'product_image_upload.pl', []);
|
|
||||||
$postData = [
|
|
||||||
'code' => $code,
|
|
||||||
'imagefield' => $imageField,
|
|
||||||
'imgupload_' . $imageField => fopen($imagePath, 'r')
|
|
||||||
];
|
|
||||||
return $this->fetchPost($url, $postData, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A search function
|
|
||||||
* @param string $search a search term (fulltext)
|
|
||||||
* @param integer $page Number of the page
|
|
||||||
* @param integer $pageSize The page size
|
|
||||||
* @param string $sortBy the sort
|
|
||||||
* @return Collection The list of all documents found
|
|
||||||
* @throws BadRequestException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function search(string $search, int $page = 1, int $pageSize = 20, string $sortBy = 'unique_scans')
|
|
||||||
{
|
|
||||||
$parameters = [
|
|
||||||
'search_terms' => $search,
|
|
||||||
'page' => $page,
|
|
||||||
'page_size' => $pageSize,
|
|
||||||
'sort_by' => $sortBy,
|
|
||||||
'json' => '1',
|
|
||||||
];
|
|
||||||
|
|
||||||
$url = $this->buildUrl('cgi', 'search.pl', $parameters);
|
|
||||||
$result = $this->fetch($url, false);
|
|
||||||
return new Collection($result, $this->currentAPI);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function download all data from OpenFoodFact
|
|
||||||
* @param string $filePath the location where you want to put the stream
|
|
||||||
* @param string $fileType mongodb/csv/rdf
|
|
||||||
* @return bool return true when download is complete
|
|
||||||
* @throws BadRequestException
|
|
||||||
*/
|
|
||||||
public function downloadData(string $filePath, string $fileType = "mongodb")
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!isset(self::FILE_TYPE_MAP[$fileType])) {
|
|
||||||
$this->logger->warning(
|
|
||||||
'OpenFoodFact - fetch - failed - File type not recognized!',
|
|
||||||
['fileType' => $fileType, 'availableTypes' => self::FILE_TYPE_MAP]
|
|
||||||
);
|
|
||||||
throw new BadRequestException('File type not recognized!');
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = $this->buildUrl('data', self::FILE_TYPE_MAP[$fileType]);
|
|
||||||
try {
|
|
||||||
$response = $this->httpClient->request('get', $url, ['sink' => $filePath]);
|
|
||||||
} catch (GuzzleException $guzzleException) {
|
|
||||||
$this->logger->warning(sprintf('OpenFoodFact - fetch - failed - GET : %s', $url), ['exception' => $guzzleException]);
|
|
||||||
$exception = new BadRequestException($guzzleException->getMessage(), $guzzleException->getCode(), $guzzleException);
|
|
||||||
|
|
||||||
throw $exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->logger->info('OpenFoodFact - fetch - GET : ' . $url . ' - ' . $response->getStatusCode());
|
|
||||||
|
|
||||||
//TODO: validate response here (server may respond with 200 - OK but you might not get valid data as a response)
|
|
||||||
|
|
||||||
return $response->getStatusCode() == 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This private function do a http request
|
|
||||||
* @param string $url the url to fetch
|
|
||||||
* @param boolean $isJsonFile the request must be finish by '.json' ?
|
|
||||||
* @return array return the result of the request in array format
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws BadRequestException
|
|
||||||
*/
|
|
||||||
private function fetch(string $url, bool $isJsonFile = true) : array
|
|
||||||
{
|
|
||||||
|
|
||||||
$url .= ($isJsonFile? '.json' : '');
|
|
||||||
$realUrl = $url;
|
|
||||||
$cacheKey = md5($realUrl);
|
|
||||||
|
|
||||||
if (!empty($this->cache) && $this->cache->has($cacheKey)) {
|
|
||||||
$cachedResult = $this->cache->get($cacheKey);
|
|
||||||
return $cachedResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'on_stats' => function (TransferStats $stats) use (&$realUrl) {
|
|
||||||
// this function help to find redirection
|
|
||||||
// On redirect we lost some parameters like page
|
|
||||||
$realUrl= (string)$stats->getEffectiveUri();
|
|
||||||
}
|
|
||||||
];
|
|
||||||
if ($this->auth) {
|
|
||||||
$data['auth'] = array_values($this->auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$response = $this->httpClient->request('get', $url, $data);
|
|
||||||
} catch (GuzzleException $guzzleException) {
|
|
||||||
$this->logger->warning(sprintf('OpenFoodFact - fetch - failed - GET : %s', $url), ['exception' => $guzzleException]);
|
|
||||||
//TODO: What to do on a error? - return empty array?
|
|
||||||
$exception = new BadRequestException($guzzleException->getMessage(), $guzzleException->getCode(), $guzzleException);
|
|
||||||
|
|
||||||
throw $exception;
|
|
||||||
}
|
|
||||||
if ($realUrl !== $url) {
|
|
||||||
$this->logger->warning('OpenFoodFact - The url : '. $url . ' has been redirect to ' . $realUrl);
|
|
||||||
trigger_error('OpenFoodFact - Your request has been redirect');
|
|
||||||
}
|
|
||||||
$this->logger->info('OpenFoodFact - fetch - GET : ' . $url . ' - ' . $response->getStatusCode());
|
|
||||||
|
|
||||||
$jsonResult = json_decode($response->getBody(), true);
|
|
||||||
|
|
||||||
if (!empty($this->cache) && !empty($jsonResult)) {
|
|
||||||
$this->cache->set($cacheKey, $jsonResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $jsonResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function performs the same job of the "fetch" function except the call method and parameters
|
|
||||||
* @param string $url The url to fetch
|
|
||||||
* @param array $postData The post data
|
|
||||||
* @param boolean $isMultipart The data is multipart ?
|
|
||||||
* @return array return the result of the request in array format
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws BadRequestException
|
|
||||||
*/
|
|
||||||
private function fetchPost(string $url, array $postData, bool $isMultipart = false) : array
|
|
||||||
{
|
|
||||||
$data = [];
|
|
||||||
if ($this->auth) {
|
|
||||||
$data['auth'] = array_values($this->auth);
|
|
||||||
}
|
|
||||||
if ($isMultipart) {
|
|
||||||
foreach ($postData as $key => $value) {
|
|
||||||
$data['multipart'][] = [
|
|
||||||
'name' => $key,
|
|
||||||
'contents' => $value
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$data['form_params'] = $postData;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cacheKey = md5($url . json_encode($data));
|
|
||||||
|
|
||||||
if (!empty($this->cache) && $this->cache->has($cacheKey)) {
|
|
||||||
return $this->cache->get($cacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$response = $this->httpClient->request('post', $url, $data);
|
|
||||||
}catch (GuzzleException $guzzleException){
|
|
||||||
$exception = new BadRequestException($guzzleException->getMessage(), $guzzleException->getCode(), $guzzleException);
|
|
||||||
|
|
||||||
throw $exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->logger->info('OpenFoodFact - fetch - GET : ' . $url . ' - ' . $response->getStatusCode());
|
|
||||||
|
|
||||||
$jsonResult = json_decode($response->getBody(), true);
|
|
||||||
|
|
||||||
if (!empty($this->cache) && !empty($jsonResult)) {
|
|
||||||
$this->cache->set($cacheKey, $jsonResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $jsonResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This private function generates an url according to the parameters
|
|
||||||
* @param string|null $service
|
|
||||||
* @param string|array|null $resourceType
|
|
||||||
* @param string|array|null $parameters
|
|
||||||
* @return string the generated url
|
|
||||||
*/
|
|
||||||
private function buildUrl(string $service = null, $resourceType = null, $parameters = null) : string
|
|
||||||
{
|
|
||||||
$baseUrl = null;
|
|
||||||
switch ($service) {
|
|
||||||
case 'api':
|
|
||||||
$baseUrl = implode('/', [
|
|
||||||
$this->geoUrl,
|
|
||||||
$service,
|
|
||||||
'v0',
|
|
||||||
$resourceType,
|
|
||||||
$parameters
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
case 'data':
|
|
||||||
$baseUrl = implode('/', [
|
|
||||||
$this->geoUrl,
|
|
||||||
$service,
|
|
||||||
$resourceType
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
case 'cgi':
|
|
||||||
$baseUrl = implode('/', [
|
|
||||||
$this->geoUrl,
|
|
||||||
$service,
|
|
||||||
$resourceType
|
|
||||||
]);
|
|
||||||
$baseUrl .= '?' . http_build_query($parameters);
|
|
||||||
break;
|
|
||||||
case null:
|
|
||||||
default:
|
|
||||||
if (is_array($resourceType)) {
|
|
||||||
$resourceType = implode('/', $resourceType);
|
|
||||||
}
|
|
||||||
if ($resourceType == 'ingredients') {
|
|
||||||
//need test
|
|
||||||
$resourceType = implode('/', ["state", "complete", $resourceType]);
|
|
||||||
$parameters = 1;
|
|
||||||
}
|
|
||||||
$baseUrl = implode('/', array_filter([
|
|
||||||
$this->geoUrl,
|
|
||||||
$resourceType,
|
|
||||||
$parameters
|
|
||||||
], function ($value) {
|
|
||||||
return !empty($value);
|
|
||||||
}));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $baseUrl;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts;
|
|
||||||
|
|
||||||
use Iterator;
|
|
||||||
|
|
||||||
class Collection implements Iterator
|
|
||||||
{
|
|
||||||
|
|
||||||
private $listDocuments = null;
|
|
||||||
private $count = null;
|
|
||||||
private $page = null;
|
|
||||||
private $skip = null;
|
|
||||||
private $pageSize = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initialization of the collection
|
|
||||||
* @param array|null $data the raw data
|
|
||||||
* @param string|null $api this information help to type the collection (not use yet)
|
|
||||||
*/
|
|
||||||
public function __construct(array $data = null, string $api = null)
|
|
||||||
{
|
|
||||||
$data = $data ?? [
|
|
||||||
'products' => [],
|
|
||||||
'count' => 0,
|
|
||||||
'page' => 0,
|
|
||||||
'skip' => 0,
|
|
||||||
'page_size' => 0,
|
|
||||||
];
|
|
||||||
$this->listDocuments = [];
|
|
||||||
|
|
||||||
if (!empty($data['products'])) {
|
|
||||||
$currentApi = '';
|
|
||||||
if (null !== $api) {
|
|
||||||
$currentApi = $api;
|
|
||||||
}
|
|
||||||
foreach ($data['products'] as $document) {
|
|
||||||
if($document instanceof Document){
|
|
||||||
$this->listDocuments[] = $document;
|
|
||||||
}elseif (is_array($document)){
|
|
||||||
$this->listDocuments[] = Document::createSpecificDocument($currentApi, $document);
|
|
||||||
}else {
|
|
||||||
throw new \InvalidArgumentException(sprintf('Would expect an OpenFoodFacts\Document Interface or Array here. Got: %s', gettype($document)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->count = $data['count'];
|
|
||||||
$this->page = $data['page'];
|
|
||||||
$this->skip = $data['skip'];
|
|
||||||
$this->pageSize = $data['page_size'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int get the current page
|
|
||||||
*/
|
|
||||||
public function getPage() : int
|
|
||||||
{
|
|
||||||
return $this->page;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return int get the number of element skipped
|
|
||||||
*/
|
|
||||||
public function getSkip() : int
|
|
||||||
{
|
|
||||||
return $this->skip;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return int get the number of element by page for this collection
|
|
||||||
*/
|
|
||||||
public function getPageSize() : int
|
|
||||||
{
|
|
||||||
return $this->pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int the number of element in this Collection
|
|
||||||
*/
|
|
||||||
public function pageCount() : int
|
|
||||||
{
|
|
||||||
return count($this->listDocuments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int the number of element for this search
|
|
||||||
*/
|
|
||||||
public function searchCount() : int
|
|
||||||
{
|
|
||||||
return $this->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of Iterator
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function rewind()
|
|
||||||
{
|
|
||||||
reset($this->listDocuments);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function current()
|
|
||||||
{
|
|
||||||
return current($this->listDocuments);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function key()
|
|
||||||
{
|
|
||||||
return key($this->listDocuments);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function next()
|
|
||||||
{
|
|
||||||
return next($this->listDocuments);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function valid()
|
|
||||||
{
|
|
||||||
$key = key($this->listDocuments);
|
|
||||||
return ($key !== null && $key !== false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* In mongoDB all element are object, it not possible to define property.
|
|
||||||
* All property of the mongodb entity are store in one property of this class and the magic call try to access to it
|
|
||||||
*/
|
|
||||||
class Document
|
|
||||||
{
|
|
||||||
use RecursiveSortingTrait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the whole data
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the whole data
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization the document and specify from which API it was extract
|
|
||||||
* @param array $data the whole data
|
|
||||||
* @param string $api the api name
|
|
||||||
*/
|
|
||||||
public function __construct(array $data, string $api = null)
|
|
||||||
{
|
|
||||||
$this->data = $data;
|
|
||||||
$this->api = $api;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function __get(string $name)
|
|
||||||
{
|
|
||||||
return $this->data[$name];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function __isset(string $name):bool
|
|
||||||
{
|
|
||||||
return isset($this->data[$name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a sorted representation of the complete Document Data
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getData(): array
|
|
||||||
{
|
|
||||||
$this->recursiveSortArray($this->data);
|
|
||||||
return $this->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Document in the type regarding to the API used.
|
|
||||||
* May be a Child of "Document" e.g.: FoodDocument or ProductDocument
|
|
||||||
* @param string $apiIdentifier
|
|
||||||
* @param array $data
|
|
||||||
* @return Document
|
|
||||||
*/
|
|
||||||
public static function createSpecificDocument(string $apiIdentifier, array $data): Document
|
|
||||||
{
|
|
||||||
if ($apiIdentifier === '') {
|
|
||||||
return new Document($data, $apiIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
$className = "OpenFoodFacts\Document\\" . ucfirst($apiIdentifier) . 'Document';
|
|
||||||
|
|
||||||
if (class_exists($className) && is_subclass_of($className, Document::class)) {
|
|
||||||
return new $className($data, $apiIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Document($data, $apiIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
class BeautyDocument extends Document
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
class FoodDocument extends Document
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
class PetDocument extends Document
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
|
|
||||||
class ProductDocument extends Document
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts\Exception;
|
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just an exception class for the try catch
|
|
||||||
*/
|
|
||||||
class BadRequestException extends Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts\Exception;
|
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just an exception class for the try catch
|
|
||||||
*/
|
|
||||||
class ProductNotFoundException extends Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts;
|
|
||||||
|
|
||||||
trait FilesystemTrait
|
|
||||||
{
|
|
||||||
function recursiveDeleteDirectory($dir)
|
|
||||||
{
|
|
||||||
if (is_dir($dir)) {
|
|
||||||
$objects = scandir($dir);
|
|
||||||
foreach ($objects as $object) {
|
|
||||||
if ($object != "." && $object != "..") {
|
|
||||||
if (is_dir($dir . "/" . $object)) {
|
|
||||||
$this->recursiveDeleteDirectory($dir . "/" . $object);
|
|
||||||
} else {
|
|
||||||
unlink($dir . "/" . $object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rmdir($dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OpenFoodFacts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trait RecursiveSortingTrait
|
|
||||||
*/
|
|
||||||
trait RecursiveSortingTrait
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param array $arr
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isAssoc(array $arr): bool
|
|
||||||
{
|
|
||||||
return array_keys($arr) !== range(0, count($arr) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts referenced array of arrays in a recursive way for better understandability
|
|
||||||
* @param array $arr
|
|
||||||
* @see ksort
|
|
||||||
* @see asort
|
|
||||||
*/
|
|
||||||
public function recursiveSortArray(array &$arr): void
|
|
||||||
{
|
|
||||||
if ($this->isAssoc($arr)) {
|
|
||||||
ksort($arr);
|
|
||||||
} else {
|
|
||||||
asort($arr);
|
|
||||||
}
|
|
||||||
foreach ($arr as &$a) {
|
|
||||||
if (is_array($a)) {
|
|
||||||
$this->recursiveSortArray($a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,178 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use GuzzleHttp\Exception\ServerException;
|
|
||||||
use OpenFoodFacts\FilesystemTrait;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Api;
|
|
||||||
use OpenFoodFacts\Collection;
|
|
||||||
use OpenFoodFacts\Document\FoodDocument;
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
use OpenFoodFacts\Exception\{
|
|
||||||
ProductNotFoundException,
|
|
||||||
BadRequestException
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
use Monolog\Logger;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
|
||||||
use Symfony\Component\Cache\Psr16Cache;
|
|
||||||
use Symfony\Component\Console\Logger\ConsoleLogger;
|
|
||||||
|
|
||||||
class ApiFoodCacheTest extends TestCase
|
|
||||||
{
|
|
||||||
use FilesystemTrait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Api
|
|
||||||
*/
|
|
||||||
private $api;
|
|
||||||
|
|
||||||
|
|
||||||
protected function setUp()
|
|
||||||
{
|
|
||||||
@rmdir('tests/tmp');
|
|
||||||
@mkdir('tests/tmp');
|
|
||||||
@mkdir('tests/tmp/cache');
|
|
||||||
$log = new Logger('name');
|
|
||||||
$log->pushHandler(new StreamHandler('log/test.log'));
|
|
||||||
$psr6Cache = new FilesystemAdapter(sprintf('testrun_%u', rand(0, 1000)), 10, 'tests/tmp/cache');
|
|
||||||
$cache = new Psr16Cache($psr6Cache);
|
|
||||||
|
|
||||||
$httpClient = new GuzzleHttp\Client([
|
|
||||||
// "http_errors" => false, // MUST not use as it crashes error handling
|
|
||||||
'Connection' => 'close',
|
|
||||||
CURLOPT_FORBID_REUSE => true,
|
|
||||||
CURLOPT_FRESH_CONNECT => true,
|
|
||||||
'defaults' => [
|
|
||||||
'headers' => [
|
|
||||||
'CURLOPT_USERAGENT' => 'OFF - PHP - SDK - Unit Test',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$api = new Api('food', 'fr-en', $log, $httpClient, $cache);
|
|
||||||
$this->assertInstanceOf(Api::class, $api);
|
|
||||||
$this->api = $api;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApi(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$prd = $this->api->getProduct('3057640385148');
|
|
||||||
|
|
||||||
$this->assertInstanceOf(FoodDocument::class, $prd);
|
|
||||||
$this->assertInstanceOf(Document::class, $prd);
|
|
||||||
|
|
||||||
$this->assertTrue(isset($prd->product_name));
|
|
||||||
$this->assertNotEmpty($prd->product_name);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$product = $this->api->getProduct('305764038514800');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (ProductNotFoundException $e) {
|
|
||||||
$this->assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = $this->api->downloadData('tests/mongodb', 'nopeFile');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'File type not recognized!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// $result = $this->api->downloadData('tests/tmp/mongodb');
|
|
||||||
// $this->assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiCollection(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->getByFacets([]);
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 0);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->getByFacets(['trace' => 'egg', 'country' => 'france'], 3);
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (\PHPUnit\Framework\Error\Notice $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'OpenFoodFact - Your request has been redirect');
|
|
||||||
}
|
|
||||||
|
|
||||||
$collection = $this->api->getByFacets(['trace' => 'eggs', 'country' => 'france'], 3);
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 20);
|
|
||||||
$this->assertEquals($collection->getPage(), 3);
|
|
||||||
$this->assertEquals($collection->getSkip(), 40);
|
|
||||||
$this->assertEquals($collection->getPageSize(), 20);
|
|
||||||
$this->assertGreaterThan(1000, $collection->searchCount());
|
|
||||||
|
|
||||||
foreach ($collection as $key => $doc) {
|
|
||||||
if ($key > 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertInstanceOf(FoodDocument::class, $doc);
|
|
||||||
$this->assertInstanceOf(Document::class, $doc);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiSearch(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->search('volvic', 3, 30);
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 30);
|
|
||||||
$this->assertGreaterThan(100, $collection->searchCount());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function testFacets(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->getIngredients();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 20);
|
|
||||||
$this->assertEquals($collection->getPageSize(), 20);
|
|
||||||
$this->assertGreaterThan(70000, $collection->searchCount());
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->getIngredient();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'Facet "ingredient" not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
$collection = $this->api->getPurchase_places();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$collection = $this->api->getPackaging_codes();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$collection = $this->api->getEntry_dates();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->getIngredient();
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'Facet "ingredient" not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->nope();
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$this->assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown()
|
|
||||||
{
|
|
||||||
$this->recursiveDeleteDirectory('tests/tmp');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use GuzzleHttp\Exception\ServerException;
|
|
||||||
use OpenFoodFacts\FilesystemTrait;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Api;
|
|
||||||
use OpenFoodFacts\Collection;
|
|
||||||
use OpenFoodFacts\Document\FoodDocument;
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
use OpenFoodFacts\Exception\{
|
|
||||||
ProductNotFoundException,
|
|
||||||
BadRequestException
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
use Monolog\Logger;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
|
|
||||||
class ApiFoodTest extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
use FilesystemTrait;
|
|
||||||
|
|
||||||
private $api;
|
|
||||||
|
|
||||||
protected function setUp()
|
|
||||||
{
|
|
||||||
$log = new Logger('name');
|
|
||||||
$log->pushHandler(new StreamHandler('log/test.log'));
|
|
||||||
|
|
||||||
$this->api = new Api('food', 'fr-en', $log);
|
|
||||||
@rmdir('tests/tmp');
|
|
||||||
@mkdir('tests/tmp');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApi(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$prd = $this->api->getProduct('3057640385148');
|
|
||||||
|
|
||||||
$this->assertInstanceOf(FoodDocument::class, $prd);
|
|
||||||
$this->assertInstanceOf(Document::class, $prd);
|
|
||||||
$this->assertTrue(isset($prd->product_name));
|
|
||||||
$this->assertNotEmpty($prd->product_name);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$product = $this->api->getProduct('305764038514800');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (ProductNotFoundException $e) {
|
|
||||||
$this->assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = $this->api->downloadData('tests/mongodb', 'nopeFile');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'File type not recognized!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// $result = $this->api->downloadData('tests/tmp/mongodb');
|
|
||||||
// $this->assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiCollection(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->getByFacets([]);
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 0);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->getByFacets(['trace' => 'egg', 'country' => 'france'], 3);
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (\PHPUnit\Framework\Error\Notice $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'OpenFoodFact - Your request has been redirect');
|
|
||||||
}
|
|
||||||
|
|
||||||
$collection = $this->api->getByFacets(['trace' => 'eggs', 'country' => 'france'], 3);
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 20);
|
|
||||||
$this->assertEquals($collection->getPage(), 3);
|
|
||||||
$this->assertEquals($collection->getSkip(), 40);
|
|
||||||
$this->assertEquals($collection->getPageSize(), 20);
|
|
||||||
$this->assertGreaterThan(1000, $collection->searchCount());
|
|
||||||
|
|
||||||
foreach ($collection as $key => $doc) {
|
|
||||||
if ($key > 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$this->assertInstanceOf(FoodDocument::class, $doc);
|
|
||||||
$this->assertInstanceOf(Document::class, $doc);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiAddProduct(): void
|
|
||||||
{
|
|
||||||
$this->api->activeTestMode();
|
|
||||||
try {
|
|
||||||
$prd = $this->api->getProduct('3057640385148');
|
|
||||||
$this->assertInstanceOf(FoodDocument::class, $prd);
|
|
||||||
$this->assertInstanceOf(Document::class, $prd);
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
if ($exception->getPrevious() instanceof ServerException && $exception->getPrevious()->getCode() === 503) {
|
|
||||||
$this->markTestSkipped(
|
|
||||||
'Testing API currently not available.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$postData = ['code' => $prd->code, 'product_name' => $prd->product_name];
|
|
||||||
|
|
||||||
$result = $this->api->addNewProduct($postData);
|
|
||||||
$this->assertTrue(is_bool($result));
|
|
||||||
|
|
||||||
|
|
||||||
$postData = ['product_name' => $prd->product_name];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = $this->api->addNewProduct($postData);
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertTrue(true);
|
|
||||||
}
|
|
||||||
$postData = ['code' => '', 'product_name' => $prd->product_name];
|
|
||||||
$result = $this->api->addNewProduct($postData);
|
|
||||||
$this->assertTrue(is_string($result));
|
|
||||||
$this->assertEquals($result, 'no code or invalid code');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiAddImage(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->api->activeTestMode();
|
|
||||||
try {
|
|
||||||
$prd = $this->api->getProduct('3057640385148');
|
|
||||||
$this->assertInstanceOf(Collection::class, $prd);
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
if ($exception->getPrevious() instanceof ServerException && $exception->getPrevious()->getCode() === 503) {
|
|
||||||
$this->markTestSkipped(
|
|
||||||
'Testing API currently not available.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->api->uploadImage('3057640385148', 'fronts', 'nothing');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'ImageField not valid!');
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
$this->api->uploadImage('3057640385148', 'front', 'nothing');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'Image not found');
|
|
||||||
}
|
|
||||||
$file1 = $this->createRandomImage();
|
|
||||||
|
|
||||||
$result = $this->api->uploadImage('3057640385148', 'front', $file1);
|
|
||||||
$this->assertEquals($result['status'], 'status ok');
|
|
||||||
$this->assertTrue(isset($result['imagefield']));
|
|
||||||
$this->assertTrue(isset($result['image']));
|
|
||||||
$this->assertTrue(isset($result['image']['imgid']));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiSearch(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->search('volvic', 3, 30);
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 30);
|
|
||||||
$this->assertGreaterThan(100, $collection->searchCount());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function testFacets(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->getIngredients();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 20);
|
|
||||||
$this->assertEquals($collection->getPageSize(), 20);
|
|
||||||
$this->assertGreaterThan(70000, $collection->searchCount());
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->getIngredient();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'Facet "ingredient" not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
$collection = $this->api->getPurchase_places();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$collection = $this->api->getPackaging_codes();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$collection = $this->api->getEntry_dates();
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->getIngredient();
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'Facet "ingredient" not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$collection = $this->api->nope();
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$this->assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function createRandomImage(): string
|
|
||||||
{
|
|
||||||
|
|
||||||
$width = 400;
|
|
||||||
$height = 200;
|
|
||||||
|
|
||||||
$imageRes = imagecreatetruecolor($width, $height);
|
|
||||||
for ($row = 0; $row <= $height; $row++) {
|
|
||||||
for ($column = 0; $column <= $width; $column++) {
|
|
||||||
$colour = imagecolorallocate($imageRes, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
|
|
||||||
imagesetpixel($imageRes, $column, $row, $colour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$path = 'tests/tmp/image_' . time() . '.jpg';
|
|
||||||
if (imagejpeg($imageRes, $path)) {
|
|
||||||
return $path;
|
|
||||||
}
|
|
||||||
throw new \Exception("Error Processing Request", 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown()
|
|
||||||
{
|
|
||||||
$this->recursiveDeleteDirectory('tests/tmp');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use OpenFoodFacts\FilesystemTrait;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
use OpenFoodFacts\Api;
|
|
||||||
use OpenFoodFacts\Collection;
|
|
||||||
use OpenFoodFacts\Document\PetDocument;
|
|
||||||
use OpenFoodFacts\Document;
|
|
||||||
use OpenFoodFacts\Exception\{
|
|
||||||
ProductNotFoundException,
|
|
||||||
BadRequestException
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
use Monolog\Logger;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
|
|
||||||
class ApiPetTest extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
use FilesystemTrait;
|
|
||||||
|
|
||||||
private $api;
|
|
||||||
|
|
||||||
protected function setUp()
|
|
||||||
{
|
|
||||||
$log = new Logger('name');
|
|
||||||
$log->pushHandler(new StreamHandler('log/test.log'));
|
|
||||||
|
|
||||||
$this->api = new Api('pet', 'fr', $log);
|
|
||||||
|
|
||||||
foreach (glob('tests/images/*') as $file) {
|
|
||||||
unlink($file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApi()
|
|
||||||
{
|
|
||||||
|
|
||||||
$prd = $this->api->getProduct('7613035799738');
|
|
||||||
|
|
||||||
$this->assertInstanceOf(PetDocument::class, $prd);
|
|
||||||
$this->assertInstanceOf(Document::class, $prd);
|
|
||||||
$this->assertTrue(isset($prd->product_name));
|
|
||||||
$this->assertNotEmpty($prd->product_name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiAddImage()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$this->api->uploadImage('7613035799738', 'fronts', 'nothing');
|
|
||||||
$this->assertTrue(false);
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
$this->assertEquals($e->getMessage(), 'not Available yet');
|
|
||||||
$this->markTestSkipped(
|
|
||||||
$e->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testApiSearch()
|
|
||||||
{
|
|
||||||
|
|
||||||
$collection = $this->api->search('chat', 3, 30);
|
|
||||||
|
|
||||||
$this->assertInstanceOf(Collection::class, $collection);
|
|
||||||
$this->assertEquals($collection->pageCount(), 30);
|
|
||||||
$this->assertGreaterThan(100, $collection->searchCount());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown()
|
|
||||||
{
|
|
||||||
$this->recursiveDeleteDirectory('tests/tmp');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue