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