Problem/Motivation
All sites using hourly-bookable content types — setting availability as "Available"
silently writes "Not available" to the database instead.
createHourlyEvent() accepts the user's chosen state ('available' or 'unavailable') as
the $new_state parameter, but never stores that parameter in the $d working array. All
subsequent logic in the method reads from $d, so when the state check
if ($d['new_state'] == 'available') is evaluated, the key does not exist and the condition
is always false. The method therefore unconditionally writes bee_hourly_not_available to
the database for every Update Availability form submission on an hourly-bookable node,
regardless of whether the user selected "Available" or "Unavailable".
The equivalent method createDailyEvent() does not have this bug — it correctly stores
$d['new_state'] = $new_state; at the top of the method.
Steps to reproduce
- Install BEE and configure a hourly bookable content type (e.g. "not available by default" or "generally available").
- Create a node of that type.
- Go to the node's Update Availability tab.
- Set the State to "Available", choose a date/time range, and submit.
- Check the node's calendar or query
bat_event__event_state_referencein the database.
Expected: The selected time range is recorded with state bee_hourly_available and displays green on the calendar.
Actual: The selected time range is recorded with state bee_hourly_not_available and displays red/N/A on the calendar, regardless of what the user chose. Selecting "Unavailable" produces the same result.
createHourlyEvent() uses a $d array to pass data through the method:
private function createHourlyEvent(Node $node, \DateTime $start_date, \DateTime $end_date, $type_id, $new_state) {
$d = [];
$d['node'] = $node;
$d['type_id'] = $type_id;
$d['start_date'] = $start_date;
// $new_state parameter is NEVER stored in $d
$d['temp_end_date'] = clone($end_date);
...
if ($d['new_state'] == 'available') { // $d['new_state'] is undefined → null
$d['state'] = bat_event_load_state_by_machine_name('bee_hourly_available');
}
else {
$d['state'] = bat_event_load_state_by_machine_name('bee_hourly_not_available');
// ↑ always reached, because null != 'available'
}
The $new_state parameter arrives with the correct value ('available' or 'unavailable' from the form select element) but is never assigned to $d. When $d['new_state'] is evaluated, PHP treats an undefined array key as null. null == 'available' is false, so execution always falls to the else branch and always writes bee_hourly_not_available.
Comparison: createDailyEvent() is already correct
createDailyEvent() stores the parameter immediately:
private function createDailyEvent(Node $node, \DateTime $start_date, \DateTime $end_date, $type_id, $new_state) {
$d = [];
$d['type_id'] = $type_id;
$d['start_date'] = $start_date;
$d['node'] = $node;
$d['new_state'] = $new_state; // ← correctly stored
...
if ($d['new_state'] == 'available') { // ← works correctly
createHourlyEvent() is missing this single assignment.
Impact
- All hourly-bookable nodes on all BEE sites are affected. Any user action to mark a time range as "Available" via the Update Availability form silently writes "Not available" instead.
- There is no visible error — the form submits successfully, but the stored state is always wrong.
- "Not available by default" hourly nodes cannot be opened for bookings via the availability form; administrators have no working way to mark time windows as available through the UI.
- "Generally available" hourly nodes can be marked unavailable correctly (since both selections produce
not_available), but attempting to re-open them via "Available" fails silently. - The bug is not visible in the form itself and can easily go undetected, particularly on sites where admins assume the form is functioning as labeled.
Proposed resolution
Add $d['new_state'] = $new_state; alongside the other $d assignments at the start of createHourlyEvent(), matching the pattern in createDailyEvent():
Before:
$d = [];
$d['node'] = $node;
$d['type_id'] = $type_id;
$d['start_date'] = $start_date;
$d['temp_end_date'] = clone($end_date);
After:
$d = [];
$d['node'] = $node;
$d['type_id'] = $type_id;
$d['start_date'] = $start_date;
$d['new_state'] = $new_state;
$d['temp_end_date'] = clone($end_date);
No other changes are required. The state-checking and event-writing logic is correct once $d['new_state'] is populated.
Remaining tasks
I have tested on my own system, additional testing and verification would be welcome prior to merging.
User interface changes
none
API changes
none
Data model changes
none
Sponsorship
none
Comments
Comment #2
owens-d commentedComment #3
afagioliimprove readability
Comment #4
afagioliHi!
Instead of pasting code directly in the issue queue, please follow Drupal best practices:
* Create an issue fork and push your changes there, then open a Merge Request, or
* Create a patch using git diff and attach it to this issue
Thanks
Comment #5
afagioliComment #7
afagioli