mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-24 02:13:15 +00:00
Smart facet value escaping
This commit is contained in:
@@ -20,6 +20,8 @@ use Alchemy\Phrasea\SearchEngine\Elastic\IndexerSubscriber;
|
|||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\Escaper;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\FacetsResponse;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryParser;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryParser;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
|
||||||
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine;
|
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine;
|
||||||
@@ -67,10 +69,17 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
|
|||||||
return new ElasticSearchEngine(
|
return new ElasticSearchEngine(
|
||||||
$app,
|
$app,
|
||||||
$app['elasticsearch.client'],
|
$app['elasticsearch.client'],
|
||||||
$app['elasticsearch.options']['index']
|
$app['elasticsearch.options']['index'],
|
||||||
|
$app['locales.available'],
|
||||||
|
$app['elasticsearch.record_helper'],
|
||||||
|
$app['elasticsearch.facets_response.factory']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$app['elasticsearch.facets_response.factory'] = $app->protect(function (array $response) use ($app) {
|
||||||
|
return new FacetsResponse(new Excaper(), $response);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/* Indexer related services */
|
/* Indexer related services */
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic;
|
|||||||
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\FacetsResponse;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\FacetsResponse;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||||
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
|
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
|
||||||
@@ -39,12 +40,13 @@ class ElasticSearchEngine implements SearchEngineInterface
|
|||||||
private $locales;
|
private $locales;
|
||||||
private $recordHelper;
|
private $recordHelper;
|
||||||
|
|
||||||
public function __construct(Application $app, Client $client, $indexName)
|
public function __construct(Application $app, Client $client, $indexName, array $locales, RecordHelper $recordHelper, Closure $facetsResponseFactory)
|
||||||
{
|
{
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
$this->client = $client;
|
$this->client = $client;
|
||||||
$this->locales = array_keys($app['locales.available']);
|
$this->locales = array_keys($locales);
|
||||||
$this->recordHelper = $this->app['elasticsearch.record_helper'];
|
$this->recordHelper = $recordHelper;
|
||||||
|
$this->facetsResponseFactory = $facetsResponseFactory;
|
||||||
|
|
||||||
if ('' === trim($indexName)) {
|
if ('' === trim($indexName)) {
|
||||||
throw new \InvalidArgumentException('The provided index name is invalid.');
|
throw new \InvalidArgumentException('The provided index name is invalid.');
|
||||||
@@ -292,7 +294,7 @@ class ElasticSearchEngine implements SearchEngineInterface
|
|||||||
$results[] = ElasticsearchRecordHydrator::hydrate($hit['_source'], $n++);
|
$results[] = ElasticsearchRecordHydrator::hydrate($hit['_source'], $n++);
|
||||||
}
|
}
|
||||||
|
|
||||||
$facets = new FacetsResponse($res);
|
$facets = $this->facetsResponseFactory->__invoke($res);
|
||||||
|
|
||||||
$query['ast'] = $this->app['query_parser']->parse($string)->dump();
|
$query['ast'] = $this->app['query_parser']->parse($string)->dump();
|
||||||
$query['query_main'] = $recordQuery;
|
$query['query_main'] = $recordQuery;
|
||||||
|
|||||||
@@ -7,10 +7,13 @@ use JsonSerializable;
|
|||||||
|
|
||||||
class FacetsResponse implements JsonSerializable
|
class FacetsResponse implements JsonSerializable
|
||||||
{
|
{
|
||||||
|
private $escaper;
|
||||||
private $facets = array();
|
private $facets = array();
|
||||||
|
|
||||||
public function __construct(array $response)
|
public function __construct(Escaper $escaper, array $response)
|
||||||
{
|
{
|
||||||
|
$this->escaper = $escaper;
|
||||||
|
|
||||||
if (!isset($response['aggregations'])) {
|
if (!isset($response['aggregations'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -47,12 +50,10 @@ class FacetsResponse implements JsonSerializable
|
|||||||
|
|
||||||
private function buildQuery($name, $value)
|
private function buildQuery($name, $value)
|
||||||
{
|
{
|
||||||
// Strip double quotes from values to prevent broken queries
|
$value = $this->escaper->escapeWord($value);
|
||||||
$value = str_replace('/"/u', ' ', $value);
|
|
||||||
// TODO escape value when escaping is supported in query parser
|
|
||||||
return ($name === 'Collection') ?
|
return ($name === 'Collection') ?
|
||||||
sprintf('collection:"%s"', $value) :
|
sprintf('collection:%s', $value) :
|
||||||
sprintf('"%s" IN %s', $value, $name);
|
sprintf('%s IN %s', $value, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function throwAggregationResponseError()
|
private function throwAggregationResponseError()
|
||||||
|
|||||||
Reference in New Issue
Block a user