isOpen()/getCurrent() does not respect given time

Created on 18 May 2023, over 1 year ago
Updated 24 May 2023, over 1 year ago

I have some code that checks isOpen() from OfficeHoursFormatterTrait two times.
First it checks if the location is currently open using $location->field_open_hours->isOpen().
Then it checks if the location was open an hour ago (in our case this has to be handled in a special way) using $location->field_open_hours->isOpen($time_one_hour_ago);.
Because of the getCurrent function code that checks for (isset) and returns currentSlot, the second isOpen check will always return the same result as the first isOpen check.
At the moment, I'm working around this by cloning the open hours before the second call to isOpen which works ($open_hours_clone = clone $location->field_open_hours;).
Perhaps this is something that should be changed in the module though. I'm not sure what the best approach would be, perhaps the $time variable should be stored and checked in the currentSlot check.

πŸ› Bug report
Status

Fixed

Version

1.9

Component

Code - formatter

Created by

πŸ‡ΊπŸ‡ΈUnited States olivier.bouwman Portland, Oregon

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

Comments & Activities

  • Issue created by @olivier.bouwman
  • πŸ‡³πŸ‡±Netherlands johnv

    Indeed, the paramete time must be propagated from isOpen(time) to getCurrent(time).

    At this moment, for another issue, I was changing that call, since the 'static' behaviour does not work at all.( πŸ› Add Exception Day support for 'Current day' formatter Fixed )

    Can you share your use case? I hope that it is not because fo the 'field cache does not work for anonymous users' problem. In the upcoming version, that is solved by not caching at all, when a open/closed status or 'current' formatter is used.

  • πŸ‡ΊπŸ‡ΈUnited States olivier.bouwman Portland, Oregon

    Here's a simplified version of my use case. We show wait times for locations. If a location is currently closed or was opened in the last hour, we don't show wait times. Because I have to do two isOpen checks for this use case, I had to add the $open_hours_clone = clone $location->field_open_hours; line. Without it, the result for the second isOpen is always the same as the first. I'm not sure how common this use case is but it seems like isOpen shouldn't always return the same value if a different timestamp is passed into it. Does that clarify things?

    public function getWaitData($nid) {
    
        // See if this location is currently open according to the open hours.
        $location = Node::load($nid);
        $is_open = (int) $location->field_open_hours->isOpen();
        if (!$is_open) {
          return [
            'wait_time' => t('@disabled', ['@disabled' => self::WAIT_TIMES_DISABLED]),
          ];
        }
    
        // See if this location has opened in the last hour according to the open hours.
        $open_hours_clone = clone $location->field_open_hours;
        $time_one_hour_ago = \Drupal::time()->getRequestTime() - (1*60*60);
        $was_open_one_hour_ago = (int) $open_hours_clone->isOpen($time_one_hour_ago);
        if (!$was_open_one_hour_ago) {
          return [
            'wait_time' => t('@disabled', ['@disabled' => self::WAIT_TIMES_JUST_OPENED]),
          ];
        }
    
        // more code here....
    
  • πŸ‡³πŸ‡±Netherlands johnv

    Thanks for the explanation.
    Indeed, this is an error in the code. I have already fixed it, but need to isolatie the change from other code, before i can commit it. Give me some days.

  • πŸ‡³πŸ‡±Netherlands johnv
    • johnv β†’ committed e66e649d on 8.x-1.x
      Issue #3361308: isOpen()/getCurrent() does not respect given time
      
  • Status changed to Fixed over 1 year ago
  • πŸ‡³πŸ‡±Netherlands johnv

    The change had a bit more impact than expected.
    It should now work fine.
    Also, it is also calculated once per Request, giving a bit more performance.

  • πŸ‡ΊπŸ‡ΈUnited States olivier.bouwman Portland, Oregon

    Thank you so much for the super quick fix! This works for my use case.

  • πŸ‡³πŸ‡±Netherlands johnv

    you're welcome. Nice to hear it works as expected.

  • Status changed to Needs work over 1 year ago
  • πŸ‡³πŸ‡±Netherlands johnv

    There is some nitpicking to do on the $time handling.

    • johnv β†’ committed efd66026 on 8.x-1.x
      Issue #3361308: isOpen()/getCurrent() does not respect given time
      
  • Status changed to Fixed over 1 year ago
  • πŸ‡³πŸ‡±Netherlands johnv
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024