From 1cd90a0ab30c34b78a8c7cce626ce4a89a03edea Mon Sep 17 00:00:00 2001 From: albertlast Date: Sun, 9 Aug 2026 17:21:27 +0200 Subject: [PATCH] Lets the Post event button reach the event form The "Post event" button on a topic is a plain link, so the request that opens the form carries no post data at all. initiateEvent() nonetheless handed the request straight to Event::setRequestedStartAndDuration(), which insists on being given a date and fatals with "Invalid date." when it cannot find one, so the button never reached the form. Behind that sat a second one: the properties array named 'title' and 'location' unconditionally and gave them null when the request had not supplied them. Both are typed string on Event and already default to '', so the constructor rejected the null. Calendar::post() draws the unlinked version of this same form and has neither problem, because it just constructs Event(-1) and lets it fill in the defaults. Do the same here: only name the properties the request actually gave, and only ask for the requested start when the request carries one, which is what happens when a failed post is redisplayed. Signed-off-by: Mathias Albert Signed-off-by: albertlast --- Sources/Actions/Post.php | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/Sources/Actions/Post.php b/Sources/Actions/Post.php index c765105c52..575ccf0401 100644 --- a/Sources/Actions/Post.php +++ b/Sources/Actions/Post.php @@ -780,12 +780,37 @@ protected function initiateEvent(): void } if (!isset(Utils::$context['event']) || !(Utils::$context['event'] instanceof Event)) { - $props = [ - 'title' => isset($_REQUEST['evtitle']) ? Utils::htmlspecialchars(stripslashes($_REQUEST['evtitle'])) : null, - 'location' => isset($_REQUEST['event_location']) ? Utils::htmlspecialchars(stripslashes($_REQUEST['event_location'])) : null, + $props = []; + + // Only name the ones the request actually gave. Event::$title and + // Event::$location are typed string and already default to '', so + // handing them a null for "the form has not been filled in yet" is + // a fatal rather than an empty field. + foreach (['title' => 'evtitle', 'location' => 'event_location'] as $prop => $key) { + if (isset($_REQUEST[$key])) { + $props[$prop] = Utils::htmlspecialchars(stripslashes($_REQUEST[$key])); + } + } + + // setRequestedStartAndDuration() insists on being handed a date and + // fatals with "invalid_date" when it cannot find one. Nothing + // hands it one when this form is merely being opened: the "Post + // event" button on a topic is a plain link, so there is no post + // data to read. Only ask for the requested values when the request + // actually carries some, which is the case when a failed post is + // redisplayed, and otherwise let the Event constructor default the + // start to now. That is what Calendar::post() does for the + // unlinked version of this same form. + $requested_date_keys = [ + 'year', 'month', 'day', 'hour', 'minute', 'second', + 'start_year', 'start_month', 'start_day', 'start_hour', 'start_minute', 'start_second', + 'start_date', 'start_time', 'start_datetime', ]; - Event::setRequestedStartAndDuration($props); + if (array_intersect_key($_POST, array_flip($requested_date_keys)) !== []) { + Event::setRequestedStartAndDuration($props); + } + Event::setRequestedRRule($props); Utils::$context['event'] = new Event(-1, $props); Event::setRequestedRDatesAndExDates(Utils::$context['event']);