Problem/Motivation

I am displaying the office hours as plain text that shows all our hours. I have an exception date that came up today and that exception date shows below the list of hours. The problem is it still shows "TUESDAY: 11:00 am-9:00 pm" in the main list (wrote this on a Tuesday).

Steps to reproduce

Is it possible to replaces today's hours with the exception? I tried searching and haven't seen anyone requesting this. I will write something custom to take care of this if it is not a thing. Here is what I am seeing:

SUNDAY: 11:00 am-9:00 pm
MONDAY: 11:00 am-9:00 pm
TUESDAY: 11:00 am-9:00 pm
WEDNESDAY: 11:00 am-9:00 pm
THURSDAY: 11:00 am-9:00 pm
FRIDAY: 11:00 am-10:00 pm
SATURDAY: 11:00 am-10:00 pm
<em>EXCEPTION HOURS</em>
TUESDAY, JUNE 27, 2023: 9:00 pm-10:00 pm testing

This is what I'd like to see:

SUNDAY: 11:00 am-9:00 pm
MONDAY: 11:00 am-9:00 pm
TUESDAY: 9:00 pm-10:00 pm
WEDNESDAY: 11:00 am-9:00 pm
THURSDAY: 11:00 am-9:00 pm
FRIDAY: 11:00 am-10:00 pm
SATURDAY: 11:00 am-10:00 pm
<em>EXCEPTION HOURS</em>
TUESDAY, JUNE 27, 2023: 9:00 pm-10:00 pm testing

You can see TUESDAY is replaced with the exception hours. The comment isn't much of a concern in placement but imagine it'd be next to or under that date slot.

Quoting from #3355643: Season Formatter: update weekly timetable depending on the season:

It would be useful to have one and only weekly timetable displayed.
The timetable would be updated every week, according to the season, as setted in the back office.

Quoting from #3034189: [Season] Schedule hours in advance:

We would like to be able to create weekly hours in advance, and have them publish based on the week date.

The following link gives a current recipe: https://drupalsun.com/vp/2013/11/26/scheduling-opening-hours-advance

Remaining tasks

- Add a setting
- Replace normal weekdays with Exception dates AND Seasonal dates.
- Leave seasonal weekdays intact. Do not overwrite with exceptions, since that is not current week, so not date determination possible.
- Hiding exception days is already possible using a setting
- Hiding seasonal weekdays is not yet possible using a setting

User interface changes

The Week opening hours will change as above.

API changes

Some internal functions re added, changed.

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

rondog469 created an issue. See original summary.

johnv’s picture

Component: Integration » Code - formatter
Related issues: +#3355643: Season Formatter: update weekly timetable depending on the season

I guess thisis the same request as #3355643: Season Formatter: update weekly timetable depending on the season, 'replace weekdays with exception and season hours'.
Indeed, this needs to be implemented.

rondog469’s picture

Yes that sounds similar. I ended up doing a hook_preprocess_office_hours and modified the twig template. Basically the gist was in the preprocess, check if an exception exists. If it does, find which day the exception is for and add an exception property to that day of the weeks render array. In the twig file I check if that property exists and if it does display that instead of the normal time slot

{% if item.slots['#markup'] is not empty %}
  <span class="office-hours__item-slots">
    {% if item.exception %}
      {{ item.exception.slots }}
    {% else %}
      {{ item.slots }}
    {% endif %}
  </span>
{% endif %}

I did not think of every use case for this scenario, but in my case this will work because we are open every day of the week. For example, if a day of the week is always closed and the exception is for that day, I dont think that twig condition would work.

johnv’s picture

Can you share the hook_preprocess_office_hours code? for the day calculation.

I plan to put all changes in the Formatter code, adding a setting.

SO you bot want to change the current weekday, AND keep the exception day below the weekdays?

rondog469’s picture

Sure, but as I said before I dont think this is super flexible for all cases. I wrote this for our specific needs. It could be a good starting point though.

