OfficeHoursDateHelper::format() causes fatal error

Created on 7 February 2024, 11 months ago
Updated 28 February 2024, 10 months ago

Problem/Motivation

Make the programatical calls not break.

Steps to reproduce

Let's try to update the exception hours on a node field programtically:

          $hours[] = [
            'day' => $exception_timestamp,
            'day_delta' => 0,
            'allday' => FALSE,
            'starthours' => $start,
            'endhours' => $end,
          ];
...
      $existing_hours = $node->get('field_store_hours') ?? [];
      $merged_hours = [];
      // Exception hours, $value['day'] == $exception_timestamp.
      foreach ($hours as $value) {
        $merged_hours['' . $value['day']] = $value;
      }
      $node->set('field_store_hours', $merged_hours);
      $node->save();

Let's say the start hour is 10:00 AM and end hour is 6:00 PM.

The above code works perfectly fine in 8.x-1.11 but failed in 8.x-1.12 and later (dev), with error

InvalidArgumentException: The timestamp must be numeric. in Drupal\Component\Datetime\DateTimePlus::createFromTimestamp() (line 201 of core/lib/Drupal/Component/Datetime/DateTimePlus.php).
Drupal\office_hours\OfficeHoursDateHelper::format('3:00 PM', 'Hi') (Line: 333)
Drupal\office_hours\Plugin\Field\FieldType\OfficeHoursItem::format(Array) (Line: 249)
Drupal\office_hours\Plugin\Field\FieldType\OfficeHoursItem->setValue(Array, ) (Line: 72)
...

Looking at the source of 8.x-1.12 you can see it added a condition check of
if ($time > 2400) {
before checking ":" in the string:
elseif (!strstr($time, ':')) {

https://git.drupalcode.org/project/office_hours/-/blob/8.x-1.12/src/Offi...

https://git.drupalcode.org/project/office_hours/-/blob/8.x-1.x/src/Offic...

However, PHP has weird string to number comparison:

$time = " 6:00 PM";
echo $time > 2400 ? 'T' : 'F';
> F
$time = "6:00 PM";
echo $time > 2400 ? 'T' : 'F';
> T

Note that with space in the begining , 6pm is less then 2400, but without space, 6pm somehow greater than 2400, and falls into DrupalDateTime::createFromTimestamp($time); which throws the errors.

Proposed resolution

Maybe should check string format first? if (!strstr($time, ':')) { , also the string > 2400 (number) comparision is not reliable, maybe should check if it's numeric then > 2400?

🐛 Bug report
Status

Fixed

Version

1.12

Component

Code

Created by

🇨🇦Canada yang_yi_cn

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024