Completed
Push — master ( c2ab66...fc2fb1 )
by David
03:14
created

Wordlift_Schema_Service::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 5
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
		$schemas = array(
480
			'article'       => $this->get_article_schema(),
481
			'thing'         => $this->get_thing_schema(),
482
			'creative-work' => $this->get_creative_work_schema(),
483
			'event'         => $this->get_event_schema(),
484
			'organization'  => $this->get_organization_schema(),
485
			'person'        => $this->get_person_schema(),
486
			'place'         => $this->get_place_schema(),
487
			'localbusiness' => $this->get_local_business_schema(),
488
			'recipe'        => $this->get_recipe_schema(),
489
			'web-page'      => $this->get_web_page_schema(),
490
			'offer'         => $this->get_offer_schema(),
491
		);
492
493
		// Set the taxonomy data.
494
		// Note: parent types must be defined before child types.
495
		/**
496
		 * Alter the configured schemas.
497
		 *
498
		 * Enable 3rd parties to alter WordLift's schemas array.
499
		 *
500
		 * @since  3.19.1
501
		 *
502
		 * @param    array $schemas The array of schemas.
503
		 */
504
		$this->schema = apply_filters( 'wl_schemas', $schemas );
505
506
		// Create a singleton instance of the Schema service, useful to provide static functions to global functions.
507
		self::$instance = $this;
508
509
		// Hook the `init` to allow plugins to add their schemas.
510
		add_action( 'init', array( $this, 'init' ) );
511
512
	}
513
514
	/**
515
	 * Hook to the `init`, allow late binding plugins to add their schema.
516
	 *
517
	 * @since 3.19.2
518
	 */
519
	public function init() {
520
521
		$this->schema = apply_filters( 'wl_schemas_init', $this->schema );
522
523
	}
524
525
	/**
526
	 * Get a reference to the Schema service.
527
	 *
528
	 * @since 3.1.0
529
	 *
530
	 * @return Wordlift_Schema_Service A reference to the Schema service.
531
	 */
532
	public static function get_instance() {
533
534
		return self::$instance;
535
	}
536
537
	/**
538
	 * Get the properties for a field with the specified key. The key is used as
539
	 * meta key when the field's value is stored in WordPress meta data table.
540
	 *
541
	 * @since 3.6.0
542
	 *
543
	 * @param string $key The field's key.
544
	 *
545
	 * @return null|array An array of field's properties or null if the field is not found.
546
	 */
547
	public function get_field( $key ) {
548
549
		// Parse each schema's fields until we find the one we're looking for, then
550
		// return its properties.
551
		foreach ( $this->schema as $_ => $schema ) {
552
553
			if ( ! isset( $schema['custom_fields'] ) ) {
554
				break;
555
			}
556
557
			foreach ( $schema['custom_fields'] as $field => $props ) {
558
				if ( $key === $field ) {
559
					return $props;
560
				}
561
			}
562
		}
563
564
		return null;
565
	}
566
567
	/**
568
	 * Get all renditions for each WordLift's schema.
569
	 *
570
	 * @since 3.18.0
571
	 *
572
	 * @return array An array with the schema renditions.
573
	 */
574
	public function get_renditions() {
575
		// Get the custom fields.
576
		$renditions = array_reduce(
577
			$this->schema,
578
			function ( $carry, $item ) {
579
				return array_merge( $carry, $item['linked_data'] );
580
			},
581
			array()
582
		);
583
584
		// Return the schemas.
585
		return $renditions;
586
	}
587
588
	/**
589
	 * Get the WordLift's schema.
590
	 *
591
	 * @param string $name The schema name.
592
	 *
593
	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
594
	 *
595
	 * @since 3.1.0
596
	 */
597
	public function get_schema( $name ) {
598
		// Check if the schema exists and, if not, return NULL.
599
		if ( ! isset( $this->schema[ $name ] ) ) {
600
			return null;
601
		}
602
603
		// Return the requested schema.
604
		return $this->schema[ $name ];
605
	}
606
607
	/**
608
	 * Get the WordLift's schema trough schema type uri.
609
	 *
610
	 * @param string $uri The schema uri.
611
	 *
612
	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
613
	 *
614
	 * @since 3.3.0
615
	 */
616
	public function get_schema_by_uri( $uri ) {
617
618
		foreach ( $this->schema as $name => $schema ) {
619
			if ( $schema['uri'] === $uri ) {
620
				return $schema;
621
			}
622
		}
623
624
		return null;
625
	}
626
627
	/**
628
	 * Get the 'thing' schema.
629
	 *
630
	 * @return array An array with the schema configuration.
631
	 *
632
	 * @since 3.1.0
633
	 */
634
	private function get_thing_schema() {
635
636
		return array(
637
			'css_class'     => 'wl-thing',
638
			'uri'           => 'http://schema.org/Thing',
639
			'same_as'       => array( '*' ),
640
			// set as default.
641
			'custom_fields' => array(
642
				self::FIELD_SAME_AS                            => array(
643
					'predicate'   => 'http://schema.org/sameAs',
644
					'type'        => self::DATA_TYPE_URI,
645
					'export_type' => 'http://schema.org/Thing',
646
					'constraints' => array(
647
						'cardinality' => INF,
648
					),
649
					// We need a custom metabox.
650
					'input_field' => 'sameas',
651
				),
652
				// Add the schema:url property.
653
				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...
654
				                                                                                      ->get_compat_definition(),
655
			),
656
			// {{sameAs}} not present in the microdata template,
657
			// because it is treated separately in *wl_content_embed_item_microdata*
658
			'templates'     => array(
659
				'subtitle' => '{{id}}',
660
			),
661
			'linked_data'   => array(
662
				// ### Title to rdfs:label.
663
				$this->rendition_factory->create(
664
					$this->storage_factory->post_title(),
665
					Wordlift_Query_Builder::RDFS_LABEL_URI,
666
					null,
667
					$this->language_code
668
				),
669
				// ### Title to dct:title.
670
				$this->rendition_factory->create(
671
					$this->storage_factory->post_title(),
672
					'http://purl.org/dc/terms/title',
673
					null,
674
					$this->language_code
675
				),
676
				// ### Alternative title to rdfs:label.
677
				$this->rendition_factory->create(
678
					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
679
					Wordlift_Query_Builder::RDFS_LABEL_URI,
680
					null,
681
					$this->language_code
682
				),
683
				// ### Alternative title to dct:title.
684
				$this->rendition_factory->create(
685
					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
686
					'http://purl.org/dc/terms/title',
687
					null,
688
					$this->language_code
689
				),
690
				// ### Title to schema:name.
691
				$this->rendition_factory->create(
692
					$this->storage_factory->post_title(),
693
					'http://schema.org/name',
694
					null,
695
					$this->language_code
696
				),
697
				// ### Alternative title to schema:alterName.
698
				$this->rendition_factory->create(
699
					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
700
					'http://schema.org/alternateName',
701
					null,
702
					$this->language_code
703
				),
704
				// ### schema:url.
705
				$this->rendition_factory->create(
706
					$this->storage_factory->url_property(),
707
					Wordlift_Query_Builder::SCHEMA_URL_URI,
708
					self::DATA_TYPE_URI
709
				),
710
				// ### schema:description.
711
				$this->rendition_factory->create(
712
					$this->storage_factory->post_description_no_tags_no_shortcodes(),
713
					'http://schema.org/description',
714
					null,
715
					$this->language_code
716
				),
717
				// ### owl:sameAs.
718
				$this->rendition_factory->create(
719
					$this->storage_factory->post_meta( self::FIELD_SAME_AS ),
720
					'http://www.w3.org/2002/07/owl#sameAs',
721
					self::DATA_TYPE_URI
722
				),
723
				// ### rdf:type.
724
				$this->rendition_factory->create(
725
					$this->storage_factory->schema_class(),
726
					Wordlift_Query_Builder::RDFS_TYPE_URI,
727
					self::DATA_TYPE_URI
728
				),
729
				// ### schema:image.
730
				$this->rendition_factory->create(
731
					$this->storage_factory->post_images(),
732
					Wordlift_Query_Builder::SCHEMA_IMAGE_URI,
733
					self::DATA_TYPE_URI
734
				),
735
				// ### dct:relation.
736
				$this->rendition_factory->create(
737
					$this->storage_factory->relations(),
738
					Wordlift_Query_Builder::DCTERMS_RELATION_URI,
739
					self::DATA_TYPE_URI
740
				),
741
			),
742
		);
743
744
	}
745
746
	/**
747
	 * Get the 'web-page' schema.
748
	 *
749
	 * @return array An array with the schema configuration.
750
	 *
751
	 * @since 3.18.0
752
	 */
753
	private function get_web_page_schema() {
754
755
		return array(
756
			'css_class'   => 'wl-webpage',
757
			'uri'         => 'http://schema.org/WebPage',
758
			'linked_data' => array(
759
				// ### schema:headline.
760
				$this->rendition_factory->create(
761
					$this->storage_factory->post_title(),
762
					'http://schema.org/headline',
763
					null,
764
					$this->language_code
765
				),
766
				// ### schema:url.
767
				$this->rendition_factory->create(
768
					$this->storage_factory->url_property(),
769
					Wordlift_Query_Builder::SCHEMA_URL_URI,
770
					self::DATA_TYPE_URI
771
				),
772
				// ### rdf:type.
773
				$this->rendition_factory->create(
774
					$this->storage_factory->schema_class(),
775
					Wordlift_Query_Builder::RDFS_TYPE_URI,
776
					self::DATA_TYPE_URI
777
				),
778
				// ### dcterms:references.
779
				$this->rendition_factory->create(
780
					$this->storage_factory->relations(),
781
					Wordlift_Query_Builder::DCTERMS_REFERENCES_URI,
782
					self::DATA_TYPE_URI,
783
					$this->language_code
784
				),
785
			),
786
		);
787
788
	}
789
790
	/**
791
	 * Get the 'creative work' schema.
792
	 *
793
	 * @return array An array with the schema configuration.
794
	 *
795
	 * @since 3.1.0
796
	 */
797
	private function get_creative_work_schema() {
798
799
		$schema = array(
800
			'label'         => 'CreativeWork',
801
			'description'   => 'A creative work (or a Music Album).',
802
			'parents'       => array( 'thing' ),
803
			// Give term slug as parent.
804
			'css_class'     => 'wl-creative-work',
805
			'uri'           => 'http://schema.org/CreativeWork',
806
			'same_as'       => array(
807
				'http://schema.org/MusicAlbum',
808
				'http://schema.org/Product',
809
			),
810
			'custom_fields' => array(
811
				self::FIELD_AUTHOR => array(
812
					'predicate'   => 'http://schema.org/author',
813
					'type'        => self::DATA_TYPE_URI,
814
					'export_type' => 'http://schema.org/Person',
815
					'constraints' => array(
816
						'uri_type'    => array( 'Person', 'Organization' ),
817
						'cardinality' => INF,
818
					),
819
				),
820
			),
821
			'linked_data'   => array(
822
				// ### schema:author.
823
				$this->rendition_factory->create(
824
					$this->storage_factory->author_uri(),
825
					Wordlift_Query_Builder::SCHEMA_AUTHOR_URI,
826
					self::DATA_TYPE_URI
827
				),
828
			),
829
			'templates'     => array(
830
				'subtitle' => '{{id}}',
831
			),
832
		);
833
834
		// Merge the custom fields with those provided by the thing schema.
835
		$parent_schema           = $this->get_thing_schema();
836
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
837
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
838
839
		return $schema;
840
	}
841
842
	/**
843
	 * Get the 'event' schema.
844
	 *
845
	 * @return array An array with the schema configuration.
846
	 *
847
	 * @since 3.1.0
848
	 */
849
	private function get_event_schema() {
850
851
		$schema = array(
852
			'label'         => 'Event',
853
			'description'   => 'An event . ',
854
			'parents'       => array( 'thing' ),
855
			'css_class'     => 'wl-event',
856
			'uri'           => self::SCHEMA_EVENT_TYPE,
857
			'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
858
			'custom_fields' => array(
859
				self::FIELD_DATE_START => array(
860
					'predicate'   => 'http://schema.org/startDate',
861
					'type'        => self::DATA_TYPE_DATE,
862
					'export_type' => 'xsd:dateTime',
863
					'constraints' => '',
864
				),
865
				self::FIELD_DATE_END   => array(
866
					'predicate'   => 'http://schema.org/endDate',
867
					'type'        => self::DATA_TYPE_DATE,
868
					'export_type' => 'xsd:dateTime',
869
					'constraints' => '',
870
				),
871
				self::FIELD_LOCATION   => array(
872
					'predicate'   => 'http://schema.org/location',
873
					'type'        => self::DATA_TYPE_URI,
874
					'export_type' => 'http://schema.org/PostalAddress',
875
					'constraints' => array(
876
						'uri_type'    => array( 'Place', 'LocalBusiness' ),
877
						'cardinality' => INF,
878
					),
879
				),
880
				self::FIELD_PERFORMER  => array(
881
					'predicate'   => 'http://schema.org/performer',
882
					'type'        => self::DATA_TYPE_URI,
883
					'export_type' => 'http://schema.org/Person',
884
					'constraints' => array(
885
						'uri_type'    => array( 'Person', 'Organization' ),
886
						'cardinality' => INF,
887
					),
888
				),
889
				self::FIELD_OFFERS     => array(
890
					'predicate'   => 'http://schema.org/offers',
891
					'type'        => self::DATA_TYPE_URI,
892
					'export_type' => 'http://schema.org/Offer',
893
					'constraints' => array(
894
						'uri_type'    => array( 'Offer' ),
895
						'cardinality' => INF,
896
					),
897
				),
898
			),
899
			'linked_data'   => array(
900
				// ### schema:startDate.
901
				$this->rendition_factory->create(
902
					$this->storage_factory->post_meta( self::FIELD_DATE_START ),
903
					'http://schema.org/startDate',
904
					self::DATA_TYPE_DATE_TIME
905
				),
906
				// ### schema:endDate.
907
				$this->rendition_factory->create(
908
					$this->storage_factory->post_meta( self::FIELD_DATE_END ),
909
					'http://schema.org/endDate',
910
					self::DATA_TYPE_DATE_TIME
911
				),
912
				// ### schema:location.
913
				$this->rendition_factory->create(
914
					$this->storage_factory->post_meta_to_uri( self::FIELD_LOCATION ),
915
					'http://schema.org/location',
916
					self::DATA_TYPE_URI
917
				),
918
				// ### schema:performer.
919
				$this->rendition_factory->create(
920
					$this->storage_factory->post_meta_to_uri( self::FIELD_PERFORMER ),
921
					'http://schema.org/performer',
922
					self::DATA_TYPE_URI
923
				),
924
				// ### schema:offers.
925
				$this->rendition_factory->create(
926
					$this->storage_factory->post_meta_to_uri( self::FIELD_OFFERS ),
927
					'http://schema.org/offers',
928
					self::DATA_TYPE_URI
929
				),
930
			),
931
			'templates'     => array(
932
				'subtitle' => '{{id}}',
933
			),
934
		);
935
936
		// Merge the custom fields with those provided by the thing schema.
937
		$parent_schema           = $this->get_thing_schema();
938
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
939
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
940
941
		return $schema;
942
	}
943
944
	/**
945
	 * Get the 'organization' schema.
946
	 *
947
	 * @return array An array with the schema configuration.
948
	 *
949
	 * @since 3.1.0
950
	 */
