#35 - Add stop filter for tracks
This commit is contained in:
parent
9d0e4fdb2a
commit
f4e3ee6f55
@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace App\Controller\Api\v1;
|
namespace App\Controller\Api\v1;
|
||||||
|
|
||||||
use App\Controller\Controller;
|
use App\Controller\Controller;
|
||||||
@ -42,7 +41,8 @@ class StopsController extends Controller
|
|||||||
* name="id",
|
* name="id",
|
||||||
* in="query",
|
* in="query",
|
||||||
* type="array",
|
* type="array",
|
||||||
* description="Stop identificators to retrieve at once. Can be used to bulk load data. If not specified will return all data.",
|
* description="Stop identificators to retrieve at once. Can be used to bulk load data. If not specified will
|
||||||
|
* return all data.",
|
||||||
* @SWG\Items(type="string")
|
* @SWG\Items(type="string")
|
||||||
* )
|
* )
|
||||||
*
|
*
|
||||||
@ -136,27 +136,18 @@ class StopsController extends Controller
|
|||||||
})->values();
|
})->values();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function getModifiersFromRequest(Request $request)
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function getModifiersFromRequest(Request $request): array
|
|
||||||
{
|
{
|
||||||
$modifiers = [];
|
|
||||||
|
|
||||||
if ($request->query->has('name')) {
|
if ($request->query->has('name')) {
|
||||||
$modifiers[] = FieldFilter::contains('name', $request->query->get('name'));
|
yield FieldFilter::contains('name', $request->query->get('name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->query->has('id')) {
|
if ($request->query->has('id')) {
|
||||||
$modifiers[] = new IdFilter($request->query->get('id'));
|
yield new IdFilter($request->query->get('id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->query->has('include-destinations')) {
|
if ($request->query->has('include-destinations')) {
|
||||||
$modifiers[] = new IncludeDestinations();
|
yield new IncludeDestinations();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $modifiers;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ use App\Model\Track;
|
|||||||
use App\Modifier\IdFilter;
|
use App\Modifier\IdFilter;
|
||||||
use App\Modifier\RelatedFilter;
|
use App\Modifier\RelatedFilter;
|
||||||
use App\Provider\TrackRepository;
|
use App\Provider\TrackRepository;
|
||||||
|
use App\Service\IterableUtils;
|
||||||
use Nelmio\ApiDocBundle\Annotation\Model;
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
@ -31,43 +32,31 @@ class TracksController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request, TrackRepository $repository)
|
public function index(Request $request, TrackRepository $repository)
|
||||||
{
|
{
|
||||||
switch (true) {
|
$modifiers = $this->getModifiersFromRequest($request);
|
||||||
case $request->query->has('stop'):
|
|
||||||
return $this->byStop($request, $repository);
|
return $this->json($repository->all(...$modifiers));
|
||||||
case $request->query->has('line'):
|
}
|
||||||
return $this->byLine($request, $repository);
|
|
||||||
case $request->query->has('id'):
|
private function getModifiersFromRequest(Request $request)
|
||||||
return $this->byId($request, $repository);
|
{
|
||||||
default:
|
if ($request->query->has('stop')) {
|
||||||
throw new BadRequestHttpException(
|
$stop = $request->query->get('stop');
|
||||||
sprintf(
|
$stop = Stop::reference($stop);
|
||||||
'At least one parameter of %s must be set.',
|
|
||||||
implode(', ', ['stop', 'line', 'id'])
|
yield new RelatedFilter($stop);
|
||||||
)
|
}
|
||||||
);
|
|
||||||
|
if ($request->query->has('line')) {
|
||||||
|
$line = $request->query->get('line');
|
||||||
|
$line = Line::reference($line);
|
||||||
|
|
||||||
|
yield new RelatedFilter($line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->query->has('id')) {
|
||||||
|
$id = encapsulate($request->query->get('id'));
|
||||||
|
|
||||||
|
yield new IdFilter($id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function byId(Request $request, TrackRepository $repository)
|
|
||||||
{
|
|
||||||
$id = encapsulate($request->query->get('id'));
|
|
||||||
|
|
||||||
return $this->json($repository->all(new IdFilter($id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function byStop(Request $request, TrackRepository $repository)
|
|
||||||
{
|
|
||||||
$stop = $request->query->get('stop');
|
|
||||||
$stop = array_map([Stop::class, 'reference'], encapsulate($stop));
|
|
||||||
|
|
||||||
return $this->json($repository->getByStop($stop));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function byLine(Request $request, TrackRepository $repository)
|
|
||||||
{
|
|
||||||
$line = $request->query->get('line');
|
|
||||||
$line = Line::reference($line);
|
|
||||||
|
|
||||||
return $this->json($repository->all(new RelatedFilter($line)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Handler\Database;
|
namespace App\Handler\Database;
|
||||||
|
|
||||||
use App\Entity\LineEntity;
|
|
||||||
use App\Entity\ProviderEntity;
|
|
||||||
use App\Event\HandleDatabaseModifierEvent;
|
use App\Event\HandleDatabaseModifierEvent;
|
||||||
use App\Event\HandleModifierEvent;
|
use App\Event\HandleModifierEvent;
|
||||||
use App\Handler\ModifierHandler;
|
use App\Handler\ModifierHandler;
|
||||||
use App\Model\Line;
|
use App\Model\Line;
|
||||||
use App\Model\Referable;
|
use App\Model\Stop;
|
||||||
use App\Model\Track;
|
use App\Model\Track;
|
||||||
use App\Modifier\RelatedFilter;
|
use App\Modifier\RelatedFilter;
|
||||||
use App\Service\IdUtils;
|
use App\Service\IdUtils;
|
||||||
|
use App\Service\ReferenceFactory;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||||
@ -21,22 +20,25 @@ class RelatedFilterDatabaseGenericHandler implements ModifierHandler, ServiceSub
|
|||||||
protected $mapping = [
|
protected $mapping = [
|
||||||
Track::class => [
|
Track::class => [
|
||||||
Line::class => 'line',
|
Line::class => 'line',
|
||||||
|
Stop::class => TrackByStopDatabaseHandler::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $references = [
|
|
||||||
Line::class => LineEntity::class,
|
|
||||||
];
|
|
||||||
|
|
||||||
private $em;
|
private $em;
|
||||||
private $inner;
|
private $inner;
|
||||||
private $id;
|
private $id;
|
||||||
|
private $references;
|
||||||
|
|
||||||
public function __construct(ContainerInterface $inner, EntityManagerInterface $em, IdUtils $idUtils)
|
public function __construct(
|
||||||
{
|
ContainerInterface $inner,
|
||||||
|
EntityManagerInterface $em,
|
||||||
|
IdUtils $idUtils,
|
||||||
|
ReferenceFactory $references
|
||||||
|
) {
|
||||||
$this->inner = $inner;
|
$this->inner = $inner;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->id = $idUtils;
|
$this->id = $idUtils;
|
||||||
|
$this->references = $references;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process(HandleModifierEvent $event)
|
public function process(HandleModifierEvent $event)
|
||||||
@ -65,8 +67,15 @@ class RelatedFilterDatabaseGenericHandler implements ModifierHandler, ServiceSub
|
|||||||
|
|
||||||
$relationship = $this->mapping[$type][$modifier->getRelationship()];
|
$relationship = $this->mapping[$type][$modifier->getRelationship()];
|
||||||
|
|
||||||
|
if ($this->inner->has($relationship)) {
|
||||||
|
/** @var ModifierHandler $inner */
|
||||||
|
$inner = $this->inner->get($relationship);
|
||||||
|
$inner->process($event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$parameter = sprintf(":%s_%s", $alias, $relationship);
|
$parameter = sprintf(":%s_%s", $alias, $relationship);
|
||||||
$reference = $this->getEntityReference($modifier->getRelated(), $event->getMeta()['provider']);
|
$reference = $this->references->create($modifier->getRelated(), $event->getMeta()['provider']);
|
||||||
|
|
||||||
$builder
|
$builder
|
||||||
->join(sprintf('%s.%s', $alias, $relationship), $relationship)
|
->join(sprintf('%s.%s', $alias, $relationship), $relationship)
|
||||||
@ -75,22 +84,13 @@ class RelatedFilterDatabaseGenericHandler implements ModifierHandler, ServiceSub
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: extract that to separate service
|
|
||||||
private function getEntityReference(Referable $object, ProviderEntity $provider)
|
|
||||||
{
|
|
||||||
return $this->em->getReference(
|
|
||||||
$this->references[get_class($object)],
|
|
||||||
$this->id->generate($provider, $object->getId())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public static function getSubscribedServices()
|
public static function getSubscribedServices()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
TrackRelatedFilterDatabaseHandler::class,
|
TrackByStopDatabaseHandler::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
src/Handler/Database/TrackByStopDatabaseHandler.php
Normal file
43
src/Handler/Database/TrackByStopDatabaseHandler.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Handler\Database;
|
||||||
|
|
||||||
|
use App\Entity\StopInTrack;
|
||||||
|
use App\Event\HandleDatabaseModifierEvent;
|
||||||
|
use App\Event\HandleModifierEvent;
|
||||||
|
use App\Handler\ModifierHandler;
|
||||||
|
use App\Modifier\RelatedFilter;
|
||||||
|
use App\Service\ReferenceFactory;
|
||||||
|
|
||||||
|
class TrackByStopDatabaseHandler implements ModifierHandler
|
||||||
|
{
|
||||||
|
private $references;
|
||||||
|
|
||||||
|
public function __construct(ReferenceFactory $references)
|
||||||
|
{
|
||||||
|
$this->references = $references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(HandleModifierEvent $event)
|
||||||
|
{
|
||||||
|
if (!$event instanceof HandleDatabaseModifierEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var RelatedFilter $modifier */
|
||||||
|
$modifier = $event->getModifier();
|
||||||
|
$builder = $event->getBuilder();
|
||||||
|
$alias = $event->getMeta()['alias'];
|
||||||
|
|
||||||
|
$relationship = 'stopsInTrack';
|
||||||
|
|
||||||
|
$parameter = sprintf(":%s_%s", $alias, $relationship);
|
||||||
|
$reference = $this->references->create($modifier->getRelated(), $event->getMeta()['provider']);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->join(sprintf("%s.%s", $alias, $relationship), 'stop_in_track')
|
||||||
|
->andWhere(sprintf("stop_in_track.stop = %s", $parameter))
|
||||||
|
->setParameter($parameter, $reference)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
42
src/Service/ReferenceFactory.php
Normal file
42
src/Service/ReferenceFactory.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use App\Entity\LineEntity;
|
||||||
|
use App\Entity\ProviderEntity;
|
||||||
|
use App\Entity\StopEntity;
|
||||||
|
use App\Model\Line;
|
||||||
|
use App\Model\Referable;
|
||||||
|
use App\Model\Stop;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
final class ReferenceFactory
|
||||||
|
{
|
||||||
|
protected $mapping = [
|
||||||
|
Line::class => LineEntity::class,
|
||||||
|
Stop::class => StopEntity::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
private $em;
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em, IdUtils $id)
|
||||||
|
{
|
||||||
|
$this->em = $em;
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(Referable $object, ProviderEntity $provider)
|
||||||
|
{
|
||||||
|
$class = get_class($object);
|
||||||
|
|
||||||
|
if (!array_key_exists($class, $this->mapping)) {
|
||||||
|
throw new \InvalidArgumentException(sprintf("Cannot make entity reference of %s.", $class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->em->getReference(
|
||||||
|
$this->mapping[$class],
|
||||||
|
$this->id->generate($provider, $object->getId())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user