Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-32110: Exposed more search result data from Pagefanta adapters #144

Merged
merged 2 commits into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Scenario: A content view can be configured to run and render a query and return
}
"""
When I view a content matched by the view configuration above
Then the Query results assigned to the "children" twig variable is a "Pagerfanta\Pagerfanta" object
Then the Query results assigned to the "children" twig variable is a "eZ\Publish\Core\Pagination\Pagerfanta\Pagerfanta" object

Scenario: A content view can be configured to run and render a query return a PagerFanta Object and set limit and page name
Given a content item that matches the view configuration block below
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
use eZ\Publish\Core\Pagination\Pagerfanta\Pagerfanta;
use eZ\Publish\Core\Pagination\Pagerfanta\ContentSearchHitAdapter;
use eZ\Publish\Core\Pagination\Pagerfanta\LocationSearchHitAdapter;
use eZ\Publish\Core\QueryType\ContentViewQueryTypeMapper;
use Pagerfanta\Adapter\AdapterInterface;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Request;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
namespace eZ\Publish\Core\MVC\Symfony\Controller;

use eZ\Publish\Core\MVC\Symfony\View\QueryView;
use eZ\Publish\Core\Pagination\Pagerfanta\Pagerfanta;
use eZ\Publish\Core\Pagination\Pagerfanta\AdapterFactory\SearchHitAdapterFactoryInterface;
use eZ\Publish\Core\Pagination\Pagerfanta\SearchResultAdapter;
use eZ\Publish\Core\Query\QueryFactoryInterface;
use Pagerfanta\Adapter\AdapterInterface;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\OptionsResolver\OptionsResolver;

Expand Down Expand Up @@ -92,7 +92,7 @@ private function resolveOptions(array $options): array
return $resolver->resolve($options);
}

private function getAdapter(array $options): AdapterInterface
private function getAdapter(array $options): SearchResultAdapter
{
$query = $this->queryFactory->create(
$options['query']['query_type'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
use eZ\Publish\Core\MVC\Symfony\Controller\QueryRenderController;
use eZ\Publish\Core\MVC\Symfony\View\QueryView;
use eZ\Publish\Core\Pagination\Pagerfanta\AdapterFactory\SearchHitAdapterFactoryInterface;
use eZ\Publish\Core\Pagination\Pagerfanta\Pagerfanta;
use eZ\Publish\Core\Pagination\Pagerfanta\SearchResultAdapter;
use eZ\Publish\Core\Query\QueryFactoryInterface;
use Pagerfanta\Adapter\AdapterInterface;
use Pagerfanta\Pagerfanta;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;

Expand Down Expand Up @@ -113,7 +114,7 @@ private function configureMocks(array $options): AdapterInterface
)
->willReturn($query);

$adapter = $this->createMock(AdapterInterface::class);
$adapter = $this->createMock(SearchResultAdapter::class);

$this->searchHitAdapterFactory
->method('createAdapter')
Expand Down
149 changes: 149 additions & 0 deletions eZ/Publish/Core/Pagination/Pagerfanta/AbstractSearchResultAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace eZ\Publish\Core\Pagination\Pagerfanta;

use eZ\Publish\API\Repository\SearchService;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Search\AggregationResultCollection;
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult;
use Pagerfanta\Adapter\AdapterInterface;

abstract class AbstractSearchResultAdapter implements AdapterInterface, SearchResultAdapter
{
/** @var \eZ\Publish\API\Repository\SearchService */
private $searchService;

/** @var \eZ\Publish\API\Repository\Values\Content\Query */
private $query;

/** @var array */
private $languageFilter;

/** @var \eZ\Publish\API\Repository\Values\Content\Search\AggregationResultCollection|null */
private $aggregations;

/** @var float|null */
private $time;

/** @var bool|null */
private $timedOut;

/** @var float|null */
private $maxScore;

/** @var int|null */
private $totalCount;

public function __construct(Query $query, SearchService $searchService, array $languageFilter = [])
{
$this->query = $query;
$this->searchService = $searchService;
$this->languageFilter = $languageFilter;
}

/**
* Returns the number of results.
*
* @return int The number of results.
*/
public function getNbResults()
{
if (isset($this->totalCount)) {
return $this->totalCount;
}

$countQuery = clone $this->query;
$countQuery->limit = 0;
// Skip facets/aggregations computing
$countQuery->facetBuilders = [];
$countQuery->aggregations = [];

$searchResults = $this->executeQuery(
$this->searchService,
$countQuery,
$this->languageFilter
);

return $this->totalCount = $searchResults->totalCount;
}

/**
* Returns a slice of the results, as SearchHit objects.
*
* @param int $offset The offset.
* @param int $length The length.
*
* @return \eZ\Publish\API\Repository\Values\Content\Search\SearchHit[]
*/
public function getSlice($offset, $length)
{
$query = clone $this->query;
$query->offset = $offset;
$query->limit = $length;
$query->performCount = false;

$searchResult = $this->executeQuery(
$this->searchService,
$query,
$this->languageFilter
);

$this->aggregations = $searchResult->aggregations;
$this->time = $searchResult->time;
$this->timedOut = $searchResult->timedOut;
$this->maxScore = $searchResult->maxScore;

// Set count for further use if returned by search engine despite !performCount (Solr, ES)
if (!isset($this->totalCount) && isset($searchResult->totalCount)) {
$this->totalCount = $searchResult->totalCount;
}

return $searchResult->searchHits;
}

public function getAggregations(): AggregationResultCollection
{
if ($this->aggregations === null) {
$aggregationQuery = clone $this->query;
$aggregationQuery->offset = 0;
$aggregationQuery->limit = 0;

$searchResults = $this->executeQuery(
$this->searchService,
$aggregationQuery,
$this->languageFilter
);

$this->aggregations = $searchResults->aggregations;
}

return $this->aggregations;
}

public function getTime(): ?float
{
return $this->time;
}

public function getTimedOut(): ?bool
{
return $this->timedOut;
}

public function getMaxScore(): ?float
{
return $this->maxScore;
}

abstract protected function executeQuery(
SearchService $searchService,
Query $query,
array $languageFilter
): SearchResult;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\Core\Pagination\Pagerfanta\ContentSearchHitAdapter;
use eZ\Publish\Core\Pagination\Pagerfanta\FixedSearchResultHitAdapter;
use eZ\Publish\Core\Pagination\Pagerfanta\LocationSearchHitAdapter;
use Pagerfanta\Adapter\AdapterInterface;
use Pagerfanta\Adapter\FixedAdapter;

/**
* @internal
Expand Down Expand Up @@ -46,9 +46,6 @@ public function createFixedAdapter(Query $query, array $languageFilter = []): Ad
$searchResults = $this->searchService->findContent($query, $languageFilter);
}

return new FixedAdapter(
$searchResults->totalCount,
$searchResults->searchHits
);
return new FixedSearchResultHitAdapter($searchResults);
}
}
75 changes: 7 additions & 68 deletions eZ/Publish/Core/Pagination/Pagerfanta/ContentSearchHitAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,81 +7,20 @@
namespace eZ\Publish\Core\Pagination\Pagerfanta;

use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult;
use eZ\Publish\API\Repository\SearchService;
use Pagerfanta\Adapter\AdapterInterface;

/**
* Pagerfanta adapter for eZ Publish content search.
* Will return results as SearchHit objects.
*/
class ContentSearchHitAdapter implements AdapterInterface
class ContentSearchHitAdapter extends AbstractSearchResultAdapter
{
/** @var \eZ\Publish\API\Repository\Values\Content\Query */
private $query;

/** @var \eZ\Publish\API\Repository\SearchService */
private $searchService;

/** @var array */
private $languageFilter;

/** @var int */
private $nbResults;

public function __construct(
Query $query,
protected function executeQuery(
SearchService $searchService,
array $languageFilter = []
) {
$this->query = $query;
$this->searchService = $searchService;
$this->languageFilter = $languageFilter;
}

/**
* Returns the number of results.
*
* @return int The number of results.
*/
public function getNbResults()
{
if (isset($this->nbResults)) {
return $this->nbResults;
}

$countQuery = clone $this->query;
$countQuery->limit = 0;

$searchResult = $this->searchService->findContent(
$countQuery,
$this->languageFilter
);

return $this->nbResults = $searchResult->totalCount;
}

/**
* Returns a slice of the results, as SearchHit objects.
*
* @param int $offset The offset.
* @param int $length The length.
*
* @return \eZ\Publish\API\Repository\Values\Content\Search\SearchHit[]
*/
public function getSlice($offset, $length)
{
$query = clone $this->query;
$query->offset = $offset;
$query->limit = $length;
$query->performCount = false;

$searchResult = $this->searchService->findContent($query, $this->languageFilter);

// Set count for further use if returned by search engine despite !performCount (Solr, ES)
if (!isset($this->nbResults) && isset($searchResult->totalCount)) {
$this->nbResults = $searchResult->totalCount;
}

return $searchResult->searchHits;
Query $query,
array $languageFilter
): SearchResult {
return $searchService->findContent($query, $languageFilter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace eZ\Publish\Core\Pagination\Pagerfanta;

use eZ\Publish\API\Repository\Values\Content\Search\AggregationResultCollection;
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult;

final class FixedSearchResultHitAdapter implements SearchResultAdapter
{
/** @var \eZ\Publish\API\Repository\Values\Content\Search\SearchResult */
private $searchResult;

public function __construct(SearchResult $searchResult)
{
$this->searchResult = $searchResult;
}

public function getNbResults(): int
{
return $this->searchResult->totalCount ?? -1;
}

public function getSlice($offset, $length)
{
return $this->searchResult->searchHits;
}

public function getAggregations(): AggregationResultCollection
{
return $this->searchResult->aggregations;
}

public function getTime(): ?float
{
return $this->searchResult->time;
}

public function getTimedOut(): ?bool
{
return $this->searchResult->timedOut;
}

public function getMaxScore(): ?float
{
return $this->searchResult->maxScore;
}
}
Loading