-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the LocationGuesser API that guesses a location from a content
- Loading branch information
Bertrand Dunogier
committed
Nov 25, 2020
1 parent
1d14444
commit 35c4fef
Showing
11 changed files
with
482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?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 EzSystems\EzPlatformGraphQL\Exception; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
use eZ\Publish\API\Repository\Values\Content\Location; | ||
|
||
class MultipleValidLocationsException extends \Exception | ||
{ | ||
/** | ||
* @var \eZ\Publish\API\Repository\Values\Content\Location[] | ||
*/ | ||
private $locations = []; | ||
|
||
/** | ||
* @var \eZ\Publish\API\Repository\Values\Content\Content | ||
*/ | ||
private $content; | ||
|
||
/** | ||
* @param \eZ\Publish\API\Repository\Values\Content\Content $content | ||
* @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations | ||
*/ | ||
public function __construct(Content $content, array $locations) | ||
{ | ||
$this->locations = $locations; | ||
parent::__construct( | ||
sprintf( | ||
'Could not determine which location to return for content with id %s. Possible candidates: %s)', | ||
$content->id, | ||
implode(',', array_map(function (Location $location) { return $location->pathString; }, $locations)) | ||
) | ||
); | ||
$this->content = $content; | ||
} | ||
|
||
/** | ||
* @return Location[] | ||
*/ | ||
public function getLocations(): array | ||
{ | ||
return $this->locations; | ||
} | ||
|
||
public function getContent(): Content | ||
{ | ||
return $this->content; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?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 EzSystems\EzPlatformGraphQL\Exception; | ||
|
||
use Exception; | ||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
|
||
class NoValidLocationsException extends Exception | ||
{ | ||
/** | ||
* @var \eZ\Publish\API\Repository\Values\Content\Content|\eZ\Publish\API\Repository\Values\Content\Content[] | ||
*/ | ||
private $content; | ||
|
||
/** | ||
* NoValidLocationsException constructor. | ||
* | ||
* @param \eZ\Publish\API\Repository\Values\Content\Content $content | ||
*/ | ||
public function __construct(Content $content) | ||
{ | ||
parent::__construct("No valid location could be determined for content #{$content->id}"); | ||
$this->content = $content; | ||
} | ||
|
||
public function getContent(): Content | ||
{ | ||
return $this->content; | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
src/GraphQL/Resolver/LocationGuesser/FilterLocationGuesser.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?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. | ||
*/ | ||
namespace EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser; | ||
|
||
use eZ\Publish\API\Repository\LocationService; | ||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
use eZ\Publish\API\Repository\Values\Content\Location; | ||
|
||
/** | ||
* Guesses a location based on voters. | ||
*/ | ||
class FilterLocationGuesser implements LocationGuesser | ||
{ | ||
/** | ||
* @var \EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationFilter[] | ||
*/ | ||
private $filters; | ||
|
||
/** | ||
* @var \eZ\Publish\API\Repository\LocationService | ||
*/ | ||
private $locationService; | ||
|
||
/** | ||
* @param LocationFilter[] $filters | ||
*/ | ||
public function __construct(LocationService $locationService, array $filters) | ||
{ | ||
$this->filters = $filters; | ||
$this->locationService = $locationService; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function guessLocation(Content $content): LocationGuess | ||
{ | ||
$locationList = new LocationList($content); | ||
foreach ($this->locationService->loadLocations($content->contentInfo) as $location) { | ||
$locationList->addLocation($location); | ||
} | ||
|
||
foreach ($this->filters as $filter) { | ||
$filter->filter($content, $locationList); | ||
if ($locationList->hasOneLocation()) { | ||
return new LocationGuess($content, $locationList->getLocations()); | ||
} | ||
} | ||
|
||
return new LocationGuess($content, $locationList->getLocations()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?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. | ||
*/ | ||
namespace EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
|
||
interface LocationFilter | ||
{ | ||
/** | ||
* Given a Content and a LocationList, filters out locations. | ||
* | ||
* @param \eZ\Publish\API\Repository\Values\Content\Content $content | ||
* @param \EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationList $locationList | ||
*/ | ||
public function filter(Content $content, LocationList $locationList): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?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 EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
use eZ\Publish\API\Repository\Values\Content\Location; | ||
use EzSystems\EzPlatformGraphQL\Exception; | ||
|
||
class LocationGuess | ||
{ | ||
private $content; | ||
|
||
private $locations; | ||
|
||
public function __construct(Content $content, array $locations) | ||
{ | ||
$this->content = $content; | ||
$this->locations = $locations; | ||
} | ||
|
||
/** | ||
* Returns the location guess result if the guess was successful. | ||
* | ||
* @return \eZ\Publish\API\Repository\Values\Content\Location | ||
* | ||
* @throws \EzSystems\EzPlatformGraphQL\Exception\MultipleValidLocationsException | ||
* @throws \EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\NoValidLocationsException | ||
*/ | ||
public function getLocation(): Location | ||
{ | ||
if (count($this->locations) > 1) { | ||
throw new Exception\MultipleValidLocationsException($this->content, $this->locations); | ||
} elseif (count($this->locations) === 0) { | ||
throw new NoValidLocationsException($this->content); | ||
} | ||
|
||
return $this->locations[0]; | ||
} | ||
|
||
public function isSuccessful(): bool | ||
{ | ||
return count($this->locations) === 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?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. | ||
*/ | ||
namespace EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
use eZ\Publish\API\Repository\Values\Content\Location; | ||
|
||
interface LocationGuesser | ||
{ | ||
/** | ||
* Tries to guess a valid location for a content item. | ||
* | ||
* @param \eZ\Publish\API\Repository\Values\Content\Content $content | ||
* | ||
* @return LocationGuess | ||
*/ | ||
public function guessLocation(Content $content): LocationGuess; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?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. | ||
*/ | ||
namespace EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
use eZ\Publish\API\Repository\Values\Content\Location; | ||
use EzSystems\EzPlatformGraphQL\Exception; | ||
use SplObjectStorage; | ||
|
||
/** | ||
* The result of the guesser's work. | ||
*/ | ||
class LocationList | ||
{ | ||
/** | ||
* The content item locations were guessed for. | ||
* | ||
* @var \eZ\Publish\API\Repository\Values\Content\Content | ||
*/ | ||
private $content; | ||
|
||
/** | ||
* @var \SplObjectStorage | ||
*/ | ||
private $locations; | ||
|
||
public function __construct(Content $content) | ||
{ | ||
$this->content = $content; | ||
$this->locations = new SplObjectStorage(); | ||
} | ||
|
||
public function addLocation(Location $location) | ||
{ | ||
$this->locations->attach($location); | ||
} | ||
|
||
/** | ||
* @return \eZ\Publish\API\Repository\Values\Content\Location | ||
* | ||
* @throws \EzSystems\EzPlatformGraphQL\Exception\MultipleValidLocationsException | ||
* @throws \EzSystems\EzPlatformGraphQL\Exception\NoValidLocationsException | ||
*/ | ||
public function getLocation(): Location | ||
{ | ||
if (count($this->locations) === 1) { | ||
return current($this->locations); | ||
} elseif (count($this->locations) > 1) { | ||
throw new Exception\MultipleValidLocationsException($this->content, \iterator_to_array($this->locations)); | ||
} elseif (count($this->locations) === 0) { | ||
throw new Exception\NoValidLocationsException($this->content); | ||
} | ||
} | ||
|
||
public function getLocations(): array | ||
{ | ||
return \iterator_to_array($this->locations); | ||
} | ||
|
||
/** | ||
* @param \eZ\Publish\API\Repository\Values\Content\Location $location | ||
*/ | ||
public function hasOneLocation(): bool | ||
{ | ||
return count($this->locations) === 1; | ||
} | ||
|
||
public function filter(Location $location) | ||
{ | ||
$this->locations->detach($location); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/GraphQL/Resolver/LocationGuesser/MainLocationFilter.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?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 EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Content; | ||
|
||
/** | ||
* Selects a location, if there are several, by picking the main one if it is part of the current tree root. | ||
*/ | ||
class MainLocationFilter implements LocationFilter | ||
{ | ||
public function filter(Content $content, LocationList $locationList): void | ||
{ | ||
foreach ($locationList->getLocations() as $location) { | ||
if ($location->id !== $content->contentInfo->mainLocationId) { | ||
$locationList->filter($location); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.