Skip to content

Instantly share code, notes, and snippets.

@kemoc
Created January 8, 2019 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kemoc/825dfb53b078d122d540439940a54105 to your computer and use it in GitHub Desktop.
Save kemoc/825dfb53b078d122d540439940a54105 to your computer and use it in GitHub Desktop.
eZPlatform Children query type
use eZ\Publish\Core\QueryType\QueryType;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
use eZ\Publish\API\Repository\Repository as RepositoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\API\Repository\Values\Content\Location as APILocation;
use eZ\Publish\API\Repository\Values\Content\LocationList;
use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException;
use eZ\Publish\Core\MVC\Legacy\Templating\GlobalHelper;
use eZ\Publish\Core\MVC\ConfigResolverInterface;
class ChildrenQueryType implements QueryType
{
const QUERY_ARG_PARENT_LOCATIONS = "parentLocations";
const QUERY_ARG_CONTENT_TYPE_IDENTIFIERS = "contentTypeIdentifiers";
const QUERY_ARG_DEPTH = "depth";
const QUERY_ARG_SORT_CLAUSES = "sortClauses";
const QUERY_ARG_OFFSET = "offset";
const QUERY_ARG_LIMIT = "limit";
const QUERY_ARG_ADDITIONAL_CRITERIONS = "additionalCriterions";//array of criterions
/**
* @var RepositoryInterface
*/
protected $repository;
/**
* @var ConfigResolverInterface
*/
protected $configResolver;
/**
* @var GlobalHelper
*/
protected $globalHelper;
/**
* ChildrenQueryType constructor.
* @param RepositoryInterface $repository
* @param ConfigResolverInterface $configResolver
* @param GlobalHelper $globalHelper
*/
public function __construct(
RepositoryInterface $repository,
ConfigResolverInterface $configResolver,
GlobalHelper $globalHelper
) {
$this->repository = $repository;
$this->configResolver = $configResolver;
$this->globalHelper = $globalHelper;
}
public function getGlobalHelper()
{
return $this->globalHelper;
}
public static function getName()
{
return 'AsdBundle:Children';
}
/**
* Returns array of required parameters
*
* @return array
*/
public function getSupportedParameters()
{
return [
self::QUERY_ARG_PARENT_LOCATIONS,
self::QUERY_ARG_CONTENT_TYPE_IDENTIFIERS,
self::QUERY_ARG_DEPTH,
self::QUERY_ARG_SORT_CLAUSES,
self::QUERY_ARG_OFFSET,
self::QUERY_ARG_LIMIT,
self::QUERY_ARG_ADDITIONAL_CRITERIONS
];
}
/**
* @param array $parameters
* @return LocationQuery
* @throws InvalidArgumentException
*/
public function getQuery(array $parameters = [])
{
/** @var string[] $subtrees */
$subtrees = [];
/** @var APILocation|null $firstLocation */
$firstLocation = null;
/** @var APILocation[] $parentLocations */
$parentLocations = [];
if (isset($parameters[self::QUERY_ARG_PARENT_LOCATIONS])) {
if (!is_array($parameters[self::QUERY_ARG_PARENT_LOCATIONS])) {
$parentLocations = [$parameters[self::QUERY_ARG_PARENT_LOCATIONS]];
} else {
$parentLocations = $parameters[self::QUERY_ARG_PARENT_LOCATIONS];
}
foreach ($parentLocations as $itemKey => $item) {
if ($itemKey == 0) {
$firstLocation = $item;
}
$subtrees[] = $item->pathString;
}
}
//$searchService = $this->repository->getSearchService();
$query = new LocationQuery();
$criteria = [
new Query\Criterion\Visibility(Query\Criterion\Visibility::VISIBLE),
new Query\Criterion\LanguageCode($this->getConfigResolver()->getParameter('languages'))
];
if (isset($parameters[self::QUERY_ARG_CONTENT_TYPE_IDENTIFIERS])) {
if (is_array($parameters[self::QUERY_ARG_CONTENT_TYPE_IDENTIFIERS])) {
$criteria[] = new Query\Criterion\ContentTypeIdentifier($parameters[self::QUERY_ARG_CONTENT_TYPE_IDENTIFIERS]);
} else {
$criteria[] = new Query\Criterion\ContentTypeIdentifier((string)$parameters[self::QUERY_ARG_CONTENT_TYPE_IDENTIFIERS]);
}
}
if (isset($parameters[self::QUERY_ARG_DEPTH])) {
if (is_numeric($parameters[self::QUERY_ARG_DEPTH])) {
$depth = (int)$parameters[self::QUERY_ARG_DEPTH];
if (count($parentLocations) === 1) {
$depth += $firstLocation->depth;
}
$criteria[] = new Query\Criterion\Location\Depth(Query\Criterion\Operator::LTE, $depth);
} elseif (is_array($parameters[self::QUERY_ARG_DEPTH])) {
$depthCriteria = [];
foreach ($parameters[self::QUERY_ARG_DEPTH] as $depthKey => $depthArr) {
$depthCriteria[] = new Query\Criterion\Location\Depth($depthArr[0], (int)$depthArr[1]);
}
$criteria[] = new Query\Criterion\LogicalAnd($depthCriteria);
}
}
if ($subtrees) {
if (count($subtrees) > 1) {
$criteria[] = new Query\Criterion\Subtree($subtrees);
} else {
$criteria[] = new Query\Criterion\Subtree((string)$subtrees[0]);
}
$query->sortClauses = [$this->getSortClauseBySortField($firstLocation->sortField, $firstLocation->sortOrder)];
} else {
$query->sortClauses = [
new SortClause\Location\Priority(LocationQuery::SORT_DESC),
];
}
if (isset($parameters[self::QUERY_ARG_ADDITIONAL_CRITERIONS])) {
$criteria = array_merge($criteria, $parameters[self::QUERY_ARG_ADDITIONAL_CRITERIONS]);
}
if (isset($parameters[self::QUERY_ARG_SORT_CLAUSES])) {
if (!is_array($parameters[self::QUERY_ARG_SORT_CLAUSES])) {
$sortClauses = (array)$parameters[self::QUERY_ARG_SORT_CLAUSES];
} else {
$sortClauses = $parameters[self::QUERY_ARG_SORT_CLAUSES];
}
$query->sortClauses = $sortClauses;
}
if (isset($parameters[self::QUERY_ARG_OFFSET])) {
$offset = (int)$parameters[self::QUERY_ARG_OFFSET];
if ($offset > -1) {
$query->offset = $offset;
}
}
if (isset($parameters[self::QUERY_ARG_LIMIT])) {
$limit = (int)$parameters[self::QUERY_ARG_LIMIT];
if ($limit > -1) {
$query->limit = $limit;
}
}
$query->query = new Query\Criterion\LogicalAnd($criteria);
return $query;
}
/**
* @return \eZ\Publish\Core\MVC\ConfigResolverInterface
*/
public function getConfigResolver()
{
return $this->configResolver;
}
/**
* Instantiates a correct sort clause object based on provided location sort field and sort order.
*
* @param int $sortField
* @param int $sortOrder
*
* @return \eZ\Publish\API\Repository\Values\Content\Query\SortClause
*/
public function getSortClauseBySortField($sortField, $sortOrder = APILocation::SORT_ORDER_ASC)
{
$sortOrder = $sortOrder == APILocation::SORT_ORDER_DESC ? Query::SORT_DESC : Query::SORT_ASC;
switch ($sortField) {
case APILocation::SORT_FIELD_PATH:
return new SortClause\Location\Path($sortOrder);
case APILocation::SORT_FIELD_PUBLISHED:
return new SortClause\DatePublished($sortOrder);
case APILocation::SORT_FIELD_MODIFIED:
return new SortClause\DateModified($sortOrder);
case APILocation::SORT_FIELD_SECTION:
return new SortClause\SectionIdentifier($sortOrder);
case APILocation::SORT_FIELD_DEPTH:
return new SortClause\Location\Depth($sortOrder);
//@todo: sort clause not yet implemented
// case APILocation::SORT_FIELD_CLASS_IDENTIFIER:
//@todo: sort clause not yet implemented
// case APILocation::SORT_FIELD_CLASS_NAME:
case APILocation::SORT_FIELD_PRIORITY:
return new SortClause\Location\Priority($sortOrder);
case APILocation::SORT_FIELD_NAME:
return new SortClause\ContentName($sortOrder);
//@todo: sort clause not yet implemented
// case APILocation::SORT_FIELD_MODIFIED_SUBNODE:
case APILocation::SORT_FIELD_NODE_ID:
return new SortClause\Location\Id($sortOrder);
case APILocation::SORT_FIELD_CONTENTOBJECT_ID:
return new SortClause\ContentId($sortOrder);
default:
return new SortClause\Location\Path($sortOrder);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment