Hi Guys,

Here's a patch to add the current status (open / closed) to the office hours. It is currently using the timezone of the website, but I will be adding a feature to use the timezone from a tzfield.

Please keep in mind this is essentially a re-write of the display formatter and adds some more themeing options. Previous theme functions for the display formatter should still work, but would need to be re-written to take advantage of the new processing in office_hours_field_formatter_view().

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Lazarus-Long’s picture

Sorry, was porting code from another copy I had. Forgot an if statement.

johnv’s picture

So this is an actual implementation of #696262: Show Status 'Open/Closed (now/today/soon)' in Views ?
The feature is also mentioned as a 'current status block' in #1539768: Merge 'Simple Hours' Sandbox module with 'Office hours'?

Lazarus-Long’s picture

#696262 looks to be a hard-coded display that pulls directly from the DB (bad form, no offense intended)
#1539768 describes several features, including the open/closed functionality, but does not have any code provided.

So yes, it implements a feature mentioned in both of those issues.

Lazarus-Long’s picture

And here's the second part. The display formatter can be linked to a tzfield on the same entity. This is useful for chain stores where not all the locations will be in the same timezone.

Again, the patch is from the current 7.x-1.x-dev head.

johnv’s picture

Status: Needs review » Needs work

I could not test, only apply and review code.