/**
 * Implements hook_preprocess_office_hours().
 *
 * A normal week with no exceptions is 7 items long, Sunday-Saturday.
 * If there is an exception this array will be longer. Let's figure out
 * which day of the week needs to be overridden. See template for integration.
 *
 * @TODO Array length might not be reliable especially if a day of the week is
 * consistently closed (haven't tested this). Perhaps search for the exception
 * label instead.
 */
function HOOK_preprocess_office_hours(&$vars) {
  $hourLength = count($vars['office_hours']);
  $keys = array_keys($vars['office_hours']);
  if ($hourLength > 7) {
    for ($i = 8; $i < $hourLength; $i++) {
      $key = $keys[$i];
      $dayOverrideKey = date('w', $vars['office_hours'][$key]['day']);
      $vars['items'][$dayOverrideKey]['exception'] = $vars['items'][$i];
    }
  }
}

That code outputs something like this. You can see I have an exception for Tuesday july 4th

^ array:9 [▼
  0 => array:4 [▼
    "label" => "Sunday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  1 => array:4 [▼
    "label" => "Monday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  2 => array:5 [▼
    "label" => "Tuesday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
    "exception" => array:4 [▼
      "label" => "Tuesday, July 4, 2023: "
      "slots" => array:2 [▼
        "#type" => "markup"
        "#markup" => "10:00 am-3:00 pm"
      ]
      "comments" => array:2 [▼
        "#type" => "markup"
        "#markup" => "Closing early for July 4th"
      ]
      "suffix" => "<br />"
    ]
  ]
  3 => array:4 [▼
    "label" => "Wednesday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  4 => array:4 [▼
    "label" => "Thursday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  5 => array:4 [▼
    "label" => "Friday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  6 => array:4 [▼
    "label" => "Saturday: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  7 => array:4 [▼
    "label" => "Exception hours"
    "slots" => array:2 [▶]
    "comments" => array:2 [▶]
    "suffix" => "<br />"
  ]
  8 => array:4 [▼
    "label" => "Tuesday, July 4, 2023: "
    "slots" => array:2 [▶]
    "comments" => array:2 [▼
      "#type" => "markup"
      "#markup" => "Closing early for July 4th"
    ]
    "suffix" => "<br />"
  ]
]

Here is our modified twig template. Aside from showing the exception hours I also change the current day label to read as "TODAY" and we included some collapse functionality that probably should not be included.

{% set id = 'view-hours-' ~ random(1, 50) %}
<button class="view-hours" aria-controls="{{ id }}" aria-expanded="false"><span>View All</span></button>

{% set classes = "office-hours collapse hide office-hours-status--" ~ (is_open ? "open" : "closed") %}
<div{{ attributes.addClass(classes) }} id="{{ id }}">
  {% set today =  'now'|date('w') %}
  {% for key, item in items %}
    {% set currentClass = '' %}
    {% if today == key %}
      {% set currentClass = 'current' %}
    {% endif %}
    <div class="office-hours__item {{ currentClass }}">
      {% if item.label %}
        <span class="office-hours__item-label" style="width: {{ label_length * 0.60 }}em;">
          {% if today == key %}
            Today:
          {% else %}
            {{ item.label }}
          {% endif %}
        </span>
      {% endif %}
      {% if item.slots['#markup'] is not empty %}
        <span class="office-hours__item-slots">
          {% if item.exception %}
            {{ item.exception.slots }}
          {% else %}
            {{ item.slots }}
          {% endif %}
        </span>
      {% endif %}
      {% if item.comments['#markup'] is not empty %}
        <span class="office-hours__item-comments">{{ item.comments }}</span>
      {% endif %}
      {% if item.exception.comments['#markup'] is not empty %}
        <span class="office-hours__item-comments">{{ item.exception.comments }}</span>
      {% endif %}
      <span>{{ item_separator | raw }}</span>
    </div>
  {% endfor %}
</div>
SO you bot want to change the current weekday, AND keep the exception day below the weekdays?

