Add Limit support for departure repository
This commit is contained in:
parent
1a0515742e
commit
3e695bfef7
@ -5,7 +5,10 @@ namespace App\Controller\Api\v1;
|
||||
|
||||
use App\Controller\Controller;
|
||||
use App\Model\Departure;
|
||||
use App\Modifier\FieldFilter;
|
||||
use App\Modifier\IdFilter;
|
||||
use App\Modifier\Limit;
|
||||
use App\Modifier\With;
|
||||
use App\Provider\DepartureRepository;
|
||||
use App\Provider\StopRepository;
|
||||
use App\Service\SerializerContextFactory;
|
||||
@ -33,11 +36,11 @@ class DeparturesController extends Controller
|
||||
* @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));
|
||||
|
||||
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)
|
||||
{
|
||||
$stops = $stops
|
||||
->all(new IdFilter($request->query->get('stop')))
|
||||
->flatMap(ref([ $departures, 'getForStop' ]))
|
||||
->sortBy(property('departure'));
|
||||
$stops = $stops->all(new IdFilter($request->query->get('stop')));
|
||||
$result = $departures->current($stops, ...$this->getModifiersFromRequest($request));
|
||||
|
||||
return $this->json(
|
||||
$stops->values()->slice(0, (int)$request->query->get('limit', 8)),
|
||||
$result->values()->slice(0, (int)$request->query->get('limit', 8)),
|
||||
200,
|
||||
[],
|
||||
$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])) {
|
||||
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\Modifier\Modifier;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
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\Stop;
|
||||
use App\Model\Vehicle;
|
||||
use App\Modifier\Modifier;
|
||||
use App\Provider\DepartureRepository;
|
||||
use App\Service\Proxy\ReferenceFactory;
|
||||
use Carbon\Carbon;
|
||||
@ -25,21 +26,21 @@ class DummyDepartureRepository implements DepartureRepository
|
||||
$this->reference = $reference;
|
||||
}
|
||||
|
||||
public function getForStop(Stop $stop): Collection
|
||||
public function current(iterable $stops, Modifier ...$modifiers)
|
||||
{
|
||||
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) {
|
||||
list($symbol, $type, $display, $vehicle) = $departure;
|
||||
[$symbol, $type, $display, $vehicle] = $departure;
|
||||
$scheduled = new Carbon();
|
||||
$estimated = (clone $scheduled)->addSeconds(40);
|
||||
|
||||
@ -53,4 +54,4 @@ class DummyDepartureRepository implements DepartureRepository
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,18 +10,22 @@ use App\Model\Vehicle;
|
||||
use App\Modifier\FieldFilter;
|
||||
use App\Modifier\IdFilter;
|
||||
use App\Modifier\Limit;
|
||||
use App\Modifier\Modifier;
|
||||
use App\Modifier\RelatedFilter;
|
||||
use App\Modifier\With;
|
||||
use App\Provider\Database\GenericScheduleRepository;
|
||||
use App\Provider\DepartureRepository;
|
||||
use App\Provider\LineRepository;
|
||||
use App\Provider\ScheduleRepository;
|
||||
use App\Service\IterableUtils;
|
||||
use App\Service\ModifierUtils;
|
||||
use App\Service\Proxy\ReferenceFactory;
|
||||
use Carbon\Carbon;
|
||||
use JMS\Serializer\Tests\Fixtures\Discriminator\Car;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
use Kadet\Functional\Transforms as t;
|
||||
use function App\Functions\setup;
|
||||
use function Kadet\Functional\ref;
|
||||
|
||||
class ZtmGdanskDepartureRepository implements DepartureRepository
|
||||
{
|
||||
@ -46,16 +50,22 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
|
||||
$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);
|
||||
$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 $this->processResultWithModifiers($result, $modifiers);
|
||||
}
|
||||
|
||||
private function getRealDepartures(Stop $stop)
|
||||
@ -94,14 +104,14 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
|
||||
})->values();
|
||||
}
|
||||
|
||||
private function getScheduledDepartures(Stop $stop, Carbon $time)
|
||||
private function getScheduledDepartures($stop, Carbon $time, Modifier ...$modifiers)
|
||||
{
|
||||
return $this->schedule->all(
|
||||
new RelatedFilter($stop),
|
||||
new RelatedFilter($stop, Stop::class),
|
||||
new FieldFilter('departure', $time, '>='),
|
||||
new With('track'),
|
||||
new With('destination'),
|
||||
Limit::count(16)
|
||||
...$modifiers
|
||||
);
|
||||
}
|
||||
|
||||
@ -181,4 +191,31 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
|
||||
$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