Completed
Push — master ( 0c53d4...debbec )
by David
09:08 queued 10s
created

Wordlift_Schema_Service::get_instance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Services: WordLift Schema Service.
4
 *
5
 * This file defines the Wordlift_Schema_Service class.
6
 *
7
 * @since      3.1.0
8
 * @package    Wordlift
9
 * @subpackage Wordlift/includes
10
 */
11
12
/**
13
 * Provides constants and methods related to WordLift's schema.
14
 *
15
 * @since      3.1.0
16
 * @package    Wordlift
17
 * @subpackage Wordlift/includes
18
 */
19
class Wordlift_Schema_Service {
20
21
	/**
22
	 * The 'location created' field name.
23
	 *
24
	 * @since 3.5.0
25
	 */
26
	const FIELD_LOCATION_CREATED = 'wl_location_created';
27
28
	/**
29
	 * The 'topic' field name.
30
	 *
31
	 * @since 3.5.0
32
	 */
33
	const FIELD_TOPIC = 'wl_topic';
34
35
	/**
36
	 * The 'author' field name.
37
	 *
38
	 * @since 3.1.0
39
	 */
40
	const FIELD_AUTHOR = 'wl_author';
41
42
	/**
43
	 * The 'same as' field name.
44
	 *
45
	 * @since 3.1.0
46
	 */
47
	const FIELD_SAME_AS = 'entity_same_as';
48
49
	/**
50
	 * The 'date start' field name.
51
	 *
52
	 * @since 3.1.0
53
	 */
54
	const FIELD_DATE_START = 'wl_cal_date_start';
55
56
	/**
57
	 * The 'date end' field name.
58
	 *
59
	 * @since 3.1.0
60
	 */
61
	const FIELD_DATE_END = 'wl_cal_date_end';
62
63
	/**
64
	 * The 'location' field name.
65
	 *
66
	 * @since 3.1.0
67
	 */
68
	const FIELD_LOCATION = 'wl_location';
69
70
	/**
71
	 * The 'founder' field name.
72
	 *
73
	 * @since 3.1.0
74
	 */
75
	const FIELD_FOUNDER = 'wl_founder';
76
77
	/**
78
	 * The 'knows' field name.
79
	 *
80
	 * @since 3.1.0
81
	 */
82
	const FIELD_KNOWS = 'wl_knows';
83
84
	/**
85
	 * The 'birth date' field name.
86
	 *
87
	 * @since 3.1.0
88
	 */
89
	const FIELD_BIRTH_DATE = 'wl_birth_date';
90
91
	/**
92
	 * The 'birth place' field name.
93
	 *
94
	 * @since 3.1.0
95
	 */
96
	const FIELD_BIRTH_PLACE = 'wl_birth_place';
97
98
	/**
99
	 * The 'latitude' field name.
100
	 *
101
	 * @since 3.1.0
102
	 */
103
	const FIELD_GEO_LATITUDE = 'wl_geo_latitude';
104
105
	/**
106
	 * The 'longitude' field name.
107
	 *
108
	 * @since 3.1.0
109
	 */
110
	const FIELD_GEO_LONGITUDE = 'wl_geo_longitude';
111
112
	/**
113
	 * The 'streetAddress' field name.
114
	 *
115
	 * @since 3.1.0
116
	 */
117
	const FIELD_ADDRESS = 'wl_address';
118
119
	/**
120
	 * The 'postOfficeBoxNumber' field name.
121
	 *
122
	 * @since 3.3.0
123
	 */
124
	const FIELD_ADDRESS_PO_BOX = 'wl_address_post_office_box';
125
126
	/**
127
	 * The 'postalCode' field name.
128
	 *
129
	 * @since 3.3.0
130
	 */
131
	const FIELD_ADDRESS_POSTAL_CODE = 'wl_address_postal_code';
132
133
	/**
134
	 * The 'addressLocality' field name.
135
	 *
136
	 * @since 3.3.0
137
	 */
138
	const FIELD_ADDRESS_LOCALITY = 'wl_address_locality';
139
	/**
140
	 * The 'addressRegion' field name.
141
	 *
142
	 * @since 3.3.0
143
	 */
144
	const FIELD_ADDRESS_REGION = 'wl_address_region';
145
146
	/**
147
	 * The 'addressCountry' field name.
148
	 *
149
	 * @since 3.3.0
150
	 */
151
	const FIELD_ADDRESS_COUNTRY = 'wl_address_country';
152
153
	/**
154
	 * The 'entity type' field name.
155
	 *
156
	 * @since 3.1.0
157
	 */
158
	const FIELD_ENTITY_TYPE = 'wl_entity_type_uri';
159
160
	/**
161
	 * The 'email' field name.
162
	 *
163
	 * @since 3.2.0
164
	 */
165
	const FIELD_EMAIL = 'wl_email';
166
167
	/**
168
	 * The 'affiliation' field name.
169
	 *
170
	 * @since 3.2.0
171
	 */
172
	const FIELD_AFFILIATION = 'wl_affiliation';
173
174
	/**
175
	 * The 'telephone' field name.
176
	 *
177
	 * @since 3.8.0
178
	 */
179
	const FIELD_TELEPHONE = 'wl_schema_telephone';
180
181
	/**
182
	 * The 'legalName' field name.
183
	 *
184
	 * @since 3.12.0
185
	 */
186
	const FIELD_LEGAL_NAME = 'wl_schema_legal_name';
187
188
	/**
189
	 * The 'recipeCuisine' field name.
190
	 *
191
	 * @since 3.14.0
192
	 */
193
	const FIELD_RECIPE_CUISINE = 'wl_schema_recipe_cuisine';
194
195
	/**
196
	 * The 'recipeIngredient' field name.
197
	 *
198
	 * @since 3.14.0
199
	 */
200
	const FIELD_RECIPE_INGREDIENT = 'wl_schema_recipe_ingredient';
201
202
	/**
203
	 * The 'calories' field name.
204
	 *
205
	 * @since 3.14.0
206
	 */
207
	const FIELD_NUTRITION_INFO_CALORIES = 'wl_schema_nutrition_information_calories';
208
209
	/**
210
	 * The 'recipeInstructions' field name.
211
	 *
212
	 * @since 3.14.0
213
	 */
214
	const FIELD_RECIPE_INSTRUCTIONS = 'wl_schema_recipe_instructions';
215
216
	/**
217
	 * The 'recipeYield' field name.
218
	 *
219
	 * @since 3.14.0
220
	 */
221
	const FIELD_RECIPE_YIELD = 'wl_schema_recipe_yield';
222
223
	/**
224
	 * The 'prepTime' field name.
225
	 *
226
	 * @since 3.14.0
227
	 */
228
	const FIELD_PREP_TIME = 'wl_schema_prep_time';
229
230
	/**
231
	 * The 'cookTime' field name.
232
	 *
233
	 * @since 3.14.0
234
	 */
235
	const FIELD_COOK_TIME = 'wl_schema_cook_time';
236
237
	/**
238
	 * The 'totalTime' field name.
239
	 *
240
	 * @since 3.14.0
241
	 */
242
	const FIELD_TOTAL_TIME = 'wl_schema_total_time';
243
244
	/**
245
	 * The 'performer' field name.
246
	 *
247
	 * @since 3.18.0
248
	 */
249
	const FIELD_PERFORMER = 'wl_schema_performer';
250
251
	/**
252
	 * The 'offers' field name.
253
	 *
254
	 * @since 3.18.0
255
	 */
256
	const FIELD_OFFERS = 'wl_schema_offers';
257
258
	/**
259
	 * The 'availablity' field name.
260
	 *
261
	 * @since 3.18.0
262
	 */
263
	const FIELD_AVAILABILITY = 'wl_schema_availability';
264
265
	/**
266
	 * The 'inventoryLevel' field name.
267
	 *
268
	 * @since 3.18.0
269
	 */
270
	const FIELD_INVENTORY_LEVEL = 'wl_schema_inventory_level';
271
272
	/**
273
	 * The 'price' field name.
274
	 *
275
	 * @since 3.18.0
276
	 */
277
	const FIELD_PRICE = 'wl_schema_price';
278
279
	/**
280
	 * The 'priceCurrency' field name.
281
	 *
282
	 * @since 3.18.0
283
	 */
284
	const FIELD_PRICE_CURRENCY = 'wl_schema_price_currency';
285
286
	/**
287
	 * The 'availabilityStarts' field name.
288
	 *
289
	 * @since 3.18.0
290
	 */
291
	const FIELD_AVAILABILITY_STARTS = 'wl_schema_availability_starts';
292
293
	/**
294
	 * The 'availabilityEnds' field name.
295
	 *
296
	 * @since 3.18.0
297
	 */
298
	const FIELD_AVAILABILITY_ENDS = 'wl_schema_availability_ends';
299
300
	/**
301
	 * The 'validFrom' field name.
302
	 *
303
	 * @since 3.18.0
304
	 */
305
	const FIELD_VALID_FROM = 'wl_schema_valid_from';
306
307
	/**
308
	 * The 'priceValidUntil' field name.
309
	 *
310
	 * @since 3.18.0
311
	 */
312
	const FIELD_PRICE_VALID_UNTIL = 'wl_schema_valid_until';
313
314
	/**
315
	 * The 'itemOffered' field name.
316
	 *
317
	 * @since 3.18.0
318
	 */
319
	const FIELD_ITEM_OFFERED = 'wl_schema_item_offered';
320
321
	/**
322
	 * The 'URI' data type name.
323
	 *
324
	 * @since 3.1.0
325
	 */
326
	const DATA_TYPE_URI = 'uri';
327
328
	/**
329
	 * The 'date' data type name.
330
	 *
331
	 * @since 3.1.0
332
	 */
333
	const DATA_TYPE_DATE = 'date';
334
335
	/**
336
	 * The 'dateTime' data type name.
337
	 *
338
	 * @since 3.15.0
339
	 */
340
	const DATA_TYPE_DATE_TIME = 'dateTime';
341
342
	/**
343
	 * The 'time' data type name.
344
	 *
345
	 * @since 3.14.0
346
	 */
347
	const DATA_TYPE_DURATION = 'duration';
348
349
	/**
350
	 * The 'double' data type name.
351
	 *
352
	 * @since 3.1.0
353
	 */
354
	const DATA_TYPE_DOUBLE = 'double';
355
356
	/**
357
	 * The 'string' data type name.
358
	 *
359
	 * @since 3.1.0
360
	 */
361
	const DATA_TYPE_STRING = 'string';
362
363
	/**
364
	 * The multiline text data type name.
365
	 *
366
	 * @since 3.14.0
367
	 */
368
	const DATA_TYPE_MULTILINE = 'multiline';
369
370
	/**
371
	 * The 'integer' data type name.
372
	 *
373
	 * @since 3.1.0
374
	 */
375
	const DATA_TYPE_INTEGER = 'int';
376
377
	/**
378
	 * The 'boolean' data type name.
379
	 *
380
	 * @since 3.1.0
381
	 */
382
	const DATA_TYPE_BOOLEAN = 'bool';
383
384
	/**
385
	 * The schema.org Event type URI.
386
	 *
387
	 * @since 3.1.0
388
	 */
389
	const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
390
391
	/**
392
	 * The schema.org Offer type URI.
393
	 *
394
	 * @since 3.18.0
395
	 */
396
	const SCHEMA_OFFER_TYPE = 'http://schema.org/Offer';
397
398
	/**
399
	 * The Schema service singleton instance.
400
	 *
401
	 * @since  3.1.0
402
	 * @access private
403
	 * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
404
	 */
405
	private static $instance;
406
407
	/**
408
	 * WordLift's schema.
409
	 *
410
	 * @since  3.1.0
411
	 * @access private
412
	 * @var array $schema WordLift's schema.
413
	 */
414
	private $schema;
415
416
	/**
417
	 * The Log service.
418
	 *
419
	 * @since  3.1.0
420
	 * @access private
421
	 * @var \Wordlift_Log_Service $log The Log service.
422
	 */
423
	private $log;
424
425
	/**
426
	 * The {@link Wordlift_Post_Property_Storage_Factory} instance.
427
	 *
428
	 * @since  3.15.0
429
	 * @access private
430
	 * @var \Wordlift_Storage_Factory $storage_factory The {@link Wordlift_Post_Property_Storage_Factory} instance.
431
	 */
432
	private $storage_factory;
433
434
	/**
435
	 * The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
436
	 *
437
	 * @since  3.15.0
438
	 * @access private
439
	 * @var \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
440
	 */
441
	private $rendition_factory;
442
443
	/**
444
	 * The {@link Wordlift_Configuration_Service} instance.
445
	 *
446
	 * @since  3.15.0
447
	 * @access private
448
	 * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
449
	 */
450
	private $configuration_service;
451
452
	/**
453
	 * The web site configured language code.
454
	 *
455
	 * @since  3.15.0
456
	 * @access private
457
	 * @var string $language_code The web site configured language code.
458
	 */
459
	private $language_code;
460
461
	/**
462
	 * Wordlift_Schema_Service constructor.
463
	 *
464
	 * @since 3.1.0
465
	 *
466
	 * @param \Wordlift_Storage_Factory                $storage_factory       The {@link Wordlift_Post_Property_Storage_Factory} instance.
467
	 * @param \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory     The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
468
	 * @param \Wordlift_Configuration_Service          $configuration_service The {@link Wordlift_Configuration_Service} instance.
469
	 */
470
	public function __construct( $storage_factory, $rendition_factory, $configuration_service ) {
471
472
		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
473
474
		$this->storage_factory       = $storage_factory;
475
		$this->rendition_factory     = $rendition_factory;
476
		$this->configuration_service = $configuration_service;
477
		$this->language_code         = $this->configuration_service->get_language_code();
478
479
		// Set the taxonomy data.
480
		// Note: parent types must be defined before child types.
481
		$this->schema = array(
482
			'article'       => $this->get_article_schema(),
483
			'thing'         => $this->get_thing_schema(),
484
			'creative-work' => $this->get_creative_work_schema(),
485
			'event'         => $this->get_event_schema(),
486
			'organization'  => $this->get_organization_schema(),
487
			'person'        => $this->get_person_schema(),
488
			'place'         => $this->get_place_schema(),
489
			'localbusiness' => $this->get_local_business_schema(),
490
			'recipe'        => $this->get_recipe_schema(),
491
			'web-page'      => $this->get_web_page_schema(),
492
			'offer'         => $this->get_offer_schema(),
493
		);
494
495
		// Create a singleton instance of the Schema service, useful to provide static functions to global functions.
496
		self::$instance = $this;
497
498
	}
499
500
	/**
501
	 * Get a reference to the Schema service.
502
	 *
503
	 * @since 3.1.0
504
	 *
505
	 * @return Wordlift_Schema_Service A reference to the Schema service.
506
	 */
507
	public static function get_instance() {
508
509
		return self::$instance;
510
	}
511
512
	/**
513
	 * Get the properties for a field with the specified key. The key is used as
514
	 * meta key when the field's value is stored in WordPress meta data table.
515
	 *
516
	 * @since 3.6.0
517
	 *
518
	 * @param string $key The field's key.
519
	 *
520
	 * @return null|array An array of field's properties or null if the field is not found.
521
	 */
522
	public function get_field( $key ) {
523
524
		// Parse each schema's fields until we find the one we're looking for, then
525
		// return its properties.
526
		foreach ( $this->schema as $_ => $schema ) {
527
528
			if ( ! isset( $schema['custom_fields'] ) ) {
529
				break;
530
			}
531
532
			foreach ( $schema['custom_fields'] as $field => $props ) {
533
				if ( $key === $field ) {
534
					return $props;
535
				}
536
			}
537
		}
538
539
		return null;
540
	}
541
542
	/**
543
	 * Get all renditions for each WordLift's schema.
544
	 *
545
	 * @since 3.18.0
546
	 *
547
	 * @return array An array with the schema renditions.
548
	 */
549
	public function get_renditions() {
550
		// Get the custom fields.
551
		$renditions = array_reduce(
552
			$this->schema,
553
			function ( $carry, $item ) {
554
				return array_merge( $carry, $item['linked_data'] );
555
			},
556
			array()
557
		);
558
559
		// Return the schemas.
560
		return $renditions;
561
	}
562
563
	/**
564
	 * Get the WordLift's schema.
565
	 *
566
	 * @param string $name The schema name.
567
	 *
568
	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
569
	 *
570
	 * @since 3.1.0
571
	 */
572
	public function get_schema( $name ) {
573
		// Check if the schema exists and, if not, return NULL.
574
		if ( ! isset( $this->schema[ $name ] ) ) {
575
			return null;
576
		}
577
578
		// Return the requested schema.
579
		return $this->schema[ $name ];
580
	}
581
582
	/**
583
	 * Get the WordLift's schema trough schema type uri.
584
	 *
585
	 * @param string $uri The schema uri.
586
	 *
587
	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
588
	 *
589
	 * @since 3.3.0
590
	 */
591
	public function get_schema_by_uri( $uri ) {
592
593
		foreach ( $this->schema as $name => $schema ) {
594
			if ( $schema['uri'] === $uri ) {
595
				return $schema;
596
			}
597
		}
598
599
		return null;
600
	}
601
602
	/**
603
	 * Get the 'thing' schema.
604
	 *
605
	 * @return array An array with the schema configuration.
606
	 *
607
	 * @since 3.1.0
608
	 */
609
	private function get_thing_schema() {
610
611
		return array(
612
			'css_class'     => 'wl-thing',
613
			'uri'           => 'http://schema.org/Thing',
614
			'same_as'       => array( '*' ),
615
			// set as default.
616
			'custom_fields' => array(
617
				self::FIELD_SAME_AS                            => array(
618
					'predicate'   => 'http://schema.org/sameAs',
619
					'type'        => self::DATA_TYPE_URI,
620
					'export_type' => 'http://schema.org/Thing',
621
					'constraints' => array(
622
						'cardinality' => INF,
623
					),
624
					// We need a custom metabox.
625
					'input_field' => 'sameas',
626
				),
627
				// Add the schema:url property.
628
				Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
0 ignored issues
show
Deprecated Code introduced by
The method Wordlift_Property_Service::get_compat_definition() has been deprecated.

This method has been deprecated.

Loading history...
629
																									  ->get_compat_definition(),
630
			),
631
			// {{sameAs}} not present in the microdata template,
632
			// because it is treated separately in *wl_content_embed_item_microdata*
633
			'templates'     => array(
634
				'subtitle' => '{{id}}',
635
			),
636
			'linked_data'   => array(
637
				// ### Title to rdfs:label.
638
				$this->rendition_factory->create(
639
					$this->storage_factory->post_title(),
640
					Wordlift_Query_Builder::RDFS_LABEL_URI,
641
					null,
642
					$this->language_code
643
				),
644
				// ### Title to dct:title.
645
				$this->rendition_factory->create(
646
					$this->storage_factory->post_title(),
647
					'http://purl.org/dc/terms/title',
648
					null,
649
					$this->language_code
650
				),
651
				// ### Alternative title to rdfs:label.
652
				$this->rendition_factory->create(
653
					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
654
					Wordlift_Query_Builder::RDFS_LABEL_URI,
655
					null,
656
					$this->language_code
657
				),
658
				// ### Alternative title to dct:title.
659
				$this->rendition_factory->create(
660
					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
661
					'http://purl.org/dc/terms/title',
662
					null,
663
					$this->language_code
664
				),
665
				// ### schema:url.
666
				$this->rendition_factory->create(
667
					$this->storage_factory->url_property(),
668
					Wordlift_Query_Builder::SCHEMA_URL_URI,
669
					self::DATA_TYPE_URI
670
				),
671
				// ### schema:description.
672
				$this->rendition_factory->create(
673
					$this->storage_factory->post_description_no_tags_no_shortcodes(),
674
					'http://schema.org/description',
675
					null,
676
					$this->language_code
677
				),
678
				// ### owl:sameAs.
679
				$this->rendition_factory->create(
680
					$this->storage_factory->post_meta( self::FIELD_SAME_AS ),
681
					'http://www.w3.org/2002/07/owl#sameAs',
682
					self::DATA_TYPE_URI
683
				),
684
				// ### rdf:type.
685
				$this->rendition_factory->create(
686
					$this->storage_factory->schema_class(),
687
					Wordlift_Query_Builder::RDFS_TYPE_URI,
688
					self::DATA_TYPE_URI
689
				),
690
				// ### schema:image.
691
				$this->rendition_factory->create(
692
					$this->storage_factory->post_images(),
693
					Wordlift_Query_Builder::SCHEMA_IMAGE_URI,
694
					self::DATA_TYPE_URI
695
				),
696
				// ### dct:relation.
697
				$this->rendition_factory->create(
698
					$this->storage_factory->relations(),
699
					Wordlift_Query_Builder::DCTERMS_RELATION_URI,
700
					self::DATA_TYPE_URI
701
				),
702
			),
703
		);
704
705
	}
706
707
	/**
708
	 * Get the 'web-page' schema.
709
	 *
710
	 * @return array An array with the schema configuration.
711
	 *
712
	 * @since 3.18.0
713
	 */
714
	private function get_web_page_schema() {
715
716
		return array(
717
			'css_class'   => 'wl-webpage',
718
			'uri'         => 'http://schema.org/WebPage',
719
			'linked_data' => array(
720
				// ### schema:headline.
721
				$this->rendition_factory->create(
722
					$this->storage_factory->post_title(),
723
					'http://schema.org/headline',
724
					null,
725
					$this->language_code
726
				),
727
				// ### schema:url.
728
				$this->rendition_factory->create(
729
					$this->storage_factory->url_property(),
730
					Wordlift_Query_Builder::SCHEMA_URL_URI,
731
					self::DATA_TYPE_URI
732
				),
733
				// ### rdf:type.
734
				$this->rendition_factory->create(
735
					$this->storage_factory->schema_class(),
736
					Wordlift_Query_Builder::RDFS_TYPE_URI,
737
					self::DATA_TYPE_URI
738
				),
739
				// ### dcterms:references.
740
				$this->rendition_factory->create(
741
					$this->storage_factory->relations(),
742
					Wordlift_Query_Builder::DCTERMS_REFERENCES_URI,
743
					self::DATA_TYPE_URI,
744
					$this->language_code
745
				),
746
			),
747
		);
748
749
	}
750
751
	/**
752
	 * Get the 'creative work' schema.
753
	 *
754
	 * @return array An array with the schema configuration.
755
	 *
756
	 * @since 3.1.0
757
	 */
758
	private function get_creative_work_schema() {
759
760
		$schema = array(
761
			'label'         => 'CreativeWork',
762
			'description'   => 'A creative work (or a Music Album).',
763
			'parents'       => array( 'thing' ),
764
			// Give term slug as parent.
765
			'css_class'     => 'wl-creative-work',
766
			'uri'           => 'http://schema.org/CreativeWork',
767
			'same_as'       => array(
768
				'http://schema.org/MusicAlbum',
769
				'http://schema.org/Product',
770
			),
771
			'custom_fields' => array(
772
				self::FIELD_AUTHOR => array(
773
					'predicate'   => 'http://schema.org/author',
774
					'type'        => self::DATA_TYPE_URI,
775
					'export_type' => 'http://schema.org/Person',
776
					'constraints' => array(
777
						'uri_type'    => array( 'Person', 'Organization' ),
778
						'cardinality' => INF,
779
					),
780
				),
781
			),
782
			'linked_data'   => array(
783
				// ### schema:author.
784
				$this->rendition_factory->create(
785
					$this->storage_factory->author_uri(),
786
					Wordlift_Query_Builder::SCHEMA_AUTHOR_URI,
787
					self::DATA_TYPE_URI
788
				),
789
			),
790
			'templates'     => array(
791
				'subtitle' => '{{id}}',
792
			),
793
		);
794
795
		// Merge the custom fields with those provided by the thing schema.
796
		$parent_schema           = $this->get_thing_schema();
797
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
798
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
799
800
		return $schema;
801
	}
802
803
	/**
804
	 * Get the 'event' schema.
805
	 *
806
	 * @return array An array with the schema configuration.
807
	 *
808
	 * @since 3.1.0
809
	 */
810
	private function get_event_schema() {
811
812
		$schema = array(
813
			'label'         => 'Event',
814
			'description'   => 'An event . ',
815
			'parents'       => array( 'thing' ),
816
			'css_class'     => 'wl-event',
817
			'uri'           => self::SCHEMA_EVENT_TYPE,
818
			'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
819
			'custom_fields' => array(
820
				self::FIELD_DATE_START => array(
821
					'predicate'   => 'http://schema.org/startDate',
822
					'type'        => self::DATA_TYPE_DATE,
823
					'export_type' => 'xsd:dateTime',
824
					'constraints' => '',
825
				),
826
				self::FIELD_DATE_END   => array(
827
					'predicate'   => 'http://schema.org/endDate',
828
					'type'        => self::DATA_TYPE_DATE,
829
					'export_type' => 'xsd:dateTime',
830
					'constraints' => '',
831
				),
832
				self::FIELD_LOCATION   => array(
833
					'predicate'   => 'http://schema.org/location',
834
					'type'        => self::DATA_TYPE_URI,
835
					'export_type' => 'http://schema.org/PostalAddress',
836
					'constraints' => array(
837
						'uri_type'    => array( 'Place', 'LocalBusiness' ),
838
						'cardinality' => INF,
839
					),
840
				),
841
				self::FIELD_PERFORMER  => array(
842
					'predicate'   => 'http://schema.org/performer',
843
					'type'        => self::DATA_TYPE_URI,
844
					'export_type' => 'http://schema.org/Person',
845
					'constraints' => array(
846
						'uri_type'    => array( 'Person', 'Organization' ),
847
						'cardinality' => INF,
848
					),
849
				),
850
				self::FIELD_OFFERS     => array(
851
					'predicate'   => 'http://schema.org/offers',
852
					'type'        => self::DATA_TYPE_URI,
853
					'export_type' => 'http://schema.org/Offer',
854
					'constraints' => array(
855
						'uri_type'    => array( 'Offer' ),
856
						'cardinality' => INF,
857
					),
858
				),
859
			),
860
			'linked_data'   => array(
861
				// ### schema:startDate.
862
				$this->rendition_factory->create(
863
					$this->storage_factory->post_meta( self::FIELD_DATE_START ),
864
					'http://schema.org/startDate',
865
					self::DATA_TYPE_DATE_TIME
866
				),
867
				// ### schema:endDate.
868
				$this->rendition_factory->create(
869
					$this->storage_factory->post_meta( self::FIELD_DATE_END ),
870
					'http://schema.org/endDate',
871
					self::DATA_TYPE_DATE_TIME
872
				),
873
				// ### schema:location.
874
				$this->rendition_factory->create(
875
					$this->storage_factory->post_meta_to_uri( self::FIELD_LOCATION ),
876
					'http://schema.org/location',
877
					self::DATA_TYPE_URI
878
				),
879
				// ### schema:performer.
880
				$this->rendition_factory->create(
881
					$this->storage_factory->post_meta_to_uri( self::FIELD_PERFORMER ),
882
					'http://schema.org/performer',
883
					self::DATA_TYPE_URI
884
				),
885
				// ### schema:offers.
886
				$this->rendition_factory->create(
887
					$this->storage_factory->post_meta_to_uri( self::FIELD_OFFERS ),
888
					'http://schema.org/offers',
889
					self::DATA_TYPE_URI
890
				),
891
			),
892
			'templates'     => array(
893
				'subtitle' => '{{id}}',
894
			),
895
		);
896
897
		// Merge the custom fields with those provided by the thing schema.
898
		$parent_schema           = $this->get_thing_schema();
899
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
900
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
901
902
		return $schema;
903
	}
904
905
	/**
906
	 * Get the 'organization' schema.
907
	 *
908
	 * @return array An array with the schema configuration.
909
	 *
910
	 * @since 3.1.0
911
	 */
912
	private function get_organization_schema() {
913
914
		$schema = array(
915
			'label'         => 'Organization',
916
			'description'   => 'An organization, including a government or a newspaper.',
917
			'parents'       => array( 'thing' ),
918
			'css_class'     => 'wl-organization',
919
			'uri'           => 'http://schema.org/Organization',
920
			'same_as'       => array(
921
				'http://rdf.freebase.com/ns/organization.organization',
922
				'http://rdf.freebase.com/ns/government.government',
923
				'http://schema.org/Newspaper',
924
			),
925
			'custom_fields' => array(
926
				self::FIELD_LEGAL_NAME          => array(
927
					'predicate'   => 'http://schema.org/legalName',
928
					'type'        => self::DATA_TYPE_STRING,
929
					'export_type' => 'xsd:string',
930
					'constraints' => '',
931
				),
932
				self::FIELD_FOUNDER             => array(
933
					'predicate'   => 'http://schema.org/founder',
934
					'type'        => self::DATA_TYPE_URI,
935
					'export_type' => 'http://schema.org/Person',
936
					'constraints' => array(
937
						'uri_type'    => 'Person',
938
						'cardinality' => INF,
939
					),
940
				),
941
				self::FIELD_ADDRESS             => array(
942
					'predicate'   => 'http://schema.org/streetAddress',
943
					'type'        => self::DATA_TYPE_STRING,
944
					'export_type' => 'xsd:string',
945
					'constraints' => '',
946
					// To build custom metabox.
947
					'input_field' => 'address',
948
				),
949
				self::FIELD_ADDRESS_PO_BOX      => array(
950
					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
951
					'type'        => self::DATA_TYPE_STRING,
952
					'export_type' => 'xsd:string',
953
					'constraints' => '',
954
					// To build custom metabox.
955
					'input_field' => 'address',
956
				),
957
				self::FIELD_ADDRESS_POSTAL_CODE => array(
958
					'predicate'   => 'http://schema.org/postalCode',
959
					'type'        => self::DATA_TYPE_STRING,
960
					'export_type' => 'xsd:string',
961
					'constraints' => '',
962
					// To build custom metabox.
963
					'input_field' => 'address',
964
				),
965
				self::FIELD_ADDRESS_LOCALITY    => array(
966
					'predicate'   => 'http://schema.org/addressLocality',
967
					'type'        => self::DATA_TYPE_STRING,
968
					'export_type' => 'xsd:string',
969
					'constraints' => '',
970
					// To build custom metabox.
971
					'input_field' => 'address',
972
				),
973
				self::FIELD_ADDRESS_REGION      => array(
974
					'predicate'   => 'http://schema.org/addressRegion',
975
					'type'        => self::DATA_TYPE_STRING,
976
					'export_type' => 'xsd:string',
977
					'constraints' => '',
978
					// To build custom metabox.
979
					'input_field' => 'address',
980
				),
981
				self::FIELD_ADDRESS_COUNTRY     => array(
982
					'predicate'   => 'http://schema.org/addressCountry',
983
					'type'        => self::DATA_TYPE_STRING,
984
					'export_type' => 'xsd:string',
985
					'constraints' => '',
986
					// To build custom metabox.
987
					'input_field' => 'address',
988
				),
989
				self::FIELD_EMAIL               => array(
990
					'predicate'   => 'http://schema.org/email',
991
					'type'        => self::DATA_TYPE_STRING,
992
					'export_type' => 'xsd:string',
993
					'constraints' => '',
994
				),
995
				self::FIELD_TELEPHONE           => array(
996
					'predicate'   => 'http://schema.org/telephone',
997
					'type'        => self::DATA_TYPE_STRING,
998
					'export_type' => 'xsd:string',
999
					'constraints' => '',
1000
				),
1001
			),
1002
			'linked_data'   => array(
1003
				// ### schema:legalName.
1004
				$this->rendition_factory->create(
1005
					$this->storage_factory->post_meta( self::FIELD_LEGAL_NAME ),
1006
					'http://schema.org/legalName'
1007
				),
1008
				// ### schema:founder.
1009
				$this->rendition_factory->create(
1010
					$this->storage_factory->post_meta_to_uri( self::FIELD_FOUNDER ),
1011
					'http://schema.org/founder',
1012
					self::DATA_TYPE_URI
1013
				),
1014
				// ### schema:email.
1015
				$this->rendition_factory->create(
1016
					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
1017
					'http://schema.org/email'
1018
				),
1019
				// ### schema:telephone.
1020
				$this->rendition_factory->create(
1021
					$this->storage_factory->post_meta( self::FIELD_TELEPHONE ),
1022
					'http://schema.org/telephone'
1023
				),
1024
			),
1025
			'templates'     => array(
1026
				'subtitle' => '{{id}}',
1027
			),
1028
		);
1029
1030
		// Merge the custom fields with those provided by the thing schema.
1031
		$parent_schema           = $this->get_thing_schema();
1032
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1033
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1034
1035
		return $schema;
1036
	}
1037
1038
	/**
1039
	 * Get the 'person' schema.
1040
	 *
1041
	 * @return array An array with the schema configuration.
1042
	 *
1043
	 * @since 3.1.0
1044
	 */
1045
	private function get_person_schema() {
1046
1047
		$schema = array(
1048
			'label'         => 'Person',
1049
			'description'   => 'A person (or a music artist).',
1050
			'parents'       => array( 'thing' ),
1051
			'css_class'     => 'wl-person',
1052
			'uri'           => 'http://schema.org/Person',
1053
			'same_as'       => array(
1054
				'http://rdf.freebase.com/ns/people.person',
1055
				'http://rdf.freebase.com/ns/music.artist',
1056
				'http://dbpedia.org/class/yago/LivingPeople',
1057
			),
1058
			'custom_fields' => array(
1059
				self::FIELD_KNOWS       => array(
1060
					'predicate'   => 'http://schema.org/knows',
1061
					'type'        => self::DATA_TYPE_URI,
1062
					'export_type' => 'http://schema.org/Person',
1063
					'constraints' => array(
1064
						'uri_type'    => 'Person',
1065
						'cardinality' => INF,
1066
					),
1067
				),
1068
				self::FIELD_BIRTH_DATE  => array(
1069
					'predicate'   => 'http://schema.org/birthDate',
1070
					'type'        => self::DATA_TYPE_DATE,
1071
					'export_type' => 'xsd:date',
1072
					'constraints' => '',
1073
				),
1074
				self::FIELD_BIRTH_PLACE => array(
1075
					'predicate'   => 'http://schema.org/birthPlace',
1076
					'type'        => self::DATA_TYPE_URI,
1077
					'export_type' => 'http://schema.org/Place',
1078
					'constraints' => array(
1079
						'uri_type' => 'Place',
1080
					),
1081
				),
1082
				self::FIELD_AFFILIATION => array(
1083
					'predicate'   => 'http://schema.org/affiliation',
1084
					'type'        => self::DATA_TYPE_URI,
1085
					'export_type' => 'http://schema.org/Organization',
1086
					'constraints' => array(
1087
						'uri_type'    => array(
1088
							'Organization',
1089
							'LocalBusiness',
1090
						),
1091
						'cardinality' => INF,
1092
					),
1093
				),
1094
				self::FIELD_EMAIL       => array(
1095
					'predicate'   => 'http://schema.org/email',
1096
					'type'        => self::DATA_TYPE_STRING,
1097
					'export_type' => 'xsd:string',
1098
					'constraints' => array(
1099
						'cardinality' => INF,
1100
					),
1101
				),
1102
			),
1103
			'linked_data'   => array(
1104
				// ### schema:knows.
1105
				$this->rendition_factory->create(
1106
					$this->storage_factory->post_meta_to_uri( self::FIELD_KNOWS ),
1107
					'http://schema.org/knows',
1108
					self::DATA_TYPE_URI
1109
				),
1110
				// ### schema:birthDate.
1111
				$this->rendition_factory->create(
1112
					$this->storage_factory->post_meta( self::FIELD_BIRTH_DATE ),
1113
					'http://schema.org/birthDate',
1114
					self::DATA_TYPE_DATE
1115
				),
1116
				// ### schema:birthPlace.
1117
				$this->rendition_factory->create(
1118
					$this->storage_factory->post_meta_to_uri( self::FIELD_BIRTH_PLACE ),
1119
					'http://schema.org/birthPlace',
1120
					self::DATA_TYPE_URI
1121
				),
1122
				// ### schema:affiliation.
1123
				$this->rendition_factory->create(
1124
					$this->storage_factory->post_meta_to_uri( self::FIELD_AFFILIATION ),
1125
					'http://schema.org/affiliation',
1126
					self::DATA_TYPE_URI
1127
				),
1128
				// ### schema:email.
1129
				$this->rendition_factory->create(
1130
					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
1131
					'http://schema.org/email'
1132
				),
1133
			),
1134
			'templates'     => array(
1135
				'subtitle' => '{{id}}',
1136
			),
1137
		);
1138
1139
		// Merge the custom fields with those provided by the thing schema.
1140
		$parent_schema           = $this->get_thing_schema();
1141
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1142
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1143
1144
		return $schema;
1145
1146
	}
1147
1148
	/**
1149
	 * Get the 'place' schema.
1150
	 *
1151
	 * @return array An array with the schema configuration.
1152
	 *
1153
	 * @since 3.1.0
1154
	 */
1155
	private function get_place_schema() {
1156
1157
		$schema = array(
1158
			'label'         => 'Place',
1159
			'description'   => 'A place.',
1160
			'parents'       => array( 'thing' ),
1161
			'css_class'     => 'wl-place',
1162
			'uri'           => 'http://schema.org/Place',
1163
			'same_as'       => array(
1164
				'http://rdf.freebase.com/ns/location.location',
1165
				'http://www.opengis.net/gml/_Feature',
1166
			),
1167
			'custom_fields' => array(
1168
				self::FIELD_GEO_LATITUDE        => array(
1169
					'predicate'   => 'http://schema.org/latitude',
1170
					'type'        => self::DATA_TYPE_DOUBLE,
1171
					'export_type' => 'xsd:double',
1172
					'constraints' => '',
1173
					// To build custom metabox.
1174
					'input_field' => 'coordinates',
1175
				),
1176
				self::FIELD_GEO_LONGITUDE       => array(
1177
					'predicate'   => 'http://schema.org/longitude',
1178
					'type'        => self::DATA_TYPE_DOUBLE,
1179
					'export_type' => 'xsd:double',
1180
					'constraints' => '',
1181
					// To build custom metabox.
1182
					'input_field' => 'coordinates',
1183
				),
1184
				self::FIELD_ADDRESS             => array(
1185
					'predicate'   => 'http://schema.org/streetAddress',
1186
					'type'        => self::DATA_TYPE_STRING,
1187
					'export_type' => 'xsd:string',
1188
					'constraints' => '',
1189
					// To build custom metabox.
1190
					'input_field' => 'address',
1191
				),
1192
				self::FIELD_ADDRESS_PO_BOX      => array(
1193
					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
1194
					'type'        => self::DATA_TYPE_STRING,
1195
					'export_type' => 'xsd:string',
1196
					'constraints' => '',
1197
					// To build custom metabox.
1198
					'input_field' => 'address',
1199
				),
1200
				self::FIELD_ADDRESS_POSTAL_CODE => array(
1201
					'predicate'   => 'http://schema.org/postalCode',
1202
					'type'        => self::DATA_TYPE_STRING,
1203
					'export_type' => 'xsd:string',
1204
					'constraints' => '',
1205
					// To build custom metabox.
1206
					'input_field' => 'address',
1207
				),
1208
				self::FIELD_ADDRESS_LOCALITY    => array(
1209
					'predicate'   => 'http://schema.org/addressLocality',
1210
					'type'        => self::DATA_TYPE_STRING,
1211
					'export_type' => 'xsd:string',
1212
					'constraints' => '',
1213
					// To build custom metabox.
1214
					'input_field' => 'address',
1215
				),
1216
				self::FIELD_ADDRESS_REGION      => array(
1217
					'predicate'   => 'http://schema.org/addressRegion',
1218
					'type'        => self::DATA_TYPE_STRING,
1219
					'export_type' => 'xsd:string',
1220
					'constraints' => '',
1221
					// To build custom metabox.
1222
					'input_field' => 'address',
1223
				),
1224
				self::FIELD_ADDRESS_COUNTRY     => array(
1225
					'predicate'   => 'http://schema.org/addressCountry',
1226
					'type'        => self::DATA_TYPE_STRING,
1227
					'export_type' => 'xsd:string',
1228
					'constraints' => '',
1229
					// To build custom metabox.
1230
					'input_field' => 'address',
1231
				),
1232
			),
1233
			'linked_data'   => array(
1234
				$this->rendition_factory->create_address(
1235
					$this->storage_factory,
0 ignored issues
show
Documentation introduced by
$this->storage_factory is of type object<Wordlift_Storage_Factory>, but the function expects a object<Wordlift_Storage>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1236
					$this->language_code
1237
				),
1238
			),
1239
			'templates'     => array(
1240
				'subtitle' => '{{id}}',
1241
			),
1242
		);
1243
1244
		// Merge the custom fields with those provided by the thing schema.
1245
		$parent_schema           = $this->get_thing_schema();
1246
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1247
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1248
1249
		return $schema;
1250
	}
1251
1252
	/**
1253
	 * Get the 'local business' schema.
1254
	 *
1255
	 * @return array An array with the schema configuration.
1256
	 *
1257
	 * @since 3.1.0
1258
	 */
1259
	private function get_local_business_schema() {
1260
1261
		$schema = array(
1262
			'label'         => 'LocalBusiness',
1263
			'description'   => 'A local business.',
1264
			'parents'       => array( 'place', 'organization' ),
1265
			'css_class'     => 'wl-local-business',
1266
			'uri'           => 'http://schema.org/LocalBusiness',
1267
			'same_as'       => array(
1268
				'http://rdf.freebase.com/ns/business/business_location',
1269
				'https://schema.org/Store',
1270
			),
1271
			'custom_fields' => array(),
1272
			'linked_data'   => array(),
1273
			'templates'     => array(
1274
				'subtitle' => '{{id}}',
1275
			),
1276
		);
1277
1278
		// Merge the custom fields with those provided by the place and organization schema.
1279
		$place_schema            = $this->get_place_schema();
1280
		$organization_schema     = $this->get_organization_schema();
1281
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
1282
		$schema['linked_data']   = array_merge( $schema['linked_data'], $place_schema['linked_data'], $organization_schema['linked_data'] );
1283
1284
		return $schema;
1285
	}
1286
1287
	/**
1288
	 * Get the 'recipe' schema.
1289
	 *
1290
	 * @return array An array with the schema configuration.
1291
	 *
1292
	 * @since 3.14.0
1293
	 */
1294
	private function get_recipe_schema() {
1295
1296
		$schema = array(
1297
			'label'         => 'Recipe',
1298
			'description'   => 'A Recipe.',
1299
			'parents'       => array( 'CreativeWork' ),
1300
			'css_class'     => 'wl-recipe',
1301
			'uri'           => 'http://schema.org/Recipe',
1302
			'same_as'       => array(),
1303
			'templates'     => array(
1304
				'subtitle' => '{{id}}',
1305
			),
1306
			'custom_fields' => array(
1307
				self::FIELD_RECIPE_CUISINE          => array(
1308
					'predicate'   => 'http://schema.org/recipeCuisine',
1309
					'type'        => self::DATA_TYPE_STRING,
1310
					'export_type' => 'xsd:string',
1311
					'constraints' => '',
1312
					'metabox'     => array(
1313
						'label' => __( 'Recipe cuisine', 'wordlift' ),
1314
					),
1315
				),
1316
				self::FIELD_RECIPE_INGREDIENT       => array(
1317
					'predicate'   => 'http://schema.org/recipeIngredient',
1318
					'type'        => self::DATA_TYPE_STRING,
1319
					'export_type' => 'xsd:string',
1320
					'constraints' => array(
1321
						'cardinality' => INF,
1322
					),
1323
					'metabox'     => array(
1324
						'label' => __( 'Recipe ingredient', 'wordlift' ),
1325
					),
1326
				),
1327
				self::FIELD_RECIPE_INSTRUCTIONS     => array(
1328
					'predicate'   => 'http://schema.org/recipeInstructions',
1329
					'type'        => self::DATA_TYPE_MULTILINE,
1330
					'export_type' => 'xsd:string',
1331
					'constraints' => '',
1332
					'metabox'     => array(
1333
						'class' => 'Wordlift_Metabox_Field_Multiline',
1334
						'label' => __( 'Recipe instructions', 'wordlift' ),
1335
					),
1336
				),
1337
				self::FIELD_RECIPE_YIELD            => array(
1338
					'predicate'   => 'http://schema.org/recipeYield',
1339
					'type'        => self::DATA_TYPE_STRING,
1340
					'export_type' => 'xsd:string',
1341
					'constraints' => '',
1342
					'metabox'     => array(
1343
						'label' => __( 'Recipe number of servings', 'wordlift' ),
1344
					),
1345
				),
1346
				self::FIELD_RECIPE_INGREDIENT       => array(
1347
					'predicate'   => 'http://schema.org/recipeIngredient',
1348
					'type'        => self::DATA_TYPE_STRING,
1349
					'export_type' => 'xsd:string',
1350
					'constraints' => array(
1351
						'cardinality' => INF,
1352
					),
1353
					'metabox'     => array(
1354
						'label' => __( 'Recipe ingredient', 'wordlift' ),
1355
					),
1356
				),
1357
				self::FIELD_NUTRITION_INFO_CALORIES => array(
1358
					'predicate'   => 'http://schema.org/calories',
1359
					'type'        => self::DATA_TYPE_STRING,
1360
					'export_type' => 'xsd:string',
1361
					'constraints' => '',
1362
					'metabox'     => array(
1363
						'label' => __( 'Calories (e.g. 240 calories)', 'wordlift' ),
1364
					),
1365
				),
1366
				self::FIELD_PREP_TIME               => array(
1367
					'predicate'   => 'http://schema.org/prepTime',
1368
					'type'        => self::DATA_TYPE_DURATION,
1369
					'export_type' => 'xsd:time',
1370
					'constraints' => '',
1371
					'metabox'     => array(
1372
						'class' => 'Wordlift_Metabox_Field_Duration',
1373
						'label' => __( 'Recipe preparation time (e.g. 1:30)', 'wordlift' ),
1374
					),
1375
				),
1376
				self::FIELD_COOK_TIME               => array(
1377
					'predicate'   => 'http://schema.org/cookTime',
1378
					'type'        => self::DATA_TYPE_DURATION,
1379
					'export_type' => 'xsd:time',
1380
					'constraints' => '',
1381
					'metabox'     => array(
1382
						'class' => 'Wordlift_Metabox_Field_Duration',
1383
						'label' => __( 'Recipe cook time (e.g. 1:30)', 'wordlift' ),
1384
					),
1385
				),
1386
				self::FIELD_TOTAL_TIME              => array(
1387
					'predicate'   => 'http://schema.org/totalTime',
1388
					'type'        => self::DATA_TYPE_DURATION,
1389
					'export_type' => 'xsd:time',
1390
					'constraints' => '',
1391
					'metabox'     => array(
1392
						'class' => 'Wordlift_Metabox_Field_Duration',
1393
						'label' => __( 'Recipe total time (e.g. 1:30)', 'wordlift' ),
1394
					),
1395
				),
1396
			),
1397
			'linked_data'   => array(
1398
				// ### schema:recipeCuisine.
1399
				$this->rendition_factory->create(
1400
					$this->storage_factory->post_meta( self::FIELD_RECIPE_CUISINE ),
1401
					'http://schema.org/recipeCuisine'
1402
				),
1403
				// ### schema:recipeIngredient.
1404
				$this->rendition_factory->create(
1405
					$this->storage_factory->post_meta( self::FIELD_RECIPE_INGREDIENT ),
1406
					'http://schema.org/recipeIngredient'
1407
				),
1408
				// ### schema:prepTime.
1409
				$this->rendition_factory->create(
1410
					$this->storage_factory->post_meta( self::FIELD_PREP_TIME ),
1411
					'http://schema.org/prepTime',
1412
					self::DATA_TYPE_DURATION
1413
				),
1414
				// ### schema:cookTime.
1415
				$this->rendition_factory->create(
1416
					$this->storage_factory->post_meta( self::FIELD_COOK_TIME ),
1417
					'http://schema.org/cookTime',
1418
					self::DATA_TYPE_DURATION
1419
				),
1420
				// ### schema:totalTime.
1421
				$this->rendition_factory->create(
1422
					$this->storage_factory->post_meta( self::FIELD_TOTAL_TIME ),
1423
					'http://schema.org/totalTime',
1424
					self::DATA_TYPE_DURATION
1425
				),
1426
			),
1427
		);
1428
1429
		// Merge the custom fields with those provided by the parent schema.
1430
		$parent_schema           = $this->get_creative_work_schema();
1431
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1432
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1433
1434
		return $schema;
1435
	}
1436
1437
	/**
1438
	 * Get the 'offer' schema.
1439
	 *
1440
	 * @return array An array with the schema configuration.
1441
	 *
1442
	 * @since 3.18.0
1443
	 */
1444
	private function get_offer_schema() {
1445
1446
		$schema = array(
1447
			'label'         => 'Offer',
1448
			'description'   => 'An offer. ',
1449
			'parents'       => array( 'thing' ),
1450
			'css_class'     => 'wl-offer',
1451
			'uri'           => self::SCHEMA_OFFER_TYPE,
1452
			'same_as'       => array(),
1453
			'templates'     => array(
1454
				'subtitle' => '{{id}}',
1455
			),
1456
			'custom_fields' => array(
1457
				self::FIELD_AVAILABILITY        => array(
1458
					'predicate'   => 'http://schema.org/availability',
1459
					'type'        => self::DATA_TYPE_STRING,
1460
					'export_type' => 'xsd:string',
1461
					'metabox'     => array(
1462
						'class' => 'Wordlift_Metabox_Field_Select',
1463
					),
1464
					'options'     => array(
1465
						'Discontinued'        => esc_html__( 'Discontinued', 'wordlift' ),
1466
						'InStock'             => esc_html__( 'In Stock', 'wordlift' ),
1467
						'InStoreOnly'         => esc_html__( 'In Store Only', 'wordlift' ),
1468
						'LimitedAvailability' => esc_html__( 'Limited Availability', 'wordlift' ),
1469
						'OnlineOnly'          => esc_html__( 'Online Only', 'wordlift' ),
1470
						'OutOfStock'          => esc_html__( 'Out of Stock', 'wordlift' ),
1471
						'PreOrder'            => esc_html__( 'Pre Order', 'wordlift' ),
1472
						'PreSale'             => esc_html__( 'Pre Sale', 'wordlift' ),
1473
						'SoldOut'             => esc_html__( 'Sold Out', 'wordlift' ),
1474
					),
1475
				),
1476
				self::FIELD_PRICE               => array(
1477
					'predicate'   => 'http://schema.org/price',
1478
					'type'        => self::DATA_TYPE_STRING,
1479
					'export_type' => 'xsd:integer',
1480
					'metabox'     => array(
1481
						'class' => 'Wordlift_Metabox_Field_Integer',
1482
					),
1483
				),
1484
				self::FIELD_PRICE_CURRENCY      => array(
1485
					'predicate'   => 'http://schema.org/priceCurrency',
1486
					'type'        => self::DATA_TYPE_STRING,
1487
					'export_type' => 'xsd:string',
1488
				),
1489
				self::FIELD_AVAILABILITY_STARTS => array(
1490
					'predicate'   => 'http://schema.org/availabilityStarts',
1491
					'type'        => self::DATA_TYPE_DATE,
1492
					'export_type' => 'xsd:dateTime',
1493
				),
1494
				self::FIELD_AVAILABILITY_ENDS   => array(
1495
					'predicate'   => 'http://schema.org/availabilityEnds',
1496
					'type'        => self::DATA_TYPE_DATE,
1497
					'export_type' => 'xsd:dateTime',
1498
				),
1499
				self::FIELD_INVENTORY_LEVEL     => array(
1500
					'predicate'   => 'http://schema.org/inventoryLevel',
1501
					'type'        => self::DATA_TYPE_STRING,
1502
					'export_type' => 'xsd:integer',
1503
					'metabox'     => array(
1504
						'class' => 'Wordlift_Metabox_Field_Integer',
1505
					),
1506
				),
1507
				self::FIELD_VALID_FROM          => array(
1508
					'predicate'   => 'http://schema.org/validFrom',
1509
					'type'        => self::DATA_TYPE_DATE,
1510
					'export_type' => 'xsd:dateTime',
1511
				),
1512
				self::FIELD_PRICE_VALID_UNTIL   => array(
1513
					'predicate'   => 'http://schema.org/priceValidUntil',
1514
					'type'        => self::DATA_TYPE_DATE,
1515
					'export_type' => 'xsd:dateTime',
1516
				),
1517
				self::FIELD_ITEM_OFFERED        => array(
1518
					'predicate'   => 'http://schema.org/itemOffered',
1519
					'type'        => self::DATA_TYPE_URI,
1520
					'export_type' => 'http://schema.org/Thing',
1521
					'constraints' => array(
1522
						'uri_type'    => array(
1523
							'Event',
1524
							'Thing',
1525
						),
1526
						'cardinality' => INF,
1527
					),
1528
				),
1529
			),
1530
			'linked_data'   => array(
1531
				// ### schema:availability.
1532
				$this->rendition_factory->create(
1533
					$this->storage_factory->post_meta( self::FIELD_AVAILABILITY ),
1534
					'http://schema.org/availability',
1535
					null
1536
				),
1537
				// ### schema:availabilityStarts.
1538
				$this->rendition_factory->create(
1539
					$this->storage_factory->post_meta( self::FIELD_AVAILABILITY_STARTS ),
1540
					'http://schema.org/availabilityStarts',
1541
					self::DATA_TYPE_DATE_TIME
1542
				),
1543
				// ### schema:availabilityEnds.
1544
				$this->rendition_factory->create(
1545
					$this->storage_factory->post_meta( self::FIELD_AVAILABILITY_ENDS ),
1546
					'http://schema.org/availabilityEnds',
1547
					self::DATA_TYPE_DATE_TIME
1548
				),
1549
				// ### schema:inventoryLevel.
1550
				$this->rendition_factory->create(
1551
					$this->storage_factory->post_meta( self::FIELD_INVENTORY_LEVEL ),
1552
					'http://schema.org/inventoryLevel',
1553
					self::DATA_TYPE_INTEGER
1554
				),
1555
				// ### schema:price.
1556
				$this->rendition_factory->create(
1557
					$this->storage_factory->post_meta( self::FIELD_PRICE ),
1558
					'http://schema.org/price',
1559
					self::DATA_TYPE_INTEGER
1560
				),
1561
				// ### schema:priceCurrency.
1562
				$this->rendition_factory->create(
1563
					$this->storage_factory->post_meta( self::FIELD_PRICE_CURRENCY ),
1564
					'http://schema.org/priceCurrency',
1565
					null
1566
				),
1567
				// ### schema:validFrom.
1568
				$this->rendition_factory->create(
1569
					$this->storage_factory->post_meta( self::FIELD_VALID_FROM ),
1570
					'http://schema.org/validFrom',
1571
					null
1572
				),
1573
				// ### schema:priceValidUntil.
1574
				$this->rendition_factory->create(
1575
					$this->storage_factory->post_meta( self::FIELD_PRICE_VALID_UNTIL ),
1576
					'http://schema.org/priceValidUntil',
1577
					null
1578
				),
1579
				// ### schema:itemOffered.
1580
				$this->rendition_factory->create(
1581
					$this->storage_factory->post_meta_to_uri( self::FIELD_ITEM_OFFERED ),
1582
					'http://schema.org/itemOffered',
1583
					self::DATA_TYPE_URI
1584
				),
1585
			),
1586
		);
1587
1588
		// Merge the custom fields with those provided by the thing schema.
1589
		$parent_schema           = $this->get_thing_schema();
1590
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1591
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1592
1593
		return $schema;
1594
	}
1595
1596
	/**
1597
	 * Get the 'article' schema.
1598
	 *
1599
	 * @return array An array with the schema configuration.
1600
	 *
1601
	 * @since 3.15.0
1602
	 */
1603
	private function get_article_schema() {
1604
1605
		$schema = array(
1606
			'label'         => 'Article',
1607
			'description'   => 'An Article.',
1608
			'parents'       => array(),
1609
			'css_class'     => 'wl-article',
1610
			'uri'           => 'http://schema.org/Article',
1611
			'same_as'       => array(),
1612
			'templates'     => array(
1613
				'subtitle' => '{{id}}',
1614
			),
1615
			'custom_fields' => array(),
1616
			'linked_data'   => array(
1617
				// ### schema:headline.
1618
				$this->rendition_factory->create(
1619
					$this->storage_factory->post_title(),
1620
					'http://schema.org/headline',
1621
					null,
1622
					$this->language_code
1623
				),
1624
				// ### schema:url.
1625
				$this->rendition_factory->create(
1626
					$this->storage_factory->url_property(),
1627
					Wordlift_Query_Builder::SCHEMA_URL_URI,
1628
					self::DATA_TYPE_URI
1629
				),
1630
				// ### rdf:type.
1631
				$this->rendition_factory->create(
1632
					$this->storage_factory->schema_class(),
1633
					Wordlift_Query_Builder::RDFS_TYPE_URI,
1634
					self::DATA_TYPE_URI
1635
				),
1636
				// ### dcterms:references.
1637
				$this->rendition_factory->create(
1638
					$this->storage_factory->relations(),
1639
					Wordlift_Query_Builder::DCTERMS_REFERENCES_URI,
1640
					self::DATA_TYPE_URI,
1641
					$this->language_code
1642
				),
1643
			),
1644
		);
1645
1646
		return $schema;
1647
	}
1648
1649
}
1650