Skip to content

Commit

Permalink
Merge d16d64f into 399d4b3
Browse files Browse the repository at this point in the history
  • Loading branch information
teohhanhui committed Sep 9, 2016
2 parents 399d4b3 + d16d64f commit 9562930
Show file tree
Hide file tree
Showing 7 changed files with 435 additions and 466 deletions.
32 changes: 31 additions & 1 deletion src/Bridge/Doctrine/Orm/Filter/AbstractFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
* {@inheritdoc}
Expand All @@ -33,16 +34,45 @@
abstract class AbstractFilter implements FilterInterface
{
protected $managerRegistry;
protected $requestStack;
protected $logger;
protected $properties;

public function __construct(ManagerRegistry $managerRegistry, LoggerInterface $logger = null, array $properties = null)
public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null)
{
$this->managerRegistry = $managerRegistry;
$this->requestStack = $requestStack;
$this->logger = $logger ?? new NullLogger();
$this->properties = $properties;
}

/**
* {@inheritdoc}
*/
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
$request = $this->requestStack->getCurrentRequest();
if (null === $request) {
return;
}

foreach ($this->extractProperties($request) as $property => $value) {
$this->filterProperty($property, $value, $queryBuilder, $queryNameGenerator, $resourceClass, $operationName);
}
}

/**
* Passes a property through the filter.
*
* @param string $property
* @param mixed $value
* @param QueryBuilder $queryBuilder
* @param QueryNameGeneratorInterface $queryNameGenerator
* @param string $resourceClass
* @param string|null $operationName
*/
abstract protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null);

/**
* Gets class metadata for the given resource.
*
Expand Down
115 changes: 51 additions & 64 deletions src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,76 +22,20 @@
/**
* Filters the collection by boolean values.
*
* Filters collection on equality of boolean properties. The value is specified
* as one of ( "true" | "false" | "1" | "0" ) in the query.
*
* For each property passed, if the resource does not have such property or if
* the value is not one of ( "true" | "false" | "1" | "0" ) the property is ignored.
*
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
* @author Teoh Han Hui <teohhanhui@gmail.com>
*/
class BooleanFilter extends AbstractFilter
{
private $requestStack;

public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null)
{
parent::__construct($managerRegistry, $logger, $properties);

$this->requestStack = $requestStack;
}

/**
* {@inheritdoc}
*
* Filters collection on equality of boolean properties. The value is specified as one of
* ( "true" | "false" | "1" | "0" ) in the query.
*
* For each property passed, if the resource does not have such property or if the value is not one of
* ( "true" | "false" | "1" | "0" ) the property is ignored.
*/
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
$request = $this->requestStack->getCurrentRequest();
if (null === $request) {
return;
}

$properties = $this->extractProperties($request);

foreach ($properties as $property => $value) {
if (
!$this->isPropertyEnabled($property) ||
!$this->isPropertyMapped($property, $resourceClass) ||
!$this->isBooleanField($property, $resourceClass)
) {
continue;
}

if (in_array($value, ['true', '1'], true)) {
$value = true;
} elseif (in_array($value, ['false', '0'], true)) {
$value = false;
} else {
$this->logger->notice('Invalid filter ignored', [
'exception' => new InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $property, implode('" | "', [
'true',
'false',
'1',
'0',
]))),
]);

continue;
}

$alias = 'o';
$field = $property;

if ($this->isPropertyNested($property)) {
list($alias, $field) = $this->addJoinsForNestedProperty($property, $alias, $queryBuilder, $queryNameGenerator);
}
$valueParameter = $queryNameGenerator->generateParameterName($field);

$queryBuilder
->andWhere(sprintf('%s.%s = :%s', $alias, $field, $valueParameter))
->setParameter($valueParameter, $value);
}
parent::__construct($managerRegistry, $requestStack, $logger, $properties);
}

/**
Expand Down Expand Up @@ -121,6 +65,49 @@ public function getDescription(string $resourceClass) : array
return $description;
}

/**
* {@inheritdoc}
*/
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
if (
!$this->isPropertyEnabled($property) ||
!$this->isPropertyMapped($property, $resourceClass) ||
!$this->isBooleanField($property, $resourceClass)
) {
return;
}

if (in_array($value, ['true', '1'], true)) {
$value = true;
} elseif (in_array($value, ['false', '0'], true)) {
$value = false;
} else {
$this->logger->notice('Invalid filter ignored', [
'exception' => new InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $property, implode('" | "', [
'true',
'false',
'1',
'0',
]))),
]);

return;
}

$alias = 'o';
$field = $property;

if ($this->isPropertyNested($property)) {
list($alias, $field) = $this->addJoinsForNestedProperty($property, $alias, $queryBuilder, $queryNameGenerator);
}
$valueParameter = $queryNameGenerator->generateParameterName($field);

$queryBuilder
->andWhere(sprintf('%s.%s = :%s', $alias, $field, $valueParameter))
->setParameter($valueParameter, $value);
}

/**
* Determines whether the given property refers to a boolean field.
*
Expand All @@ -129,7 +116,7 @@ public function getDescription(string $resourceClass) : array
*
* @return bool
*/
private function isBooleanField(string $property, string $resourceClass) : bool
protected function isBooleanField(string $property, string $resourceClass) : bool
{
$propertyParts = $this->splitPropertyParts($property);
$metadata = $this->getNestedMetadata($resourceClass, $propertyParts['associations']);
Expand Down
Loading

0 comments on commit 9562930

Please sign in to comment.