Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into sensorario-naming-convention
- Loading branch information
Showing
19 changed files
with
1,024 additions
and
299 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
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,131 @@ | ||
# Additional Filters | ||
|
||
Aims to limit information in response, based on predefined rules. Those rule | ||
must be stored inside your application's user. | ||
|
||
## User | ||
|
||
User must respect `\Mado\QueryBundle\Interfaces\AdditionalFilterable` interface | ||
and implement methods `getAdditionalFilters()`. | ||
|
||
## Custom Filter | ||
|
||
To work with additional filters, is necessary a custom filter. This should | ||
respect the interface `Mado\QueryBundle\Interfaces\CustomFilter`. | ||
|
||
### Example | ||
|
||
You can create your custom filter using this syntax. | ||
|
||
```php | ||
<?php | ||
|
||
namespace Mt\AdditionalFilters; | ||
|
||
class YourCustomFilter implements CustomFilter | ||
{ | ||
private static $filterMap = [ | ||
'filter_name' => \Bundle\To\EntityClass::class, | ||
]; | ||
|
||
public function __construct( | ||
EntityManagerInterface $manager, | ||
GraphWalker $dijkstraWalker, | ||
RequestStack $requestStack, | ||
LoggerInterface $logger | ||
) { | ||
$this->manager = $manager; | ||
$this->dijkstraWalker = $dijkstraWalker; | ||
$this->requestStack = $requestStack; | ||
$this->logger = $logger; | ||
} | ||
|
||
public function setUser(AdditionalFilterable $user) | ||
{ | ||
$this->additionalFilters = AdditionalFilterExtractor::fromUser($user); | ||
return $this; | ||
} | ||
|
||
public function allItemsTo(string $entity) | ||
{ | ||
$this->entity = $entity; | ||
$filters = []; | ||
$translations = [ | ||
'filter_name' => [ | ||
'from' => '_embedded.shops.id', | ||
'to' => 'id', | ||
], | ||
]; | ||
foreach ($translations as $filterName => $filterTranslation) { | ||
if ($this->additionalFilters->getFilters($filterName) != '') { | ||
$path = $this->getPathTo($filterName); | ||
$genericAdditionalFilter = Filter::box([ | ||
'ids' => $this->additionalFilters->getFilters($filterName), | ||
'path' => $path, | ||
]); | ||
$filterKey = $genericAdditionalFilter->getFieldAndOperator(); | ||
if ([] != $filterTranslation) { | ||
if ($filterKey == $filterTranslation['from'] . '|' . $genericAdditionalFilter->getOperator()) { | ||
$filterKey = $filterTranslation['to'] . '|' . $genericAdditionalFilter->getOperator(); | ||
$genericAdditionalFilter = $genericAdditionalFilter->withFullPath($filterKey); | ||
} | ||
} | ||
$filtering = $this->requestStack->getCurrentRequest()->query->get('filtering', []); | ||
$haveCheckedAdditionalFilters = false; | ||
$field = $genericAdditionalFilter->getField(); | ||
foreach( $filtering as $filterKey => $value) { | ||
$genericQueryStringFilter = Filter::fromQueryStringFilter([ | ||
$filterKey => $value | ||
]); | ||
if ($genericAdditionalFilter->getField() == $genericQueryStringFilter->getField()) { | ||
if ( | ||
$genericAdditionalFilter->getOperator() == 'list' | ||
&& $genericAdditionalFilter->getOperator() == $genericQueryStringFilter->getOperator() | ||
) { | ||
$haveCheckedAdditionalFilters = true; | ||
$additionalFiltersIds = explode(',', $genericAdditionalFilter->getIds()); | ||
$querystringIds = explode(',', $genericQueryStringFilter->getIds()); | ||
$intersection = array_intersect($querystringIds, $additionalFiltersIds); | ||
$ids = join(',', $intersection); | ||
if ($intersection == []) { | ||
throw new ForbiddenContentException( | ||
'Oops! Forbidden requested id ' . $value | ||
. ' is not available. Available are ' | ||
. $genericAdditionalFilter->getIds() | ||
); | ||
} | ||
$filters[$genericAdditionalFilter->getFieldAndOperator()] = $ids; | ||
} | ||
} | ||
} | ||
if (!$haveCheckedAdditionalFilters) { | ||
$ids = $genericAdditionalFilter->getIds(); | ||
$filters[$genericAdditionalFilter->getFieldAndOperator()] = $ids; | ||
} | ||
} | ||
} | ||
|
||
return $filters; | ||
} | ||
|
||
public function getPathTo(string $filter) | ||
{ | ||
$this->dijkstraWalker->buildPathBetween( | ||
$this->entity, | ||
self::getEntityFromFilter($filter) | ||
); | ||
return $this->dijkstraWalker->getPath(); | ||
} | ||
|
||
public static function getEntityFromFilter(string $filterName) | ||
{ | ||
return self::$filterMap[$filterName]; | ||
} | ||
|
||
public function setEntity(string $entity) | ||
{ | ||
$this->entity = $entity; | ||
return $this; | ||
} | ||
} | ||
``` |
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
7 changes: 7 additions & 0 deletions
7
src/Mado/QueryBundle/Exceptions/ForbiddenContentException.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,7 @@ | ||
<?php | ||
|
||
namespace Mado\QueryBundle\Exceptions; | ||
|
||
final class ForbiddenContentException extends \Exception | ||
{ | ||
} |
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,9 @@ | ||
<?php | ||
|
||
namespace Mado\QueryBundle\Exceptions; | ||
|
||
use Exception; | ||
|
||
final class InvalidFiltersException extends Exception | ||
{ | ||
} |
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,8 @@ | ||
<?php | ||
|
||
namespace Mado\QueryBundle\Interfaces; | ||
|
||
interface AdditionalFilterable | ||
{ | ||
public function getAdditionalFilters(); | ||
} |
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,28 @@ | ||
<?php | ||
|
||
namespace Mado\QueryBundle\Interfaces; | ||
|
||
use Doctrine\ORM\EntityManagerInterface; | ||
use Mado\QueryBundle\Component\Meta\GraphWalker; | ||
use Psr\Log\LoggerInterface; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
interface CustomFilter | ||
{ | ||
public function __construct( | ||
EntityManagerInterface $manager, | ||
GraphWalker $walter, | ||
RequestStack $requestStack, | ||
LoggerInterface $logger | ||
); | ||
|
||
public function setUser(AdditionalFilterable $user); | ||
|
||
public function allItemsTo(string $entity); | ||
|
||
public function getPathTo(string $fullyQualifiedClassName); | ||
|
||
public static function getEntityFromFilter(string $filterName); | ||
|
||
public function setEntity(string $entity); | ||
} |
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,116 @@ | ||
<?php | ||
|
||
namespace Mado\QueryBundle\Objects; | ||
|
||
class Filter | ||
{ | ||
private $rawFilter; | ||
|
||
private $ids; | ||
|
||
private $operator; | ||
|
||
public static function box(array $params) | ||
{ | ||
$rawIds = $params['ids']; | ||
$path = $params['path']; | ||
|
||
$operator = key($rawIds); | ||
$ids = join(',', current($rawIds)); | ||
|
||
return new self([ | ||
'raw_filter' => self::buildRawFilter($path, $operator), | ||
'ids' => $ids, | ||
'operator' => $operator, | ||
'path' => $path, | ||
]); | ||
} | ||
|
||
private static function buildRawFilter($path, $operator) | ||
{ | ||
return $path . '.id|' . $operator; | ||
} | ||
|
||
private function __construct(array $params) | ||
{ | ||
$this->rawFilter = $params['raw_filter']; | ||
$this->ids = $params['ids']; | ||
$this->operator = $params['operator']; | ||
$this->path = $params['path']; | ||
} | ||
|
||
public function getFieldAndOperator() | ||
{ | ||
return $this->rawFilter; | ||
} | ||
|
||
public function getIds() | ||
{ | ||
return $this->ids; | ||
} | ||
|
||
public function getOperator() | ||
{ | ||
return $this->operator; | ||
} | ||
|
||
public function getPath() | ||
{ | ||
return $this->path; | ||
} | ||
|
||
public function withPath($path) | ||
{ | ||
$rawFilter = self::buildRawFilter($path, $this->operator); | ||
|
||
if ($path == '') { | ||
$rawFilter = str_replace('.', '', $rawFilter); | ||
} | ||
|
||
return new self([ | ||
'raw_filter' => $rawFilter, | ||
'ids' => $this->ids, | ||
'operator' => $this->operator, | ||
'path' => $path, | ||
]); | ||
} | ||
|
||
public function withFullPath($path) | ||
{ | ||
$explodedPath = explode('|', $path); | ||
|
||
$path = $explodedPath[0]; | ||
$operator = $explodedPath[1]; | ||
|
||
return new self([ | ||
'raw_filter' => join('|', $explodedPath), | ||
'ids' => $this->ids, | ||
'operator' => $operator, | ||
'path' => $path, | ||
]); | ||
} | ||
|
||
public function getField() | ||
{ | ||
$explodedPath = explode('|', $this->getFieldAndOperator()); | ||
|
||
$field = $explodedPath[0]; | ||
|
||
return $field; | ||
} | ||
|
||
public static function fromQueryStringFilter(array $params) | ||
{ | ||
return new self([ | ||
'raw_filter' => key($params), | ||
'ids' => current($params), | ||
'operator' => explode('|', key($params))[1], | ||
'path' => null, | ||
]); | ||
} | ||
|
||
public function getValue() | ||
{ | ||
return $this->ids; | ||
} | ||
} |
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
Oops, something went wrong.