Reimplemented shifts json export
This commit is contained in:
parent
b0b4cb54ec
commit
7eccf2c535
|
@ -100,6 +100,7 @@ $route->get('/api[/{resource:.+}]', 'ApiController@index');
|
|||
$route->get('/atom', 'FeedController@atom');
|
||||
$route->get('/ical', 'FeedController@ical');
|
||||
$route->get('/rss', 'FeedController@rss');
|
||||
$route->get('/shifts-json-export', 'FeedController@shifts');
|
||||
|
||||
// Design
|
||||
$route->get('/design', 'DesignController@index');
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
use Carbon\CarbonTimeZone;
|
||||
use Engelsystem\Http\Exceptions\HttpForbidden;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Shifts\NeededAngelType;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
|
@ -378,84 +376,3 @@ function shift_next_controller()
|
|||
|
||||
throw_redirect(page_link_to('user_shifts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Export filtered shifts via JSON.
|
||||
* (Like shifts view)
|
||||
*/
|
||||
function shifts_json_export_controller()
|
||||
{
|
||||
$user = auth()->userFromApi();
|
||||
|
||||
if (!$user) {
|
||||
throw new HttpForbidden('{"error":"Missing or invalid ?key="}', ['content-type' => 'application/json']);
|
||||
}
|
||||
|
||||
if (!auth()->can('shifts_json_export')) {
|
||||
throw new HttpForbidden('{"error":"Not allowed"}', ['content-type' => 'application/json']);
|
||||
}
|
||||
|
||||
$shifts = Shifts_by_user(auth()->user()->id);
|
||||
$shifts->sortBy('start_date');
|
||||
$timeZone = CarbonTimeZone::create(config('timezone'));
|
||||
|
||||
$shiftsData = [];
|
||||
foreach ($shifts as $shift) {
|
||||
// Data required for the Fahrplan app integration https://github.com/johnjohndoe/engelsystem
|
||||
// See engelsystem-base/src/main/kotlin/info/metadude/kotlin/library/engelsystem/models/Shift.kt
|
||||
$data = [
|
||||
// Name of the shift (type)
|
||||
'name' => $shift->shiftType->name,
|
||||
// Shift / Talk title
|
||||
'title' => $shift->title,
|
||||
// Shift description
|
||||
'description' => $shift->description,
|
||||
|
||||
// Users comment
|
||||
'Comment' => $shift->user_comment,
|
||||
|
||||
// Shift id
|
||||
'SID' => $shift->id,
|
||||
// Shift type id
|
||||
'shifttype_id' => $shift->shift_type_id,
|
||||
// Talk URL
|
||||
'URL' => $shift->url,
|
||||
|
||||
// Room name
|
||||
'Name' => $shift->room->name,
|
||||
// Location map url
|
||||
'map_url' => $shift->room->map_url,
|
||||
|
||||
// Start timestamp
|
||||
/** @deprecated start_date should be used */
|
||||
'start' => $shift->start->timestamp,
|
||||
// Start date
|
||||
'start_date' => $shift->start->toRfc3339String(),
|
||||
// End timestamp
|
||||
/** @deprecated end_date should be used */
|
||||
'end' => $shift->end->timestamp,
|
||||
// End date
|
||||
'end_date' => $shift->end->toRfc3339String(),
|
||||
|
||||
// Timezone offset like "+01:00"
|
||||
/** @deprecated should be retrieved from start_date or end_date */
|
||||
'timezone' => $timeZone->toOffsetName(),
|
||||
// The events timezone like "Europe/Berlin"
|
||||
'event_timezone' => $timeZone->getName(),
|
||||
];
|
||||
|
||||
$shiftsData[] = [
|
||||
// Model data
|
||||
...$shift->toArray(),
|
||||
|
||||
// legacy fields (ignoring created / updated (at/by) data)
|
||||
'RID' => $shift->room_id,
|
||||
|
||||
// Fahrplan app required data
|
||||
...$data
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
raw_output(json_encode($shiftsData));
|
||||
}
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
|
||||
namespace Engelsystem\Controllers;
|
||||
|
||||
use Carbon\CarbonTimeZone;
|
||||
use Engelsystem\Helpers\Authenticator;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\News;
|
||||
use Engelsystem\Models\Shifts\ShiftEntry;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class FeedController extends BaseController
|
||||
{
|
||||
/** @var array<string, string> */
|
||||
protected array $permissions = [
|
||||
'atom' => 'atom',
|
||||
'rss' => 'atom',
|
||||
'ical' => 'ical',
|
||||
'atom' => 'atom',
|
||||
'rss' => 'atom',
|
||||
'ical' => 'ical',
|
||||
'shifts' => 'shifts_json_export',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
|
@ -52,6 +55,75 @@ class FeedController extends BaseController
|
|||
->withView('api/ical', ['shiftEntries' => $shifts]);
|
||||
}
|
||||
|
||||
public function shifts(): Response
|
||||
{
|
||||
/** @var Collection|ShiftEntry[] $shiftEntries */
|
||||
$shiftEntries = $this->getShifts();
|
||||
$timeZone = CarbonTimeZone::create(config('timezone'));
|
||||
|
||||
$response = [];
|
||||
foreach ($shiftEntries as $entry) {
|
||||
$shift = $entry->shift;
|
||||
// Data required for the Fahrplan app integration https://github.com/johnjohndoe/engelsystem
|
||||
// See engelsystem-base/src/main/kotlin/info/metadude/kotlin/library/engelsystem/models/Shift.kt
|
||||
// ! All attributes not defined in $data might change at any time !
|
||||
$data = [
|
||||
// Name of the shift (type)
|
||||
'name' => $shift->shiftType->name,
|
||||
// Shift / Talk title
|
||||
'title' => $shift->title,
|
||||
// Shift description
|
||||
'description' => $shift->description,
|
||||
|
||||
// Users comment
|
||||
'Comment' => $entry->user_comment,
|
||||
|
||||
// Shift id
|
||||
'SID' => $shift->id,
|
||||
// Shift type id
|
||||
'shifttype_id' => $shift->shiftType->id,
|
||||
// Talk URL
|
||||
'URL' => $shift->url,
|
||||
|
||||
// Room id
|
||||
'RID' => $shift->room->id,
|
||||
// Room name
|
||||
'Name' => $shift->room->name,
|
||||
// Location map url
|
||||
'map_url' => $shift->room->map_url,
|
||||
|
||||
// Start timestamp
|
||||
/** @deprecated start_date should be used */
|
||||
'start' => $shift->start->timestamp,
|
||||
// Start date
|
||||
'start_date' => $shift->start->toRfc3339String(),
|
||||
// End timestamp
|
||||
/** @deprecated end_date should be used */
|
||||
'end' => $shift->end->timestamp,
|
||||
// End date
|
||||
'end_date' => $shift->end->toRfc3339String(),
|
||||
|
||||
// Timezone offset like "+01:00"
|
||||
/** @deprecated should be retrieved from start_date or end_date */
|
||||
'timezone' => $timeZone->toOffsetName(),
|
||||
// The events timezone like "Europe/Berlin"
|
||||
'event_timezone' => $timeZone->getName(),
|
||||
];
|
||||
|
||||
$response[] = [
|
||||
// Model data
|
||||
...$entry->toArray(),
|
||||
|
||||
// Fahrplan app required data
|
||||
...$data
|
||||
];
|
||||
}
|
||||
|
||||
return $this->response
|
||||
->withAddedHeader('content-type', 'application/json; charset=utf-8')
|
||||
->withContent(json_encode($response));
|
||||
}
|
||||
|
||||
protected function getNews(): Collection
|
||||
{
|
||||
$news = $this->request->has('meetings')
|
||||
|
|
|
@ -21,7 +21,6 @@ class LegacyMiddleware implements MiddlewareInterface
|
|||
'rooms',
|
||||
'shift_entries',
|
||||
'shifts',
|
||||
'shifts_json_export',
|
||||
'users',
|
||||
'user_driver_licenses',
|
||||
'admin_shifts_history',
|
||||
|
@ -77,10 +76,6 @@ class LegacyMiddleware implements MiddlewareInterface
|
|||
protected function loadPage(string $page): array
|
||||
{
|
||||
switch ($page) {
|
||||
case 'shifts_json_export':
|
||||
require_once realpath(__DIR__ . '/../../includes/controller/shifts_controller.php');
|
||||
shifts_json_export_controller();
|
||||
break;
|
||||
case 'public_dashboard':
|
||||
return public_dashboard_controller();
|
||||
case 'angeltypes':
|
||||
|
|
|
@ -51,6 +51,16 @@ class ShiftEntry extends BaseModel
|
|||
'freeloaded_comment' => '',
|
||||
];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = [ // phpcs:ignore
|
||||
'freeloaded' => 'bool',
|
||||
];
|
||||
|
||||
/** @var array<string> Attributes which should not be serialized */
|
||||
protected $hidden = [ // phpcs:ignore
|
||||
'freeloaded_comment',
|
||||
];
|
||||
|
||||
public function shift(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Shift::class);
|
||||
|
|
|
@ -110,6 +110,59 @@ class FeedControllerTest extends ControllerTest
|
|||
$controller->ical();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\FeedController::shifts
|
||||
* @covers \Engelsystem\Controllers\FeedController::getShifts
|
||||
*/
|
||||
public function testShifts(): void
|
||||
{
|
||||
$this->request = $this->request->withQueryParams(['key' => 'fo0']);
|
||||
$this->auth = new Authenticator(
|
||||
$this->request,
|
||||
new Session(new MockArraySessionStorage()),
|
||||
new User(),
|
||||
);
|
||||
$controller = new FeedController($this->auth, $this->request, $this->response);
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create(['api_key' => 'fo0']);
|
||||
ShiftEntry::factory(3)->create(['user_id' => $user->id]);
|
||||
|
||||
$this->setExpects(
|
||||
$this->response,
|
||||
'withAddedHeader',
|
||||
['content-type', 'application/json; charset=utf-8'],
|
||||
$this->response
|
||||
);
|
||||
|
||||
$this->response->expects($this->once())
|
||||
->method('withContent')
|
||||
->willReturnCallback(function ($jsonData) {
|
||||
$data = json_decode($jsonData, true);
|
||||
$this->assertIsArray($data);
|
||||
|
||||
$this->assertCount(3, $data);
|
||||
$this->assertTrue($data[0]['start'] < $data[1]['start']);
|
||||
|
||||
// Ensure dates exist used by Fahrplan app
|
||||
foreach (
|
||||
[
|
||||
'name', 'title', 'description',
|
||||
'Comment',
|
||||
'SID', 'shifttype_id', 'URL',
|
||||
'RID', 'Name', 'map_url',
|
||||
'start', 'start_date', 'end', 'end_date',
|
||||
'timezone', 'event_timezone',
|
||||
] as $requiredAttribute
|
||||
) {
|
||||
$this->assertArrayHasKey($requiredAttribute, $data[0]);
|
||||
}
|
||||
|
||||
return $this->response;
|
||||
});
|
||||
$controller->shifts();
|
||||
}
|
||||
|
||||
|
||||
public function getNewsMeetingsDataProvider(): array
|
||||
{
|
||||
|
|
|
@ -33,5 +33,7 @@ class ShiftEntryTest extends ModelTest
|
|||
$this->assertEquals($shift->id, $model->shift->id);
|
||||
$this->assertEquals($angelType->id, $model->angelType->id);
|
||||
$this->assertEquals($user->id, $model->user->id);
|
||||
|
||||
$this->assertArrayNotHasKey('freeloaded_comment', $model->toArray());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue