Skip to content

Commit 11f7e02

Browse files
authored
Merge pull request #254 from spatie/feature/reciprocal-structured-data
Allow date without year in validFrom/validTo structured data
2 parents 48b4532 + ce002fc commit 11f7e02

File tree

2 files changed

+218
-2
lines changed

2 files changed

+218
-2
lines changed

src/OpeningHoursSpecificationParser.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ private function addExceptionsHours(
122122
mixed $opens,
123123
mixed $closes,
124124
): void {
125-
if (! preg_match('/^\d{4}-\d{2}-\d{2}$/', $validFrom)) {
125+
if (! preg_match('/^(?:\d{4}-)?\d{2}-\d{2}$/', $validFrom)) {
126126
throw new InvalidOpeningHoursSpecification('Invalid validFrom date');
127127
}
128128

129-
if (! preg_match('/^\d{4}-\d{2}-\d{2}$/', $validThrough)) {
129+
if (! preg_match('/^(?:\d{4}-)?\d{2}-\d{2}$/', $validThrough)) {
130130
throw new InvalidOpeningHoursSpecification('Invalid validThrough date');
131131
}
132132

tests/OpeningHoursSpecificationParserTest.php

+216
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,222 @@ public function testClosedDay(): void
188188
$this->assertSame('', (string) $openingHours->forDay(Day::MONDAY));
189189
}
190190

191+
public function testCreateFromPreviousExport(): void
192+
{
193+
$timetable = OpeningHours::create([
194+
'monday' => ['09:00-12:00', '13:00-18:00'],
195+
'tuesday' => ['09:00-12:00', '13:00-18:00'],
196+
'wednesday' => ['09:00-12:00'],
197+
'thursday' => ['09:00-12:00', '13:00-18:00'],
198+
'friday' => ['09:00-12:00', '13:00-20:00'],
199+
'saturday' => ['09:00-12:00', '13:00-16:00'],
200+
'sunday' => [],
201+
'exceptions' => [
202+
'2016-11-11' => ['09:00-12:00'],
203+
'2016-12-25' => [],
204+
'01-01' => [], // Recurring on each 1st of January
205+
'12-25' => ['09:00-12:00'], // Recurring on each 25th of December
206+
],
207+
]);
208+
209+
$array = $timetable->asStructuredData();
210+
self::assertSame([
211+
[
212+
'@type' => 'OpeningHoursSpecification',
213+
'dayOfWeek' => 'Monday',
214+
'opens' => '09:00',
215+
'closes' => '12:00',
216+
],
217+
[
218+
'@type' => 'OpeningHoursSpecification',
219+
'dayOfWeek' => 'Monday',
220+
'opens' => '13:00',
221+
'closes' => '18:00',
222+
],
223+
[
224+
'@type' => 'OpeningHoursSpecification',
225+
'dayOfWeek' => 'Tuesday',
226+
'opens' => '09:00',
227+
'closes' => '12:00',
228+
],
229+
[
230+
'@type' => 'OpeningHoursSpecification',
231+
'dayOfWeek' => 'Tuesday',
232+
'opens' => '13:00',
233+
'closes' => '18:00',
234+
],
235+
[
236+
'@type' => 'OpeningHoursSpecification',
237+
'dayOfWeek' => 'Wednesday',
238+
'opens' => '09:00',
239+
'closes' => '12:00',
240+
],
241+
[
242+
'@type' => 'OpeningHoursSpecification',
243+
'dayOfWeek' => 'Thursday',
244+
'opens' => '09:00',
245+
'closes' => '12:00',
246+
],
247+
[
248+
'@type' => 'OpeningHoursSpecification',
249+
'dayOfWeek' => 'Thursday',
250+
'opens' => '13:00',
251+
'closes' => '18:00',
252+
],
253+
[
254+
'@type' => 'OpeningHoursSpecification',
255+
'dayOfWeek' => 'Friday',
256+
'opens' => '09:00',
257+
'closes' => '12:00',
258+
],
259+
[
260+
'@type' => 'OpeningHoursSpecification',
261+
'dayOfWeek' => 'Friday',
262+
'opens' => '13:00',
263+
'closes' => '20:00',
264+
],
265+
[
266+
'@type' => 'OpeningHoursSpecification',
267+
'dayOfWeek' => 'Saturday',
268+
'opens' => '09:00',
269+
'closes' => '12:00',
270+
],
271+
[
272+
'@type' => 'OpeningHoursSpecification',
273+
'dayOfWeek' => 'Saturday',
274+
'opens' => '13:00',
275+
'closes' => '16:00',
276+
],
277+
[
278+
'@type' => 'OpeningHoursSpecification',
279+
'opens' => '09:00',
280+
'closes' => '12:00',
281+
'validFrom' => '2016-11-11',
282+
'validThrough' => '2016-11-11',
283+
],
284+
[
285+
'@type' => 'OpeningHoursSpecification',
286+
'opens' => '00:00',
287+
'closes' => '00:00',
288+
'validFrom' => '2016-12-25',
289+
'validThrough' => '2016-12-25',
290+
],
291+
[
292+
'@type' => 'OpeningHoursSpecification',
293+
'opens' => '00:00',
294+
'closes' => '00:00',
295+
'validFrom' => '01-01',
296+
'validThrough' => '01-01',
297+
],
298+
[
299+
'@type' => 'OpeningHoursSpecification',
300+
'opens' => '09:00',
301+
'closes' => '12:00',
302+
'validFrom' => '12-25',
303+
'validThrough' => '12-25',
304+
],
305+
], $array);
306+
307+
$newOpeningHours = OpeningHours::createFromStructuredData($array);
308+
309+
self::assertSame([
310+
[
311+
'@type' => 'OpeningHoursSpecification',
312+
'dayOfWeek' => 'Monday',
313+
'opens' => '09:00',
314+
'closes' => '12:00',
315+
],
316+
[
317+
'@type' => 'OpeningHoursSpecification',
318+
'dayOfWeek' => 'Monday',
319+
'opens' => '13:00',
320+
'closes' => '18:00',
321+
],
322+
[
323+
'@type' => 'OpeningHoursSpecification',
324+
'dayOfWeek' => 'Tuesday',
325+
'opens' => '09:00',
326+
'closes' => '12:00',
327+
],
328+
[
329+
'@type' => 'OpeningHoursSpecification',
330+
'dayOfWeek' => 'Tuesday',
331+
'opens' => '13:00',
332+
'closes' => '18:00',
333+
],
334+
[
335+
'@type' => 'OpeningHoursSpecification',
336+
'dayOfWeek' => 'Wednesday',
337+
'opens' => '09:00',
338+
'closes' => '12:00',
339+
],
340+
[
341+
'@type' => 'OpeningHoursSpecification',
342+
'dayOfWeek' => 'Thursday',
343+
'opens' => '09:00',
344+
'closes' => '12:00',
345+
],
346+
[
347+
'@type' => 'OpeningHoursSpecification',
348+
'dayOfWeek' => 'Thursday',
349+
'opens' => '13:00',
350+
'closes' => '18:00',
351+
],
352+
[
353+
'@type' => 'OpeningHoursSpecification',
354+
'dayOfWeek' => 'Friday',
355+
'opens' => '09:00',
356+
'closes' => '12:00',
357+
],
358+
[
359+
'@type' => 'OpeningHoursSpecification',
360+
'dayOfWeek' => 'Friday',
361+
'opens' => '13:00',
362+
'closes' => '20:00',
363+
],
364+
[
365+
'@type' => 'OpeningHoursSpecification',
366+
'dayOfWeek' => 'Saturday',
367+
'opens' => '09:00',
368+
'closes' => '12:00',
369+
],
370+
[
371+
'@type' => 'OpeningHoursSpecification',
372+
'dayOfWeek' => 'Saturday',
373+
'opens' => '13:00',
374+
'closes' => '16:00',
375+
],
376+
[
377+
'@type' => 'OpeningHoursSpecification',
378+
'opens' => '09:00',
379+
'closes' => '12:00',
380+
'validFrom' => '2016-11-11',
381+
'validThrough' => '2016-11-11',
382+
],
383+
[
384+
'@type' => 'OpeningHoursSpecification',
385+
'opens' => '00:00',
386+
'closes' => '00:00',
387+
'validFrom' => '2016-12-25',
388+
'validThrough' => '2016-12-25',
389+
],
390+
[
391+
'@type' => 'OpeningHoursSpecification',
392+
'opens' => '00:00',
393+
'closes' => '00:00',
394+
'validFrom' => '01-01',
395+
'validThrough' => '01-01',
396+
],
397+
[
398+
'@type' => 'OpeningHoursSpecification',
399+
'opens' => '09:00',
400+
'closes' => '12:00',
401+
'validFrom' => '12-25',
402+
'validThrough' => '12-25',
403+
],
404+
], $newOpeningHours->asStructuredData());
405+
}
406+
191407
public function testInvalidJson(): void
192408
{
193409
self::expectExceptionObject(new InvalidOpeningHoursSpecification(

0 commit comments

Comments
 (0)