CMS 4.5.0: `GET /api/schedule/{id}/events` always returns HTTP 500 (TypeError)

CMS 4.5.0: GET /api/schedule/{id}/events always returns HTTP 500 (TypeError)

Version: CMS 4.5.0 (Docker, Package xibo-cms · GitHub ), upgraded from 4.4.4
Players: Windows 4 R407.2
Affects: every caller of the schedule event list API — not installation specific

Summary

Schedule::eventList() passes the route parameter $id straight into
DisplayGroupFactory::getById(). In 4.5.0 that factory method gained a strict int
type declaration, but the call site was not updated. Route parameters are always
strings in PHP, so the call throws a TypeError on every request.

The deprecated GET /api/schedule/data/events is affected too: it forwards to the
same handler, so existing integrations that still use it break on upgrade as well.

Error from the CMS log

page:    /schedule/{id}/events
message: Xibo\Factory\DisplayGroupFactory::getById(): Argument #1 ($displayGroupId)
         must be of type int, string given, called in
         /var/www/cms/lib/Controller/Schedule.php on line 131

What changed between 4.4.4 and 4.5.0

lib/Factory/DisplayGroupFactory.php:

// 4.4.4
public function getById($displayGroupId)

// 4.5.0
public function getById(int $displayGroupId, bool $disableUserCheck = true): DisplayGroup

lib/Controller/Schedule.php line 131 was not adjusted:

public function eventList(Request $request, Response $response, $id): Response|ResponseInterface
{
    $displayGroup = $this->displayGroupFactory->getById($id);   // $id is a string

Note that the route has no numeric constraint either, unlike the neighbouring
schedule routes which use {id:[0-9]+}:

$app->get('/schedule/{id}/events', ['\Xibo\Controller\Schedule','eventList'])
    ->setName('schedule.events');

Steps to reproduce

TOKEN=$(curl -s -X POST "<cms-url>/api/authorize/access_token" \
  -d grant_type=client_credentials -d client_id=<id> -d client_secret=<secret> \
  | jq -r .access_token)

# 500 — new endpoint
curl -s -H "Authorization: Bearer $TOKEN" "<cms-url>/api/schedule/8/events"

# 500 — deprecated endpoint, forwards to the same handler
curl -s -H "Authorization: Bearer $TOKEN" \
  -G --data-urlencode "displayGroupIds[]=8" "<cms-url>/api/schedule/data/events"

Both return:

{"success":false,"error":500,"message":"Unexpected Error, please contact support."}

Replacing 8 with any valid display group ID gives the same result, with or without
a date / startDate / endDate parameter. Adding ?date=<Y-m-d> produces a
second error further along, Call to a member function second() on null.

Expected

A list of scheduled events for the given display group, as in 4.4.4.

Impact

Any integration that reads scheduled events through the API stops working after
upgrading to 4.5.0. In our case an automated sync that publishes council meeting
times to a display group aborted on every run.

Suggested fix

Cast at the call site, e.g. getById((int)$id), and optionally constrain the route
to {id:[0-9]+} for consistency with the other schedule routes.

Workaround

GET /api/schedule?displayGroupIds[]=<id> returns the same events and is not
deprecated. Note the response shape differs: a flat array, where
/schedule/data/events nested each event under event inside a result key.

Hi, thanks for reporting this issue. I’ll raise it with the team and work on a fix.

The issue is logged here: CMS 4.5.0: `GET /api/schedule/{id}/events` always returns HTTP 500 (TypeError) · Issue #3894 · xibosignage/xibo · GitHub

Thank you for your support