951
	private function get_organization_schema() {
952
953
		$schema = array(
954
			'label'         => 'Organization',
955
			'description'   => 'An organization, including a government or a newspaper.',
956
			'parents'       => array( 'thing' ),
957
			'css_class'     => 'wl-organization',
958
			'uri'           => 'http://schema.org/Organization',
959
			'same_as'       => array(
960
				'http://rdf.freebase.com/ns/organization.organization',
961
				'http://rdf.freebase.com/ns/government.government',
962
				'http://schema.org/Newspaper',
963
			),
964
			'custom_fields' => array(
965
				self::FIELD_LEGAL_NAME          => array(
966
					'predicate'   => 'http://schema.org/legalName',
967
					'type'        => self::DATA_TYPE_STRING,
968
					'export_type' => 'xsd:string',
969
					'constraints' => '',
970
				),
971
				self::FIELD_FOUNDER             => array(
972
					'predicate'   => 'http://schema.org/founder',
973
					'type'        => self::DATA_TYPE_URI,
974
					'export_type' => 'http://schema.org/Person',
975
					'constraints' => array(
976
						'uri_type'    => 'Person',
977
						'cardinality' => INF,
978
					),
979
				),
980
				self::FIELD_ADDRESS             => array(
981
					'predicate'   => 'http://schema.org/streetAddress',
982
					'type'        => self::DATA_TYPE_STRING,
983
					'export_type' => 'xsd:string',
984
					'constraints' => '',
985
					// To build custom metabox.
986
					'input_field' => 'address',
987
				),
988
				self::FIELD_ADDRESS_PO_BOX      => array(
989
					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
990
					'type'        => self::DATA_TYPE_STRING,
991
					'export_type' => 'xsd:string',
992
					'constraints' => '',
993
					// To build custom metabox.
994
					'input_field' => 'address',
995
				),
996
				self::FIELD_ADDRESS_POSTAL_CODE => array(
997
					'predicate'   => 'http://schema.org/postalCode',
998
					'type'        => self::DATA_TYPE_STRING,
999
					'export_type' => 'xsd:string',
1000
					'constraints' => '',
1001
					// To build custom metabox.
1002
					'input_field' => 'address',
1003
				),
1004
				self::FIELD_ADDRESS_LOCALITY    => array(
1005
					'predicate'   => 'http://schema.org/addressLocality',
1006
					'type'        => self::DATA_TYPE_STRING,
1007
					'export_type' => 'xsd:string',
1008
					'constraints' => '',
1009
					// To build custom metabox.
1010
					'input_field' => 'address',
1011
				),
1012
				self::FIELD_ADDRESS_REGION      => array(
1013
					'predicate'   => 'http://schema.org/addressRegion',
1014
					'type'        => self::DATA_TYPE_STRING,
1015
					'export_type' => 'xsd:string',
1016
					'constraints' => '',
1017
					// To build custom metabox.
1018
					'input_field' => 'address',
1019
				),
1020
				self::FIELD_ADDRESS_COUNTRY     => array(
1021
					'predicate'   => 'http://schema.org/addressCountry',
1022
					'type'        => self::DATA_TYPE_STRING,
1023
					'export_type' => 'xsd:string',
1024
					'constraints' => '',
1025
					// To build custom metabox.
1026
					'input_field' => 'address',
1027
				),
1028
				self::FIELD_EMAIL               => array(
1029
					'predicate'   => 'http://schema.org/email',
1030
					'type'        => self::DATA_TYPE_STRING,
1031
					'export_type' => 'xsd:string',
1032
					'constraints' => '',
1033
				),
1034
				self::FIELD_TELEPHONE           => array(
1035
					'predicate'   => 'http://schema.org/telephone',
1036
					'type'        => self::DATA_TYPE_STRING,
1037
					'export_type' => 'xsd:string',
1038
					'constraints' => '',
1039
				),
1040
			),
1041
			'linked_data'   => array(
1042
				// ### schema:legalName.
1043
				$this->rendition_factory->create(
1044
					$this->storage_factory->post_meta( self::FIELD_LEGAL_NAME ),
1045
					'http://schema.org/legalName'
1046
				),
1047
				// ### schema:founder.
1048
				$this->rendition_factory->create(
1049
					$this->storage_factory->post_meta_to_uri( self::FIELD_FOUNDER ),
1050
					'http://schema.org/founder',
1051
					self::DATA_TYPE_URI
1052
				),
1053
				// ### schema:email.
1054
				$this->rendition_factory->create(
1055
					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
1056
					'http://schema.org/email'
1057
				),
1058
				// ### schema:telephone.
1059
				$this->rendition_factory->create(
1060
					$this->storage_factory->post_meta( self::FIELD_TELEPHONE ),
1061
					'http://schema.org/telephone'
1062
				),
1063
			),
1064
			'templates'     => array(
1065
				'subtitle' => '{{id}}',
1066
			),
1067
		);
1068
1069
		// Merge the custom fields with those provided by the thing schema.
1070
		$parent_schema           = $this->get_thing_schema();
1071
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1072
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1073
1074
		return $schema;
1075
	}
1076
1077
	/**
1078
	 * Get the 'person' schema.
1079
	 *
1080
	 * @return array An array with the schema configuration.
1081
	 *
1082
	 * @since 3.1.0
1083
	 */
1084
	private function get_person_schema() {
1085
1086
		$schema = array(
1087
			'label'         => 'Person',
1088
			'description'   => 'A person (or a music artist).',
1089
			'parents'       => array( 'thing' ),
1090
			'css_class'     => 'wl-person',
1091
			'uri'           => 'http://schema.org/Person',
1092
			'same_as'       => array(
1093
				'http://rdf.freebase.com/ns/people.person',
1094
				'http://rdf.freebase.com/ns/music.artist',
1095
				'http://dbpedia.org/class/yago/LivingPeople',
1096
			),
1097
			'custom_fields' => array(
1098
				self::FIELD_KNOWS       => array(
1099
					'predicate'   => 'http://schema.org/knows',
1100
					'type'        => self::DATA_TYPE_URI,
1101
					'export_type' => 'http://schema.org/Person',
1102
					'constraints' => array(
1103
						'uri_type'    => 'Person',
1104
						'cardinality' => INF,
1105
					),
1106
				),
1107
				self::FIELD_BIRTH_DATE  => array(
1108
					'predicate'   => 'http://schema.org/birthDate',
1109
					'type'        => self::DATA_TYPE_DATE,
1110
					'export_type' => 'xsd:date',
1111
					'constraints' => '',
1112
				),
1113
				self::FIELD_BIRTH_PLACE => array(
1114
					'predicate'   => 'http://schema.org/birthPlace',
1115
					'type'        => self::DATA_TYPE_URI,
1116
					'export_type' => 'http://schema.org/Place',
1117
					'constraints' => array(
1118
						'uri_type' => 'Place',
1119
					),
1120
				),
1121
				self::FIELD_AFFILIATION => array(
1122
					'predicate'   => 'http://schema.org/affiliation',
1123
					'type'        => self::DATA_TYPE_URI,
1124
					'export_type' => 'http://schema.org/Organization',
1125
					'constraints' => array(
1126
						'uri_type'    => array(
1127
							'Organization',
1128
							'LocalBusiness',
1129
						),
1130
						'cardinality' => INF,
1131
					),
1132
				),
1133
				self::FIELD_EMAIL       => array(
1134
					'predicate'   => 'http://schema.org/email',
1135
					'type'        => self::DATA_TYPE_STRING,
1136
					'export_type' => 'xsd:string',
1137
					'constraints' => array(
1138
						'cardinality' => INF,
1139
					),
1140
				),
1141
			),
1142
			'linked_data'   => array(
1143
				// ### schema:knows.
1144
				$this->rendition_factory->create(
1145
					$this->storage_factory->post_meta_to_uri( self::FIELD_KNOWS ),
1146
					'http://schema.org/knows',
1147
					self::DATA_TYPE_URI
1148
				),
1149
				// ### schema:birthDate.
1150
				$this->rendition_factory->create(
1151
					$this->storage_factory->post_meta( self::FIELD_BIRTH_DATE ),
1152
					'http://schema.org/birthDate',
1153
					self::DATA_TYPE_DATE
1154
				),
1155
				// ### schema:birthPlace.
1156
				$this->rendition_factory->create(
1157
					$this->storage_factory->post_meta_to_uri( self::FIELD_BIRTH_PLACE ),
1158
					'http://schema.org/birthPlace',
1159
					self::DATA_TYPE_URI
1160
				),
1161
				// ### schema:affiliation.
1162
				$this->rendition_factory->create(
1163
					$this->storage_factory->post_meta_to_uri( self::FIELD_AFFILIATION ),
1164
					'http://schema.org/affiliation',
1165
					self::DATA_TYPE_URI
1166
				),
1167
				// ### schema:email.
1168
				$this->rendition_factory->create(
1169
					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
1170
					'http://schema.org/email'
1171
				),
1172
			),
1173
			'templates'     => array(
1174
				'subtitle' => '{{id}}',
1175
			),
1176
		);
1177
1178
		// Merge the custom fields with those provided by the thing schema.
1179
		$parent_schema           = $this->get_thing_schema();
1180
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1181
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1182
1183
		return $schema;
1184
1185
	}
