Completed
Push — develop ( 8562e2...0b8786 )
by David
03:10
created
src/includes/class-wordlift-schema-service.php 1 patch
Indentation   +786 added lines, -786 removed lines patch added patch discarded remove patch
@@ -15,791 +15,791 @@
 block discarded – undo
15 15
  */
16 16
 class Wordlift_Schema_Service {
17 17
 
18
-	/**
19
-	 * The 'location created' field name.
20
-	 *
21
-	 * @since 3.5.0
22
-	 */
23
-	const FIELD_LOCATION_CREATED = 'wl_location_created';
24
-
25
-	/**
26
-	 * The 'topic' field name.
27
-	 *
28
-	 * @since 3.5.0
29
-	 */
30
-	const FIELD_TOPIC = 'wl_topic';
31
-
32
-	/**
33
-	 * The 'author' field name.
34
-	 *
35
-	 * @since 3.1.0
36
-	 */
37
-	const FIELD_AUTHOR = 'wl_author';
38
-
39
-	/**
40
-	 * The 'same as' field name.
41
-	 *
42
-	 * @since 3.1.0
43
-	 */
44
-	const FIELD_SAME_AS = 'entity_same_as';
45
-
46
-	/**
47
-	 * The 'date start' field name.
48
-	 *
49
-	 * @since 3.1.0
50
-	 */
51
-	const FIELD_DATE_START = 'wl_cal_date_start';
52
-
53
-	/**
54
-	 * The 'date end' field name.
55
-	 *
56
-	 * @since 3.1.0
57
-	 */
58
-	const FIELD_DATE_END = 'wl_cal_date_end';
59
-
60
-	/**
61
-	 * The 'location' field name.
62
-	 *
63
-	 * @since 3.1.0
64
-	 */
65
-	const FIELD_LOCATION = 'wl_location';
66
-
67
-	/**
68
-	 * The 'founder' field name.
69
-	 *
70
-	 * @since 3.1.0
71
-	 */
72
-	const FIELD_FOUNDER = 'wl_founder';
73
-
74
-	/**
75
-	 * The 'knows' field name.
76
-	 *
77
-	 * @since 3.1.0
78
-	 */
79
-	const FIELD_KNOWS = 'wl_knows';
80
-
81
-	/**
82
-	 * The 'birth date' field name.
83
-	 *
84
-	 * @since 3.1.0
85
-	 */
86
-	const FIELD_BIRTH_DATE = 'wl_birth_date';
87
-
88
-	/**
89
-	 * The 'birth place' field name.
90
-	 *
91
-	 * @since 3.1.0
92
-	 */
93
-	const FIELD_BIRTH_PLACE = 'wl_birth_place';
94
-
95
-	/**
96
-	 * The 'latitude' field name.
97
-	 *
98
-	 * @since 3.1.0
99
-	 */
100
-	const FIELD_GEO_LATITUDE = 'wl_geo_latitude';
101
-
102
-	/**
103
-	 * The 'longitude' field name.
104
-	 *
105
-	 * @since 3.1.0
106
-	 */
107
-	const FIELD_GEO_LONGITUDE = 'wl_geo_longitude';
108
-
109
-	/**
110
-	 * The 'streetAddress' field name.
111
-	 *
112
-	 * @since 3.1.0
113
-	 */
114
-	const FIELD_ADDRESS = 'wl_address';
115
-
116
-	/**
117
-	 * The 'postOfficeBoxNumber' field name.
118
-	 *
119
-	 * @since 3.3.0
120
-	 */
121
-	const FIELD_ADDRESS_PO_BOX = 'wl_address_post_office_box';
122
-
123
-	/**
124
-	 * The 'postalCode' field name.
125
-	 *
126
-	 * @since 3.3.0
127
-	 */
128
-	const FIELD_ADDRESS_POSTAL_CODE = 'wl_address_postal_code';
129
-
130
-	/**
131
-	 * The 'addressLocality' field name.
132
-	 *
133
-	 * @since 3.3.0
134
-	 */
135
-	const FIELD_ADDRESS_LOCALITY = 'wl_address_locality';
136
-	/**
137
-	 * The 'addressRegion' field name.
138
-	 *
139
-	 * @since 3.3.0
140
-	 */
141
-	const FIELD_ADDRESS_REGION = 'wl_address_region';
142
-
143
-	/**
144
-	 * The 'addressCountry' field name.
145
-	 *
146
-	 * @since 3.3.0
147
-	 */
148
-	const FIELD_ADDRESS_COUNTRY = 'wl_address_country';
149
-
150
-	/**
151
-	 * The 'entity type' field name.
152
-	 *
153
-	 * @since 3.1.0
154
-	 */
155
-	const FIELD_ENTITY_TYPE = 'wl_entity_type_uri';
156
-
157
-	/**
158
-	 * The 'email' field name.
159
-	 *
160
-	 * @since 3.2.0
161
-	 */
162
-	const FIELD_EMAIL = 'wl_email';
163
-
164
-	/**
165
-	 * The 'affiliation' field name.
166
-	 *
167
-	 * @since 3.2.0
168
-	 */
169
-	const FIELD_AFFILIATION = 'wl_affiliation';
170
-
171
-	/**
172
-	 * The 'telephone' field name.
173
-	 *
174
-	 * @since 3.8.0
175
-	 */
176
-	const FIELD_TELEPHONE = 'wl_schema_telephone';
177
-
178
-	/**
179
-	 * The 'URI' data type name.
180
-	 *
181
-	 * @since 3.1.0
182
-	 */
183
-	const DATA_TYPE_URI = 'uri';
184
-
185
-	/**
186
-	 * The 'date' data type name.
187
-	 *
188
-	 * @since 3.1.0
189
-	 */
190
-	const DATA_TYPE_DATE = 'date';
191
-
192
-	/**
193
-	 * The 'double' data type name.
194
-	 *
195
-	 * @since 3.1.0
196
-	 */
197
-	const DATA_TYPE_DOUBLE = 'double';
198
-
199
-	/**
200
-	 * The 'string' data type name.
201
-	 *
202
-	 * @since 3.1.0
203
-	 */
204
-	const DATA_TYPE_STRING = 'string';
205
-
206
-	/**
207
-	 * The 'integer' data type name.
208
-	 *
209
-	 * @since 3.1.0
210
-	 */
211
-	const DATA_TYPE_INTEGER = 'int';
212
-
213
-	/**
214
-	 * The 'boolean' data type name.
215
-	 *
216
-	 * @since 3.1.0
217
-	 */
218
-	const DATA_TYPE_BOOLEAN = 'bool';
219
-
220
-	/**
221
-	 * The schema.org Event type URI.
222
-	 *
223
-	 * @since 3.1.0
224
-	 */
225
-	const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
226
-
227
-	/**
228
-	 * The Schema service singleton instance.
229
-	 *
230
-	 * @since  3.1.0
231
-	 * @access private
232
-	 * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
233
-	 */
234
-	private static $instance;
235
-
236
-	/**
237
-	 * WordLift's schema.
238
-	 *
239
-	 * @since  3.1.0
240
-	 * @access private
241
-	 * @var array $schema WordLift's schema.
242
-	 */
243
-	private $schema;
244
-
245
-	/**
246
-	 * The Log service.
247
-	 *
248
-	 * @since  3.1.0
249
-	 * @access private
250
-	 * @var \Wordlift_Log_Service $log_service The Log service.
251
-	 */
252
-	private $log_service;
253
-
254
-	/**
255
-	 * Wordlift_Schema_Service constructor.
256
-	 *
257
-	 * @since 3.1.0
258
-	 */
259
-	public function __construct() {
260
-
261
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
262
-
263
-		// Create a singleton instance of the Schema service, useful to provide static functions to global functions.
264
-		self::$instance = $this;
265
-
266
-		// Set the taxonomy data.
267
-		// Note: parent types must be defined before child types.
268
-		$this->schema = array(
269
-			'thing'         => $this->get_thing_schema(),
270
-			'creative-work' => $this->get_creative_work_schema(),
271
-			'event'         => $this->get_event_schema(),
272
-			'organization'  => $this->get_organization_schema(),
273
-			'person'        => $this->get_person_schema(),
274
-			'place'         => $this->get_place_schema(),
275
-			'localbusiness' => $this->get_local_business_schema(),
276
-		);
277
-
278
-	}
279
-
280
-	/**
281
-	 * Get a reference to the Schema service.
282
-	 *
283
-	 * @since 3.1.0
284
-	 *
285
-	 * @return Wordlift_Schema_Service A reference to the Schema service.
286
-	 */
287
-	public static function get_instance() {
288
-
289
-		return self::$instance;
290
-	}
291
-
292
-	/**
293
-	 * Get the properties for a field with the specified key. The key is used as
294
-	 * meta key when the field's value is stored in WordPress meta data table.
295
-	 *
296
-	 * @since 3.6.0
297
-	 *
298
-	 * @param string $key The field's key.
299
-	 *
300
-	 * @return null|array An array of field's properties or null if the field is not found.
301
-	 */
302
-	public function get_field( $key ) {
303
-
304
-		// Parse each schema's fields until we find the one we're looking for, then
305
-		// return its properties.
306
-		foreach ( $this->schema as $_ => $schema ) {
307
-
308
-			if ( ! isset( $schema['custom_fields'] ) ) {
309
-				break;
310
-			}
311
-
312
-			foreach ( $schema['custom_fields'] as $field => $props ) {
313
-				if ( $key === $field ) {
314
-					return $props;
315
-				}
316
-			}
317
-		}
318
-
319
-		return null;
320
-	}
321
-
322
-	/**
323
-	 * Get the WordLift's schema.
324
-	 *
325
-	 * @param string $name The schema name.
326
-	 *
327
-	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
328
-	 *
329
-	 * @since 3.1.0
330
-	 */
331
-	public function get_schema( $name ) {
332
-
333
-		// Check if the schema exists and, if not, return NULL.
334
-		if ( ! isset( $this->schema[ $name ] ) ) {
335
-			return null;
336
-		}
337
-
338
-		// Return the requested schema.
339
-		return $this->schema[ $name ];
340
-	}
341
-
342
-	/**
343
-	 * Get the WordLift's schema trough schema type uri.
344
-	 *
345
-	 * @param string $uri The schema uri.
346
-	 *
347
-	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
348
-	 *
349
-	 * @since 3.3.0
350
-	 */
351
-	public function get_schema_by_uri( $uri ) {
352
-
353
-		foreach ( $this->schema as $name => $schema ) {
354
-			if ( $schema['uri'] === $uri ) {
355
-				return $schema;
356
-			}
357
-		}
358
-
359
-		return null;
360
-	}
361
-
362
-	/**
363
-	 * Get the 'thing' schema.
364
-	 *
365
-	 * @return array An array with the schema configuration.
366
-	 *
367
-	 * @since 3.1.0
368
-	 */
369
-	private function get_thing_schema() {
370
-
371
-		return array(
372
-			'css_class'     => 'wl-thing',
373
-			'uri'           => 'http://schema.org/Thing',
374
-			'same_as'       => array( '*' ),
375
-			// set as default.
376
-			'custom_fields' => array(
377
-				self::FIELD_SAME_AS                            => array(
378
-					'predicate'   => 'http://schema.org/sameAs',
379
-					'type'        => self::DATA_TYPE_URI,
380
-					'export_type' => 'http://schema.org/Thing',
381
-					'constraints' => array(
382
-						'cardinality' => INF,
383
-					),
384
-					// we need a custom metabox
385
-					'input_field' => 'sameas',
386
-				),
387
-				// Add the schema:url property.
388
-				Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
389
-				                                                                                      ->get_compat_definition(),
390
-			),
391
-			// {{sameAs}} not present in the microdata template,
392
-			// because it is treated separately in *wl_content_embed_item_microdata*
393
-			'templates'     => array(
394
-				'subtitle' => '{{id}}',
395
-			),
396
-		);
397
-
398
-	}
399
-
400
-	/**
401
-	 * Get the 'creative work' schema.
402
-	 *
403
-	 * @return array An array with the schema configuration.
404
-	 *
405
-	 * @since 3.1.0
406
-	 */
407
-	private function get_creative_work_schema() {
408
-
409
-		$schema = array(
410
-			'label'         => 'CreativeWork',
411
-			'description'   => 'A creative work (or a Music Album).',
412
-			'parents'       => array( 'thing' ),
413
-			// Give term slug as parent.
414
-			'css_class'     => 'wl-creative-work',
415
-			'uri'           => 'http://schema.org/CreativeWork',
416
-			'same_as'       => array(
417
-				'http://schema.org/MusicAlbum',
418
-				'http://schema.org/Product',
419
-			),
420
-			'custom_fields' => array(
421
-				self::FIELD_AUTHOR => array(
422
-					'predicate'   => 'http://schema.org/author',
423
-					'type'        => self::DATA_TYPE_URI,
424
-					'export_type' => 'http://schema.org/Person',
425
-					'constraints' => array(
426
-						'uri_type'    => array( 'Person', 'Organization' ),
427
-						'cardinality' => INF,
428
-					),
429
-				),
430
-			),
431
-			'templates'     => array(
432
-				'subtitle' => '{{id}}',
433
-			),
434
-		);
435
-
436
-		// Merge the custom fields with those provided by the thing schema.
437
-		$thing_schema            = $this->get_thing_schema();
438
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
439
-
440
-		return $schema;
441
-	}
442
-
443
-	/**
444
-	 * Get the 'event' schema.
445
-	 *
446
-	 * @return array An array with the schema configuration.
447
-	 *
448
-	 * @since 3.1.0
449
-	 */
450
-	private function get_event_schema() {
451
-
452
-		$schema = array(
453
-			'label'         => 'Event',
454
-			'description'   => 'An event . ',
455
-			'parents'       => array( 'thing' ),
456
-			'css_class'     => 'wl-event',
457
-			'uri'           => self::SCHEMA_EVENT_TYPE,
458
-			'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
459
-			'custom_fields' => array(
460
-				self::FIELD_DATE_START => array(
461
-					'predicate'   => 'http://schema.org/startDate',
462
-					'type'        => self::DATA_TYPE_DATE,
463
-					'export_type' => 'xsd:datetime',
464
-					'constraints' => '',
465
-				),
466
-				self::FIELD_DATE_END   => array(
467
-					'predicate'   => 'http://schema.org/endDate',
468
-					'type'        => self::DATA_TYPE_DATE,
469
-					'export_type' => 'xsd:datetime',
470
-					'constraints' => '',
471
-				),
472
-				self::FIELD_LOCATION   => array(
473
-					'predicate'   => 'http://schema.org/location',
474
-					'type'        => self::DATA_TYPE_URI,
475
-					'export_type' => 'http://schema.org/PostalAddress',
476
-					'constraints' => array(
477
-						'uri_type'    => array( 'Place', 'LocalBusiness' ),
478
-						'cardinality' => INF,
479
-					),
480
-				),
481
-			),
482
-			'templates'     => array(
483
-				'subtitle' => '{{id}}',
484
-			),
485
-		);
486
-
487
-		// Merge the custom fields with those provided by the thing schema.
488
-		$thing_schema            = $this->get_thing_schema();
489
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
490
-
491
-		return $schema;
492
-	}
493
-
494
-	/**
495
-	 * Get the 'organization' schema.
496
-	 *
497
-	 * @return array An array with the schema configuration.
498
-	 *
499
-	 * @since 3.1.0
500
-	 */
501
-	private function get_organization_schema() {
502
-
503
-		$schema = array(
504
-			'label'         => 'Organization',
505
-			'description'   => 'An organization, including a government or a newspaper.',
506
-			'parents'       => array( 'thing' ),
507
-			'css_class'     => 'wl-organization',
508
-			'uri'           => 'http://schema.org/Organization',
509
-			'same_as'       => array(
510
-				'http://rdf.freebase.com/ns/organization.organization',
511
-				'http://rdf.freebase.com/ns/government.government',
512
-				'http://schema.org/Newspaper',
513
-			),
514
-			'custom_fields' => array(
515
-				self::FIELD_FOUNDER             => array(
516
-					'predicate'   => 'http://schema.org/founder',
517
-					'type'        => self::DATA_TYPE_URI,
518
-					'export_type' => 'http://schema.org/Person',
519
-					'constraints' => array(
520
-						'uri_type'    => 'Person',
521
-						'cardinality' => INF,
522
-					),
523
-				),
524
-				self::FIELD_ADDRESS             => array(
525
-					'predicate'   => 'http://schema.org/streetAddress',
526
-					'type'        => self::DATA_TYPE_STRING,
527
-					'export_type' => 'xsd:string',
528
-					'constraints' => '',
529
-					// To build custom metabox.
530
-					'input_field' => 'address',
531
-				),
532
-				self::FIELD_ADDRESS_PO_BOX      => array(
533
-					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
534
-					'type'        => self::DATA_TYPE_STRING,
535
-					'export_type' => 'xsd:string',
536
-					'constraints' => '',
537
-					// To build custom metabox.
538
-					'input_field' => 'address',
539
-				),
540
-				self::FIELD_ADDRESS_POSTAL_CODE => array(
541
-					'predicate'   => 'http://schema.org/postalCode',
542
-					'type'        => self::DATA_TYPE_STRING,
543
-					'export_type' => 'xsd:string',
544
-					'constraints' => '',
545
-					// To build custom metabox.
546
-					'input_field' => 'address',
547
-				),
548
-				self::FIELD_ADDRESS_LOCALITY    => array(
549
-					'predicate'   => 'http://schema.org/addressLocality',
550
-					'type'        => self::DATA_TYPE_STRING,
551
-					'export_type' => 'xsd:string',
552
-					'constraints' => '',
553
-					// To build custom metabox.
554
-					'input_field' => 'address',
555
-				),
556
-				self::FIELD_ADDRESS_REGION      => array(
557
-					'predicate'   => 'http://schema.org/addressRegion',
558
-					'type'        => self::DATA_TYPE_STRING,
559
-					'export_type' => 'xsd:string',
560
-					'constraints' => '',
561
-					// To build custom metabox.
562
-					'input_field' => 'address',
563
-				),
564
-				self::FIELD_ADDRESS_COUNTRY     => array(
565
-					'predicate'   => 'http://schema.org/addressCountry',
566
-					'type'        => self::DATA_TYPE_STRING,
567
-					'export_type' => 'xsd:string',
568
-					'constraints' => '',
569
-					// To build custom metabox.
570
-					'input_field' => 'address',
571
-				),
572
-				self::FIELD_EMAIL               => array(
573
-					'predicate'   => 'http://schema.org/email',
574
-					'type'        => self::DATA_TYPE_STRING,
575
-					'export_type' => 'xsd:string',
576
-					'constraints' => '',
577
-				),
578
-				self::FIELD_TELEPHONE           => array(
579
-					'predicate'   => 'http://schema.org/telephone',
580
-					'type'        => self::DATA_TYPE_STRING,
581
-					'export_type' => 'xsd:string',
582
-					'constraints' => '',
583
-				),
584
-			),
585
-			'templates'     => array(
586
-				'subtitle' => '{{id}}',
587
-			),
588
-		);
589
-
590
-		// Merge the custom fields with those provided by the thing schema.
591
-		$thing_schema            = $this->get_thing_schema();
592
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
593
-
594
-		return $schema;
595
-	}
596
-
597
-	/**
598
-	 * Get the 'person' schema.
599
-	 *
600
-	 * @return array An array with the schema configuration.
601
-	 *
602
-	 * @since 3.1.0
603
-	 */
604
-	private function get_person_schema() {
605
-
606
-		$schema = array(
607
-			'label'         => 'Person',
608
-			'description'   => 'A person (or a music artist).',
609
-			'parents'       => array( 'thing' ),
610
-			'css_class'     => 'wl-person',
611
-			'uri'           => 'http://schema.org/Person',
612
-			'same_as'       => array(
613
-				'http://rdf.freebase.com/ns/people.person',
614
-				'http://rdf.freebase.com/ns/music.artist',
615
-				'http://dbpedia.org/class/yago/LivingPeople',
616
-			),
617
-			'custom_fields' => array(
618
-				self::FIELD_KNOWS       => array(
619
-					'predicate'   => 'http://schema.org/knows',
620
-					'type'        => self::DATA_TYPE_URI,
621
-					'export_type' => 'http://schema.org/Person',
622
-					'constraints' => array(
623
-						'uri_type'    => 'Person',
624
-						'cardinality' => INF,
625
-					),
626
-				),
627
-				self::FIELD_BIRTH_DATE  => array(
628
-					'predicate'   => 'http://schema.org/birthDate',
629
-					'type'        => self::DATA_TYPE_DATE,
630
-					'export_type' => 'xsd:date',
631
-					'constraints' => '',
632
-				),
633
-				self::FIELD_BIRTH_PLACE => array(
634
-					'predicate'   => 'http://schema.org/birthPlace',
635
-					'type'        => self::DATA_TYPE_URI,
636
-					'export_type' => 'http://schema.org/Place',
637
-					'constraints' => array(
638
-						'uri_type' => 'Place',
639
-					),
640
-				),
641
-				self::FIELD_AFFILIATION => array(
642
-					'predicate'   => 'http://schema.org/affiliation',
643
-					'type'        => self::DATA_TYPE_URI,
644
-					'export_type' => 'http://schema.org/Organization',
645
-					'constraints' => array(
646
-						'uri_type'    => array(
647
-							'Organization',
648
-							'LocalBusiness',
649
-						),
650
-						'cardinality' => INF,
651
-					),
652
-				),
653
-				self::FIELD_EMAIL       => array(
654
-					'predicate'   => 'http://schema.org/email',
655
-					'type'        => self::DATA_TYPE_STRING,
656
-					'export_type' => 'xsd:string',
657
-					'constraints' => array(
658
-						'cardinality' => INF,
659
-					),
660
-				),
661
-			),
662
-			'templates'     => array(
663
-				'subtitle' => '{{id}}',
664
-			),
665
-		);
666
-
667
-		// Merge the custom fields with those provided by the thing schema.
668
-		$thing_schema            = $this->get_thing_schema();
669
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
670
-
671
-		return $schema;
672
-
673
-	}
674
-
675
-	/**
676
-	 * Get the 'place' schema.
677
-	 *
678
-	 * @return array An array with the schema configuration.
679
-	 *
680
-	 * @since 3.1.0
681
-	 */
682
-	private function get_place_schema() {
683
-
684
-		$schema = array(
685
-			'label'         => 'Place',
686
-			'description'   => 'A place.',
687
-			'parents'       => array( 'thing' ),
688
-			'css_class'     => 'wl-place',
689
-			'uri'           => 'http://schema.org/Place',
690
-			'same_as'       => array(
691
-				'http://rdf.freebase.com/ns/location.location',
692
-				'http://www.opengis.net/gml/_Feature',
693
-			),
694
-			'custom_fields' => array(
695
-				self::FIELD_GEO_LATITUDE        => array(
696
-					'predicate'   => 'http://schema.org/latitude',
697
-					'type'        => self::DATA_TYPE_DOUBLE,
698
-					'export_type' => 'xsd:double',
699
-					'constraints' => '',
700
-					// To build custom metabox.
701
-					'input_field' => 'coordinates',
702
-				),
703
-				self::FIELD_GEO_LONGITUDE       => array(
704
-					'predicate'   => 'http://schema.org/longitude',
705
-					'type'        => self::DATA_TYPE_DOUBLE,
706
-					'export_type' => 'xsd:double',
707
-					'constraints' => '',
708
-					// To build custom metabox.
709
-					'input_field' => 'coordinates',
710
-				),
711
-				self::FIELD_ADDRESS             => array(
712
-					'predicate'   => 'http://schema.org/streetAddress',
713
-					'type'        => self::DATA_TYPE_STRING,
714
-					'export_type' => 'xsd:string',
715
-					'constraints' => '',
716
-					// To build custom metabox.
717
-					'input_field' => 'address',
718
-				),
719
-				self::FIELD_ADDRESS_PO_BOX      => array(
720
-					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
721
-					'type'        => self::DATA_TYPE_STRING,
722
-					'export_type' => 'xsd:string',
723
-					'constraints' => '',
724
-					// To build custom metabox.
725
-					'input_field' => 'address',
726
-				),
727
-				self::FIELD_ADDRESS_POSTAL_CODE => array(
728
-					'predicate'   => 'http://schema.org/postalCode',
729
-					'type'        => self::DATA_TYPE_STRING,
730
-					'export_type' => 'xsd:string',
731
-					'constraints' => '',
732
-					// To build custom metabox.
733
-					'input_field' => 'address',
734
-				),
735
-				self::FIELD_ADDRESS_LOCALITY    => array(
736
-					'predicate'   => 'http://schema.org/addressLocality',
737
-					'type'        => self::DATA_TYPE_STRING,
738
-					'export_type' => 'xsd:string',
739
-					'constraints' => '',
740
-					// To build custom metabox.
741
-					'input_field' => 'address',
742
-				),
743
-				self::FIELD_ADDRESS_REGION      => array(
744
-					'predicate'   => 'http://schema.org/addressRegion',
745
-					'type'        => self::DATA_TYPE_STRING,
746
-					'export_type' => 'xsd:string',
747
-					'constraints' => '',
748
-					// To build custom metabox.
749
-					'input_field' => 'address',
750
-				),
751
-				self::FIELD_ADDRESS_COUNTRY     => array(
752
-					'predicate'   => 'http://schema.org/addressCountry',
753
-					'type'        => self::DATA_TYPE_STRING,
754
-					'export_type' => 'xsd:string',
755
-					'constraints' => '',
756
-					// To build custom metabox.
757
-					'input_field' => 'address',
758
-				),
759
-			),
760
-			'templates'     => array(
761
-				'subtitle' => '{{id}}',
762
-			),
763
-		);
764
-
765
-		// Merge the custom fields with those provided by the thing schema.
766
-		$thing_schema            = $this->get_thing_schema();
767
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
768
-
769
-		return $schema;
770
-	}
771
-
772
-	/**
773
-	 * Get the 'local business' schema.
774
-	 *
775
-	 * @return array An array with the schema configuration.
776
-	 *
777
-	 * @since 3.1.0
778
-	 */
779
-	private function get_local_business_schema() {
780
-
781
-		$schema = array(
782
-			'label'         => 'LocalBusiness',
783
-			'description'   => 'A local business.',
784
-			'parents'       => array( 'place', 'organization' ),
785
-			'css_class'     => 'wl-local-business',
786
-			'uri'           => 'http://schema.org/LocalBusiness',
787
-			'same_as'       => array(
788
-				'http://rdf.freebase.com/ns/business/business_location',
789
-				'https://schema.org/Store',
790
-			),
791
-			'custom_fields' => array(),
792
-			'templates'     => array(
793
-				'subtitle' => '{{id}}',
794
-			),
795
-		);
796
-
797
-		// Merge the custom fields with those provided by the place and organization schema.
798
-		$place_schema            = $this->get_place_schema();
799
-		$organization_schema     = $this->get_organization_schema();
800
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
801
-
802
-		return $schema;
803
-	}
18
+    /**
19
+     * The 'location created' field name.
20
+     *
21
+     * @since 3.5.0
22
+     */
23
+    const FIELD_LOCATION_CREATED = 'wl_location_created';
24
+
25
+    /**
26
+     * The 'topic' field name.
27
+     *
28
+     * @since 3.5.0
29
+     */
30
+    const FIELD_TOPIC = 'wl_topic';
31
+
32
+    /**
33
+     * The 'author' field name.
34
+     *
35
+     * @since 3.1.0
36
+     */
37
+    const FIELD_AUTHOR = 'wl_author';
38
+
39
+    /**
40
+     * The 'same as' field name.
41
+     *
42
+     * @since 3.1.0
43
+     */
44
+    const FIELD_SAME_AS = 'entity_same_as';
45
+
46
+    /**
47
+     * The 'date start' field name.
48
+     *
49
+     * @since 3.1.0
50
+     */
51
+    const FIELD_DATE_START = 'wl_cal_date_start';
52
+
53
+    /**
54
+     * The 'date end' field name.
55
+     *
56
+     * @since 3.1.0
57
+     */
58
+    const FIELD_DATE_END = 'wl_cal_date_end';
59
+
60
+    /**
61
+     * The 'location' field name.
62
+     *
63
+     * @since 3.1.0
64
+     */
65
+    const FIELD_LOCATION = 'wl_location';
66
+
67
+    /**
68
+     * The 'founder' field name.
69
+     *
70
+     * @since 3.1.0
71
+     */
72
+    const FIELD_FOUNDER = 'wl_founder';
73
+
74
+    /**
75
+     * The 'knows' field name.
76
+     *
77
+     * @since 3.1.0
78
+     */
79
+    const FIELD_KNOWS = 'wl_knows';
80
+
81
+    /**
82
+     * The 'birth date' field name.
83
+     *
84
+     * @since 3.1.0
85
+     */
86
+    const FIELD_BIRTH_DATE = 'wl_birth_date';
87
+
88
+    /**
89
+     * The 'birth place' field name.
90
+     *
91
+     * @since 3.1.0
92
+     */
93
+    const FIELD_BIRTH_PLACE = 'wl_birth_place';
94
+
95
+    /**
96
+     * The 'latitude' field name.
97
+     *
98
+     * @since 3.1.0
99
+     */
100
+    const FIELD_GEO_LATITUDE = 'wl_geo_latitude';
101
+
102
+    /**
103
+     * The 'longitude' field name.
104
+     *
105
+     * @since 3.1.0
106
+     */
107
+    const FIELD_GEO_LONGITUDE = 'wl_geo_longitude';
108
+
109
+    /**
110
+     * The 'streetAddress' field name.
111
+     *
112
+     * @since 3.1.0
113
+     */
114
+    const FIELD_ADDRESS = 'wl_address';
115
+
116
+    /**
117
+     * The 'postOfficeBoxNumber' field name.
118
+     *
119
+     * @since 3.3.0
120
+     */
121
+    const FIELD_ADDRESS_PO_BOX = 'wl_address_post_office_box';
122
+
123
+    /**
124
+     * The 'postalCode' field name.
125
+     *
126
+     * @since 3.3.0
127
+     */
128
+    const FIELD_ADDRESS_POSTAL_CODE = 'wl_address_postal_code';
129
+
130
+    /**
131
+     * The 'addressLocality' field name.
132
+     *
133
+     * @since 3.3.0
134
+     */
135
+    const FIELD_ADDRESS_LOCALITY = 'wl_address_locality';
136
+    /**
137
+     * The 'addressRegion' field name.
138
+     *
139
+     * @since 3.3.0
140
+     */
141
+    const FIELD_ADDRESS_REGION = 'wl_address_region';
142
+
143
+    /**
144
+     * The 'addressCountry' field name.
145
+     *
146
+     * @since 3.3.0
147
+     */
148
+    const FIELD_ADDRESS_COUNTRY = 'wl_address_country';
149
+
150
+    /**
151
+     * The 'entity type' field name.
152
+     *
153
+     * @since 3.1.0
154
+     */
155
+    const FIELD_ENTITY_TYPE = 'wl_entity_type_uri';
156
+
157
+    /**
158
+     * The 'email' field name.
159
+     *
160
+     * @since 3.2.0
161
+     */
162
+    const FIELD_EMAIL = 'wl_email';
163
+
164
+    /**
165
+     * The 'affiliation' field name.
166
+     *
167
+     * @since 3.2.0
168
+     */
169
+    const FIELD_AFFILIATION = 'wl_affiliation';
170
+
171
+    /**
172
+     * The 'telephone' field name.
173
+     *
174
+     * @since 3.8.0
175
+     */
176
+    const FIELD_TELEPHONE = 'wl_schema_telephone';
177
+
178
+    /**
179
+     * The 'URI' data type name.
180
+     *
181
+     * @since 3.1.0
182
+     */
183
+    const DATA_TYPE_URI = 'uri';
184
+
185
+    /**
186
+     * The 'date' data type name.
187
+     *
188
+     * @since 3.1.0
189
+     */
190
+    const DATA_TYPE_DATE = 'date';
191
+
192
+    /**
193
+     * The 'double' data type name.
194
+     *
195
+     * @since 3.1.0
196
+     */
197
+    const DATA_TYPE_DOUBLE = 'double';
198
+
199
+    /**
200
+     * The 'string' data type name.
201
+     *
202
+     * @since 3.1.0
203
+     */
204
+    const DATA_TYPE_STRING = 'string';
205
+
206
+    /**
207
+     * The 'integer' data type name.
208
+     *
209
+     * @since 3.1.0
210
+     */
211
+    const DATA_TYPE_INTEGER = 'int';
212
+
213
+    /**
214
+     * The 'boolean' data type name.
215
+     *
216
+     * @since 3.1.0
217
+     */
218
+    const DATA_TYPE_BOOLEAN = 'bool';
219
+
220
+    /**
221
+     * The schema.org Event type URI.
222
+     *
223
+     * @since 3.1.0
224
+     */
225
+    const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
226
+
227
+    /**
228
+     * The Schema service singleton instance.
229
+     *
230
+     * @since  3.1.0
231
+     * @access private
232
+     * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
233
+     */
234
+    private static $instance;
235
+
236
+    /**
237
+     * WordLift's schema.
238
+     *
239
+     * @since  3.1.0
240
+     * @access private
241
+     * @var array $schema WordLift's schema.
242
+     */
243
+    private $schema;
244
+
245
+    /**
246
+     * The Log service.
247
+     *
248
+     * @since  3.1.0
249
+     * @access private
250
+     * @var \Wordlift_Log_Service $log_service The Log service.
251
+     */
252
+    private $log_service;
253
+
254
+    /**
255
+     * Wordlift_Schema_Service constructor.
256
+     *
257
+     * @since 3.1.0
258
+     */
259
+    public function __construct() {
260
+
261
+        $this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
262
+
263
+        // Create a singleton instance of the Schema service, useful to provide static functions to global functions.
264
+        self::$instance = $this;
265
+
266
+        // Set the taxonomy data.
267
+        // Note: parent types must be defined before child types.
268
+        $this->schema = array(
269
+            'thing'         => $this->get_thing_schema(),
270
+            'creative-work' => $this->get_creative_work_schema(),
271
+            'event'         => $this->get_event_schema(),
272
+            'organization'  => $this->get_organization_schema(),
273
+            'person'        => $this->get_person_schema(),
274
+            'place'         => $this->get_place_schema(),
275
+            'localbusiness' => $this->get_local_business_schema(),
276
+        );
277
+
278
+    }
279
+
280
+    /**
281
+     * Get a reference to the Schema service.
282
+     *
283
+     * @since 3.1.0
284
+     *
285
+     * @return Wordlift_Schema_Service A reference to the Schema service.
286
+     */
287
+    public static function get_instance() {
288
+
289
+        return self::$instance;
290
+    }
291
+
292
+    /**
293
+     * Get the properties for a field with the specified key. The key is used as
294
+     * meta key when the field's value is stored in WordPress meta data table.
295
+     *
296
+     * @since 3.6.0
297
+     *
298
+     * @param string $key The field's key.
299
+     *
300
+     * @return null|array An array of field's properties or null if the field is not found.
301
+     */
302
+    public function get_field( $key ) {
303
+
304
+        // Parse each schema's fields until we find the one we're looking for, then
305
+        // return its properties.
306
+        foreach ( $this->schema as $_ => $schema ) {
307
+
308
+            if ( ! isset( $schema['custom_fields'] ) ) {
309
+                break;
310
+            }
311
+
312
+            foreach ( $schema['custom_fields'] as $field => $props ) {
313
+                if ( $key === $field ) {
314
+                    return $props;
315
+                }
316
+            }
317
+        }
318
+
319
+        return null;
320
+    }
321
+
322
+    /**
323
+     * Get the WordLift's schema.
324
+     *
325
+     * @param string $name The schema name.
326
+     *
327
+     * @return array|null An array with the schema configuration or NULL if the schema is not found.
328
+     *
329
+     * @since 3.1.0
330
+     */
331
+    public function get_schema( $name ) {
332
+
333
+        // Check if the schema exists and, if not, return NULL.
334
+        if ( ! isset( $this->schema[ $name ] ) ) {
335
+            return null;
336
+        }
337
+
338
+        // Return the requested schema.
339
+        return $this->schema[ $name ];
340
+    }
341
+
342
+    /**
343
+     * Get the WordLift's schema trough schema type uri.
344
+     *
345
+     * @param string $uri The schema uri.
346
+     *
347
+     * @return array|null An array with the schema configuration or NULL if the schema is not found.
348
+     *
349
+     * @since 3.3.0
350
+     */
351
+    public function get_schema_by_uri( $uri ) {
352
+
353
+        foreach ( $this->schema as $name => $schema ) {
354
+            if ( $schema['uri'] === $uri ) {
355
+                return $schema;
356
+            }
357
+        }
358
+
359
+        return null;
360
+    }
361
+
362
+    /**
363
+     * Get the 'thing' schema.
364
+     *
365
+     * @return array An array with the schema configuration.
366
+     *
367
+     * @since 3.1.0
368
+     */
369
+    private function get_thing_schema() {
370
+
371
+        return array(
372
+            'css_class'     => 'wl-thing',
373
+            'uri'           => 'http://schema.org/Thing',
374
+            'same_as'       => array( '*' ),
375
+            // set as default.
376
+            'custom_fields' => array(
377
+                self::FIELD_SAME_AS                            => array(
378
+                    'predicate'   => 'http://schema.org/sameAs',
379
+                    'type'        => self::DATA_TYPE_URI,
380
+                    'export_type' => 'http://schema.org/Thing',
381
+                    'constraints' => array(
382
+                        'cardinality' => INF,
383
+                    ),
384
+                    // we need a custom metabox
385
+                    'input_field' => 'sameas',
386
+                ),
387
+                // Add the schema:url property.
388
+                Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
389
+                                                                                                        ->get_compat_definition(),
390
+            ),
391
+            // {{sameAs}} not present in the microdata template,
392
+            // because it is treated separately in *wl_content_embed_item_microdata*
393
+            'templates'     => array(
394
+                'subtitle' => '{{id}}',
395
+            ),
396
+        );
397
+
398
+    }
399
+
400
+    /**
401
+     * Get the 'creative work' schema.
402
+     *
403
+     * @return array An array with the schema configuration.
404
+     *
405
+     * @since 3.1.0
406
+     */
407
+    private function get_creative_work_schema() {
408
+
409
+        $schema = array(
410
+            'label'         => 'CreativeWork',
411
+            'description'   => 'A creative work (or a Music Album).',
412
+            'parents'       => array( 'thing' ),
413
+            // Give term slug as parent.
414
+            'css_class'     => 'wl-creative-work',
415
+            'uri'           => 'http://schema.org/CreativeWork',
416
+            'same_as'       => array(
417
+                'http://schema.org/MusicAlbum',
418
+                'http://schema.org/Product',
419
+            ),
420
+            'custom_fields' => array(
421
+                self::FIELD_AUTHOR => array(
422
+                    'predicate'   => 'http://schema.org/author',
423
+                    'type'        => self::DATA_TYPE_URI,
424
+                    'export_type' => 'http://schema.org/Person',
425
+                    'constraints' => array(
426
+                        'uri_type'    => array( 'Person', 'Organization' ),
427
+                        'cardinality' => INF,
428
+                    ),
429
+                ),
430
+            ),
431
+            'templates'     => array(
432
+                'subtitle' => '{{id}}',
433
+            ),
434
+        );
435
+
436
+        // Merge the custom fields with those provided by the thing schema.
437
+        $thing_schema            = $this->get_thing_schema();
438
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
439
+
440
+        return $schema;
441
+    }
442
+
443
+    /**
444
+     * Get the 'event' schema.
445
+     *
446
+     * @return array An array with the schema configuration.
447
+     *
448
+     * @since 3.1.0
449
+     */
450
+    private function get_event_schema() {
451
+
452
+        $schema = array(
453
+            'label'         => 'Event',
454
+            'description'   => 'An event . ',
455
+            'parents'       => array( 'thing' ),
456
+            'css_class'     => 'wl-event',
457
+            'uri'           => self::SCHEMA_EVENT_TYPE,
458
+            'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
459
+            'custom_fields' => array(
460
+                self::FIELD_DATE_START => array(
461
+                    'predicate'   => 'http://schema.org/startDate',
462
+                    'type'        => self::DATA_TYPE_DATE,
463
+                    'export_type' => 'xsd:datetime',
464
+                    'constraints' => '',
465
+                ),
466
+                self::FIELD_DATE_END   => array(
467
+                    'predicate'   => 'http://schema.org/endDate',
468
+                    'type'        => self::DATA_TYPE_DATE,
469
+                    'export_type' => 'xsd:datetime',
470
+                    'constraints' => '',
471
+                ),
472
+                self::FIELD_LOCATION   => array(
473
+                    'predicate'   => 'http://schema.org/location',
474
+                    'type'        => self::DATA_TYPE_URI,
475
+                    'export_type' => 'http://schema.org/PostalAddress',
476
+                    'constraints' => array(
477
+                        'uri_type'    => array( 'Place', 'LocalBusiness' ),
478
+                        'cardinality' => INF,
479
+                    ),
480
+                ),
481
+            ),
482
+            'templates'     => array(
483
+                'subtitle' => '{{id}}',
484
+            ),
485
+        );
486
+
487
+        // Merge the custom fields with those provided by the thing schema.
488
+        $thing_schema            = $this->get_thing_schema();
489
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
490
+
491
+        return $schema;
492
+    }
493
+
494
+    /**
495
+     * Get the 'organization' schema.
496
+     *
497
+     * @return array An array with the schema configuration.
498
+     *
499
+     * @since 3.1.0
500
+     */
501
+    private function get_organization_schema() {
502
+
503
+        $schema = array(
504
+            'label'         => 'Organization',
505
+            'description'   => 'An organization, including a government or a newspaper.',
506
+            'parents'       => array( 'thing' ),
507
+            'css_class'     => 'wl-organization',
508
+            'uri'           => 'http://schema.org/Organization',
509
+            'same_as'       => array(
510
+                'http://rdf.freebase.com/ns/organization.organization',
511
+                'http://rdf.freebase.com/ns/government.government',
512
+                'http://schema.org/Newspaper',
513
+            ),
514
+            'custom_fields' => array(
515
+                self::FIELD_FOUNDER             => array(
516
+                    'predicate'   => 'http://schema.org/founder',
517
+                    'type'        => self::DATA_TYPE_URI,
518
+                    'export_type' => 'http://schema.org/Person',
519
+                    'constraints' => array(
520
+                        'uri_type'    => 'Person',
521
+                        'cardinality' => INF,
522
+                    ),
523
+                ),
524
+                self::FIELD_ADDRESS             => array(
525
+                    'predicate'   => 'http://schema.org/streetAddress',
526
+                    'type'        => self::DATA_TYPE_STRING,
527
+                    'export_type' => 'xsd:string',
528
+                    'constraints' => '',
529
+                    // To build custom metabox.
530
+                    'input_field' => 'address',
531
+                ),
532
+                self::FIELD_ADDRESS_PO_BOX      => array(
533
+                    'predicate'   => 'http://schema.org/postOfficeBoxNumber',
534
+                    'type'        => self::DATA_TYPE_STRING,
535
+                    'export_type' => 'xsd:string',
536
+                    'constraints' => '',
537
+                    // To build custom metabox.
538
+                    'input_field' => 'address',
539
+                ),
540
+                self::FIELD_ADDRESS_POSTAL_CODE => array(
541
+                    'predicate'   => 'http://schema.org/postalCode',
542
+                    'type'        => self::DATA_TYPE_STRING,
543
+                    'export_type' => 'xsd:string',
544
+                    'constraints' => '',
545
+                    // To build custom metabox.
546
+                    'input_field' => 'address',
547
+                ),
548
+                self::FIELD_ADDRESS_LOCALITY    => array(
549
+                    'predicate'   => 'http://schema.org/addressLocality',
550
+                    'type'        => self::DATA_TYPE_STRING,
551
+                    'export_type' => 'xsd:string',
552
+                    'constraints' => '',
553
+                    // To build custom metabox.
554
+                    'input_field' => 'address',
555
+                ),
556
+                self::FIELD_ADDRESS_REGION      => array(
557
+                    'predicate'   => 'http://schema.org/addressRegion',
558
+                    'type'        => self::DATA_TYPE_STRING,
559
+                    'export_type' => 'xsd:string',
560
+                    'constraints' => '',
561
+                    // To build custom metabox.
562
+                    'input_field' => 'address',
563
+                ),
564
+                self::FIELD_ADDRESS_COUNTRY     => array(
565
+                    'predicate'   => 'http://schema.org/addressCountry',
566
+                    'type'        => self::DATA_TYPE_STRING,
567
+                    'export_type' => 'xsd:string',
568
+                    'constraints' => '',
569
+                    // To build custom metabox.
570
+                    'input_field' => 'address',
571
+                ),
572
+                self::FIELD_EMAIL               => array(
573
+                    'predicate'   => 'http://schema.org/email',
574
+                    'type'        => self::DATA_TYPE_STRING,
575
+                    'export_type' => 'xsd:string',
576
+                    'constraints' => '',
577
+                ),
578
+                self::FIELD_TELEPHONE           => array(
579
+                    'predicate'   => 'http://schema.org/telephone',
580
+                    'type'        => self::DATA_TYPE_STRING,
581
+                    'export_type' => 'xsd:string',
582
+                    'constraints' => '',
583
+                ),
584
+            ),
585
+            'templates'     => array(
586
+                'subtitle' => '{{id}}',
587
+            ),
588
+        );
589
+
590
+        // Merge the custom fields with those provided by the thing schema.
591
+        $thing_schema            = $this->get_thing_schema();
592
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
593
+
594
+        return $schema;
595
+    }
596
+
597
+    /**
598
+     * Get the 'person' schema.
599
+     *
600
+     * @return array An array with the schema configuration.
601
+     *
602
+     * @since 3.1.0
603
+     */
604
+    private function get_person_schema() {
605
+
606
+        $schema = array(
607
+            'label'         => 'Person',
608
+            'description'   => 'A person (or a music artist).',
609
+            'parents'       => array( 'thing' ),
610
+            'css_class'     => 'wl-person',
611
+            'uri'           => 'http://schema.org/Person',
612
+            'same_as'       => array(
613
+                'http://rdf.freebase.com/ns/people.person',
614
+                'http://rdf.freebase.com/ns/music.artist',
615
+                'http://dbpedia.org/class/yago/LivingPeople',
616
+            ),
617
+            'custom_fields' => array(
618
+                self::FIELD_KNOWS       => array(
619
+                    'predicate'   => 'http://schema.org/knows',
620
+                    'type'        => self::DATA_TYPE_URI,
621
+                    'export_type' => 'http://schema.org/Person',
622
+                    'constraints' => array(
623
+                        'uri_type'    => 'Person',
624
+                        'cardinality' => INF,
625
+                    ),
626
+                ),
627
+                self::FIELD_BIRTH_DATE  => array(
628
+                    'predicate'   => 'http://schema.org/birthDate',
629
+                    'type'        => self::DATA_TYPE_DATE,
630
+                    'export_type' => 'xsd:date',
631
+                    'constraints' => '',
632
+                ),
633
+                self::FIELD_BIRTH_PLACE => array(
634
+                    'predicate'   => 'http://schema.org/birthPlace',
635
+                    'type'        => self::DATA_TYPE_URI,
636
+                    'export_type' => 'http://schema.org/Place',
637
+                    'constraints' => array(
638
+                        'uri_type' => 'Place',
639
+                    ),
640
+                ),
641
+                self::FIELD_AFFILIATION => array(
642
+                    'predicate'   => 'http://schema.org/affiliation',
643
+                    'type'        => self::DATA_TYPE_URI,
644
+                    'export_type' => 'http://schema.org/Organization',
645
+                    'constraints' => array(
646
+                        'uri_type'    => array(
647
+                            'Organization',
648
+                            'LocalBusiness',
649
+                        ),
650
+                        'cardinality' => INF,
651
+                    ),
652
+                ),
653
+                self::FIELD_EMAIL       => array(
654
+                    'predicate'   => 'http://schema.org/email',
655
+                    'type'        => self::DATA_TYPE_STRING,
656
+                    'export_type' => 'xsd:string',
657
+                    'constraints' => array(
658
+                        'cardinality' => INF,
659
+                    ),
660
+                ),
661
+            ),
662
+            'templates'     => array(
663
+                'subtitle' => '{{id}}',
664
+            ),
665
+        );
666
+
667
+        // Merge the custom fields with those provided by the thing schema.
668
+        $thing_schema            = $this->get_thing_schema();
669
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
670
+
671
+        return $schema;
672
+
673
+    }
674
+
675
+    /**
676
+     * Get the 'place' schema.
677
+     *
678
+     * @return array An array with the schema configuration.
679
+     *
680
+     * @since 3.1.0
681
+     */
682
+    private function get_place_schema() {
683
+
684
+        $schema = array(
685
+            'label'         => 'Place',
686
+            'description'   => 'A place.',
687
+            'parents'       => array( 'thing' ),
688
+            'css_class'     => 'wl-place',
689
+            'uri'           => 'http://schema.org/Place',
690
+            'same_as'       => array(
691
+                'http://rdf.freebase.com/ns/location.location',
692
+                'http://www.opengis.net/gml/_Feature',
693
+            ),
694
+            'custom_fields' => array(
695
+                self::FIELD_GEO_LATITUDE        => array(
696
+                    'predicate'   => 'http://schema.org/latitude',
697
+                    'type'        => self::DATA_TYPE_DOUBLE,
698
+                    'export_type' => 'xsd:double',
699
+                    'constraints' => '',
700
+                    // To build custom metabox.
701
+                    'input_field' => 'coordinates',
702
+                ),
703
+                self::FIELD_GEO_LONGITUDE       => array(
704
+                    'predicate'   => 'http://schema.org/longitude',
705
+                    'type'        => self::DATA_TYPE_DOUBLE,
706
+                    'export_type' => 'xsd:double',
707
+                    'constraints' => '',
708
+                    // To build custom metabox.
709
+                    'input_field' => 'coordinates',
710
+                ),
711
+                self::FIELD_ADDRESS             => array(
712
+                    'predicate'   => 'http://schema.org/streetAddress',
713
+                    'type'        => self::DATA_TYPE_STRING,
714
+                    'export_type' => 'xsd:string',
715
+                    'constraints' => '',
716
+                    // To build custom metabox.
717
+                    'input_field' => 'address',
718
+                ),
719
+                self::FIELD_ADDRESS_PO_BOX      => array(
720
+                    'predicate'   => 'http://schema.org/postOfficeBoxNumber',
721
+                    'type'        => self::DATA_TYPE_STRING,
722
+                    'export_type' => 'xsd:string',
723
+                    'constraints' => '',
724
+                    // To build custom metabox.
725
+                    'input_field' => 'address',
726
+                ),
727
+                self::FIELD_ADDRESS_POSTAL_CODE => array(
728
+                    'predicate'   => 'http://schema.org/postalCode',
729
+                    'type'        => self::DATA_TYPE_STRING,
730
+                    'export_type' => 'xsd:string',
731
+                    'constraints' => '',
732
+                    // To build custom metabox.
733
+                    'input_field' => 'address',
734
+                ),
735
+                self::FIELD_ADDRESS_LOCALITY    => array(
736
+                    'predicate'   => 'http://schema.org/addressLocality',
737
+                    'type'        => self::DATA_TYPE_STRING,
738
+                    'export_type' => 'xsd:string',
739
+                    'constraints' => '',
740
+                    // To build custom metabox.
741
+                    'input_field' => 'address',
742
+                ),
743
+                self::FIELD_ADDRESS_REGION      => array(
744
+                    'predicate'   => 'http://schema.org/addressRegion',
745
+                    'type'        => self::DATA_TYPE_STRING,
746
+                    'export_type' => 'xsd:string',
747
+                    'constraints' => '',
748
+                    // To build custom metabox.
749
+                    'input_field' => 'address',
750
+                ),
751
+                self::FIELD_ADDRESS_COUNTRY     => array(
752
+                    'predicate'   => 'http://schema.org/addressCountry',
753
+                    'type'        => self::DATA_TYPE_STRING,
754
+                    'export_type' => 'xsd:string',
755
+                    'constraints' => '',
756
+                    // To build custom metabox.
757
+                    'input_field' => 'address',
758
+                ),
759
+            ),
760
+            'templates'     => array(
761
+                'subtitle' => '{{id}}',
762
+            ),
763
+        );
764
+
765
+        // Merge the custom fields with those provided by the thing schema.
766
+        $thing_schema            = $this->get_thing_schema();
767
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
768
+
769
+        return $schema;
770
+    }
771
+
772
+    /**
773
+     * Get the 'local business' schema.
774
+     *
775
+     * @return array An array with the schema configuration.
776
+     *
777
+     * @since 3.1.0
778
+     */
779
+    private function get_local_business_schema() {
780
+
781
+        $schema = array(
782
+            'label'         => 'LocalBusiness',
783
+            'description'   => 'A local business.',
784
+            'parents'       => array( 'place', 'organization' ),
785
+            'css_class'     => 'wl-local-business',
786
+            'uri'           => 'http://schema.org/LocalBusiness',
787
+            'same_as'       => array(
788
+                'http://rdf.freebase.com/ns/business/business_location',
789
+                'https://schema.org/Store',
790
+            ),
791
+            'custom_fields' => array(),
792
+            'templates'     => array(
793
+                'subtitle' => '{{id}}',
794
+            ),
795
+        );
796
+
797
+        // Merge the custom fields with those provided by the place and organization schema.
798
+        $place_schema            = $this->get_place_schema();
799
+        $organization_schema     = $this->get_organization_schema();
800
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
801
+
802
+        return $schema;
803
+    }
804 804
 
805 805
 }
Please login to merge, or discard this patch.