Skip to content

Commit 1bd4d65

Browse files
author
Dominik Brader
authored
Support JSON_1.0 (#69)
* Support JSON_1.0. * Limit to one alivetest per Client lifecycle. * "setRevision" method now allows semantic versioning strings.
1 parent 8e8c4ee commit 1bd4d65

File tree

66 files changed

+7834
-85
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+7834
-85
lines changed

.gitattributes

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
.gitattributes export-ignore
2+
.gitignore export-ignore
3+
.travis.yml export-ignore
4+
phpunit.xml export-ignore
5+
26
/.github/ export-ignore
37
/.git/ export-ignore
4-
.gitignore export-ignore
5-
/phpunit.xml export-ignore
8+
/examples/ export-ignore
69
/tests/ export-ignore
7-
.travis.yml export-ignore

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
/vendor/
33
composer.lock
44
.php_cs.cache
5-
coverage.xml
5+
coverage.xml

README.md

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
1. [Installation](#installation)
1414
1. [Basic usage](#basic-usage)
1515
1. [Examples](#examples)
16-
1. [Found a bug?](#found-a-bug)
16+
1. [Projects using this library](#projects-using-this-library)
17+
1. [FINDOLOGIC-API In Action](#findologic-api-in-action)
18+
1. [Bug report](#bug-report)
1719
1. [Contributing](#contributing)
1820

1921
## Synopsis
@@ -23,21 +25,22 @@ FINDOLOGIC-API is an object oriented wrapper for the Findologic API, with over 3
2325
This library not only helps requesting the Findologic API, but also getting data from the response and mapping them to corresponding objects.
2426
You won't have to mess around with sending requests and getting the data from the Findologic's response anymore.
2527

26-
You want to get filters? Just call `->getMainFilters()` on your response object. It really is that simple and if you dont trust us,
27-
try out the [Basic Usage](#basic-usage) or test the [Examples](#examples).
28+
You want to get filters? Just call `Response::getMainFilters()`. It really is that simple, just
29+
try out the [Basic Usage](#basic-usage) or see some [Examples](#examples).
2830

2931
To have a better understanding about the API, please make sure to read the general Findologic API documentation. We already got you covered with quicklinks to it:
3032

3133
* [Requesting the API](https://docs.findologic.com/doku.php?id=integration_documentation:request)
32-
* [XML response](https://docs.findologic.com/doku.php?id=integration_documentation:response_xml)
34+
* [Response: XML](https://docs.findologic.com/doku.php?id=integration_documentation:response_xml) | [API spec (non-interactive)](https://github.com/findologic/xml-response-schema/blob/master/schema.xsd)
35+
* Response: JSON | [API spec (interactive)](https://service.findologic.com/ps/centralized-frontend/spec/) | [API spec (non-interactive)](https://github.com/findologic/json-response-schema/blob/0.x/resources/schema.json)
3336

3437
### Limitations
3538

3639
Currently, we support the following response formats:
3740

3841
| Response Type | Format | Version | Supported | End of life |
3942
|-------------------|--------|---------|--------------------------------------------------|-------------------------------|
40-
| Search/Navigation | JSON | 1.0 | :heavy_multiplication_x: → See [this PR](https://github.com/findologic/findologic-api/pull/69) | Not in the foreseeable future |
43+
| Search/Navigation | JSON | 1.0 | :heavy_check_mark: | Not in the foreseeable future |
4144
| | XML | 2.1 | :heavy_check_mark: | Not in the foreseeable future |
4245
| | XML | 2.0 | :heavy_multiplication_x: → Use XML_2.1 instead | 2019-10-18 |
4346
| | HTML | any | :heavy_check_mark: → The response is not parsed | Not in the foreseeable future |
@@ -69,37 +72,45 @@ require_once __DIR__ . '/vendor/autoload.php';
6972
use FINDOLOGIC\Api\Config;
7073
use FINDOLOGIC\Api\Client;
7174
use FINDOLOGIC\Api\Requests\SearchNavigation\SearchRequest;
72-
use FINDOLOGIC\Api\Responses\Xml21\Xml21Response;
75+
use FINDOLOGIC\Api\Responses\Json10\Json10Response;
7376

74-
$config = new Config();
75-
// ServiceId/Shopkey, you can find it in the customer account.
76-
$config->setServiceId('ABCDABCDABCDABCDABCDABCDABCDABCD');
77-
78-
// Client used for requests
77+
// Set your ServiceId/Shopkey, which can be found in the customer account.
78+
$config = new Config('ABCDABCDABCDABCDABCDABCDABCDABCD');
7979
$client = new Client($config);
8080

8181
$searchRequest = new SearchRequest();
8282
$searchRequest
83-
->setQuery('shirt') // Users search query
84-
->setShopUrl('blubbergurken.de') // Url of the shop
85-
->setUserIp('127.0.0.1') // Users IP
86-
->setReferer($_SERVER['HTTP_REFERER']) // Page where search was fired
87-
->setRevision('1.0.0'); // Version of your API wrapper
88-
89-
/** @var Xml21Response $xmlResponse */
90-
$xmlResponse = $client->send($searchRequest);
91-
92-
var_dump($xmlResponse->getMainFilters()); // Get all main filters easily
93-
var_dump($xmlResponse->getOtherFilters()); // Get all other filters easily
94-
var_dump($xmlResponse); // Entire response, full of helper methods
83+
->setQuery('shirt') // Users search query.
84+
->setShopUrl('blubbergurken.de') // Url of the shop.
85+
->setUserIp('127.0.0.1') // Users IP.
86+
->setReferer($_SERVER['HTTP_REFERER']) // Page where search was fired.
87+
->setRevision('1.0.0') // Version of your API wrapper.
88+
->setOutputAdapter('JSON_1.0'); // Optional setting of output format.
89+
90+
/** @var Json10Response $jsonResponse */
91+
$jsonResponse = $client->send($searchRequest);
92+
93+
var_dump($jsonResponse->getResult()->getItems()); // Get all products/items.
94+
var_dump($jsonResponse->getResult()->getMainFilters()); // Get all main filters easily.
95+
var_dump($jsonResponse->getResult()->getOtherFilters()); // Get all other filters easily.
96+
var_dump($jsonResponse); // Entire response, full of helper methods.
9597
```
9698

9799
## Examples
98100

101+
* Working examples can be found in the
102+
[`/examples`](https://github.com/findologic/findologic-api/tree/master/examples) directory.
99103
* The documentation can be found in our
100104
[Project Wiki](https://github.com/findologic/findologic-api/wiki).
101105

102-
## Found a bug?
106+
### Projects using this library
107+
108+
* [FINDOLOGIC Shopware 6 plugin](https://github.com/findologic/plugin-shopware-6)
109+
* [FINDOLOGIC Shopware 5 plugin](https://github.com/findologic/plugin-shopware-5)
110+
* [Simple Symfony 5 demo](https://github.com/TheKeymaster/findologic-api-demo-symfony) (shows a simple FINDOLOGIC-API integration)
111+
* Many more to come...
112+
113+
## Bug Report
103114

104115
We need your help! If you find any bug, please submit an issue and use our template! Be as precise as possible
105116
so we can reproduce your case easier. For further information, please refer to our issue template at

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
},
5252
"autoload-dev": {
5353
"psr-4": {
54-
"FINDOLOGIC\\Api\\Tests\\": "tests/Tests/"
54+
"FINDOLOGIC\\Api\\Tests\\": "tests/"
5555
}
5656
},
5757
"scripts": {

examples/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Examples
2+
3+
In here you can find various examples for multiple use cases. Please note
4+
that all examples use the JSON response format.
5+
6+
## List of all examples
7+
8+
You can immediately try these examples on your own. Simply run `php -S localhost:8080`
9+
inside in this folder, and open http://localhost:8080 in your preferred browser.
10+
11+
The following list ist also shown in the browser:
12+
13+
| File name | Description |
14+
|----------------------------------------------------------------------------------------------------------|------------------------------------------------------|
15+
| [simple_search.php](https://github.com/findologic/findologic-api/tree/master/examples/simple_search.php) | Shows a basic search implementation without filters. |
16+
| | |
17+
| | |
18+
| | |
19+
| | |

examples/index.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
5+
<meta charset="UTF-8">
6+
<title>FINDOLOGIC-API examples</title>
7+
</head>
8+
<body>
9+
10+
<table class="table">
11+
<tr>
12+
<th>File name</th>
13+
<th>Description</th>
14+
</tr>
15+
<tr>
16+
<td>
17+
<a href="simple_search.php">simple_search.php</a>
18+
</td>
19+
<td>
20+
Shows a basic search implementation without filters.
21+
</td>
22+
</tr>
23+
<tr>
24+
<td>
25+
<a href="simple_filters.php">simple_filters.php</a>
26+
</td>
27+
<td>
28+
Gives an overview of available filter types.
29+
</td>
30+
</tr>
31+
</table>
32+
</body>
33+
</html>

examples/simple_search.php

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
// This example shows a simple shop search without filters.
4+
5+
use FINDOLOGIC\Api\Client;
6+
use FINDOLOGIC\Api\Config;
7+
use FINDOLOGIC\Api\Requests\SearchNavigation\SearchRequest;
8+
use FINDOLOGIC\Api\Responses\Json10\Json10Response;
9+
use FINDOLOGIC\Api\Responses\Json10\Properties\Item;
10+
11+
/**
12+
* SET YOUR SERVICE ID / SHOPKEY HERE.
13+
*/
14+
const SERVICE_ID = '';
15+
16+
const ITEM_TEMPLATE = <<<EOL
17+
<div class="col-3">
18+
<div class="card">
19+
<a href="%s">
20+
<img class="card-img-top mt-3" src="%s" alt="%s">
21+
</a>
22+
<div class="card-body">
23+
<h5 class="card-title">%s</h5>
24+
<p class="card-text">%s</p>
25+
<div class="price-information">
26+
<h4>%.2f %s</h4>
27+
<a href="%s" class="btn btn-primary">Buy</a>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
EOL;
33+
34+
function fetchProducts()
35+
{
36+
require_once __DIR__ . '/../vendor/autoload.php';
37+
38+
$config = new Config(isset($_GET['shopkey']) ? $_GET['shopkey'] : SERVICE_ID);
39+
$client = new Client($config);
40+
41+
$searchRequest = new SearchRequest();
42+
$searchRequest
43+
->setQuery(isset($_GET['query']) ? $_GET['query'] : '')
44+
->setShopUrl('your-shop.com')
45+
->setUserIp('127.0.0.1')
46+
->setReferer('http://google.com/')
47+
->setRevision('1.0.0')
48+
->setOutputAdapter('JSON_1.0');
49+
50+
/** @var Json10Response $response */
51+
$response = $client->send($searchRequest);
52+
53+
return getRenderedProducts($response);
54+
}
55+
56+
function getRenderedProducts(Json10Response $response)
57+
{
58+
$rendered = '';
59+
$count = 0;
60+
foreach ($response->getResult()->getItems() as $item) {
61+
if ($count % 4 == 0 || $count === 0) {
62+
if ($count !== 0) {
63+
$rendered .= '</div>';
64+
}
65+
$rendered .= '<div class="row mb-4">';
66+
}
67+
68+
$rendered .= wrapItem($item, $response->getResult()->getMetadata()->getCurrencySymbol());
69+
70+
$count++;
71+
}
72+
73+
return $rendered;
74+
}
75+
76+
function wrapItem(Item $item, $currencySymbol)
77+
{
78+
return sprintf(
79+
ITEM_TEMPLATE,
80+
$item->getUrl(),
81+
$item->getImageUrl(),
82+
$item->getName(),
83+
$item->getName(),
84+
$item->getSummary(),
85+
$item->getPrice(),
86+
$currencySymbol,
87+
$item->getUrl()
88+
);
89+
}
90+
91+
?>
92+
93+
<!DOCTYPE html>
94+
<html lang="en">
95+
<head>
96+
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
97+
<meta charset="UTF-8">
98+
<title>FINDOLOGIC-API simple search example</title>
99+
<style>
100+
img.card-img-top {
101+
display: block;
102+
max-width: 100%;
103+
width: 100%;
104+
max-height: 200px;
105+
object-fit: contain;
106+
}
107+
button {
108+
width: 100%
109+
}
110+
.col-3 .card {
111+
height: 100%;
112+
}
113+
.card-text {
114+
overflow: hidden;
115+
white-space: nowrap;
116+
text-overflow: ellipsis;
117+
margin-bottom: 100px;
118+
}
119+
.price-information {
120+
position: absolute;
121+
bottom: 20px;
122+
}
123+
</style>
124+
</head>
125+
<body>
126+
<div class="ml-5 mr-5">
127+
<h2>Simple search example</h2>
128+
</div>
129+
<div class="ml-5 mr-5">
130+
<form action="simple_search.php">
131+
<div class="row">
132+
<div class="col-3">
133+
<input class="form-control" type="text" placeholder="ENTER YOUR SHOPKEY HERE" aria-label="Search" name="shopkey" value="<?php echo isset($_GET['shopkey']) ? $_GET['shopkey'] : SERVICE_ID ?>">
134+
</div>
135+
<div class="col-8">
136+
<input class="form-control" type="text" placeholder="Search" aria-label="Search" name="query">
137+
</div>
138+
<div class="col-1">
139+
<button type="submit" class="btn btn-primary">Search</button>
140+
</div>
141+
</div>
142+
</form>
143+
<h5 class="mt-2">Search results for <strong><?php echo isset($_GET['query']) ? htmlentities($_GET['query']) : '' ?></strong></h5>
144+
<div>
145+
<?php echo fetchProducts(); ?>
146+
</div>
147+
</div>
148+
</body>
149+
</html>

src/Client.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88
use FINDOLOGIC\Api\Requests\SearchNavigation\SearchNavigationRequest;
99
use FINDOLOGIC\Api\Responses\Response;
1010
use FINDOLOGIC\GuzzleHttp\Exception\GuzzleException;
11-
use GuzzleHttp\Psr7\Response as GuzzleResponse;
11+
use Psr\Http\Message\ResponseInterface as GuzzleResponse;
1212

1313
class Client
1414
{
15-
const METHOD_GET = 'GET';
16-
1715
/** @var Config */
1816
private $config;
1917

18+
/**
19+
* @var bool Weither an alivetest was sent or not. Only one alivetest is sent per client lifetime.
20+
*/
21+
private $alivetestSent = false;
22+
2023
public function __construct(Config $config)
2124
{
2225
$this->config = $config;
@@ -67,15 +70,21 @@ private function sendRequest(Request $request)
6770
* SearchRequest/NavigationRequest.
6871
*
6972
* @param Request $request
70-
* @return GuzzleResponse|null|void
73+
* @return GuzzleResponse|null
7174
*/
7275
private function doAlivetest(Request $request)
7376
{
74-
if ($request instanceof SearchNavigationRequest) {
75-
// We need to make sure that the alivetest uses the same parameters as the request itself.
76-
$alivetestRequest = new AlivetestRequest();
77-
$alivetestRequest->setParams($request->getParams());
78-
return $this->sendRequest($alivetestRequest);
77+
if (!$request instanceof SearchNavigationRequest || $this->alivetestSent) {
78+
return null;
7979
}
80+
81+
// We need to make sure that the alivetest uses the same parameters as the request itself.
82+
$alivetestRequest = new AlivetestRequest();
83+
$alivetestRequest->setParams($request->getParams());
84+
85+
$response = $this->sendRequest($alivetestRequest);
86+
$this->alivetestSent = true;
87+
88+
return $response;
8089
}
8190
}

0 commit comments

Comments
 (0)