Skip Navigation

[Resolved] Opening hours

This support ticket is created 6 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+01:00)

Author
Posts
#746173

I saw all topics (5, but specifically https://toolset.com/forums/topic/opening-hours-and-closedopen-status/ and https://toolset.com/forums/topic/i-would-like-to-display-an-open-today-date-here-9am-5pm-message/) related to opening hours 'full table view' (all days) and 'opened now view' (moment of page visit). However, I can't see that it can work for me. So, I have two main CPT, Sites (museums, hospitals, ...) and Places (hotels, restaurants, shops,...). Each need Opening Hours functionality. Issue is that it should to be inserted via CRED by users and displayed to visitors (n real time).

1) It is not clear for me, if I create child PT 'Weekdays' with Field Group 'Opening Details' ('special days' should be there also), how to enable it for users on CRED for Sites (example) to fill the form. Issue is that for me appear that for every Sitio should to be added it's own opening hours POSTS, instead to be selected existing fields (or posts). To be clear, I created it and it works, but it show me literally millions of Weekday CPT (count that every user creates minimum 15 posts - 2 per day and one for Sunday, plus holidays). So, 1000 users mean not less than 20000 Weekdays child posts (!!!).

Isn't that redundancy (especially with many users)??? How WordPress database will handle it??? If you (Toolset) state how that is just fine to have such amount of posts, no problem (but I doubt that search and database generally can handle it smoothly).

2) As Toolset not support time and any of topics exactly explain how to display current state of OPENING (opened/Closed), can you be slightly more precise how to do it.

#748200

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

results.png
field-group.png
enter-times.png

Hi Ljuba

The new Types 3.0 adds repeating field groups, and this seems to me a good candidate for using it.

See screenshot enter-times.png where I set up an example to see how it might work in practice, where I think the UI is quite manageable.

You can see how I created that in field-group.png.

I have an "Opening Times" repeatable field group, which contains a select field for the day, and a nested repeatable field group to add opening times (because we might want to have multiple times for each day to allow for closed-for-lunch etc.).

So far so good, with one big caveat.

Adding support for this to CRED Forms didn't make the cut-off so it won't be available in the initial release, but it will be prioritised for a subsequent update once that is out of the way.

I don't think you can do this on the front-end with the current stable versions in anything like a reasonable UI.

To display the opening times you'll then need to create a View, in fact, in this case because you have a nested repeating field group, two (nested) Views.

So in my example my main View queries the main "Opening Times" repeating field group.

I set ordering by the custom field Day of week, ascending.

I need to add a Query Filter to set which post the repeating fields belong to, which I do with a repeatable field group owner filter "Select items from the Opening times group that are related to the Post where this View is shown."

In the Loop Output I output the day of the week with the types shortcode for that field, and I also insert my second nested View to display the times for that day.

That View displays my nested repeatable field group, Times, which I'm ordering by the "From" field, ascending.

I again need a Query Filter to say which repeating fields to display: "Select items from the Times group that are a related to the current post in the loop."

Then in the Loop Output I print the times, like so:

<p>[types field="from"][/types] - [types field="to"][/types]</p>

OK. Pause for breath.

I'm going to submit this reply now, and then resume with how me might display whether a restaurant is currently open or not.

Now might be a good time to mention that there are plugins for this specific purpose which provide much greater functionality such as special holiday opening hours etc. that I'm not going to address here (I'll let you think about that; it may require writing custom code to achieve, depending on how you want it implemented).

One example would be https://wordpress.org/plugins/wp-opening-hours/, but that suffers the common limitation that it requires back-end access.

#749463

Actually, I don't think that it is so complicated (first part), but for me was two issues:

1) I was confused why Toolset support 'force' solution with child PT instead of Field Group. If I'm not wrong, you confirmed me that Field Group could be used. In current versions, I see that very simple via conditional logic with 7 (14) times manually repeated fields (as you did on images) and with new version, repeatable feature will simplified even more. In other words, I can't see functional difference for present versions and version 3.0, as 'output' number of fields will be 100% same (7 or 14). So, this part I will take as 'solved'. It is better to have 50 fields than 20000 child posts (or not?).