1186
1187
	/**
1188
	 * Get the 'place' schema.
1189
	 *
1190
	 * @return array An array with the schema configuration.
1191
	 *
1192
	 * @since 3.1.0
1193
	 */
1194
	private function get_place_schema() {
1195
1196
		$schema = array(
1197
			'label'         => 'Place',
1198
			'description'   => 'A place.',
1199
			'parents'       => array( 'thing' ),
1200
			'css_class'     => 'wl-place',
1201
			'uri'           => 'http://schema.org/Place',
1202
			'same_as'       => array(
1203
				'http://rdf.freebase.com/ns/location.location',
1204
				'http://www.opengis.net/gml/_Feature',
1205
			),
1206
			'custom_fields' => array(
1207
				self::FIELD_GEO_LATITUDE        => array(
1208
					'predicate'   => 'http://schema.org/latitude',
1209
					'type'        => self::DATA_TYPE_DOUBLE,
1210
					'export_type' => 'xsd:double',
1211
					'constraints' => '',
1212
					// To build custom metabox.
1213
					'input_field' => 'coordinates',
1214
				),
1215
				self::FIELD_GEO_LONGITUDE       => array(
1216
					'predicate'   => 'http://schema.org/longitude',
1217
					'type'        => self::DATA_TYPE_DOUBLE,
1218
					'export_type' => 'xsd:double',
1219
					'constraints' => '',
1220
					// To build custom metabox.
1221
					'input_field' => 'coordinates',
1222
				),
1223
				self::FIELD_ADDRESS             => array(
1224
					'predicate'   => 'http://schema.org/streetAddress',
1225
					'type'        => self::DATA_TYPE_STRING,
1226
					'export_type' => 'xsd:string',
1227
					'constraints' => '',
1228
					// To build custom metabox.
1229
					'input_field' => 'address',
1230
				),
1231
				self::FIELD_ADDRESS_PO_BOX      => array(
1232
					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
1233
					'type'        => self::DATA_TYPE_STRING,
1234
					'export_type' => 'xsd:string',
1235
					'constraints' => '',
1236
					// To build custom metabox.
1237
					'input_field' => 'address',
1238
				),
1239
				self::FIELD_ADDRESS_POSTAL_CODE => array(
1240
					'predicate'   => 'http://schema.org/postalCode',
1241
					'type'        => self::DATA_TYPE_STRING,
1242
					'export_type' => 'xsd:string',
1243
					'constraints' => '',
1244
					// To build custom metabox.
1245
					'input_field' => 'address',
1246
				),
1247
				self::FIELD_ADDRESS_LOCALITY    => array(
1248
					'predicate'   => 'http://schema.org/addressLocality',
1249
					'type'        => self::DATA_TYPE_STRING,
1250
					'export_type' => 'xsd:string',
1251
					'constraints' => '',
1252
					// To build custom metabox.
1253
					'input_field' => 'address',
1254
				),
1255
				self::FIELD_ADDRESS_REGION      => array(
1256
					'predicate'   => 'http://schema.org/addressRegion',
1257
					'type'        => self::DATA_TYPE_STRING,
1258
					'export_type' => 'xsd:string',
1259
					'constraints' => '',
1260
					// To build custom metabox.
1261
					'input_field' => 'address',
1262
				),
1263
				self::FIELD_ADDRESS_COUNTRY     => array(
1264
					'predicate'   => 'http://schema.org/addressCountry',
1265
					'type'        => self::DATA_TYPE_STRING,
1266
					'export_type' => 'xsd:string',
1267
					'constraints' => '',
1268
					// To build custom metabox.
1269
					'input_field' => 'address',
1270
				),
1271
			),
1272
			'linked_data'   => array(
1273
				$this->rendition_factory->create_address(
1274
					$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...
1275
					$this->language_code
1276
				),
1277
			),
1278
			'templates'     => array(
1279
				'subtitle' => '{{id}}',
1280
			),
1281
		);
1282
1283
		// Merge the custom fields with those provided by the thing schema.
1284
		$parent_schema           = $this->get_thing_schema();
1285
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1286
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1287
1288
		return $schema;
1289
	}