+++ b/office_hours.elements.inc
@@ -71,6 +71,11 @@ function _office_hours_select_process($element, &$form_state, $form) {
   if (is_numeric($element['#default_hours'])) {
     list($defhr, $defmin, $ampm) = _office_hours_return_defaults($element['#default_hours'], $element['#hoursformat']); 
   }
+  else {
+    $defhr = 0;
+    $defmin = '';
+    $ampm = 'am';
+  }

- There is a difference in $defhr between your code and the initialization in _office_hours_return_defaults(). Is this intentional? (we could commit this separately.)
- You better move this part into _office_hours_return_defaults(), and change it to:

@@ -71,6 +71,11 @@ function _office_hours_select_process($element, &$form_state, $form) {
-   if (is_numeric($element['#default_hours'])) {
-     list($defhr, $defmin, $ampm) = _office_hours_return_defaults($element['#default_hours'], $element['#hoursformat']); 
+   list($defhr, $defmin, $ampm) = _office_hours_return_defaults($element['#default_hours'], $element['#hoursformat']); 
-   }
  if ($timezone)
    $currentDT->setTimezone(new DateTimeZone($timezone));

- Please use {} after the if-statement;

 function _office_hours_field_formatter_defaults($settings = array()) {
-  return array_merge(array(
+  return array_replace_recursive(array(
     'daysformat' => 'long',

- This is an introduction of a PHP5.3 function. Please find a PHP5.2 alternative. I could do no further tests because of this.

Lazarus-Long’s picture

I just set the defaults there to what I was normally receiving from the function. It shouldn't change any of the functionality, but I like keeping the defaults in the default function. I'll move them over.

Coding conventions are no problem.

drupal_array_merge_deep should be a direct replacement for array_replace_recursive. I'll test it later tonight.

Lazarus-Long’s picture

FileSize
22.52 KB

Ignore this, forgot to get the latest changes to the origin branch

Lazarus-Long’s picture

FileSize
21.24 KB

Realized after I posted the patch that the element changes have nothing to do with the status feature, but were a fix I merged in from another branch I was working on. Fixes a problem with the $ampm variable not being set in certain instances. Left it in because it should be merged anyway.

This patch is again diff'd against the 7.x-1.x branch and should solve all of the issues found in #5

johnv’s picture

OK, this applies nicely.
Couldn't find the new feature, though.
Can you post instructions how to use it?

Lazarus-Long’s picture

The new settings are in the display formatter settings. At the bottom there will be a field group for the current status, and a drop down for the timezone field selector (the entity will require a tzfield to use that part). You may need to flush the cache to see the new settings.

johnv’s picture

Status: Needs work » Needs review

OK, I'll try

johnv’s picture

Status: Needs review » Needs work

This looks promising, but I would create a separate formatter for it, for the following reasons:
-- this feature deserves a better, more prominent place. A proper formatter gives an initial choice to the user;
-- the code can be more isolated; the current patch is very big, and it took me a while to apply it manually. Isolation separates this feature from your work on refacturing the formatter.
-- the current version does not allow to NOT show the opening times. (I can imagine separate blocks: 1 with regular opening times, 1 with more prominent OPEN NOW!)

Lazarus-Long’s picture

I'm not sure what you mean by the initial choice. There's not really any other place to put it other than the display formatter. We could put it higher in the setting form, but that's just styling at that point.

The code essentially replaces the process and theme functions, but leaves pretty much everything else alone. I'm not entirely sure how much more isolated it could become.

The current version has 3 options for the position: hidden, above, and below. Is that what you're referring to?

johnv’s picture

I mean creating a second formatter 'Office hours - current status', next to the default 'Office hours' one.
This second formatter would have its own callback-function where 'Current status' is formatted.
The settings can be either in 2 forms, or hidden, depending on the choice of formatter.

Lazarus-Long’s picture

We could have a second display formatter, but I'm not sure there's a way to display a second display formatter for the same field (please tell me if there is).

johnv’s picture

That's not difficult:
1. in office_hours.module

function office_hours_field_info() {
   68   return array(
   69     'office_hours' => array(
   ...
   75      ),
+  69     'office_hours_status' => array(
+  ...
+  75      ),
   76   );
   77 }

2. in office_hours.theme.inc

 function office_hours_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  12   $element = array();
  13   if ($items) {
+ switch $display['type']:
+         case 'office_hours':
  14     $element[0] = array('#markup' => theme($field['type'] . '_formatter_default',
+          case 'office_hours_status':
  14     $element[0] = array('#markup' => theme($field['type'] . '_formatter_status',
  19   }
  20   return $element;
  21 }

3. now implement function theme_office_hours_formatter_status($vars)

See Field Formatter API for more details.

Lazarus-Long’s picture

Sorry, I wasn't clear. I know you can have multiple formatters in the same module. I was referring to displaying multiple formatters at the same time for the same field (ie: one for the times block, and one for the status).

johnv’s picture

I don't think you can show the same field twice on a node-view-page, that's true.
You can add the same field twice in Views. And you can add blocks with different data on the same page.

Lazarus-Long’s picture

Twice in views is fine, but that won't help people who want to display the status on the node's page. It could be both though: included in the default formatter, and another formatter that only shows the status. Would help with Views where people only want to list locations currently open as well.

johnv’s picture

Your suggestion #19 looks fine. Can you roll a patch against latest version?

Lazarus-Long’s picture

Sorry, going to be a bit busy this and next week. In the process of moving between continents. I'll see if I can have something together this week though.

adelka’s picture

can't wait for this feature - subscribe!

Gessle’s picture

This sounds good!

adelka’s picture

I would like to ask about this feature, because its very important for my project.
Will it be implemented til the end of year? Maybe is it possible to support somehow?

thank you!

johnv’s picture

@adelka, do you know some php? You can help by adapting patch from #8, and post a fresh patch. Then I'll try and get it in.

adelka’s picture

@ juhnv, I know basic of php - principles, function etc. But unfortunately I dont feel I can handle so difficult task. :(
Can I help by testing or anything else?

johnv’s picture

I have applied the prefious patches to durrent dev-version. Please test it.
Only did some minimal testing.

I'd like to add an option to ONLY show the Current status, not only before/after.

adelka’s picture

I've tested it on last dev version 7.x-1.x-dev.

Worked great, I tried also display current status in views!

Just few notes =>

1. I had following errors:

Notice: Undefined index: #bundle v office_hours_field_formatter_settings_form() (riadok 193 z /data/d/a/darcekpodlateba.sk/web/sites/all/modules/office_hours/office_hours.module).
Notice: Undefined index: #entity_type v office_hours_field_formatter_settings_form() (riadok 193 z /data/d/a/darcekpodlateba.sk/web/sites/all/modules/office_hours/office_hours.module).

both caused by views.

2. it would by great to show only current status by views (right now I can hide only day notation). Of course, text can be hidden byt CSS.
3. amazing feature can be filter of current status - so I can for example expose the filter and show only opened entities.

Great job! THANK YOU!

johnv’s picture

Status: Needs work » Fixed
FileSize
9.61 KB

This is added in commit 18770b9 .

You can add the Current status before, after, of instead of the hours listings.
There is no support for other timezones, yet.
There is no support for selecting currently open/closed locations in a Views selection box.

Thanks to Lazarus-Long for the initial patch.

jackfoust’s picture

Loving this feature in the dev module, but I'm wondering.. Would it also make sense to include the current day's time below the open/close message if you use the 'hiding hours' position?

johnv’s picture

With some token support? 'Open in x hours' is a much wanted feature too.

adelka’s picture

To add some more ideas, I think CSS class for opened/closed status can be great, so I we can format for example opened div to green and closed div to red color.

Will be there new release for 7th verzion, so we can just updade module?

johnv’s picture

@adelka, check out latest dev for new css-classes. I'll create a new version the coming weeks.
@jackfoust, what do you mean? Just showing the time, like a clock? Only when it is closed, or also when opened?

I was wondering about the opening-soon feature: if the location is closed, you could display 'opening in 3 hours'. But it would be even better to show a 'closing in 3 hours' message, to persuade people to come NOW, TODAY to your store, library, restaurant.

jackfoust’s picture

@johnv, I was thinking of something along the lines of the following. I have taxonomy branches with office hours attached.

Branch A
Currently Open!
Tuesday 8:00 AM - 10:00 PM

Branch B
Currently Closed!
Tuesday 8:00 AM - 10:30 AM

adelka’s picture

Just to be sure, I've understood well - "There is no support for selecting currently open/closed locations in a Views selection box." means that it's not possible because views module doesn't allow that?
sorry, if its stupid question...

johnv’s picture

@adleka, to be able to show currently open locations, this module must provide the correct data to Views.
patches are welcome.

Status: Fixed » Closed (fixed)

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

johnv’s picture

Status: Closed (fixed) » Fixed
FileSize
23.3 KB

I did a rework of this, integrating the current_status feature better with the hours format.
@jackfoust, there is also a 1-line format, too.

Daniel Schaefer’s picture

Regarding Views filter: I did a quick (and dirty) workaround using jQuery, reading the status from the display formatter. Of course this method only makes sense when all items are displayed on one page. But it does the trick for me, for now.

JS:

jQuery(document).ready(function($) {
	$('#filter-open').click(function(e) {
                            // Replace .views-col with the according most outer container of the view item
		$(".oh-current-closed").parentsUntil(".views-col").css("display", "none");
	});
$('#filter-all').click(function(e) {
	$(".oh-current-closed").parentsUntil(".views-col").css("display", "block");
});

});

HTML:

<button id="filter-open">Currently open</button>
<button id="filter-all">Show all</button>

I would love to see a proper Views filter "Open / Closed", though. I can do quite some PHP but I don't really know where to start here. Hints are welcome!

johnv’s picture

@dsjena, this sounds nice. Can you re-post this in a new issue? Thanx.

patriktakac’s picture

I've installed update, nice feature.

Unfotunatelly, It's not working correctly when opening hours are set to:
1./ 0:00-0:00 - I expected something like opened nonstop
2./ 20:00-6:00 - opened also after midnight - show closed for example when it's 21:00
3./ 8:00-0:00 - show closed for example when it's 21:00. When I changed 0:00 to 23:45, status "currently open" was shown correctly.

johnv’s picture

@patriktakac, nice catch.
ad 1. This is not implemented yet. See #1661512: Open all day (From 00 hrs to 24 hrs) (D7)
ad 2/3. can you open a follow-up issue?

Status: Fixed » Closed (fixed)

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