In our case we did not need to display the exception under the current week so I just hid it with CSS.

.office-hours__item:nth-child(n+8) {
  display: none;
}

You can also see this in action here under the photos and center column: https://www.stonebrewing.com/visit/bistros/escondido

We dont currently have an exception on these locations right now. The output above was for our testing on dev.

johnv’s picture

Title: Replace today's time with the exception time » Replace today's hours with Exception hours in Week Formatter
Version: 8.x-1.11 » 8.x-1.x-dev
Related issues: +#3307517: Add Exception Day support for 'Current day' formatter

FYI, #3307517: Add Exception Day support for 'Current day' formatter is now committed.

Adding it to the complete formatter was a bridge too far, atm.
All was handled in php, not theming/twig.

johnv’s picture

Status: Active » Needs work
StatusFileSize
new8.04 KB

Please find a first try attached.

geoffreyr made their first commit to this issue’s fork.

geoffreyr’s picture

@johnv Thank you for your patch! I've set up an issue fork at https://git.drupalcode.org/issue/office_hours-3370722/-/tree/3370722-rep... that applies the patch, fixes some typing issues I found, and adjusts some of the iterator logic as it wasn't replacing the first default slot of days with an exception.

My use case is displaying today's opening hours for a list of venues, so it's pretty narrow compared to the needs of everyone that uses this module. I reckon that we'll want to make replacements optional so it applies to some formatters and not others. Either way, we'll need some more eyes on it to see if the behaviour that we're seeing is what we want. Also, tests. I need to write some tests.

johnv’s picture

Indeed, this feature might be optional.

for your use case, "displaying today's opening hours for a list of venues", you might check the formatter setting to display 'current' or 'next' open day. That already contains this functionality since it queries getCurrent().

geoffreyr’s picture

Yes, the View that I'm using this on is set to display only the current day.

I've just pushed an update that adds a replace_exceptions key in exceptions config that determines whether to run the exceptions replacement logic. Hopefully this helps, let me know if there's anything else you'd like me to take a look at.

johnv’s picture

On another note: I see you made a correction here: ' week midnight UTC'.
would you be so kind to grep the source code for 'midnight', and check if there are more errors?
Obviously, you are in another time zone then I am. Not sure how to handle it.

geoffreyr’s picture

I've checked your patch and there aren't any further instances that need updating.

The reason that I needed to add UTC string to the 1st param of DrupalDateTime constructor is because I found that the dates used to index $exceptions wouldn't match those for the DrupalDateTime unless I specifically added it; there was always an offset equivalent to the difference between my timezone and UTC.

johnv’s picture

I mean other instances in the office_hours module, not in the patch.
So, I can test other midnights by just changing the time zone in my user profile, or the site settings?

johnv’s picture

johnv’s picture

Issue summary: View changes
johnv’s picture

Category: Support request » Feature request
Issue summary: View changes

larowlan made their first commit to this issue’s fork.

johnv’s picture

@larowlan, I see you are working on this, thanks.
ITMT, please review $sorted_days = $this->sortedList->getSortedItemList($today);
This is new code, needed for the proper support of seasons and exceptions.
I think it can be used for this purpose, too.
You only need to select the proper days for the current weekd display, and rename the date to the weekday in the key.

larowlan’s picture

Full disclaimer I'm working on a project with geoffreyr and just rerolled his MR because it no longer applied

johnv’s picture

Sorry for pulling the ground under your feet.
But you now have a #3423491: Better OfficeHoursItemListSorter.php.
This feature must use that prepared, sorted list, keyed with date.

johnv’s picture

Issue summary: View changes

  • johnv committed 03bd3d68 on 8.x-1.x
    Issue #3370722 by geoffreyr, johnv, larowlan, rondog469: Replace today's...
johnv’s picture

Version: 8.x-1.x-dev » 8.x-1.16
Status: Needs work » Fixed

Please check latest dev version. Thanks a lot for you contributions.

johnv’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.