1290
1291
	/**
1292
	 * Get the 'local business' schema.
1293
	 *
1294
	 * @return array An array with the schema configuration.
1295
	 *
1296
	 * @since 3.1.0
1297
	 */
1298
	private function get_local_business_schema() {
1299
1300
		$schema = array(
1301
			'label'         => 'LocalBusiness',
1302
			'description'   => 'A local business.',
1303
			'parents'       => array( 'place', 'organization' ),
1304
			'css_class'     => 'wl-local-business',
1305
			'uri'           => 'http://schema.org/LocalBusiness',
1306
			'same_as'       => array(
1307
				'http://rdf.freebase.com/ns/business/business_location',
1308
				'https://schema.org/Store',
1309
			),
1310
			'custom_fields' => array(),
1311
			'linked_data'   => array(),
1312
			'templates'     => array(
1313
				'subtitle' => '{{id}}',
1314
			),
1315
		);
1316
1317
		// Merge the custom fields with those provided by the place and organization schema.
1318
		$place_schema            = $this->get_place_schema();
1319
		$organization_schema     = $this->get_organization_schema();
1320
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
1321
		$schema['linked_data']   = array_merge( $schema['linked_data'], $place_schema['linked_data'], $organization_schema['linked_data'] );
1322
1323
		return $schema;
1324
	}
1325
1326
	/**
1327
	 * Get the 'recipe' schema.
1328
	 *
1329
	 * @return array An array with the schema configuration.
1330
	 *
1331
	 * @since 3.14.0
1332
	 */
1333
	private function get_recipe_schema() {
1334
1335
		$schema = array(
1336
			'label'         => 'Recipe',
1337
			'description'   => 'A Recipe.',
1338
			'parents'       => array( 'CreativeWork' ),
1339
			'css_class'     => 'wl-recipe',
1340
			'uri'           => 'http://schema.org/Recipe',
1341
			'same_as'       => array(),
1342
			'templates'     => array(
1343
				'subtitle' => '{{id}}',
1344
			),
1345
			'custom_fields' => array(
1346
				self::FIELD_RECIPE_CUISINE          => array(
1347
					'predicate'   => 'http://schema.org/recipeCuisine',
1348
					'type'        => self::DATA_TYPE_STRING,
1349
					'export_type' => 'xsd:string',
1350
					'constraints' => '',
1351
					'metabox'     => array(
1352
						'label' => __( 'Recipe cuisine', 'wordlift' ),
1353
					),
1354
				),
1355
				self::FIELD_RECIPE_INGREDIENT       => array(
1356
					'predicate'   => 'http://schema.org/recipeIngredient',
1357
					'type'        => self::DATA_TYPE_STRING,
1358
					'export_type' => 'xsd:string',
1359
					'constraints' => array(
1360
						'cardinality' => INF,
1361
					),
1362
					'metabox'     => array(
1363
						'label' => __( 'Recipe ingredient', 'wordlift' ),
1364
					),
1365
				),
1366
				self::FIELD_RECIPE_INSTRUCTIONS     => array(
1367
					'predicate'   => 'http://schema.org/recipeInstructions',
1368
					'type'        => self::DATA_TYPE_MULTILINE,
1369
					'export_type' => 'xsd:string',
1370
					'constraints' => '',
1371
					'metabox'     => array(
1372
						'class' => 'Wordlift_Metabox_Field_Multiline',
1373
						'label' => __( 'Recipe instructions', 'wordlift' ),
1374
					),
1375
				),
1376
				self::FIELD_RECIPE_YIELD            => array(
1377
					'predicate'   => 'http://schema.org/recipeYield',
1378
					'type'        => self::DATA_TYPE_STRING,
1379
					'export_type' => 'xsd:string',
1380
					'constraints' => '',
1381
					'metabox'     => array(
1382
						'label' => __( 'Recipe number of servings', 'wordlift' ),
1383
					),
1384
				),
1385
				self::FIELD_RECIPE_INGREDIENT       => array(
1386
					'predicate'   => 'http://schema.org/recipeIngredient',
1387
					'type'        => self::DATA_TYPE_STRING,
1388
					'export_type' => 'xsd:string',
1389
					'constraints' => array(
1390
						'cardinality' => INF,
1391
					),
1392
					'metabox'     => array(
1393
						'label' => __( 'Recipe ingredient', 'wordlift' ),
1394
					),
1395
				),
1396
				self::FIELD_NUTRITION_INFO_CALORIES => array(
1397
					'predicate'   => 'http://schema.org/calories',
1398
					'type'        => self::DATA_TYPE_STRING,
1399
					'export_type' => 'xsd:string',
1400
					'constraints' => '',
1401
					'metabox'     => array(
1402
						'label' => __( 'Calories (e.g. 240 calories)', 'wordlift' ),
1403
					),
1404
				),
1405
				self::FIELD_PREP_TIME               => array(
1406
					'predicate'   => 'http://schema.org/prepTime',
1407
					'type'        => self::DATA_TYPE_DURATION,
1408
					'export_type' => 'xsd:time',
1409
					'constraints' => '',
1410
					'metabox'     => array(
1411
						'class' => 'Wordlift_Metabox_Field_Duration',
1412
						'label' => __( 'Recipe preparation time (e.g. 1:30)', 'wordlift' ),
1413
					),
1414
				),
1415
				self::FIELD_COOK_TIME               => array(
1416
					'predicate'   => 'http://schema.org/cookTime',
1417
					'type'        => self::DATA_TYPE_DURATION,
1418
					'export_type' => 'xsd:time',
1419
					'constraints' => '',
1420
					'metabox'     => array(
1421
						'class' => 'Wordlift_Metabox_Field_Duration',
1422
						'label' => __( 'Recipe cook time (e.g. 1:30)', 'wordlift' ),
1423
					),
1424
				),
1425
				self::FIELD_TOTAL_TIME              => array(
1426
					'predicate'   => 'http://schema.org/totalTime',
1427
					'type'        => self::DATA_TYPE_DURATION,
1428
					'export_type' => 'xsd:time',
1429
					'constraints' => '',
1430
					'metabox'     => array(
1431
						'class' => 'Wordlift_Metabox_Field_Duration',
1432
						'label' => __( 'Recipe total time (e.g. 1:30)', 'wordlift' ),
1433
					),
1434
				),
1435
			),
1436
			'linked_data'   => array(
1437
				// ### schema:recipeCuisine.
1438
				$this->rendition_factory->create(
1439
					$this->storage_factory->post_meta( self::FIELD_RECIPE_CUISINE ),
1440
					'http://schema.org/recipeCuisine'
1441
				),
1442
				// ### schema:recipeIngredient.
1443
				$this->rendition_factory->create(
1444
					$this->storage_factory->post_meta( self::FIELD_RECIPE_INGREDIENT ),
1445
					'http://schema.org/recipeIngredient'
1446
				),
1447
				// ### schema:recipeInstructions.
1448
				$this->rendition_factory->create(
1449
					$this->storage_factory->post_meta( self::FIELD_RECIPE_INSTRUCTIONS ),
1450
					'http://schema.org/recipeInstructions'
1451
				),
1452
				// ### schema:recipeYield.
1453
				$this->rendition_factory->create(
1454
					$this->storage_factory->post_meta( self::FIELD_RECIPE_YIELD ),
1455
					'http://schema.org/recipeYield'
1456
				),
1457
				// ### schema:prepTime.
1458
				$this->rendition_factory->create(
1459
					$this->storage_factory->post_meta( self::FIELD_PREP_TIME ),
1460
					'http://schema.org/prepTime',
1461
					self::DATA_TYPE_DURATION
1462
				),
1463
				// ### schema:cookTime.
1464
				$this->rendition_factory->create(
1465
					$this->storage_factory->post_meta( self::FIELD_COOK_TIME ),
1466
					'http://schema.org/cookTime',
1467
					self::DATA_TYPE_DURATION
1468
				),
1469
				// ### schema:totalTime.
1470
				$this->rendition_factory->create(
1471
					$this->storage_factory->post_meta( self::FIELD_TOTAL_TIME ),
1472
					'http://schema.org/totalTime',
1473
					self::DATA_TYPE_DURATION
1474
				),
1475
			),
1476
		);
1477
1478
		// Merge the custom fields with those provided by the parent schema.
1479
		$parent_schema           = $this->get_creative_work_schema();
1480
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1481
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1482
1483
		return $schema;
1484
	}