2) Obviously, main problem is - how to present current state of opening when Toolset don't support hours. That's for what I'm waiting (reply/answer).

#750684

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

1. Actually the implementation in the new version is based upon what is currently possible, making child posts to act as containers for the repeating groups of fields. For every group of repeating fields added, a container post is published. It's just that it happens automatically in the new version with a much better UI, and will be added to CRED before too long.

The data needs to be stored somehow, and there is not so much difference between storing it entirely in post meta or partly as posts with post meta.

2. It's not going to be possible to achieve without some amount of custom code.

On my example above I can produce a similar set up for nested Views where with the first View I pass the current weekday as a shortcode attribute (which I would have to generate with a custom shortcode) and use that to display today's hours for the current restaurant.

If there were only one set of hours it wouldn't be too difficult to use conditional shortcodes to show an open badge if the current time in the same 00:00 format were greater than From and less than To, but that breaks down when you have multiple possible hours for the same day and would require writing a custom shortcode to use in this context which takes all of the From-To's for the current day for the current restaurant and compares them to the current time to return either "open" or "closed".

But the specifics depend very much on your implementation of setting up the data in the first place. I could show you how it would work with my set up, but I won't prepare that if you are doing something very different.

#751722

I think that I get you entirely. Also, I will get your claim about posts/meta despite that I don't think the same (there are reasons for it, but irrelevant for topic). As it is weekend, I will make (prepare) website with first issue done and I would like if you will than show me how to set open/close 'badge'. So, please open private channel for credentials of the site.

#753132

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

Sure, I have set up a private reply and will look at it Monday.

#777929

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

Screen Shot 2018-05-01 at 13.55.25.png

Hi Ljuba

For the main functionality, I see that you have created a CPT "horas de apetura" to act as a container for the repeating fields "dias de la semana", "estado de apetura", y "jornada", where you also additionally have fields for the opening and closing hours (all-day hours or morning and afternoon hours, depending on the setting for jornada).

For each sitio you will add a child horas de apetura post that will specify the day, whether or not it is open that day, and, if open, whether it is open in a single shift or two separate shifts, together with the hours.

I entered some sample data for the current sitios post.

I created a View to display the times for the current Sitio (i.e. this View will be added to the template for displaying single sitio posts).

The View queries the Horas de apertura post type, ordered by the días de la semana field.

The View output necessarily uses nested conditional shortcodes to display the correct fields depending on whether this is a day where the site is open, and, if so, whether it has two shifts or one.

So it looks like this:

<p>[types field='dias-de-la-semana'][/types] : 
  [wpv-conditional if="( $(wpcf-estado-de-apertura) eq '2' )"]Cerrado[/wpv-conditional]
  [wpv-conditional if="( $(wpcf-estado-de-apertura) eq '1' )"]
    [wpv-conditional if="( $(wpcf-jornada) eq '1' )"]
      de [types field='hora-de-apertura'][/types] a [types field='hora-de-cierre'][/types]
    [/wpv-conditional]
    [wpv-conditional if="( $(wpcf-jornada) eq '2' )"]
      de [types field='hora-de-apertura-de-la-manana'][/types] a [types field='hora-de-cierre-de-la-manana'][/types] y de [types field='hora-de-apertura-de-la-tarde'][/types] a [types field='hora-de-cierre-de-la-tarde'][/types]
    [/wpv-conditional]  
  [/wpv-conditional]
</p>

I then added that to a content template I created for single sitio posts (I disabled elementor for the time being to avoid any template conflict).

You can see the results in the screenshot.

What's missing is the logic for displaying whether the site is open or closed currently.

For that I had to register a custom shortcode which performs all the logic and returns the text "abierto" or "cerrado" based upon the current time.

That shortcode (I added it with the Code Snippets plugin) looks like this:

