Skip to content

Commit

Permalink
IBX-7653: Add FilterParser and IsContainer criterion parser
Browse files Browse the repository at this point in the history
  • Loading branch information
tischsoic committed Feb 22, 2024
1 parent b420bb5 commit 245d179
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/bundle/Resources/config/input_parsers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ services:
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.ContentQuery }

Ibexa\Rest\Server\Input\Parser\FilterParser:
parent: Ibexa\Rest\Server\Common\Parser
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.Filter }

Ibexa\Rest\Server\Input\Parser\LocationQuery:
parent: Ibexa\Rest\Server\Common\Parser
class: Ibexa\Rest\Server\Input\Parser\LocationQuery
Expand Down Expand Up @@ -441,6 +446,14 @@ services:
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.UserMetadata }

Ibexa\Rest\Server\Input\Parser\Criterion\IsContainer:
parent: Ibexa\Rest\Server\Common\Parser
class: Ibexa\Rest\Server\Input\Parser\Criterion\IsContainer
arguments:
$parserTools: '@Ibexa\Rest\Input\ParserTools'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.IsContainer }

Ibexa\Rest\Server\Input\Parser\Criterion\IsUserBased:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
Expand Down
35 changes: 35 additions & 0 deletions src/lib/Server/Input/Parser/Criterion/IsContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

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

namespace Ibexa\Rest\Server\Input\Parser\Criterion;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\IsContainer as IsContainerCriterion;
use Ibexa\Contracts\Rest\Exceptions;
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
use Ibexa\Rest\Input\BaseParser;
use Ibexa\Rest\Input\ParserTools;

class IsContainer extends BaseParser
{
/** @var \Ibexa\Rest\Input\ParserTools */
protected $parserTools;

public function __construct(ParserTools $parserTools)
{
$this->parserTools = $parserTools;
}

public function parse(array $data, ParsingDispatcher $parsingDispatcher): IsContainerCriterion
{
if (!array_key_exists('IsContainer', $data)) {
throw new Exceptions\Parser('Invalid <IsContainer> format');
}

return new IsContainerCriterion($this->parserTools->parseBooleanValue($data['IsContainer']));
}
}
98 changes: 98 additions & 0 deletions src/lib/Server/Input/Parser/FilterParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace Ibexa\Rest\Server\Input\Parser;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion as CriterionValue;
use Ibexa\Contracts\Core\Repository\Values\Filter\Filter;
use Ibexa\Contracts\Rest\Exceptions;
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
use Ibexa\Rest\Input\BaseParser;

/**
* @internal
*/
final class FilterParser extends BaseParser
{
/**
* Parses input structure to a Query.
*
* @param array $data
* @param \Ibexa\Contracts\Rest\Input\ParsingDispatcher $parsingDispatcher
*
* @throws \Ibexa\Contracts\Rest\Exceptions\Parser
*
* @return \Ibexa\Contracts\Core\Repository\Values\Filter\Filter
*/
public function parse(array $data, ParsingDispatcher $parsingDispatcher): Filter
{
$filter = new Filter();
if (array_key_exists('criteria', $data) && is_array($data['criteria'])) {
$filter->andWithCriterion($this->processCriteriaArray($data['criteria'], $parsingDispatcher));
}

// limit
if (array_key_exists('limit', $data)) {
$filter->withLimit((int)$data['limit']);
}

// offset
if (array_key_exists('offset', $data)) {
$filter->withOffset((int)$data['offset']);
}

return $filter;
}

/**
* @param array $criteriaArray
* @param \Ibexa\Contracts\Rest\Input\ParsingDispatcher $parsingDispatcher
*
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion|null A criterion, or a LogicalAnd with a set of Criterion, or null if an empty array was given
*/
private function processCriteriaArray(array $criteriaArray, ParsingDispatcher $parsingDispatcher)
{
if (count($criteriaArray) === 0) {
return null;
}

$criteria = [];
foreach ($criteriaArray as $criteriaSpec) {
$criterionName = $criteriaSpec['type'];
$criterionData = $criteriaSpec['value'];

$criteria[] = $this->dispatchCriterion($criterionName, $criterionData, $parsingDispatcher);
}

return (count($criteria) === 1) ? $criteria[0] : new CriterionValue\LogicalAnd($criteria);
}

/**
* Dispatches parsing of a criterion name + data to its own parser.
*
* @param string $criterionName
* @param mixed $criterionData
* @param \Ibexa\Contracts\Rest\Input\ParsingDispatcher $parsingDispatcher
*
* @throws \Ibexa\Contracts\Rest\Exceptions\Parser
*
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion
*/
public function dispatchCriterion($criterionName, $criterionData, ParsingDispatcher $parsingDispatcher)
{
$mediaType = $this->getCriterionMediaType($criterionName);
try {
return $parsingDispatcher->parse([$criterionName => $criterionData], $mediaType);
} catch (Exceptions\Parser $e) {
throw new Exceptions\Parser("Invalid Criterion id <$criterionName> in <AND>", 0, $e);
}
}

protected function getCriterionMediaType($criterionName)
{
return 'application/vnd.ibexa.api.internal.criterion.' . $criterionName;
}
}

0 comments on commit 245d179

Please sign in to comment.