1485
1486
	/**
1487
	 * Get the 'offer' schema.
1488
	 *
1489
	 * @return array An array with the schema configuration.
1490
	 *
1491
	 * @since 3.18.0
1492
	 */
1493
	private function get_offer_schema() {
1494
1495
		$schema = array(
1496
			'label'         => 'Offer',
1497
			'description'   => 'An offer. ',
1498
			'parents'       => array( 'thing' ),
1499
			'css_class'     => 'wl-offer',
1500
			'uri'           => self::SCHEMA_OFFER_TYPE,
1501
			'same_as'       => array(),
1502
			'templates'     => array(
1503
				'subtitle' => '{{id}}',
1504
			),
1505
			'custom_fields' => array(
1506
				self::FIELD_AVAILABILITY        => array(
1507
					'predicate'   => 'http://schema.org/availability',
1508
					'type'        => self::DATA_TYPE_STRING,
1509
					'export_type' => 'xsd:string',
1510
					'metabox'     => array(
1511
						'class' => 'Wordlift_Metabox_Field_Select',
1512
					),
1513
					'options'     => array(
1514
						'Discontinued'        => esc_html__( 'Discontinued', 'wordlift' ),
1515
						'InStock'             => esc_html__( 'In Stock', 'wordlift' ),
1516
						'InStoreOnly'         => esc_html__( 'In Store Only', 'wordlift' ),
1517
						'LimitedAvailability' => esc_html__( 'Limited Availability', 'wordlift' ),
1518
						'OnlineOnly'          => esc_html__( 'Online Only', 'wordlift' ),
1519
						'OutOfStock'          => esc_html__( 'Out of Stock', 'wordlift' ),
1520
						'PreOrder'            => esc_html__( 'Pre Order', 'wordlift' ),
1521
						'PreSale'             => esc_html__( 'Pre Sale', 'wordlift' ),
1522
						'SoldOut'             => esc_html__( 'Sold Out', 'wordlift' ),
1523
					),
1524
				),
1525
				self::FIELD_PRICE               => array(
1526
					'predicate'   => 'http://schema.org/price',
1527
					'type'        => self::DATA_TYPE_STRING,
1528
					'export_type' => 'xsd:integer',
1529
					'metabox'     => array(
1530
						'class' => 'Wordlift_Metabox_Field_Integer',
1531
					),
1532
				),
1533
				self::FIELD_PRICE_CURRENCY      => array(
1534
					'predicate'   => 'http://schema.org/priceCurrency',
1535
					'type'        => self::DATA_TYPE_STRING,
1536
					'export_type' => 'xsd:string',
1537
				),
1538
				self::FIELD_AVAILABILITY_STARTS => array(
1539
					'predicate'   => 'http://schema.org/availabilityStarts',
1540
					'type'        => self::DATA_TYPE_DATE,
1541
					'export_type' => 'xsd:dateTime',
1542
				),
1543
				self::FIELD_AVAILABILITY_ENDS   => array(
1544
					'predicate'   => 'http://schema.org/availabilityEnds',
1545
					'type'        => self::DATA_TYPE_DATE,
1546
					'export_type' => 'xsd:dateTime',
1547
				),
1548
				self::FIELD_INVENTORY_LEVEL     => array(
1549
					'predicate'   => 'http://schema.org/inventoryLevel',
1550
					'type'        => self::DATA_TYPE_STRING,
1551
					'export_type' => 'xsd:integer',
1552
					'metabox'     => array(
1553
						'class' => 'Wordlift_Metabox_Field_Integer',
1554
					),
1555
				),
1556
				self::FIELD_VALID_FROM          => array(
1557
					'predicate'   => 'http://schema.org/validFrom',
1558
					'type'        => self::DATA_TYPE_DATE,
1559
					'export_type' => 'xsd:dateTime',
1560
				),
1561
				self::FIELD_PRICE_VALID_UNTIL   => array(
1562
					'predicate'   => 'http://schema.org/priceValidUntil',
1563
					'type'        => self::DATA_TYPE_DATE,
1564
					'export_type' => 'xsd:dateTime',
1565
				),
1566
				self::FIELD_ITEM_OFFERED        => array(
1567
					'predicate'   => 'http://schema.org/itemOffered',
1568
					'type'        => self::DATA_TYPE_URI,
1569
					'export_type' => 'http://schema.org/Thing',
1570
					'constraints' => array(
1571
						'uri_type'    => array(
1572
							'Event',
1573
							'Thing',
1574
						),
1575
						'cardinality' => INF,
1576
					),
1577
				),
1578
			),
1579
			'linked_data'   => array(
1580
				// ### schema:availability.
1581
				$this->rendition_factory->create(
1582
					$this->storage_factory->post_meta( self::FIELD_AVAILABILITY ),
1583
					'http://schema.org/availability',
1584
					null
1585
				),
1586
				// ### schema:availabilityStarts.
1587
				$this->rendition_factory->create(
1588
					$this->storage_factory->post_meta( self::FIELD_AVAILABILITY_STARTS ),
1589
					'http://schema.org/availabilityStarts',
1590
					self::DATA_TYPE_DATE_TIME
1591
				),
1592
				// ### schema:availabilityEnds.
1593
				$this->rendition_factory->create(
1594
					$this->storage_factory->post_meta( self::FIELD_AVAILABILITY_ENDS ),
1595
					'http://schema.org/availabilityEnds',
1596
					self::DATA_TYPE_DATE_TIME
1597
				),
1598
				// ### schema:inventoryLevel.
1599
				$this->rendition_factory->create(
1600
					$this->storage_factory->post_meta( self::FIELD_INVENTORY_LEVEL ),
1601
					'http://schema.org/inventoryLevel',
1602
					self::DATA_TYPE_INTEGER
1603
				),
1604
				// ### schema:price.
1605
				$this->rendition_factory->create(
1606
					$this->storage_factory->post_meta( self::FIELD_PRICE ),
1607
					'http://schema.org/price',
1608
					self::DATA_TYPE_INTEGER
1609
				),
1610
				// ### schema:priceCurrency.
1611
				$this->rendition_factory->create(
1612
					$this->storage_factory->post_meta( self::FIELD_PRICE_CURRENCY ),
1613
					'http://schema.org/priceCurrency',
1614
					null
1615
				),
1616
				// ### schema:validFrom.
1617
				$this->rendition_factory->create(
1618
					$this->storage_factory->post_meta( self::FIELD_VALID_FROM ),
1619
					'http://schema.org/validFrom',
1620
					null
1621
				),
1622
				// ### schema:priceValidUntil.
1623
				$this->rendition_factory->create(
1624
					$this->storage_factory->post_meta( self::FIELD_PRICE_VALID_UNTIL ),
1625
					'http://schema.org/priceValidUntil',
1626
					null
1627
				),
1628
				// ### schema:itemOffered.
1629
				$this->rendition_factory->create(
1630
					$this->storage_factory->post_meta_to_uri( self::FIELD_ITEM_OFFERED ),
1631
					'http://schema.org/itemOffered',
1632
					self::DATA_TYPE_URI
1633
				),
1634
			),
1635
		);
1636
1637
		// Merge the custom fields with those provided by the thing schema.
1638
		$parent_schema           = $this->get_thing_schema();
1639
		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1640
		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1641
1642
		return $schema;
1643
	}