add_shortcode( 'abierto', function(){

	$now = date( "H");

	// get the hora de apetura for today's weekday
	global $post;

	$args = array(
		'post_status'		=>	'publish',
		'post_type'			=>	'horario-de-apertura',
		'meta_query'		=>	array(
			array(
				'key'			=>	'_wpcf_belongs_sitio_id',
				'value'			=>	$post->ID,
				'compare'		=>	'='
			),
			array(
				'key'			=>	'wpcf-dias-de-la-semana',
				'value'			=>	date( "N" ),
				'compare'		=>	'='
			),
			'relation'			=>	'AND'
		)
	);

	$horarios = get_posts( $args );

	$estado = get_post_meta( $horarios[0]->ID, 'wpcf-estado-de-apertura', true );

	if ( $estado == 2 ) {
		return "Cerrado";
	}

	$jornada = get_post_meta( $horarios[0]->ID, 'wpcf-jornada', true );

	if ( $jornada == 1 ) {

		$apertura = get_post_meta( $horarios[0]->ID, 'wpcf-hora-de-apertura', true );
		$cierre = get_post_meta( $horarios[0]->ID, 'wpcf-hora-de-cierre', true );

		if ( $now >= $apertura && $now < $cierre ) {
			return "Abierto!";
		} else {
			return "Cerrado";
		}

	} elseif ( $jornada == 2 ) {

		$apertura1 = get_post_meta( $horarios[0]->ID, 'wpcf-hora-de-apertura-de-la-manana', true );
		$cierre1 = get_post_meta( $horarios[0]->ID, 'wpcf-hora-de-cierre-de-la-manana', true );
		$apertura2 = get_post_meta( $horarios[0]->ID, 'wpcf-hora-de-apertura-de-la-tarde', true );
		$cierre2 = get_post_meta( $horarios[0]->ID, 'wpcf-hora-de-cierre-de-la-tarde', true );

		if ( ( $now >= $apertura1 && $now < $cierre1 ) || ( $now >= $apertura2 && $now < $cierre2 ) ) {
			return "Abierto!";
		} else {
			return "Cerrado";			
		}
	} 

	// catch all
	return "Cerrado*";
});

Note that this is a basic implementation - I didn't make any allowance for the fact that your horario can go past midnight into the next day, you'll need to add some special handling for that.

As for the special dates I haven't looked into that. I already spent longer than I should on this, but I had a little free time, and I think implementing the special days should just be a question of adding more specific logic to the existing set up with the conditional shortcodes and the custom shortcode that determines whether the site is currently open.

Once you have looked over what I've done so far, come back to me with a specific question if needs be.

#779863
001.jpg

Hi Nigel,

First, thanks a lot for effort, because (as I can get) you did exactly what is the goal (you understand request 101%).

1) I would like first to know your opinion, did I structured well CPT, Field Groups, ... for 'working hours' purpose. Here please take in account that I get in mind also further extension (will not be implemented on begin) on Events ('opening hours'), what is kind of different (at least, as it is non repeating opening schedule, but also vs connection of functionality of the 'tickets for Events', than 'upcoming Events & Holidays view', ....).

2) "I created a View to display the times for the current Sitio (i.e. this View will be added to the template for displaying single sitio posts)."

Thanks a lot for that (100% perfect done, exactly as I needed). This is the first crucial point, as I will need it also vs display the view in Template regards 'free/paid' Lugares (businesses - Sitios will be displayed for all sites as they are not commercial). So, now I can easy to include/exclude the 'opening hours view'.

3) "For that I had to register a custom shortcode which performs all the logic and returns the text "abierto" or "cerrado" based upon the current time."

Thanks a lot (again) for that. This is the main part of the ticket. However, for me not looks that it working. Please see attached image and observe marked spots. It shows 'Closed' (3) despite that it should to be 'Open' vs current time (2) and 'opening hours' (1).

P.S. My PC is in Guayaquil Time as well the General Settings of WordPress.

4) Purpose of special dates are mainly for owners to assign (future) 'Close' state, as for Place restoration, vacation of business, closed vs some event in business (weddings), closed because of holidays (especially - Sitios), ...

