diff --git a/app/Console/Commands/RefreshCurrentTrips.php b/app/Console/Commands/RefreshCurrentTrips.php index f6cc80afc..437e133ad 100644 --- a/app/Console/Commands/RefreshCurrentTrips.php +++ b/app/Console/Commands/RefreshCurrentTrips.php @@ -61,7 +61,7 @@ public function handle(): int { $this->info('Refreshing trip ' . $trip->trip_id . ' (' . $trip->linename . ')...'); $trip->update(['last_refreshed' => now()]); - $rawHafas = $this->getDataProvider()::fetchRawHafasTrip($trip->trip_id, $trip->linename); + $rawHafas = $this->getDataProvider()->fetchRawHafasTrip($trip->trip_id, $trip->linename); $updatedCounts = HafasStopoverService::refreshStopovers($rawHafas); $this->info('Updated ' . $updatedCounts->stopovers . ' stopovers.'); diff --git a/app/DataProviders/DataProviderInterface.php b/app/DataProviders/DataProviderInterface.php index b8cfd85bc..6dba69387 100644 --- a/app/DataProviders/DataProviderInterface.php +++ b/app/DataProviders/DataProviderInterface.php @@ -8,19 +8,17 @@ interface DataProviderInterface { - public static function fetchHafasTrip(string $tripID, string $lineName); + public function fetchHafasTrip(string $tripID, string $lineName); - public static function fetchRawHafasTrip(string $tripId, string $lineName); + public function fetchRawHafasTrip(string $tripId, string $lineName); - public static function getStations(string $query, int $results); + public function getStations(string $query, int $results); - public static function getDepartures(Station $station, Carbon $when, int $duration = 15, TravelType $type = null, bool $localtime = false); + public function getDepartures(Station $station, Carbon $when, int $duration = 15, TravelType $type = null, bool $localtime = false); - public static function fetchDepartures(Station $station, Carbon $when, int $duration, TravelType $type, bool $skipTimeShift); + public function getNearbyStations(float $latitude, float $longitude, int $results); - public static function getNearbyStations(float $latitude, float $longitude, int $results); + public function getStationByRilIdentifier(string $rilIdentifier); - public static function getStationByRilIdentifier(string $rilIdentifier); - - public static function getStationsByFuzzyRilIdentifier(string $rilIdentifier); + public function getStationsByFuzzyRilIdentifier(string $rilIdentifier); } diff --git a/app/DataProviders/HafasController.php b/app/DataProviders/HafasController.php index 80de81a9b..ac9833756 100644 --- a/app/DataProviders/HafasController.php +++ b/app/DataProviders/HafasController.php @@ -25,20 +25,20 @@ class HafasController extends Controller implements DataProviderInterface { - private static function getHttpClient(): PendingRequest { + + private function client(): PendingRequest { return Http::baseUrl(config('trwl.db_rest')) ->timeout(config('trwl.db_rest_timeout')); } - public static function getStationByRilIdentifier(string $rilIdentifier): ?Station { + public function getStationByRilIdentifier(string $rilIdentifier): ?Station { $station = Station::where('rilIdentifier', $rilIdentifier)->first(); if ($station !== null) { return $station; } try { - $response = self::getHttpClient() - ->get("/stations/$rilIdentifier"); + $response = $this->client()->get("/stations/$rilIdentifier"); if ($response->ok() && !empty($response->body()) && $response->body() !== '[]') { $data = json_decode($response->body(), false, 512, JSON_THROW_ON_ERROR); $station = StationRepository::parseHafasStopObject($data); @@ -49,29 +49,30 @@ public static function getStationByRilIdentifier(string $rilIdentifier): ?Statio return $station; } - public static function getStationsByFuzzyRilIdentifier(string $rilIdentifier): ?Collection { + public function getStationsByFuzzyRilIdentifier(string $rilIdentifier): ?Collection { $stations = Station::where('rilIdentifier', 'LIKE', "$rilIdentifier%")->orderBy('rilIdentifier')->get(); if ($stations->count() > 0) { return $stations; } - return collect([self::getStationByRilIdentifier(rilIdentifier: $rilIdentifier)]); + return collect([$this->getStationByRilIdentifier(rilIdentifier: $rilIdentifier)]); } /** * @throws HafasException */ - public static function getStations(string $query, int $results = 10): Collection { + public function getStations(string $query, int $results = 10): Collection { try { - $response = self::getHttpClient() - ->get("/locations", - [ - 'query' => $query, - 'fuzzy' => 'true', - 'stops' => 'true', - 'addresses' => 'false', - 'poi' => 'false', - 'results' => $results - ]); + $response = $this->client()->get( + "/locations", + [ + 'query' => $query, + 'fuzzy' => 'true', + 'stops' => 'true', + 'addresses' => 'false', + 'poi' => 'false', + 'results' => $results + ] + ); $data = json_decode($response->body(), false, 512, JSON_THROW_ON_ERROR); if (empty($data) || !$response->ok()) { @@ -87,13 +88,16 @@ public static function getStations(string $query, int $results = 10): Collection /** * @throws HafasException */ - public static function getNearbyStations(float $latitude, float $longitude, int $results = 8): Collection { + public function getNearbyStations(float $latitude, float $longitude, int $results = 8): Collection { try { - $response = self::getHttpClient()->get("/stops/nearby", [ - 'latitude' => $latitude, - 'longitude' => $longitude, - 'results' => $results - ]); + $response = $this->client()->get( + "/stops/nearby", + [ + 'latitude' => $latitude, + 'longitude' => $longitude, + 'results' => $results + ] + ); if (!$response->ok()) { throw new HafasException(__('messages.exception.generalHafas')); @@ -117,14 +121,13 @@ public static function getNearbyStations(float $latitude, float $longitude, int * @throws HafasException * @throws JsonException */ - public static function fetchDepartures( + private function fetchDepartures( Station $station, Carbon $when, int $duration = 15, TravelType $type = null, bool $skipTimeShift = false ) { - $client = self::getHttpClient(); $time = $skipTimeShift ? $when : (clone $when)->shiftTimezone("Europe/Berlin"); $query = [ 'when' => $time->toIso8601String(), @@ -140,7 +143,7 @@ public static function fetchDepartures( HTT::TRAM->value => FptfHelper::checkTravelType($type, TravelType::TRAM), HTT::TAXI->value => FptfHelper::checkTravelType($type, TravelType::TAXI), ]; - $response = $client->get('/stops/' . $station->ibnr . '/departures', $query); + $response = $this->client()->get('/stops/' . $station->ibnr . '/departures', $query); if (!$response->ok()) { throw new HafasException(__('messages.exception.generalHafas')); @@ -159,7 +162,7 @@ public static function fetchDepartures( * @return Collection * @throws HafasException */ - public static function getDepartures( + public function getDepartures( Station $station, Carbon $when, int $duration = 15, @@ -169,7 +172,7 @@ public static function getDepartures( try { $requestTime = is_null($station->time_offset) || $localtime ? $when : (clone $when)->subHours($station->time_offset); - $data = self::fetchDepartures( + $data = $this->fetchDepartures( $station, $requestTime, $duration, @@ -188,14 +191,14 @@ public static function getDepartures( // Check if the timezone for this station is equal in its offset to Europe/Berlin. // If so, fetch again **without** adjusting the timezone if ($timezone === CarbonTimeZone::create("Europe/Berlin")->toOffsetName()) { - $data = self::fetchDepartures($station, $when, $duration, $type, true); + $data = $this->fetchDepartures($station, $when, $duration, $type, true); $station->shift_time = false; $station->save(); break; } // if the timezone is not equal to Europe/Berlin, fetch the offset - $data = self::fetchDepartures($station, (clone $when)->subHours($offset), $duration, $type); + $data = $this->fetchDepartures($station, (clone $when)->subHours($offset), $duration, $type); $station->time_offset = $offset; $station->save(); @@ -236,8 +239,8 @@ public static function getDepartures( /** * @throws HafasException|JsonException */ - public static function fetchRawHafasTrip(string $tripId, string $lineName) { - $tripResponse = self::getHttpClient()->get("trips/" . rawurlencode($tripId), [ + public function fetchRawHafasTrip(string $tripId, string $lineName) { + $tripResponse = $this->client()->get("trips/" . rawurlencode($tripId), [ 'lineName' => $lineName, 'polyline' => 'true', 'stopovers' => 'true' @@ -265,8 +268,8 @@ public static function fetchRawHafasTrip(string $tripId, string $lineName) { * @return Trip * @throws HafasException|JsonException */ - public static function fetchHafasTrip(string $tripID, string $lineName): Trip { - $tripJson = self::fetchRawHafasTrip($tripID, $lineName); + public function fetchHafasTrip(string $tripID, string $lineName): Trip { + $tripJson = $this->fetchRawHafasTrip($tripID, $lineName); $origin = Repositories\StationRepository::parseHafasStopObject($tripJson->origin); $destination = Repositories\StationRepository::parseHafasStopObject($tripJson->destination); $operator = null; diff --git a/app/DataProviders/HafasStopoverService.php b/app/DataProviders/HafasStopoverService.php index 62e580f53..0bc726ae1 100644 --- a/app/DataProviders/HafasStopoverService.php +++ b/app/DataProviders/HafasStopoverService.php @@ -85,7 +85,7 @@ public static function refreshStopovers(stdClass $rawHafas): stdClass { * @throws HafasException */ public function refreshStopover(Stopover $stopover): void { - $departure = $this->dataProvider::getDepartures( + $departure = $this->dataProvider->getDepartures( station: $stopover->station, when: $stopover->departure_planned, )->filter(function(stdClass $trip) use ($stopover) { diff --git a/app/DataProviders/Repositories/StationRepository.php b/app/DataProviders/Repositories/StationRepository.php index 1e3836d6a..55bcd28fa 100644 --- a/app/DataProviders/Repositories/StationRepository.php +++ b/app/DataProviders/Repositories/StationRepository.php @@ -28,9 +28,10 @@ public static function parseHafasStopObject(stdClass $hafasStop): Station { $data['rilIdentifier'] = $hafasStop->ril100; } - return Station::updateOrCreate([ - 'ibnr' => $hafasStop->id - ], $data); + return Station::updateOrCreate( + ['ibnr' => $hafasStop->id], + $data + ); } public static function parseHafasStops(array $hafasResponse): Collection { diff --git a/app/Http/Controllers/API/v1/EventController.php b/app/Http/Controllers/API/v1/EventController.php index 14fc68a57..50404045b 100644 --- a/app/Http/Controllers/API/v1/EventController.php +++ b/app/Http/Controllers/API/v1/EventController.php @@ -249,7 +249,7 @@ public function suggest(Request $request): JsonResponse { ]); if (isset($validated['nearestStation'])) { - $stations = $this->dataProvider::getStations($validated['nearestStation'], 1); + $stations = $this->dataProvider->getStations($validated['nearestStation'], 1); if (count($stations) === 0) { return $this->sendError(error: __('events.request.station_not_found'), code: 400); } diff --git a/app/Http/Controllers/API/v1/TransportController.php b/app/Http/Controllers/API/v1/TransportController.php index f04170ecf..bd44e4158 100644 --- a/app/Http/Controllers/API/v1/TransportController.php +++ b/app/Http/Controllers/API/v1/TransportController.php @@ -153,7 +153,7 @@ public function getDepartures(Request $request, int $stationId): JsonResponse { $station = Station::findOrFail($stationId); try { - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $station, when: $timestamp, type: TravelType::tryFrom($validated['travelType'] ?? null), @@ -311,7 +311,7 @@ public function getNextStationByCoordinates(Request $request): JsonResponse { ]); try { - $nearestStation = $this->dataProvider::getNearbyStations( + $nearestStation = $this->dataProvider->getNearbyStations( latitude: $validated['latitude'], longitude: $validated['longitude'], results: 1 diff --git a/app/Http/Controllers/Frontend/Admin/CheckinController.php b/app/Http/Controllers/Frontend/Admin/CheckinController.php index 16a16200a..ace48b5d9 100644 --- a/app/Http/Controllers/Frontend/Admin/CheckinController.php +++ b/app/Http/Controllers/Frontend/Admin/CheckinController.php @@ -36,6 +36,8 @@ class CheckinController * @deprecated adapt admin panel to api endpoints */ public static function lookupStation(string|int $query): Station { + $dataProvider = (new DataProviderFactory)->create(HafasController::class); + //Lookup by station ibnr if (is_numeric($query)) { $station = Station::where('ibnr', $query)->first(); @@ -46,14 +48,14 @@ public static function lookupStation(string|int $query): Station { //Lookup by ril identifier if (!is_numeric($query) && strlen($query) <= 5 && ctype_upper($query)) { - $station = (new DataProviderFactory)->create(HafasController::class)::getStationByRilIdentifier($query); + $station = $dataProvider->getStationByRilIdentifier($query); if ($station !== null) { return $station; } } //Lookup HAFAS - $station = (new DataProviderFactory)->create(HafasController::class)::getStations(query: $query, results: 1)->first(); + $station = $dataProvider->getStations(query: $query, results: 1)->first(); if ($station !== null) { return $station; } @@ -69,14 +71,14 @@ public static function lookupStation(string|int $query): Station { * * @return array * @throws HafasException - * @deprecated use DataProviderInterface::getDepartures(...) directly instead (-> less overhead) + * @deprecated use DataProviderInterface->getDepartures(...) directly instead (-> less overhead) */ #[ArrayShape([ 'station' => Station::class, 'departures' => Collection::class, 'times' => "array" ])] - public static function getDepartures( + public static function getDeprecatedDepartures( string|int $stationQuery, Carbon $when = null, TravelType $travelType = null, @@ -91,7 +93,7 @@ public static function getDepartures( 'next' => $when->clone()->addMinutes(15) ]; - $departures = (new DataProviderFactory)->create(HafasController::class)::getDepartures( + $departures = (new DataProviderFactory)->create(HafasController::class)->getDepartures( station: $station, when: $when, type: $travelType, @@ -128,7 +130,7 @@ public function renderStationboard(Request $request): View|RedirectResponse { if (isset($validated['station'])) { try { - $trainStationboardResponse = self::getDepartures( + $trainStationboardResponse = self::getDeprecatedDepartures( stationQuery: $validated['station'], when: $when, travelType: TravelType::tryFrom($validated['filter'] ?? null), diff --git a/app/Http/Controllers/Frontend/Admin/EventController.php b/app/Http/Controllers/Frontend/Admin/EventController.php index edaaa8084..fd74a9fb9 100644 --- a/app/Http/Controllers/Frontend/Admin/EventController.php +++ b/app/Http/Controllers/Frontend/Admin/EventController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Frontend\Admin; use App\DataProviders\DataProviderFactory; +use App\DataProviders\DataProviderInterface; use App\DataProviders\HafasController; use App\Enum\EventRejectionReason; use App\Exceptions\HafasException; @@ -21,6 +22,12 @@ class EventController extends Controller { + private DataProviderInterface $dataProvider; + + public function __construct(string $dataProvider = null) { + $dataProvider ??= HafasController::class; + $this->dataProvider = (new DataProviderFactory())->create($dataProvider); + } private const VALIDATOR_RULES = [ 'name' => ['required', 'max:255'], @@ -148,7 +155,7 @@ public function acceptSuggestion(Request $request): RedirectResponse { } if (isset($validated['nearest_station_name'])) { - $station = (new DataProviderFactory)->create(HafasController::class)::getStations($validated['nearest_station_name'], 1)->first(); + $station = $this->dataProvider->getStations($validated['nearest_station_name'], 1)->first(); if ($station === null) { return back()->with('alert-danger', 'Die Station konnte nicht gefunden werden.'); @@ -188,7 +195,7 @@ public function create(Request $request): RedirectResponse { $station = null; if (isset($validated['nearest_station_name'])) { - $station = (new DataProviderFactory)->create(HafasController::class)::getStations($validated['nearest_station_name'], 1)->first(); + $station = $this->dataProvider->getStations($validated['nearest_station_name'], 1)->first(); if ($station === null) { return back()->with('alert-danger', 'Die Station konnte nicht gefunden werden.'); @@ -220,7 +227,7 @@ public function edit(int $id, Request $request): RedirectResponse { if (strlen($validated['nearest_station_name'] ?? '') === 0) { $validated['station_id'] = null; } elseif ($validated['nearest_station_name'] && $validated['nearest_station_name'] !== $event->station->name) { - $station = (new DataProviderFactory)->create(HafasController::class)::getStations($validated['nearest_station_name'], 1)->first(); + $station = $this->dataProvider->getStations($validated['nearest_station_name'], 1)->first(); if ($station === null) { return back()->with('alert-danger', 'Die Station konnte nicht gefunden werden.'); diff --git a/app/Http/Controllers/TransportController.php b/app/Http/Controllers/TransportController.php index b9378bb3e..c4ffc8103 100644 --- a/app/Http/Controllers/TransportController.php +++ b/app/Http/Controllers/TransportController.php @@ -4,7 +4,6 @@ use App\DataProviders\DataProviderFactory; use App\DataProviders\DataProviderInterface; -use App\DataProviders\HafasController; use App\Exceptions\HafasException; use App\Http\Resources\StationResource; use App\Models\Checkin; @@ -38,11 +37,11 @@ public function __construct(string $dataProvider) { */ public function getTrainStationAutocomplete(string $query): Collection { if (!is_numeric($query) && strlen($query) <= 5 && ctype_upper($query)) { - $stations = (new DataProviderFactory)->create(HafasController::class)::getStationsByFuzzyRilIdentifier(rilIdentifier: $query); + $stations = $this->dataProvider->getStationsByFuzzyRilIdentifier(rilIdentifier: $query); } if (!isset($stations) || $stations[0] === null) { - $stations = (new DataProviderFactory)->create(HafasController::class)::getStations($query); + $stations = $this->dataProvider->getStations($query); } return $stations->map(function(Station $station) { diff --git a/app/Repositories/CheckinHydratorRepository.php b/app/Repositories/CheckinHydratorRepository.php index 005178564..1bd1a7868 100644 --- a/app/Repositories/CheckinHydratorRepository.php +++ b/app/Repositories/CheckinHydratorRepository.php @@ -33,7 +33,7 @@ public function getHafasTrip(string $tripID, string $lineName): Trip { $trip = Trip::where('id', $tripID)->where('linename', $lineName)->first(); } $trip = $trip ?? Trip::where('trip_id', $tripID)->where('linename', $lineName)->first(); - return $trip ?? $dataProvider::fetchHafasTrip($tripID, $lineName); + return $trip ?? $dataProvider->fetchHafasTrip($tripID, $lineName); } public function findEvent(int $id): ?Event { diff --git a/tests/Feature/CheckinTest.php b/tests/Feature/CheckinTest.php index 765d45f5c..d9d1df3fd 100644 --- a/tests/Feature/CheckinTest.php +++ b/tests/Feature/CheckinTest.php @@ -34,7 +34,7 @@ public function stationboardTest(): void { $requestDate = Carbon::parse(self::DEPARTURE_TIME); - $trainStationboard = CheckinController::getDepartures( + $trainStationboard = CheckinController::getDeprecatedDepartures( stationQuery: self::FRANKFURT_HBF['name'], when: $requestDate ); diff --git a/tests/Feature/StationSearchTest.php b/tests/Feature/StationSearchTest.php index 646a396d3..2db2ad9fa 100644 --- a/tests/Feature/StationSearchTest.php +++ b/tests/Feature/StationSearchTest.php @@ -65,13 +65,16 @@ public function testIbnrLocalSearch(): void { $this->assertEquals(Station::find($expected->id)->name, $station->name); } + /** + * @throws HafasException + */ public function testGetNearbyStations(): void { Http::fake(["*/stops/nearby*" => Http::response([array_merge( self::HANNOVER_HBF, ["distance" => 421] )])]); - $result = $this->dataProvider::getNearbyStations( + $result = $this->dataProvider->getNearbyStations( self::HANNOVER_HBF['location']['latitude'], self::HANNOVER_HBF['location']['longitude']); @@ -83,7 +86,7 @@ public function testGetNearbyStationFails(): void { Http::fake(Http::response(status: 503)); $this->assertThrows(function() { - $this->dataProvider::getNearbyStations( + $this->dataProvider->getNearbyStations( self::HANNOVER_HBF['location']['latitude'], self::HANNOVER_HBF['location']['longitude']); }, HafasException::class); diff --git a/tests/Feature/Transport/BackendCheckinTest.php b/tests/Feature/Transport/BackendCheckinTest.php index 4ebeed85e..3527caa46 100644 --- a/tests/Feature/Transport/BackendCheckinTest.php +++ b/tests/Feature/Transport/BackendCheckinTest.php @@ -42,7 +42,7 @@ public function testStationNotOnTripException() { $user = User::factory()->create(); $stationHannover = HafasHelpers::getStationById(8000152); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $stationHannover, when: Carbon::parse('2023-01-12 08:00'), type: TravelType::EXPRESS, @@ -73,7 +73,7 @@ public function testSwitchedOriginAndDestinationShouldThrowException() { $user = User::factory()->create(); $station = HafasHelpers::getStationById(8000105); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $station, when: Carbon::parse('2023-01-12 08:00'), type: TravelType::EXPRESS, @@ -107,7 +107,7 @@ public function testDuplicateCheckinsShouldThrowException() { $user = User::factory()->create(); $station = HafasHelpers::getStationById(8000105); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $station, when: Carbon::parse('2023-01-12 08:00'), type: TravelType::EXPRESS, @@ -148,7 +148,7 @@ public function testCheckinAtBus603Potsdam(): void { // First: Get a train that's fine for our stuff $timestamp = Carbon::parse("2023-01-15 10:15"); try { - $trainStationboard = CheckinController::getDepartures( + $trainStationboard = CheckinController::getDeprecatedDepartures( stationQuery: 'Schloss Cecilienhof, Potsdam', when: $timestamp, travelType: TravelType::BUS @@ -215,7 +215,7 @@ public function testCheckinAtBerlinRingbahnRollingOverSuedkreuz(): void { // First: Get a train that's fine for our stuff // The 10:00 train actually quits at Südkreuz, but the 10:05 does not. $station = HafasHelpers::getStationById(8089110); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $station, when: Carbon::parse('2023-01-16 10:00'), ); @@ -268,7 +268,7 @@ public function testDistanceCalculationOnRingLinesForFirstOccurrence(): void { $user = User::factory()->create(); $stationPlantagenPotsdam = HafasHelpers::getStationById(736165); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $stationPlantagenPotsdam, when: Carbon::parse('2023-01-16 10:00'), type: TravelType::TRAM, @@ -322,7 +322,7 @@ public function testDistanceCalculationOnRingLinesForSecondOccurrence(): void { $user = User::factory()->create(); $stationPlantagenPotsdam = HafasHelpers::getStationById(736165); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $stationPlantagenPotsdam, when: Carbon::parse('2023-01-16 10:00'), ); @@ -375,7 +375,7 @@ public function testBusAirAtFrankfurtAirport(): void { $user = User::factory()->create(); $station = HafasHelpers::getStationById(102932); // Flughafen Terminal 1, Frankfurt a.M. - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $station, when: Carbon::parse('2023-01-16 10:00'), type: TravelType::BUS, @@ -416,7 +416,7 @@ public function testChangeTripDestination(): void { $user = User::factory()->create(); $station = HafasHelpers::getStationById(self::FRANKFURT_HBF['id']); - $departures = $this->dataProvider::getDepartures( + $departures = $this->dataProvider->getDepartures( station: $station, when: Carbon::parse('2023-01-16 08:00'), type: TravelType::EXPRESS,