1644
1645
	/**
1646
	 * Get the 'article' schema.
1647
	 *
1648
	 * @return array An array with the schema configuration.
1649
	 *
1650
	 * @since 3.15.0
1651
	 */
1652
	private function get_article_schema() {
1653
1654
		$schema = array(
1655
			'label'         => 'Article',
1656
			'description'   => 'An Article.',
1657
			'parents'       => array(),
1658
			'css_class'     => 'wl-article',
1659
			'uri'           => 'http://schema.org/Article',
1660
			'same_as'       => array(),
1661
			'templates'     => array(
1662
				'subtitle' => '{{id}}',
1663
			),
1664
			'custom_fields' => array(),
1665
			'linked_data'   => array(
1666
				// ### schema:headline.
1667
				$this->rendition_factory->create(
1668
					$this->storage_factory->post_title(),
1669
					'http://schema.org/headline',
1670
					null,
1671
					$this->language_code
1672
				),
1673
				// ### schema:url.
1674
				$this->rendition_factory->create(
1675
					$this->storage_factory->url_property(),
1676
					Wordlift_Query_Builder::SCHEMA_URL_URI,
1677
					self::DATA_TYPE_URI
1678
				),
1679
				// ### rdf:type.
1680
				$this->rendition_factory->create(
1681
					$this->storage_factory->schema_class(),
1682
					Wordlift_Query_Builder::RDFS_TYPE_URI,
1683
					self::DATA_TYPE_URI
1684
				),
1685
				// ### dcterms:references.
1686
				$this->rendition_factory->create(
1687
					$this->storage_factory->relations(),
1688
					Wordlift_Query_Builder::DCTERMS_REFERENCES_URI,
1689
					self::DATA_TYPE_URI,
1690
					$this->language_code
1691
				),
1692
			),
1693
		);
1694
1695
		return $schema;
1696
	}
1697
1698
}
1699