However, It should also to work as 'special opening hours' (as far as I can imagine, only for Events in Events CPT), but also for other "dias festivos' (officials and not officials). In Ecuador by law is different opening hours (extended) of the bars, restaurants, ... for such days. That's why I tried to make kind of 'modular structure' (from point one, above), to be capable to use 'opening hours' functionality in wide of the scenarios.

BTW Maybe is not bad idea if Toolset will use this for new Demo site with all this variations of the time schedule, as it cover mostly everything.

#803772

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

Screen Shot 2018-05-03 at 12.56.16.png

Hi Ljuba

OK, sorry, the time I was using would have been GMT and not local.

In the code I supplied you should change the following line:

	$now = current_time( "H:i");

Also, I hadn't noticed, but your custom field group horas de apertura, the select option values need to be the same as the display values. See the screenshot where I changed it on my local copy of your site. (And recall that I mentioned you will need to adapt the code to allow for the fact that your horas de apertura extend beyond midnight.)

It took me a little while to follow how you had set up the data structure, but once I had it was fairly straightforward to follow and to work out what was required in terms of displaying the hours and working out if a place was currently open or closed.

I see that you have set up additional fields for special days and holidays, but it is not obvious to me how you intend to use them. But the principles are largely the same as we already covered for the standard days.

Because the standard days are just text labels for days and times and are not actual dates I think it would be difficult to mix them. So if next week Tuesday was a national holiday, you cannot readily display

Mon: 12:00 - 22:00
Tue: Closed for holiday
Wed: 12:00 - 23:00
etc..

You would need to display something more like

Normal hours:
Mon: 12:00 - 22:00
Tue: 12:00 - 22:00
Wed: 12:00 - 23:00
etc.

Special hours:
Tues 8 May : Closed for holiday

You will be able to update the code I suggested for the custom shortcode to determine whether the store is open or not to handle holidays and or special dates, but the code is going to become more complex.

That's one reason we would be unlikely to turn this into a demo, I think. Although some of the first demos we created require custom code (e.g. the Classifieds site) the intention with the demos is to showcase what can be done with Toolset alone, or—at least—with minimal customisation.

#804225

1) "OK, sorry, the time I was using would have been GMT and not local."

All fine, I just asked, as I thought that something else could be issue. However, do you recommend GMT or local (or it is the same?), as it is about tourist info website (so, should be worldwide accessible, as known surf destination, in other languages also)?

2) "And recall that I mentioned you will need to adapt the code to allow for the fact that your horas de apertura extend beyond midnight."

Yes, you did, but form me is not exactly clear how to do it.

3) Together

"I see that you have set up additional fields for special days and holidays, but it is not obvious to me how you intend to use them. But the principles are largely the same as we already covered for the standard days."

"You would need to display something more like"

First, most websites (even most famous like Yelp!) do not offer this options and I'm aware that it is very very very 'extra' feature (but nice and functional).

Yes, output should to be something as you exposed, for purpose to display 'Extended Opening Hours' functionality.

But, interesting part (that's why I wrote for demo) is that I think that my structure and idea of usage can be multifunctional, as 'special days' can be literally everything. Can be used in any kind of websites (classifieds, Fairs, Clubs, restaurants, museums, ...) for 'Extended Opening Hours' (as you displayed), 'Events Happening Hours', 'Events Coming Hours' (same Field Groups but shortcode change and display 'Start in 2 days 13 hours 22 min'), 'Deal Expiration', .... Example, Cinema website with regular/holidays opening hours, coming premiers, tickets discounts offer expiration, ....

Finally, thanks for GREAT JOB (help). I will try to implement it in 'special days'. However, please just answer on points 1 (make me clear) and 2 (optional).

#813118

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

Hi Ljuba

I'm just finishing up and have a week's vacation, I'm sorry I don't have more time to spend on this.

Here are my brief comments, you can post new questions in the forum next week or resume discussing this when I'm back.

1. Your site settings will be for Ecuador time, right? So stick with that, what I did above will work with the local time.

2. You'll need some if-then logic: if it is the early hours then you will be comparing the hours of the previous day not the current day. Sorry I don't have time to elaborate.

3. Good luck!

#820186

Thanks a lot.

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.