#35 - Add Limit support for departure repository
This commit is contained in:
parent
f3a6c3e8eb
commit
db30d69cdb
@ -5,7 +5,10 @@ namespace App\Controller\Api\v1;
|
|||||||
|
|
||||||
use App\Controller\Controller;
|
use App\Controller\Controller;
|
||||||
use App\Model\Departure;
|
use App\Model\Departure;
|
||||||
|
use App\Modifier\FieldFilter;
|
||||||
use App\Modifier\IdFilter;
|
use App\Modifier\IdFilter;
|
||||||
|
use App\Modifier\Limit;
|
||||||
|
use App\Modifier\With;
|
||||||
use App\Provider\DepartureRepository;
|
use App\Provider\DepartureRepository;
|
||||||
use App\Provider\StopRepository;
|
use App\Provider\StopRepository;
|
||||||
use App\Service\SerializerContextFactory;
|
use App\Service\SerializerContextFactory;
|
||||||
@ -33,11 +36,11 @@ class DeparturesController extends Controller
|
|||||||
* @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=Departure::class)))
|
* @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=Departure::class)))
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function stop(DepartureRepository $departures, StopRepository $stops, $stop)
|
public function stop(DepartureRepository $departures, StopRepository $stops, $stop, Request $request)
|
||||||
{
|
{
|
||||||
$stop = $stops->first(new IdFilter($stop));
|
$stop = $stops->first(new IdFilter($stop));
|
||||||
|
|
||||||
return $this->json($departures->getForStop($stop));
|
return $this->json($departures->current(collect($stop), ...$this->getModifiersFromRequest($request)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,16 +68,21 @@ class DeparturesController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function stops(DepartureRepository $departures, StopRepository $stops, Request $request)
|
public function stops(DepartureRepository $departures, StopRepository $stops, Request $request)
|
||||||
{
|
{
|
||||||
$stops = $stops
|
$stops = $stops->all(new IdFilter($request->query->get('stop')));
|
||||||
->all(new IdFilter($request->query->get('stop')))
|
$result = $departures->current($stops, ...$this->getModifiersFromRequest($request));
|
||||||
->flatMap(ref([ $departures, 'getForStop' ]))
|
|
||||||
->sortBy(property('departure'));
|
|
||||||
|
|
||||||
return $this->json(
|
return $this->json(
|
||||||
$stops->values()->slice(0, (int)$request->query->get('limit', 8)),
|
$result->values()->slice(0, (int)$request->query->get('limit', 8)),
|
||||||
200,
|
200,
|
||||||
[],
|
[],
|
||||||
$this->serializerContextFactory->create(Departure::class, ['Default'])
|
$this->serializerContextFactory->create(Departure::class, ['Default'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getModifiersFromRequest(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->query->has('limit')) {
|
||||||
|
yield Limit::count($request->query->getInt('limit'));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class RelatedFilterDatabaseGenericHandler implements ModifierHandler, ServiceSub
|
|||||||
|
|
||||||
if (!array_key_exists($modifier->getRelationship(), $this->mapping[$type])) {
|
if (!array_key_exists($modifier->getRelationship(), $this->mapping[$type])) {
|
||||||
throw new \InvalidArgumentException(
|
throw new \InvalidArgumentException(
|
||||||
sprintf("Relationship %s is not supported for .", $type)
|
sprintf("Relationship %s is not supported for %s.", $modifier->getRelationship(), $type)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@ namespace App\Provider;
|
|||||||
|
|
||||||
|
|
||||||
use App\Model\Stop;
|
use App\Model\Stop;
|
||||||
|
use App\Modifier\Modifier;
|
||||||
use Tightenco\Collect\Support\Collection;
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
|
||||||
interface DepartureRepository extends Repository
|
interface DepartureRepository extends Repository
|
||||||
{
|
{
|
||||||
public function getForStop(Stop $stop): Collection;
|
public function current(iterable $stops, Modifier ...$modifiers);
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ use App\Model\Departure;
|
|||||||
use App\Model\Line;
|
use App\Model\Line;
|
||||||
use App\Model\Stop;
|
use App\Model\Stop;
|
||||||
use App\Model\Vehicle;
|
use App\Model\Vehicle;
|
||||||
|
use App\Modifier\Modifier;
|
||||||
use App\Provider\DepartureRepository;
|
use App\Provider\DepartureRepository;
|
||||||
use App\Service\Proxy\ReferenceFactory;
|
use App\Service\Proxy\ReferenceFactory;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
@ -25,21 +26,21 @@ class DummyDepartureRepository implements DepartureRepository
|
|||||||
$this->reference = $reference;
|
$this->reference = $reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getForStop(Stop $stop): Collection
|
public function current(iterable $stops, Modifier ...$modifiers)
|
||||||
{
|
{
|
||||||
return collect([
|
return collect([
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
[ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
|
[1, Line::TYPE_TRAM, 'lorem ipsum', 2137],
|
||||||
])->map(function ($departure) use ($stop) {
|
])->map(function ($departure) use ($stop) {
|
||||||
list($symbol, $type, $display, $vehicle) = $departure;
|
[$symbol, $type, $display, $vehicle] = $departure;
|
||||||
$scheduled = new Carbon();
|
$scheduled = new Carbon();
|
||||||
$estimated = (clone $scheduled)->addSeconds(40);
|
$estimated = (clone $scheduled)->addSeconds(40);
|
||||||
|
|
||||||
|
@ -10,18 +10,22 @@ use App\Model\Vehicle;
|
|||||||
use App\Modifier\FieldFilter;
|
use App\Modifier\FieldFilter;
|
||||||
use App\Modifier\IdFilter;
|
use App\Modifier\IdFilter;
|
||||||
use App\Modifier\Limit;
|
use App\Modifier\Limit;
|
||||||
|
use App\Modifier\Modifier;
|
||||||
use App\Modifier\RelatedFilter;
|
use App\Modifier\RelatedFilter;
|
||||||
use App\Modifier\With;
|
use App\Modifier\With;
|
||||||
use App\Provider\Database\GenericScheduleRepository;
|
use App\Provider\Database\GenericScheduleRepository;
|
||||||
use App\Provider\DepartureRepository;
|
use App\Provider\DepartureRepository;
|
||||||
use App\Provider\LineRepository;
|
use App\Provider\LineRepository;
|
||||||
use App\Provider\ScheduleRepository;
|
use App\Provider\ScheduleRepository;
|
||||||
|
use App\Service\IterableUtils;
|
||||||
|
use App\Service\ModifierUtils;
|
||||||
use App\Service\Proxy\ReferenceFactory;
|
use App\Service\Proxy\ReferenceFactory;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use JMS\Serializer\Tests\Fixtures\Discriminator\Car;
|
use JMS\Serializer\Tests\Fixtures\Discriminator\Car;
|
||||||
use Tightenco\Collect\Support\Collection;
|
use Tightenco\Collect\Support\Collection;
|
||||||
use Kadet\Functional\Transforms as t;
|
use Kadet\Functional\Transforms as t;
|
||||||
use function App\Functions\setup;
|
use function App\Functions\setup;
|
||||||
|
use function Kadet\Functional\ref;
|
||||||
|
|
||||||
class ZtmGdanskDepartureRepository implements DepartureRepository
|
class ZtmGdanskDepartureRepository implements DepartureRepository
|
||||||
{
|
{
|
||||||
@ -46,16 +50,22 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
|
|||||||
$this->schedule = $schedule;
|
$this->schedule = $schedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getForStop(Stop $stop): Collection
|
public function current(iterable $stops, Modifier ...$modifiers)
|
||||||
{
|
{
|
||||||
$real = $this->getRealDepartures($stop);
|
$real = IterableUtils::toCollection($stops)
|
||||||
|
->flatMap(ref([$this, 'getRealDepartures']))
|
||||||
|
->sortBy(t\property('estimated'))
|
||||||
|
;
|
||||||
|
|
||||||
$now = Carbon::now()->second(0);
|
$now = Carbon::now()->second(0);
|
||||||
$first = $real->map(t\getter('scheduled'))->min() ?? $now;
|
$first = $real->map(t\getter('scheduled'))->min() ?? $now;
|
||||||
$scheduled = $this->getScheduledDepartures($stop, $first);
|
$scheduled = $this->getScheduledDepartures($stops, $first, ...$this->extractModifiers($modifiers));
|
||||||
|
|
||||||
return $this->pair($scheduled, $real)->filter(function (Departure $departure) use ($now) {
|
$result = $this->pair($scheduled, $real)->filter(function (Departure $departure) use ($now) {
|
||||||
return $departure->getDeparture() > $now;
|
return $departure->getDeparture() > $now;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return $this->processResultWithModifiers($result, $modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRealDepartures(Stop $stop)
|
private function getRealDepartures(Stop $stop)
|
||||||
@ -94,14 +104,14 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
|
|||||||
})->values();
|
})->values();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getScheduledDepartures(Stop $stop, Carbon $time)
|
private function getScheduledDepartures($stop, Carbon $time, Modifier ...$modifiers)
|
||||||
{
|
{
|
||||||
return $this->schedule->all(
|
return $this->schedule->all(
|
||||||
new RelatedFilter($stop),
|
new RelatedFilter($stop, Stop::class),
|
||||||
new FieldFilter('departure', $time, '>='),
|
new FieldFilter('departure', $time, '>='),
|
||||||
new With('track'),
|
new With('track'),
|
||||||
new With('destination'),
|
new With('destination'),
|
||||||
Limit::count(16)
|
...$modifiers
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,4 +191,31 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
|
|||||||
$converted->setStop($stop->getStop());
|
$converted->setStop($stop->getStop());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function extractModifiers(iterable $modifiers)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
/** @var Limit $limit */
|
||||||
|
if ($limit = ModifierUtils::getOfType($modifiers, Limit::class)) {
|
||||||
|
$result[] = new Limit($limit->getOffset(), $limit->getCount() * 2);
|
||||||
|
} else {
|
||||||
|
$result[] = Limit::count(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processResultWithModifiers(Collection $result, iterable $modifiers)
|
||||||
|
{
|
||||||
|
foreach ($modifiers as $modifier) {
|
||||||
|
switch (true) {
|
||||||
|
case $modifier instanceof Limit:
|
||||||
|
$result = $result->slice($modifier->getOffset(), $modifier->getCount());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
29
src/Service/ModifierUtils.php
Normal file
29
src/Service/ModifierUtils.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use Kadet\Functional\Predicate;
|
||||||
|
use function Kadet\Functional\Predicates\instance;
|
||||||
|
|
||||||
|
final class ModifierUtils
|
||||||
|
{
|
||||||
|
public static function get(iterable $modifiers, Predicate $predicate)
|
||||||
|
{
|
||||||
|
return collect($modifiers)->first($predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getOfType(iterable $modifiers, $class)
|
||||||
|
{
|
||||||
|
return self::get($modifiers, instance($class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function hasAny(iterable $modifiers, Predicate $predicate)
|
||||||
|
{
|
||||||
|
return collect($modifiers)->contains($predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function hasAnyOfType(iterable $modifiers, $class)
|
||||||
|
{
|
||||||
|
return collect($modifiers)->contains(instance($class));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user