Completed
Pull Request — develop (#751)
by David
04:13
created
src/includes/class-wordlift-schema-service.php 2 patches
Indentation   +1285 added lines, -1285 removed lines patch added patch discarded remove patch
@@ -18,1290 +18,1290 @@
 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 'URI' data type name.
246
-	 *
247
-	 * @since 3.1.0
248
-	 */
249
-	const DATA_TYPE_URI = 'uri';
250
-
251
-	/**
252
-	 * The 'date' data type name.
253
-	 *
254
-	 * @since 3.1.0
255
-	 */
256
-	const DATA_TYPE_DATE = 'date';
257
-
258
-	/**
259
-	 * The 'dateTime' data type name.
260
-	 *
261
-	 * @since 3.15.0
262
-	 */
263
-	const DATA_TYPE_DATE_TIME = 'dateTime';
264
-
265
-	/**
266
-	 * The 'time' data type name.
267
-	 *
268
-	 * @since 3.14.0
269
-	 */
270
-	const DATA_TYPE_DURATION = 'duration';
271
-
272
-	/**
273
-	 * The 'double' data type name.
274
-	 *
275
-	 * @since 3.1.0
276
-	 */
277
-	const DATA_TYPE_DOUBLE = 'double';
278
-
279
-	/**
280
-	 * The 'string' data type name.
281
-	 *
282
-	 * @since 3.1.0
283
-	 */
284
-	const DATA_TYPE_STRING = 'string';
285
-
286
-	/**
287
-	 * The multiline text data type name.
288
-	 *
289
-	 * @since 3.14.0
290
-	 */
291
-	const DATA_TYPE_MULTILINE = 'multiline';
292
-
293
-	/**
294
-	 * The 'integer' data type name.
295
-	 *
296
-	 * @since 3.1.0
297
-	 */
298
-	const DATA_TYPE_INTEGER = 'int';
299
-
300
-	/**
301
-	 * The 'boolean' data type name.
302
-	 *
303
-	 * @since 3.1.0
304
-	 */
305
-	const DATA_TYPE_BOOLEAN = 'bool';
306
-
307
-	/**
308
-	 * The schema.org Event type URI.
309
-	 *
310
-	 * @since 3.1.0
311
-	 */
312
-	const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
313
-
314
-	/**
315
-	 * The Schema service singleton instance.
316
-	 *
317
-	 * @since  3.1.0
318
-	 * @access private
319
-	 * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
320
-	 */
321
-	private static $instance;
322
-
323
-	/**
324
-	 * WordLift's schema.
325
-	 *
326
-	 * @since  3.1.0
327
-	 * @access private
328
-	 * @var array $schema WordLift's schema.
329
-	 */
330
-	private $schema;
331
-
332
-	/**
333
-	 * The Log service.
334
-	 *
335
-	 * @since  3.1.0
336
-	 * @access private
337
-	 * @var \Wordlift_Log_Service $log The Log service.
338
-	 */
339
-	private $log;
340
-
341
-	/**
342
-	 * The {@link Wordlift_Post_Property_Storage_Factory} instance.
343
-	 *
344
-	 * @since  3.15.0
345
-	 * @access private
346
-	 * @var \Wordlift_Storage_Factory $storage_factory The {@link Wordlift_Post_Property_Storage_Factory} instance.
347
-	 */
348
-	private $storage_factory;
349
-
350
-	/**
351
-	 * The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
352
-	 *
353
-	 * @since  3.15.0
354
-	 * @access private
355
-	 * @var \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
356
-	 */
357
-	private $rendition_factory;
358
-
359
-	/**
360
-	 * The {@link Wordlift_Configuration_Service} instance.
361
-	 *
362
-	 * @since  3.15.0
363
-	 * @access private
364
-	 * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
365
-	 */
366
-	private $configuration_service;
367
-
368
-	/**
369
-	 * The web site configured language code.
370
-	 *
371
-	 * @since  3.15.0
372
-	 * @access private
373
-	 * @var string $language_code The web site configured language code.
374
-	 */
375
-	private $language_code;
376
-
377
-	/**
378
-	 * Wordlift_Schema_Service constructor.
379
-	 *
380
-	 * @since 3.1.0
381
-	 *
382
-	 * @param \Wordlift_Storage_Factory                $storage_factory       The {@link Wordlift_Post_Property_Storage_Factory} instance.
383
-	 * @param \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory     The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
384
-	 * @param \Wordlift_Configuration_Service          $configuration_service The {@link Wordlift_Configuration_Service} instance.
385
-	 */
386
-	public function __construct( $storage_factory, $rendition_factory, $configuration_service ) {
387
-
388
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
389
-
390
-		$this->storage_factory       = $storage_factory;
391
-		$this->rendition_factory     = $rendition_factory;
392
-		$this->configuration_service = $configuration_service;
393
-		$this->language_code         = $this->configuration_service->get_language_code();
394
-
395
-		// Set the taxonomy data.
396
-		// Note: parent types must be defined before child types.
397
-		$this->schema = array(
398
-			'article'       => $this->get_article_schema(),
399
-			'thing'         => $this->get_thing_schema(),
400
-			'creative-work' => $this->get_creative_work_schema(),
401
-			'event'         => $this->get_event_schema(),
402
-			'organization'  => $this->get_organization_schema(),
403
-			'person'        => $this->get_person_schema(),
404
-			'place'         => $this->get_place_schema(),
405
-			'localbusiness' => $this->get_local_business_schema(),
406
-			'recipe'        => $this->get_recipe_schema(),
407
-		);
408
-
409
-		// Create a singleton instance of the Schema service, useful to provide static functions to global functions.
410
-		self::$instance = $this;
411
-
412
-	}
413
-
414
-	/**
415
-	 * Get a reference to the Schema service.
416
-	 *
417
-	 * @since 3.1.0
418
-	 *
419
-	 * @return Wordlift_Schema_Service A reference to the Schema service.
420
-	 */
421
-	public static function get_instance() {
422
-
423
-		return self::$instance;
424
-	}
425
-
426
-	/**
427
-	 * Get the properties for a field with the specified key. The key is used as
428
-	 * meta key when the field's value is stored in WordPress meta data table.
429
-	 *
430
-	 * @since 3.6.0
431
-	 *
432
-	 * @param string $key The field's key.
433
-	 *
434
-	 * @return null|array An array of field's properties or null if the field is not found.
435
-	 */
436
-	public function get_field( $key ) {
437
-
438
-		// Parse each schema's fields until we find the one we're looking for, then
439
-		// return its properties.
440
-		foreach ( $this->schema as $_ => $schema ) {
441
-
442
-			if ( ! isset( $schema['custom_fields'] ) ) {
443
-				break;
444
-			}
445
-
446
-			foreach ( $schema['custom_fields'] as $field => $props ) {
447
-				if ( $key === $field ) {
448
-					return $props;
449
-				}
450
-			}
451
-		}
452
-
453
-		return null;
454
-	}
455
-
456
-	/**
457
-	 * Get the WordLift's schema.
458
-	 *
459
-	 * @param string $name The schema name.
460
-	 *
461
-	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
462
-	 *
463
-	 * @since 3.1.0
464
-	 */
465
-	public function get_schema( $name ) {
466
-		// Check if the schema exists and, if not, return NULL.
467
-		if ( ! isset( $this->schema[ $name ] ) ) {
468
-			return null;
469
-		}
470
-
471
-		// Return the requested schema.
472
-		return $this->schema[ $name ];
473
-	}
474
-
475
-	/**
476
-	 * Get the WordLift's schema trough schema type uri.
477
-	 *
478
-	 * @param string $uri The schema uri.
479
-	 *
480
-	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
481
-	 *
482
-	 * @since 3.3.0
483
-	 */
484
-	public function get_schema_by_uri( $uri ) {
485
-
486
-		foreach ( $this->schema as $name => $schema ) {
487
-			if ( $schema['uri'] === $uri ) {
488
-				return $schema;
489
-			}
490
-		}
491
-
492
-		return null;
493
-	}
494
-
495
-	/**
496
-	 * Get the 'thing' schema.
497
-	 *
498
-	 * @return array An array with the schema configuration.
499
-	 *
500
-	 * @since 3.1.0
501
-	 */
502
-	private function get_thing_schema() {
503
-
504
-		return array(
505
-			'css_class'     => 'wl-thing',
506
-			'uri'           => 'http://schema.org/Thing',
507
-			'same_as'       => array( '*' ),
508
-			// set as default.
509
-			'custom_fields' => array(
510
-				self::FIELD_SAME_AS                            => array(
511
-					'predicate'   => 'http://schema.org/sameAs',
512
-					'type'        => self::DATA_TYPE_URI,
513
-					'export_type' => 'http://schema.org/Thing',
514
-					'constraints' => array(
515
-						'cardinality' => INF,
516
-					),
517
-					// We need a custom metabox.
518
-					'input_field' => 'sameas',
519
-				),
520
-				// Add the schema:url property.
521
-				Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
522
-																									  ->get_compat_definition(),
523
-			),
524
-			// {{sameAs}} not present in the microdata template,
525
-			// because it is treated separately in *wl_content_embed_item_microdata*
526
-			'templates'     => array(
527
-				'subtitle' => '{{id}}',
528
-			),
529
-			'linked_data'   => array(
530
-				// ### Title to rdfs:label.
531
-				$this->rendition_factory->create(
532
-					$this->storage_factory->post_title(),
533
-					Wordlift_Query_Builder::RDFS_LABEL_URI,
534
-					null,
535
-					$this->language_code
536
-				),
537
-				// ### Title to dct:title.
538
-				$this->rendition_factory->create(
539
-					$this->storage_factory->post_title(),
540
-					'http://purl.org/dc/terms/title',
541
-					null,
542
-					$this->language_code
543
-				),
544
-				// ### Alternative title to rdfs:label.
545
-				$this->rendition_factory->create(
546
-					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
547
-					Wordlift_Query_Builder::RDFS_LABEL_URI,
548
-					null,
549
-					$this->language_code
550
-				),
551
-				// ### Alternative title to dct:title.
552
-				$this->rendition_factory->create(
553
-					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
554
-					'http://purl.org/dc/terms/title',
555
-					null,
556
-					$this->language_code
557
-				),
558
-				// ### schema:url.
559
-				$this->rendition_factory->create(
560
-					$this->storage_factory->url_property(),
561
-					Wordlift_Query_Builder::SCHEMA_URL_URI,
562
-					self::DATA_TYPE_URI
563
-				),
564
-				// ### schema:description.
565
-				$this->rendition_factory->create(
566
-					$this->storage_factory->post_description_no_tags_no_shortcodes(),
567
-					'http://schema.org/description',
568
-					null,
569
-					$this->language_code
570
-				),
571
-				// ### owl:sameAs.
572
-				$this->rendition_factory->create(
573
-					$this->storage_factory->post_meta( self::FIELD_SAME_AS ),
574
-					'http://www.w3.org/2002/07/owl#sameAs',
575
-					self::DATA_TYPE_URI
576
-				),
577
-				// ### rdf:type.
578
-				$this->rendition_factory->create(
579
-					$this->storage_factory->schema_class( $this ),
580
-					Wordlift_Query_Builder::RDFS_TYPE_URI,
581
-					self::DATA_TYPE_URI
582
-				),
583
-				// ### schema:image.
584
-				$this->rendition_factory->create(
585
-					$this->storage_factory->post_images(),
586
-					Wordlift_Query_Builder::SCHEMA_IMAGE_URI,
587
-					self::DATA_TYPE_URI
588
-				),
589
-				// ### dct:relation.
590
-				$this->rendition_factory->create(
591
-					$this->storage_factory->relations(),
592
-					Wordlift_Query_Builder::DCTERMS_RELATION_URI,
593
-					self::DATA_TYPE_URI
594
-				),
595
-			),
596
-		);
597
-
598
-	}
599
-
600
-	/**
601
-	 * Get the 'creative work' schema.
602
-	 *
603
-	 * @return array An array with the schema configuration.
604
-	 *
605
-	 * @since 3.1.0
606
-	 */
607
-	private function get_creative_work_schema() {
608
-
609
-		$schema = array(
610
-			'label'         => 'CreativeWork',
611
-			'description'   => 'A creative work (or a Music Album).',
612
-			'parents'       => array( 'thing' ),
613
-			// Give term slug as parent.
614
-			'css_class'     => 'wl-creative-work',
615
-			'uri'           => 'http://schema.org/CreativeWork',
616
-			'same_as'       => array(
617
-				'http://schema.org/MusicAlbum',
618
-				'http://schema.org/Product',
619
-			),
620
-			'custom_fields' => array(
621
-				self::FIELD_AUTHOR => array(
622
-					'predicate'   => 'http://schema.org/author',
623
-					'type'        => self::DATA_TYPE_URI,
624
-					'export_type' => 'http://schema.org/Person',
625
-					'constraints' => array(
626
-						'uri_type'    => array( 'Person', 'Organization' ),
627
-						'cardinality' => INF,
628
-					),
629
-				),
630
-			),
631
-			'linked_data'   => array(
632
-				// ### schema:author.
633
-				$this->rendition_factory->create(
634
-					$this->storage_factory->author_uri(),
635
-					Wordlift_Query_Builder::SCHEMA_AUTHOR_URI,
636
-					self::DATA_TYPE_URI
637
-				),
638
-			),
639
-			'templates'     => array(
640
-				'subtitle' => '{{id}}',
641
-			),
642
-		);
643
-
644
-		// Merge the custom fields with those provided by the thing schema.
645
-		$parent_schema           = $this->get_thing_schema();
646
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
647
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
648
-
649
-		return $schema;
650
-	}
651
-
652
-	/**
653
-	 * Get the 'event' schema.
654
-	 *
655
-	 * @return array An array with the schema configuration.
656
-	 *
657
-	 * @since 3.1.0
658
-	 */
659
-	private function get_event_schema() {
660
-
661
-		$schema = array(
662
-			'label'         => 'Event',
663
-			'description'   => 'An event . ',
664
-			'parents'       => array( 'thing' ),
665
-			'css_class'     => 'wl-event',
666
-			'uri'           => self::SCHEMA_EVENT_TYPE,
667
-			'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
668
-			'custom_fields' => array(
669
-				self::FIELD_DATE_START => array(
670
-					'predicate'   => 'http://schema.org/startDate',
671
-					'type'        => self::DATA_TYPE_DATE,
672
-					'export_type' => 'xsd:dateTime',
673
-					'constraints' => '',
674
-				),
675
-				self::FIELD_DATE_END   => array(
676
-					'predicate'   => 'http://schema.org/endDate',
677
-					'type'        => self::DATA_TYPE_DATE,
678
-					'export_type' => 'xsd:dateTime',
679
-					'constraints' => '',
680
-				),
681
-				self::FIELD_LOCATION   => array(
682
-					'predicate'   => 'http://schema.org/location',
683
-					'type'        => self::DATA_TYPE_URI,
684
-					'export_type' => 'http://schema.org/PostalAddress',
685
-					'constraints' => array(
686
-						'uri_type'    => array( 'Place', 'LocalBusiness' ),
687
-						'cardinality' => INF,
688
-					),
689
-				),
690
-			),
691
-			'linked_data'   => array(
692
-				// ### schema:startDate.
693
-				$this->rendition_factory->create(
694
-					$this->storage_factory->post_meta( self::FIELD_DATE_START ),
695
-					'http://schema.org/startDate',
696
-					self::DATA_TYPE_DATE_TIME
697
-				),
698
-				// ### schema:endDate.
699
-				$this->rendition_factory->create(
700
-					$this->storage_factory->post_meta( self::FIELD_DATE_END ),
701
-					'http://schema.org/endDate',
702
-					self::DATA_TYPE_DATE_TIME
703
-				),
704
-				// ### schema:location.
705
-				$this->rendition_factory->create(
706
-					$this->storage_factory->post_meta_to_uri( self::FIELD_LOCATION ),
707
-					'http://schema.org/location',
708
-					self::DATA_TYPE_URI
709
-				),
710
-			),
711
-			'templates'     => array(
712
-				'subtitle' => '{{id}}',
713
-			),
714
-		);
715
-
716
-		// Merge the custom fields with those provided by the thing schema.
717
-		$parent_schema           = $this->get_thing_schema();
718
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
719
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
720
-
721
-		return $schema;
722
-	}
723
-
724
-	/**
725
-	 * Get the 'organization' schema.
726
-	 *
727
-	 * @return array An array with the schema configuration.
728
-	 *
729
-	 * @since 3.1.0
730
-	 */
731
-	private function get_organization_schema() {
732
-
733
-		$schema = array(
734
-			'label'         => 'Organization',
735
-			'description'   => 'An organization, including a government or a newspaper.',
736
-			'parents'       => array( 'thing' ),
737
-			'css_class'     => 'wl-organization',
738
-			'uri'           => 'http://schema.org/Organization',
739
-			'same_as'       => array(
740
-				'http://rdf.freebase.com/ns/organization.organization',
741
-				'http://rdf.freebase.com/ns/government.government',
742
-				'http://schema.org/Newspaper',
743
-			),
744
-			'custom_fields' => array(
745
-				self::FIELD_LEGAL_NAME          => array(
746
-					'predicate'   => 'http://schema.org/legalName',
747
-					'type'        => self::DATA_TYPE_STRING,
748
-					'export_type' => 'xsd:string',
749
-					'constraints' => '',
750
-				),
751
-				self::FIELD_FOUNDER             => array(
752
-					'predicate'   => 'http://schema.org/founder',
753
-					'type'        => self::DATA_TYPE_URI,
754
-					'export_type' => 'http://schema.org/Person',
755
-					'constraints' => array(
756
-						'uri_type'    => 'Person',
757
-						'cardinality' => INF,
758
-					),
759
-				),
760
-				self::FIELD_ADDRESS             => array(
761
-					'predicate'   => 'http://schema.org/streetAddress',
762
-					'type'        => self::DATA_TYPE_STRING,
763
-					'export_type' => 'xsd:string',
764
-					'constraints' => '',
765
-					// To build custom metabox.
766
-					'input_field' => 'address',
767
-				),
768
-				self::FIELD_ADDRESS_PO_BOX      => array(
769
-					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
770
-					'type'        => self::DATA_TYPE_STRING,
771
-					'export_type' => 'xsd:string',
772
-					'constraints' => '',
773
-					// To build custom metabox.
774
-					'input_field' => 'address',
775
-				),
776
-				self::FIELD_ADDRESS_POSTAL_CODE => array(
777
-					'predicate'   => 'http://schema.org/postalCode',
778
-					'type'        => self::DATA_TYPE_STRING,
779
-					'export_type' => 'xsd:string',
780
-					'constraints' => '',
781
-					// To build custom metabox.
782
-					'input_field' => 'address',
783
-				),
784
-				self::FIELD_ADDRESS_LOCALITY    => array(
785
-					'predicate'   => 'http://schema.org/addressLocality',
786
-					'type'        => self::DATA_TYPE_STRING,
787
-					'export_type' => 'xsd:string',
788
-					'constraints' => '',
789
-					// To build custom metabox.
790
-					'input_field' => 'address',
791
-				),
792
-				self::FIELD_ADDRESS_REGION      => array(
793
-					'predicate'   => 'http://schema.org/addressRegion',
794
-					'type'        => self::DATA_TYPE_STRING,
795
-					'export_type' => 'xsd:string',
796
-					'constraints' => '',
797
-					// To build custom metabox.
798
-					'input_field' => 'address',
799
-				),
800
-				self::FIELD_ADDRESS_COUNTRY     => array(
801
-					'predicate'   => 'http://schema.org/addressCountry',
802
-					'type'        => self::DATA_TYPE_STRING,
803
-					'export_type' => 'xsd:string',
804
-					'constraints' => '',
805
-					// To build custom metabox.
806
-					'input_field' => 'address',
807
-				),
808
-				self::FIELD_EMAIL               => array(
809
-					'predicate'   => 'http://schema.org/email',
810
-					'type'        => self::DATA_TYPE_STRING,
811
-					'export_type' => 'xsd:string',
812
-					'constraints' => '',
813
-				),
814
-				self::FIELD_TELEPHONE           => array(
815
-					'predicate'   => 'http://schema.org/telephone',
816
-					'type'        => self::DATA_TYPE_STRING,
817
-					'export_type' => 'xsd:string',
818
-					'constraints' => '',
819
-				),
820
-			),
821
-			'linked_data'   => array(
822
-				// ### schema:legalName.
823
-				$this->rendition_factory->create(
824
-					$this->storage_factory->post_meta( self::FIELD_LEGAL_NAME ),
825
-					'http://schema.org/legalName'
826
-				),
827
-				// ### schema:founder.
828
-				$this->rendition_factory->create(
829
-					$this->storage_factory->post_meta_to_uri( self::FIELD_FOUNDER ),
830
-					'http://schema.org/founder',
831
-					self::DATA_TYPE_URI
832
-				),
833
-				// ### schema:email.
834
-				$this->rendition_factory->create(
835
-					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
836
-					'http://schema.org/email'
837
-				),
838
-				// ### schema:telephone.
839
-				$this->rendition_factory->create(
840
-					$this->storage_factory->post_meta( self::FIELD_TELEPHONE ),
841
-					'http://schema.org/telephone'
842
-				),
843
-			),
844
-			'templates'     => array(
845
-				'subtitle' => '{{id}}',
846
-			),
847
-		);
848
-
849
-		// Merge the custom fields with those provided by the thing schema.
850
-		$parent_schema           = $this->get_thing_schema();
851
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
852
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
853
-
854
-		return $schema;
855
-	}
856
-
857
-	/**
858
-	 * Get the 'person' schema.
859
-	 *
860
-	 * @return array An array with the schema configuration.
861
-	 *
862
-	 * @since 3.1.0
863
-	 */
864
-	private function get_person_schema() {
865
-
866
-		$schema = array(
867
-			'label'         => 'Person',
868
-			'description'   => 'A person (or a music artist).',
869
-			'parents'       => array( 'thing' ),
870
-			'css_class'     => 'wl-person',
871
-			'uri'           => 'http://schema.org/Person',
872
-			'same_as'       => array(
873
-				'http://rdf.freebase.com/ns/people.person',
874
-				'http://rdf.freebase.com/ns/music.artist',
875
-				'http://dbpedia.org/class/yago/LivingPeople',
876
-			),
877
-			'custom_fields' => array(
878
-				self::FIELD_KNOWS       => array(
879
-					'predicate'   => 'http://schema.org/knows',
880
-					'type'        => self::DATA_TYPE_URI,
881
-					'export_type' => 'http://schema.org/Person',
882
-					'constraints' => array(
883
-						'uri_type'    => 'Person',
884
-						'cardinality' => INF,
885
-					),
886
-				),
887
-				self::FIELD_BIRTH_DATE  => array(
888
-					'predicate'   => 'http://schema.org/birthDate',
889
-					'type'        => self::DATA_TYPE_DATE,
890
-					'export_type' => 'xsd:date',
891
-					'constraints' => '',
892
-				),
893
-				self::FIELD_BIRTH_PLACE => array(
894
-					'predicate'   => 'http://schema.org/birthPlace',
895
-					'type'        => self::DATA_TYPE_URI,
896
-					'export_type' => 'http://schema.org/Place',
897
-					'constraints' => array(
898
-						'uri_type' => 'Place',
899
-					),
900
-				),
901
-				self::FIELD_AFFILIATION => array(
902
-					'predicate'   => 'http://schema.org/affiliation',
903
-					'type'        => self::DATA_TYPE_URI,
904
-					'export_type' => 'http://schema.org/Organization',
905
-					'constraints' => array(
906
-						'uri_type'    => array(
907
-							'Organization',
908
-							'LocalBusiness',
909
-						),
910
-						'cardinality' => INF,
911
-					),
912
-				),
913
-				self::FIELD_EMAIL       => array(
914
-					'predicate'   => 'http://schema.org/email',
915
-					'type'        => self::DATA_TYPE_STRING,
916
-					'export_type' => 'xsd:string',
917
-					'constraints' => array(
918
-						'cardinality' => INF,
919
-					),
920
-				),
921
-			),
922
-			'linked_data'   => array(
923
-				// ### schema:knows.
924
-				$this->rendition_factory->create(
925
-					$this->storage_factory->post_meta_to_uri( self::FIELD_KNOWS ),
926
-					'http://schema.org/knows',
927
-					self::DATA_TYPE_URI
928
-				),
929
-				// ### schema:birthDate.
930
-				$this->rendition_factory->create(
931
-					$this->storage_factory->post_meta( self::FIELD_BIRTH_DATE ),
932
-					'http://schema.org/birthDate',
933
-					self::DATA_TYPE_DATE
934
-				),
935
-				// ### schema:birthPlace.
936
-				$this->rendition_factory->create(
937
-					$this->storage_factory->post_meta_to_uri( self::FIELD_BIRTH_PLACE ),
938
-					'http://schema.org/birthPlace',
939
-					self::DATA_TYPE_URI
940
-				),
941
-				// ### schema:affiliation.
942
-				$this->rendition_factory->create(
943
-					$this->storage_factory->post_meta_to_uri( self::FIELD_AFFILIATION ),
944
-					'http://schema.org/affiliation',
945
-					self::DATA_TYPE_URI
946
-				),
947
-				// ### schema:email.
948
-				$this->rendition_factory->create(
949
-					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
950
-					'http://schema.org/email'
951
-				),
952
-			),
953
-			'templates'     => array(
954
-				'subtitle' => '{{id}}',
955
-			),
956
-		);
957
-
958
-		// Merge the custom fields with those provided by the thing schema.
959
-		$parent_schema           = $this->get_thing_schema();
960
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
961
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
962
-
963
-		return $schema;
964
-
965
-	}
966
-
967
-	/**
968
-	 * Get the 'place' schema.
969
-	 *
970
-	 * @return array An array with the schema configuration.
971
-	 *
972
-	 * @since 3.1.0
973
-	 */
974
-	private function get_place_schema() {
975
-
976
-		$schema = array(
977
-			'label'         => 'Place',
978
-			'description'   => 'A place.',
979
-			'parents'       => array( 'thing' ),
980
-			'css_class'     => 'wl-place',
981
-			'uri'           => 'http://schema.org/Place',
982
-			'same_as'       => array(
983
-				'http://rdf.freebase.com/ns/location.location',
984
-				'http://www.opengis.net/gml/_Feature',
985
-			),
986
-			'custom_fields' => array(
987
-				self::FIELD_GEO_LATITUDE        => array(
988
-					'predicate'   => 'http://schema.org/latitude',
989
-					'type'        => self::DATA_TYPE_DOUBLE,
990
-					'export_type' => 'xsd:double',
991
-					'constraints' => '',
992
-					// To build custom metabox.
993
-					'input_field' => 'coordinates',
994
-				),
995
-				self::FIELD_GEO_LONGITUDE       => array(
996
-					'predicate'   => 'http://schema.org/longitude',
997
-					'type'        => self::DATA_TYPE_DOUBLE,
998
-					'export_type' => 'xsd:double',
999
-					'constraints' => '',
1000
-					// To build custom metabox.
1001
-					'input_field' => 'coordinates',
1002
-				),
1003
-				self::FIELD_ADDRESS             => array(
1004
-					'predicate'   => 'http://schema.org/streetAddress',
1005
-					'type'        => self::DATA_TYPE_STRING,
1006
-					'export_type' => 'xsd:string',
1007
-					'constraints' => '',
1008
-					// To build custom metabox.
1009
-					'input_field' => 'address',
1010
-				),
1011
-				self::FIELD_ADDRESS_PO_BOX      => array(
1012
-					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
1013
-					'type'        => self::DATA_TYPE_STRING,
1014
-					'export_type' => 'xsd:string',
1015
-					'constraints' => '',
1016
-					// To build custom metabox.
1017
-					'input_field' => 'address',
1018
-				),
1019
-				self::FIELD_ADDRESS_POSTAL_CODE => array(
1020
-					'predicate'   => 'http://schema.org/postalCode',
1021
-					'type'        => self::DATA_TYPE_STRING,
1022
-					'export_type' => 'xsd:string',
1023
-					'constraints' => '',
1024
-					// To build custom metabox.
1025
-					'input_field' => 'address',
1026
-				),
1027
-				self::FIELD_ADDRESS_LOCALITY    => array(
1028
-					'predicate'   => 'http://schema.org/addressLocality',
1029
-					'type'        => self::DATA_TYPE_STRING,
1030
-					'export_type' => 'xsd:string',
1031
-					'constraints' => '',
1032
-					// To build custom metabox.
1033
-					'input_field' => 'address',
1034
-				),
1035
-				self::FIELD_ADDRESS_REGION      => array(
1036
-					'predicate'   => 'http://schema.org/addressRegion',
1037
-					'type'        => self::DATA_TYPE_STRING,
1038
-					'export_type' => 'xsd:string',
1039
-					'constraints' => '',
1040
-					// To build custom metabox.
1041
-					'input_field' => 'address',
1042
-				),
1043
-				self::FIELD_ADDRESS_COUNTRY     => array(
1044
-					'predicate'   => 'http://schema.org/addressCountry',
1045
-					'type'        => self::DATA_TYPE_STRING,
1046
-					'export_type' => 'xsd:string',
1047
-					'constraints' => '',
1048
-					// To build custom metabox.
1049
-					'input_field' => 'address',
1050
-				),
1051
-			),
1052
-			'linked_data'   => array(),
1053
-			'templates'     => array(
1054
-				'subtitle' => '{{id}}',
1055
-			),
1056
-		);
1057
-
1058
-		// Merge the custom fields with those provided by the thing schema.
1059
-		$parent_schema           = $this->get_thing_schema();
1060
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1061
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1062
-
1063
-		return $schema;
1064
-	}
1065
-
1066
-	/**
1067
-	 * Get the 'local business' schema.
1068
-	 *
1069
-	 * @return array An array with the schema configuration.
1070
-	 *
1071
-	 * @since 3.1.0
1072
-	 */
1073
-	private function get_local_business_schema() {
1074
-
1075
-		$schema = array(
1076
-			'label'         => 'LocalBusiness',
1077
-			'description'   => 'A local business.',
1078
-			'parents'       => array( 'place', 'organization' ),
1079
-			'css_class'     => 'wl-local-business',
1080
-			'uri'           => 'http://schema.org/LocalBusiness',
1081
-			'same_as'       => array(
1082
-				'http://rdf.freebase.com/ns/business/business_location',
1083
-				'https://schema.org/Store',
1084
-			),
1085
-			'custom_fields' => array(),
1086
-			'linked_data'   => array(),
1087
-			'templates'     => array(
1088
-				'subtitle' => '{{id}}',
1089
-			),
1090
-		);
1091
-
1092
-		// Merge the custom fields with those provided by the place and organization schema.
1093
-		$place_schema            = $this->get_place_schema();
1094
-		$organization_schema     = $this->get_organization_schema();
1095
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
1096
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $place_schema['linked_data'], $organization_schema['linked_data'] );
1097
-
1098
-		return $schema;
1099
-	}
1100
-
1101
-	/**
1102
-	 * Get the 'recipe' schema.
1103
-	 *
1104
-	 * @return array An array with the schema configuration.
1105
-	 *
1106
-	 * @since 3.14.0
1107
-	 */
1108
-	private function get_recipe_schema() {
1109
-
1110
-		$schema = array(
1111
-			'label'         => 'Recipe',
1112
-			'description'   => 'A Recipe.',
1113
-			'parents'       => array( 'CreativeWork' ),
1114
-			'css_class'     => 'wl-recipe',
1115
-			'uri'           => 'http://schema.org/Recipe',
1116
-			'same_as'       => array(),
1117
-			'templates'     => array(
1118
-				'subtitle' => '{{id}}',
1119
-			),
1120
-			'custom_fields' => array(
1121
-				self::FIELD_RECIPE_CUISINE          => array(
1122
-					'predicate'   => 'http://schema.org/recipeCuisine',
1123
-					'type'        => self::DATA_TYPE_STRING,
1124
-					'export_type' => 'xsd:string',
1125
-					'constraints' => '',
1126
-					'metabox'     => array(
1127
-						'label' => __( 'Recipe cuisine', 'wordlift' ),
1128
-					),
1129
-				),
1130
-				self::FIELD_RECIPE_INGREDIENT       => array(
1131
-					'predicate'   => 'http://schema.org/recipeIngredient',
1132
-					'type'        => self::DATA_TYPE_STRING,
1133
-					'export_type' => 'xsd:string',
1134
-					'constraints' => array(
1135
-						'cardinality' => INF,
1136
-					),
1137
-					'metabox'     => array(
1138
-						'label' => __( 'Recipe ingredient', 'wordlift' ),
1139
-					),
1140
-				),
1141
-				self::FIELD_RECIPE_INSTRUCTIONS     => array(
1142
-					'predicate'   => 'http://schema.org/recipeInstructions',
1143
-					'type'        => self::DATA_TYPE_MULTILINE,
1144
-					'export_type' => 'xsd:string',
1145
-					'constraints' => '',
1146
-					'metabox'     => array(
1147
-						'class' => 'Wordlift_Metabox_Field_Multiline',
1148
-						'label' => __( 'Recipe instructions', 'wordlift' ),
1149
-					),
1150
-				),
1151
-				self::FIELD_RECIPE_YIELD            => array(
1152
-					'predicate'   => 'http://schema.org/recipeYield',
1153
-					'type'        => self::DATA_TYPE_STRING,
1154
-					'export_type' => 'xsd:string',
1155
-					'constraints' => '',
1156
-					'metabox'     => array(
1157
-						'label' => __( 'Recipe number of servings', 'wordlift' ),
1158
-					),
1159
-				),
1160
-				self::FIELD_RECIPE_INGREDIENT       => array(
1161
-					'predicate'   => 'http://schema.org/recipeIngredient',
1162
-					'type'        => self::DATA_TYPE_STRING,
1163
-					'export_type' => 'xsd:string',
1164
-					'constraints' => array(
1165
-						'cardinality' => INF,
1166
-					),
1167
-					'metabox'     => array(
1168
-						'label' => __( 'Recipe ingredient', 'wordlift' ),
1169
-					),
1170
-				),
1171
-				self::FIELD_NUTRITION_INFO_CALORIES => array(
1172
-					'predicate'   => 'http://schema.org/calories',
1173
-					'type'        => self::DATA_TYPE_STRING,
1174
-					'export_type' => 'xsd:string',
1175
-					'constraints' => '',
1176
-					'metabox'     => array(
1177
-						'label' => __( 'Calories (e.g. 240 calories)', 'wordlift' ),
1178
-					),
1179
-				),
1180
-				self::FIELD_PREP_TIME               => array(
1181
-					'predicate'   => 'http://schema.org/prepTime',
1182
-					'type'        => self::DATA_TYPE_DURATION,
1183
-					'export_type' => 'xsd:time',
1184
-					'constraints' => '',
1185
-					'metabox'     => array(
1186
-						'class' => 'Wordlift_Metabox_Field_Duration',
1187
-						'label' => __( 'Recipe preparation time (e.g. 1:30)', 'wordlift' ),
1188
-					),
1189
-				),
1190
-				self::FIELD_COOK_TIME               => array(
1191
-					'predicate'   => 'http://schema.org/cookTime',
1192
-					'type'        => self::DATA_TYPE_DURATION,
1193
-					'export_type' => 'xsd:time',
1194
-					'constraints' => '',
1195
-					'metabox'     => array(
1196
-						'class' => 'Wordlift_Metabox_Field_Duration',
1197
-						'label' => __( 'Recipe cook time (e.g. 1:30)', 'wordlift' ),
1198
-					),
1199
-				),
1200
-				self::FIELD_TOTAL_TIME              => array(
1201
-					'predicate'   => 'http://schema.org/totalTime',
1202
-					'type'        => self::DATA_TYPE_DURATION,
1203
-					'export_type' => 'xsd:time',
1204
-					'constraints' => '',
1205
-					'metabox'     => array(
1206
-						'class' => 'Wordlift_Metabox_Field_Duration',
1207
-						'label' => __( 'Recipe total time (e.g. 1:30)', 'wordlift' ),
1208
-					),
1209
-				),
1210
-			),
1211
-			'linked_data'   => array(
1212
-				// ### schema:recipeCuisine.
1213
-				$this->rendition_factory->create(
1214
-					$this->storage_factory->post_meta( self::FIELD_RECIPE_CUISINE ),
1215
-					'http://schema.org/recipeCuisine'
1216
-				),
1217
-				// ### schema:recipeIngredient.
1218
-				$this->rendition_factory->create(
1219
-					$this->storage_factory->post_meta( self::FIELD_RECIPE_INGREDIENT ),
1220
-					'http://schema.org/recipeIngredient'
1221
-				),
1222
-				// ### schema:prepTime.
1223
-				$this->rendition_factory->create(
1224
-					$this->storage_factory->post_meta( self::FIELD_PREP_TIME ),
1225
-					'http://schema.org/prepTime',
1226
-					self::DATA_TYPE_DURATION
1227
-				),
1228
-				// ### schema:cookTime.
1229
-				$this->rendition_factory->create(
1230
-					$this->storage_factory->post_meta( self::FIELD_COOK_TIME ),
1231
-					'http://schema.org/cookTime',
1232
-					self::DATA_TYPE_DURATION
1233
-				),
1234
-				// ### schema:totalTime.
1235
-				$this->rendition_factory->create(
1236
-					$this->storage_factory->post_meta( self::FIELD_TOTAL_TIME ),
1237
-					'http://schema.org/totalTime',
1238
-					self::DATA_TYPE_DURATION
1239
-				),
1240
-			),
1241
-		);
1242
-
1243
-		// Merge the custom fields with those provided by the parent schema.
1244
-		$parent_schema           = $this->get_creative_work_schema();
1245
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1246
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1247
-
1248
-		return $schema;
1249
-	}
1250
-
1251
-	/**
1252
-	 * Get the 'article' schema.
1253
-	 *
1254
-	 * @return array An array with the schema configuration.
1255
-	 *
1256
-	 * @since 3.15.0
1257
-	 */
1258
-	private function get_article_schema() {
1259
-
1260
-		$schema = array(
1261
-			'label'         => 'Article',
1262
-			'description'   => 'An Article.',
1263
-			'parents'       => array(),
1264
-			'css_class'     => 'wl-article',
1265
-			'uri'           => 'http://schema.org/Article',
1266
-			'same_as'       => array(),
1267
-			'templates'     => array(
1268
-				'subtitle' => '{{id}}',
1269
-			),
1270
-			'custom_fields' => array(),
1271
-			'linked_data'   => array(),
1272
-		);
1273
-
1274
-		return $schema;
1275
-	}
1276
-
1277
-	/**
1278
-	 * Get all the predicates.
1279
-	 *
1280
-	 * @since 3.15.0
1281
-	 *
1282
-	 * @return array An array of predicates.
1283
-	 */
1284
-	public function get_all_predicates() {
1285
-
1286
-		// Get the custom fields.
1287
-		$renditions = array_reduce( $this->schema, function ( $carry, $item ) {
1288
-			return array_merge( $carry, $item['linked_data'] );
1289
-		}, array() );
1290
-
1291
-		// Create a new array of predicates from the custom fields. The initial
1292
-		// array contains just the `http://www.w3.org/1999/02/22-rdf-syntax-ns#type`
1293
-		// (a, rdf:type) predicate (use the full URI).
1294
-		$predicates = array_unique( array_reduce( $renditions, function ( $carry, $item ) {
1295
-			return array_merge( $carry, (array) $item->get_predicate() );
1296
-		}, array() ) );
1297
-
1298
-		/**
1299
-		 * Filter: 'wl_schema_predicates' - Allow third parties to hook and add additional predicates.
1300
-		 *
1301
-		 * @since  3.17.0
1302
-		 * @api arr $predicates Schema.org predicates.
1303
-		 */
1304
-		return apply_filters( 'wl_schema_predicates', $predicates );
1305
-	}
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 'URI' data type name.
246
+     *
247
+     * @since 3.1.0
248
+     */
249
+    const DATA_TYPE_URI = 'uri';
250
+
251
+    /**
252
+     * The 'date' data type name.
253
+     *
254
+     * @since 3.1.0
255
+     */
256
+    const DATA_TYPE_DATE = 'date';
257
+
258
+    /**
259
+     * The 'dateTime' data type name.
260
+     *
261
+     * @since 3.15.0
262
+     */
263
+    const DATA_TYPE_DATE_TIME = 'dateTime';
264
+
265
+    /**
266
+     * The 'time' data type name.
267
+     *
268
+     * @since 3.14.0
269
+     */
270
+    const DATA_TYPE_DURATION = 'duration';
271
+
272
+    /**
273
+     * The 'double' data type name.
274
+     *
275
+     * @since 3.1.0
276
+     */
277
+    const DATA_TYPE_DOUBLE = 'double';
278
+
279
+    /**
280
+     * The 'string' data type name.
281
+     *
282
+     * @since 3.1.0
283
+     */
284
+    const DATA_TYPE_STRING = 'string';
285
+
286
+    /**
287
+     * The multiline text data type name.
288
+     *
289
+     * @since 3.14.0
290
+     */
291
+    const DATA_TYPE_MULTILINE = 'multiline';
292
+
293
+    /**
294
+     * The 'integer' data type name.
295
+     *
296
+     * @since 3.1.0
297
+     */
298
+    const DATA_TYPE_INTEGER = 'int';
299
+
300
+    /**
301
+     * The 'boolean' data type name.
302
+     *
303
+     * @since 3.1.0
304
+     */
305
+    const DATA_TYPE_BOOLEAN = 'bool';
306
+
307
+    /**
308
+     * The schema.org Event type URI.
309
+     *
310
+     * @since 3.1.0
311
+     */
312
+    const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
313
+
314
+    /**
315
+     * The Schema service singleton instance.
316
+     *
317
+     * @since  3.1.0
318
+     * @access private
319
+     * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
320
+     */
321
+    private static $instance;
322
+
323
+    /**
324
+     * WordLift's schema.
325
+     *
326
+     * @since  3.1.0
327
+     * @access private
328
+     * @var array $schema WordLift's schema.
329
+     */
330
+    private $schema;
331
+
332
+    /**
333
+     * The Log service.
334
+     *
335
+     * @since  3.1.0
336
+     * @access private
337
+     * @var \Wordlift_Log_Service $log The Log service.
338
+     */
339
+    private $log;
340
+
341
+    /**
342
+     * The {@link Wordlift_Post_Property_Storage_Factory} instance.
343
+     *
344
+     * @since  3.15.0
345
+     * @access private
346
+     * @var \Wordlift_Storage_Factory $storage_factory The {@link Wordlift_Post_Property_Storage_Factory} instance.
347
+     */
348
+    private $storage_factory;
349
+
350
+    /**
351
+     * The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
352
+     *
353
+     * @since  3.15.0
354
+     * @access private
355
+     * @var \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
356
+     */
357
+    private $rendition_factory;
358
+
359
+    /**
360
+     * The {@link Wordlift_Configuration_Service} instance.
361
+     *
362
+     * @since  3.15.0
363
+     * @access private
364
+     * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
365
+     */
366
+    private $configuration_service;
367
+
368
+    /**
369
+     * The web site configured language code.
370
+     *
371
+     * @since  3.15.0
372
+     * @access private
373
+     * @var string $language_code The web site configured language code.
374
+     */
375
+    private $language_code;
376
+
377
+    /**
378
+     * Wordlift_Schema_Service constructor.
379
+     *
380
+     * @since 3.1.0
381
+     *
382
+     * @param \Wordlift_Storage_Factory                $storage_factory       The {@link Wordlift_Post_Property_Storage_Factory} instance.
383
+     * @param \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory     The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
384
+     * @param \Wordlift_Configuration_Service          $configuration_service The {@link Wordlift_Configuration_Service} instance.
385
+     */
386
+    public function __construct( $storage_factory, $rendition_factory, $configuration_service ) {
387
+
388
+        $this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
389
+
390
+        $this->storage_factory       = $storage_factory;
391
+        $this->rendition_factory     = $rendition_factory;
392
+        $this->configuration_service = $configuration_service;
393
+        $this->language_code         = $this->configuration_service->get_language_code();
394
+
395
+        // Set the taxonomy data.
396
+        // Note: parent types must be defined before child types.
397
+        $this->schema = array(
398
+            'article'       => $this->get_article_schema(),
399
+            'thing'         => $this->get_thing_schema(),
400
+            'creative-work' => $this->get_creative_work_schema(),
401
+            'event'         => $this->get_event_schema(),
402
+            'organization'  => $this->get_organization_schema(),
403
+            'person'        => $this->get_person_schema(),
404
+            'place'         => $this->get_place_schema(),
405
+            'localbusiness' => $this->get_local_business_schema(),
406
+            'recipe'        => $this->get_recipe_schema(),
407
+        );
408
+
409
+        // Create a singleton instance of the Schema service, useful to provide static functions to global functions.
410
+        self::$instance = $this;
411
+
412
+    }
413
+
414
+    /**
415
+     * Get a reference to the Schema service.
416
+     *
417
+     * @since 3.1.0
418
+     *
419
+     * @return Wordlift_Schema_Service A reference to the Schema service.
420
+     */
421
+    public static function get_instance() {
422
+
423
+        return self::$instance;
424
+    }
425
+
426
+    /**
427
+     * Get the properties for a field with the specified key. The key is used as
428
+     * meta key when the field's value is stored in WordPress meta data table.
429
+     *
430
+     * @since 3.6.0
431
+     *
432
+     * @param string $key The field's key.
433
+     *
434
+     * @return null|array An array of field's properties or null if the field is not found.
435
+     */
436
+    public function get_field( $key ) {
437
+
438
+        // Parse each schema's fields until we find the one we're looking for, then
439
+        // return its properties.
440
+        foreach ( $this->schema as $_ => $schema ) {
441
+
442
+            if ( ! isset( $schema['custom_fields'] ) ) {
443
+                break;
444
+            }
445
+
446
+            foreach ( $schema['custom_fields'] as $field => $props ) {
447
+                if ( $key === $field ) {
448
+                    return $props;
449
+                }
450
+            }
451
+        }
452
+
453
+        return null;
454
+    }
455
+
456
+    /**
457
+     * Get the WordLift's schema.
458
+     *
459
+     * @param string $name The schema name.
460
+     *
461
+     * @return array|null An array with the schema configuration or NULL if the schema is not found.
462
+     *
463
+     * @since 3.1.0
464
+     */
465
+    public function get_schema( $name ) {
466
+        // Check if the schema exists and, if not, return NULL.
467
+        if ( ! isset( $this->schema[ $name ] ) ) {
468
+            return null;
469
+        }
470
+
471
+        // Return the requested schema.
472
+        return $this->schema[ $name ];
473
+    }
474
+
475
+    /**
476
+     * Get the WordLift's schema trough schema type uri.
477
+     *
478
+     * @param string $uri The schema uri.
479
+     *
480
+     * @return array|null An array with the schema configuration or NULL if the schema is not found.
481
+     *
482
+     * @since 3.3.0
483
+     */
484
+    public function get_schema_by_uri( $uri ) {
485
+
486
+        foreach ( $this->schema as $name => $schema ) {
487
+            if ( $schema['uri'] === $uri ) {
488
+                return $schema;
489
+            }
490
+        }
491
+
492
+        return null;
493
+    }
494
+
495
+    /**
496
+     * Get the 'thing' schema.
497
+     *
498
+     * @return array An array with the schema configuration.
499
+     *
500
+     * @since 3.1.0
501
+     */
502
+    private function get_thing_schema() {
503
+
504
+        return array(
505
+            'css_class'     => 'wl-thing',
506
+            'uri'           => 'http://schema.org/Thing',
507
+            'same_as'       => array( '*' ),
508
+            // set as default.
509
+            'custom_fields' => array(
510
+                self::FIELD_SAME_AS                            => array(
511
+                    'predicate'   => 'http://schema.org/sameAs',
512
+                    'type'        => self::DATA_TYPE_URI,
513
+                    'export_type' => 'http://schema.org/Thing',
514
+                    'constraints' => array(
515
+                        'cardinality' => INF,
516
+                    ),
517
+                    // We need a custom metabox.
518
+                    'input_field' => 'sameas',
519
+                ),
520
+                // Add the schema:url property.
521
+                Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
522
+                                                                                                        ->get_compat_definition(),
523
+            ),
524
+            // {{sameAs}} not present in the microdata template,
525
+            // because it is treated separately in *wl_content_embed_item_microdata*
526
+            'templates'     => array(
527
+                'subtitle' => '{{id}}',
528
+            ),
529
+            'linked_data'   => array(
530
+                // ### Title to rdfs:label.
531
+                $this->rendition_factory->create(
532
+                    $this->storage_factory->post_title(),
533
+                    Wordlift_Query_Builder::RDFS_LABEL_URI,
534
+                    null,
535
+                    $this->language_code
536
+                ),
537
+                // ### Title to dct:title.
538
+                $this->rendition_factory->create(
539
+                    $this->storage_factory->post_title(),
540
+                    'http://purl.org/dc/terms/title',
541
+                    null,
542
+                    $this->language_code
543
+                ),
544
+                // ### Alternative title to rdfs:label.
545
+                $this->rendition_factory->create(
546
+                    $this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
547
+                    Wordlift_Query_Builder::RDFS_LABEL_URI,
548
+                    null,
549
+                    $this->language_code
550
+                ),
551
+                // ### Alternative title to dct:title.
552
+                $this->rendition_factory->create(
553
+                    $this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
554
+                    'http://purl.org/dc/terms/title',
555
+                    null,
556
+                    $this->language_code
557
+                ),
558
+                // ### schema:url.
559
+                $this->rendition_factory->create(
560
+                    $this->storage_factory->url_property(),
561
+                    Wordlift_Query_Builder::SCHEMA_URL_URI,
562
+                    self::DATA_TYPE_URI
563
+                ),
564
+                // ### schema:description.
565
+                $this->rendition_factory->create(
566
+                    $this->storage_factory->post_description_no_tags_no_shortcodes(),
567
+                    'http://schema.org/description',
568
+                    null,
569
+                    $this->language_code
570
+                ),
571
+                // ### owl:sameAs.
572
+                $this->rendition_factory->create(
573
+                    $this->storage_factory->post_meta( self::FIELD_SAME_AS ),
574
+                    'http://www.w3.org/2002/07/owl#sameAs',
575
+                    self::DATA_TYPE_URI
576
+                ),
577
+                // ### rdf:type.
578
+                $this->rendition_factory->create(
579
+                    $this->storage_factory->schema_class( $this ),
580
+                    Wordlift_Query_Builder::RDFS_TYPE_URI,
581
+                    self::DATA_TYPE_URI
582
+                ),
583
+                // ### schema:image.
584
+                $this->rendition_factory->create(
585
+                    $this->storage_factory->post_images(),
586
+                    Wordlift_Query_Builder::SCHEMA_IMAGE_URI,
587
+                    self::DATA_TYPE_URI
588
+                ),
589
+                // ### dct:relation.
590
+                $this->rendition_factory->create(
591
+                    $this->storage_factory->relations(),
592
+                    Wordlift_Query_Builder::DCTERMS_RELATION_URI,
593
+                    self::DATA_TYPE_URI
594
+                ),
595
+            ),
596
+        );
597
+
598
+    }
599
+
600
+    /**
601
+     * Get the 'creative work' schema.
602
+     *
603
+     * @return array An array with the schema configuration.
604
+     *
605
+     * @since 3.1.0
606
+     */
607
+    private function get_creative_work_schema() {
608
+
609
+        $schema = array(
610
+            'label'         => 'CreativeWork',
611
+            'description'   => 'A creative work (or a Music Album).',
612
+            'parents'       => array( 'thing' ),
613
+            // Give term slug as parent.
614
+            'css_class'     => 'wl-creative-work',
615
+            'uri'           => 'http://schema.org/CreativeWork',
616
+            'same_as'       => array(
617
+                'http://schema.org/MusicAlbum',
618
+                'http://schema.org/Product',
619
+            ),
620
+            'custom_fields' => array(
621
+                self::FIELD_AUTHOR => array(
622
+                    'predicate'   => 'http://schema.org/author',
623
+                    'type'        => self::DATA_TYPE_URI,
624
+                    'export_type' => 'http://schema.org/Person',
625
+                    'constraints' => array(
626
+                        'uri_type'    => array( 'Person', 'Organization' ),
627
+                        'cardinality' => INF,
628
+                    ),
629
+                ),
630
+            ),
631
+            'linked_data'   => array(
632
+                // ### schema:author.
633
+                $this->rendition_factory->create(
634
+                    $this->storage_factory->author_uri(),
635
+                    Wordlift_Query_Builder::SCHEMA_AUTHOR_URI,
636
+                    self::DATA_TYPE_URI
637
+                ),
638
+            ),
639
+            'templates'     => array(
640
+                'subtitle' => '{{id}}',
641
+            ),
642
+        );
643
+
644
+        // Merge the custom fields with those provided by the thing schema.
645
+        $parent_schema           = $this->get_thing_schema();
646
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
647
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
648
+
649
+        return $schema;
650
+    }
651
+
652
+    /**
653
+     * Get the 'event' schema.
654
+     *
655
+     * @return array An array with the schema configuration.
656
+     *
657
+     * @since 3.1.0
658
+     */
659
+    private function get_event_schema() {
660
+
661
+        $schema = array(
662
+            'label'         => 'Event',
663
+            'description'   => 'An event . ',
664
+            'parents'       => array( 'thing' ),
665
+            'css_class'     => 'wl-event',
666
+            'uri'           => self::SCHEMA_EVENT_TYPE,
667
+            'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
668
+            'custom_fields' => array(
669
+                self::FIELD_DATE_START => array(
670
+                    'predicate'   => 'http://schema.org/startDate',
671
+                    'type'        => self::DATA_TYPE_DATE,
672
+                    'export_type' => 'xsd:dateTime',
673
+                    'constraints' => '',
674
+                ),
675
+                self::FIELD_DATE_END   => array(
676
+                    'predicate'   => 'http://schema.org/endDate',
677
+                    'type'        => self::DATA_TYPE_DATE,
678
+                    'export_type' => 'xsd:dateTime',
679
+                    'constraints' => '',
680
+                ),
681
+                self::FIELD_LOCATION   => array(
682
+                    'predicate'   => 'http://schema.org/location',
683
+                    'type'        => self::DATA_TYPE_URI,
684
+                    'export_type' => 'http://schema.org/PostalAddress',
685
+                    'constraints' => array(
686
+                        'uri_type'    => array( 'Place', 'LocalBusiness' ),
687
+                        'cardinality' => INF,
688
+                    ),
689
+                ),
690
+            ),
691
+            'linked_data'   => array(
692
+                // ### schema:startDate.
693
+                $this->rendition_factory->create(
694
+                    $this->storage_factory->post_meta( self::FIELD_DATE_START ),
695
+                    'http://schema.org/startDate',
696
+                    self::DATA_TYPE_DATE_TIME
697
+                ),
698
+                // ### schema:endDate.
699
+                $this->rendition_factory->create(
700
+                    $this->storage_factory->post_meta( self::FIELD_DATE_END ),
701
+                    'http://schema.org/endDate',
702
+                    self::DATA_TYPE_DATE_TIME
703
+                ),
704
+                // ### schema:location.
705
+                $this->rendition_factory->create(
706
+                    $this->storage_factory->post_meta_to_uri( self::FIELD_LOCATION ),
707
+                    'http://schema.org/location',
708
+                    self::DATA_TYPE_URI
709
+                ),
710
+            ),
711
+            'templates'     => array(
712
+                'subtitle' => '{{id}}',
713
+            ),
714
+        );
715
+
716
+        // Merge the custom fields with those provided by the thing schema.
717
+        $parent_schema           = $this->get_thing_schema();
718
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
719
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
720
+
721
+        return $schema;
722
+    }
723
+
724
+    /**
725
+     * Get the 'organization' schema.
726
+     *
727
+     * @return array An array with the schema configuration.
728
+     *
729
+     * @since 3.1.0
730
+     */
731
+    private function get_organization_schema() {
732
+
733
+        $schema = array(
734
+            'label'         => 'Organization',
735
+            'description'   => 'An organization, including a government or a newspaper.',
736
+            'parents'       => array( 'thing' ),
737
+            'css_class'     => 'wl-organization',
738
+            'uri'           => 'http://schema.org/Organization',
739
+            'same_as'       => array(
740
+                'http://rdf.freebase.com/ns/organization.organization',
741
+                'http://rdf.freebase.com/ns/government.government',
742
+                'http://schema.org/Newspaper',
743
+            ),
744
+            'custom_fields' => array(
745
+                self::FIELD_LEGAL_NAME          => array(
746
+                    'predicate'   => 'http://schema.org/legalName',
747
+                    'type'        => self::DATA_TYPE_STRING,
748
+                    'export_type' => 'xsd:string',
749
+                    'constraints' => '',
750
+                ),
751
+                self::FIELD_FOUNDER             => array(
752
+                    'predicate'   => 'http://schema.org/founder',
753
+                    'type'        => self::DATA_TYPE_URI,
754
+                    'export_type' => 'http://schema.org/Person',
755
+                    'constraints' => array(
756
+                        'uri_type'    => 'Person',
757
+                        'cardinality' => INF,
758
+                    ),
759
+                ),
760
+                self::FIELD_ADDRESS             => array(
761
+                    'predicate'   => 'http://schema.org/streetAddress',
762
+                    'type'        => self::DATA_TYPE_STRING,
763
+                    'export_type' => 'xsd:string',
764
+                    'constraints' => '',
765
+                    // To build custom metabox.
766
+                    'input_field' => 'address',
767
+                ),
768
+                self::FIELD_ADDRESS_PO_BOX      => array(
769
+                    'predicate'   => 'http://schema.org/postOfficeBoxNumber',
770
+                    'type'        => self::DATA_TYPE_STRING,
771
+                    'export_type' => 'xsd:string',
772
+                    'constraints' => '',
773
+                    // To build custom metabox.
774
+                    'input_field' => 'address',
775
+                ),
776
+                self::FIELD_ADDRESS_POSTAL_CODE => array(
777
+                    'predicate'   => 'http://schema.org/postalCode',
778
+                    'type'        => self::DATA_TYPE_STRING,
779
+                    'export_type' => 'xsd:string',
780
+                    'constraints' => '',
781
+                    // To build custom metabox.
782
+                    'input_field' => 'address',
783
+                ),
784
+                self::FIELD_ADDRESS_LOCALITY    => array(
785
+                    'predicate'   => 'http://schema.org/addressLocality',
786
+                    'type'        => self::DATA_TYPE_STRING,
787
+                    'export_type' => 'xsd:string',
788
+                    'constraints' => '',
789
+                    // To build custom metabox.
790
+                    'input_field' => 'address',
791
+                ),
792
+                self::FIELD_ADDRESS_REGION      => array(
793
+                    'predicate'   => 'http://schema.org/addressRegion',
794
+                    'type'        => self::DATA_TYPE_STRING,
795
+                    'export_type' => 'xsd:string',
796
+                    'constraints' => '',
797
+                    // To build custom metabox.
798
+                    'input_field' => 'address',
799
+                ),
800
+                self::FIELD_ADDRESS_COUNTRY     => array(
801
+                    'predicate'   => 'http://schema.org/addressCountry',
802
+                    'type'        => self::DATA_TYPE_STRING,
803
+                    'export_type' => 'xsd:string',
804
+                    'constraints' => '',
805
+                    // To build custom metabox.
806
+                    'input_field' => 'address',
807
+                ),
808
+                self::FIELD_EMAIL               => array(
809
+                    'predicate'   => 'http://schema.org/email',
810
+                    'type'        => self::DATA_TYPE_STRING,
811
+                    'export_type' => 'xsd:string',
812
+                    'constraints' => '',
813
+                ),
814
+                self::FIELD_TELEPHONE           => array(
815
+                    'predicate'   => 'http://schema.org/telephone',
816
+                    'type'        => self::DATA_TYPE_STRING,
817
+                    'export_type' => 'xsd:string',
818
+                    'constraints' => '',
819
+                ),
820
+            ),
821
+            'linked_data'   => array(
822
+                // ### schema:legalName.
823
+                $this->rendition_factory->create(
824
+                    $this->storage_factory->post_meta( self::FIELD_LEGAL_NAME ),
825
+                    'http://schema.org/legalName'
826
+                ),
827
+                // ### schema:founder.
828
+                $this->rendition_factory->create(
829
+                    $this->storage_factory->post_meta_to_uri( self::FIELD_FOUNDER ),
830
+                    'http://schema.org/founder',
831
+                    self::DATA_TYPE_URI
832
+                ),
833
+                // ### schema:email.
834
+                $this->rendition_factory->create(
835
+                    $this->storage_factory->post_meta( self::FIELD_EMAIL ),
836
+                    'http://schema.org/email'
837
+                ),
838
+                // ### schema:telephone.
839
+                $this->rendition_factory->create(
840
+                    $this->storage_factory->post_meta( self::FIELD_TELEPHONE ),
841
+                    'http://schema.org/telephone'
842
+                ),
843
+            ),
844
+            'templates'     => array(
845
+                'subtitle' => '{{id}}',
846
+            ),
847
+        );
848
+
849
+        // Merge the custom fields with those provided by the thing schema.
850
+        $parent_schema           = $this->get_thing_schema();
851
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
852
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
853
+
854
+        return $schema;
855
+    }
856
+
857
+    /**
858
+     * Get the 'person' schema.
859
+     *
860
+     * @return array An array with the schema configuration.
861
+     *
862
+     * @since 3.1.0
863
+     */
864
+    private function get_person_schema() {
865
+
866
+        $schema = array(
867
+            'label'         => 'Person',
868
+            'description'   => 'A person (or a music artist).',
869
+            'parents'       => array( 'thing' ),
870
+            'css_class'     => 'wl-person',
871
+            'uri'           => 'http://schema.org/Person',
872
+            'same_as'       => array(
873
+                'http://rdf.freebase.com/ns/people.person',
874
+                'http://rdf.freebase.com/ns/music.artist',
875
+                'http://dbpedia.org/class/yago/LivingPeople',
876
+            ),
877
+            'custom_fields' => array(
878
+                self::FIELD_KNOWS       => array(
879
+                    'predicate'   => 'http://schema.org/knows',
880
+                    'type'        => self::DATA_TYPE_URI,
881
+                    'export_type' => 'http://schema.org/Person',
882
+                    'constraints' => array(
883
+                        'uri_type'    => 'Person',
884
+                        'cardinality' => INF,
885
+                    ),
886
+                ),
887
+                self::FIELD_BIRTH_DATE  => array(
888
+                    'predicate'   => 'http://schema.org/birthDate',
889
+                    'type'        => self::DATA_TYPE_DATE,
890
+                    'export_type' => 'xsd:date',
891
+                    'constraints' => '',
892
+                ),
893
+                self::FIELD_BIRTH_PLACE => array(
894
+                    'predicate'   => 'http://schema.org/birthPlace',
895
+                    'type'        => self::DATA_TYPE_URI,
896
+                    'export_type' => 'http://schema.org/Place',
897
+                    'constraints' => array(
898
+                        'uri_type' => 'Place',
899
+                    ),
900
+                ),
901
+                self::FIELD_AFFILIATION => array(
902
+                    'predicate'   => 'http://schema.org/affiliation',
903
+                    'type'        => self::DATA_TYPE_URI,
904
+                    'export_type' => 'http://schema.org/Organization',
905
+                    'constraints' => array(
906
+                        'uri_type'    => array(
907
+                            'Organization',
908
+                            'LocalBusiness',
909
+                        ),
910
+                        'cardinality' => INF,
911
+                    ),
912
+                ),
913
+                self::FIELD_EMAIL       => array(
914
+                    'predicate'   => 'http://schema.org/email',
915
+                    'type'        => self::DATA_TYPE_STRING,
916
+                    'export_type' => 'xsd:string',
917
+                    'constraints' => array(
918
+                        'cardinality' => INF,
919
+                    ),
920
+                ),
921
+            ),
922
+            'linked_data'   => array(
923
+                // ### schema:knows.
924
+                $this->rendition_factory->create(
925
+                    $this->storage_factory->post_meta_to_uri( self::FIELD_KNOWS ),
926
+                    'http://schema.org/knows',
927
+                    self::DATA_TYPE_URI
928
+                ),
929
+                // ### schema:birthDate.
930
+                $this->rendition_factory->create(
931
+                    $this->storage_factory->post_meta( self::FIELD_BIRTH_DATE ),
932
+                    'http://schema.org/birthDate',
933
+                    self::DATA_TYPE_DATE
934
+                ),
935
+                // ### schema:birthPlace.
936
+                $this->rendition_factory->create(
937
+                    $this->storage_factory->post_meta_to_uri( self::FIELD_BIRTH_PLACE ),
938
+                    'http://schema.org/birthPlace',
939
+                    self::DATA_TYPE_URI
940
+                ),
941
+                // ### schema:affiliation.
942
+                $this->rendition_factory->create(
943
+                    $this->storage_factory->post_meta_to_uri( self::FIELD_AFFILIATION ),
944
+                    'http://schema.org/affiliation',
945
+                    self::DATA_TYPE_URI
946
+                ),
947
+                // ### schema:email.
948
+                $this->rendition_factory->create(
949
+                    $this->storage_factory->post_meta( self::FIELD_EMAIL ),
950
+                    'http://schema.org/email'
951
+                ),
952
+            ),
953
+            'templates'     => array(
954
+                'subtitle' => '{{id}}',
955
+            ),
956
+        );
957
+
958
+        // Merge the custom fields with those provided by the thing schema.
959
+        $parent_schema           = $this->get_thing_schema();
960
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
961
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
962
+
963
+        return $schema;
964
+
965
+    }
966
+
967
+    /**
968
+     * Get the 'place' schema.
969
+     *
970
+     * @return array An array with the schema configuration.
971
+     *
972
+     * @since 3.1.0
973
+     */
974
+    private function get_place_schema() {
975
+
976
+        $schema = array(
977
+            'label'         => 'Place',
978
+            'description'   => 'A place.',
979
+            'parents'       => array( 'thing' ),
980
+            'css_class'     => 'wl-place',
981
+            'uri'           => 'http://schema.org/Place',
982
+            'same_as'       => array(
983
+                'http://rdf.freebase.com/ns/location.location',
984
+                'http://www.opengis.net/gml/_Feature',
985
+            ),
986
+            'custom_fields' => array(
987
+                self::FIELD_GEO_LATITUDE        => array(
988
+                    'predicate'   => 'http://schema.org/latitude',
989
+                    'type'        => self::DATA_TYPE_DOUBLE,
990
+                    'export_type' => 'xsd:double',
991
+                    'constraints' => '',
992
+                    // To build custom metabox.
993
+                    'input_field' => 'coordinates',
994
+                ),
995
+                self::FIELD_GEO_LONGITUDE       => array(
996
+                    'predicate'   => 'http://schema.org/longitude',
997
+                    'type'        => self::DATA_TYPE_DOUBLE,
998
+                    'export_type' => 'xsd:double',
999
+                    'constraints' => '',
1000
+                    // To build custom metabox.
1001
+                    'input_field' => 'coordinates',
1002
+                ),
1003
+                self::FIELD_ADDRESS             => array(
1004
+                    'predicate'   => 'http://schema.org/streetAddress',
1005
+                    'type'        => self::DATA_TYPE_STRING,
1006
+                    'export_type' => 'xsd:string',
1007
+                    'constraints' => '',
1008
+                    // To build custom metabox.
1009
+                    'input_field' => 'address',
1010
+                ),
1011
+                self::FIELD_ADDRESS_PO_BOX      => array(
1012
+                    'predicate'   => 'http://schema.org/postOfficeBoxNumber',
1013
+                    'type'        => self::DATA_TYPE_STRING,
1014
+                    'export_type' => 'xsd:string',
1015
+                    'constraints' => '',
1016
+                    // To build custom metabox.
1017
+                    'input_field' => 'address',
1018
+                ),
1019
+                self::FIELD_ADDRESS_POSTAL_CODE => array(
1020
+                    'predicate'   => 'http://schema.org/postalCode',
1021
+                    'type'        => self::DATA_TYPE_STRING,
1022
+                    'export_type' => 'xsd:string',
1023
+                    'constraints' => '',
1024
+                    // To build custom metabox.
1025
+                    'input_field' => 'address',
1026
+                ),
1027
+                self::FIELD_ADDRESS_LOCALITY    => array(
1028
+                    'predicate'   => 'http://schema.org/addressLocality',
1029
+                    'type'        => self::DATA_TYPE_STRING,
1030
+                    'export_type' => 'xsd:string',
1031
+                    'constraints' => '',
1032
+                    // To build custom metabox.
1033
+                    'input_field' => 'address',
1034
+                ),
1035
+                self::FIELD_ADDRESS_REGION      => array(
1036
+                    'predicate'   => 'http://schema.org/addressRegion',
1037
+                    'type'        => self::DATA_TYPE_STRING,
1038
+                    'export_type' => 'xsd:string',
1039
+                    'constraints' => '',
1040
+                    // To build custom metabox.
1041
+                    'input_field' => 'address',
1042
+                ),
1043
+                self::FIELD_ADDRESS_COUNTRY     => array(
1044
+                    'predicate'   => 'http://schema.org/addressCountry',
1045
+                    'type'        => self::DATA_TYPE_STRING,
1046
+                    'export_type' => 'xsd:string',
1047
+                    'constraints' => '',
1048
+                    // To build custom metabox.
1049
+                    'input_field' => 'address',
1050
+                ),
1051
+            ),
1052
+            'linked_data'   => array(),
1053
+            'templates'     => array(
1054
+                'subtitle' => '{{id}}',
1055
+            ),
1056
+        );
1057
+
1058
+        // Merge the custom fields with those provided by the thing schema.
1059
+        $parent_schema           = $this->get_thing_schema();
1060
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1061
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1062
+
1063
+        return $schema;
1064
+    }
1065
+
1066
+    /**
1067
+     * Get the 'local business' schema.
1068
+     *
1069
+     * @return array An array with the schema configuration.
1070
+     *
1071
+     * @since 3.1.0
1072
+     */
1073
+    private function get_local_business_schema() {
1074
+
1075
+        $schema = array(
1076
+            'label'         => 'LocalBusiness',
1077
+            'description'   => 'A local business.',
1078
+            'parents'       => array( 'place', 'organization' ),
1079
+            'css_class'     => 'wl-local-business',
1080
+            'uri'           => 'http://schema.org/LocalBusiness',
1081
+            'same_as'       => array(
1082
+                'http://rdf.freebase.com/ns/business/business_location',
1083
+                'https://schema.org/Store',
1084
+            ),
1085
+            'custom_fields' => array(),
1086
+            'linked_data'   => array(),
1087
+            'templates'     => array(
1088
+                'subtitle' => '{{id}}',
1089
+            ),
1090
+        );
1091
+
1092
+        // Merge the custom fields with those provided by the place and organization schema.
1093
+        $place_schema            = $this->get_place_schema();
1094
+        $organization_schema     = $this->get_organization_schema();
1095
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
1096
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $place_schema['linked_data'], $organization_schema['linked_data'] );
1097
+
1098
+        return $schema;
1099
+    }
1100
+
1101
+    /**
1102
+     * Get the 'recipe' schema.
1103
+     *
1104
+     * @return array An array with the schema configuration.
1105
+     *
1106
+     * @since 3.14.0
1107
+     */
1108
+    private function get_recipe_schema() {
1109
+
1110
+        $schema = array(
1111
+            'label'         => 'Recipe',
1112
+            'description'   => 'A Recipe.',
1113
+            'parents'       => array( 'CreativeWork' ),
1114
+            'css_class'     => 'wl-recipe',
1115
+            'uri'           => 'http://schema.org/Recipe',
1116
+            'same_as'       => array(),
1117
+            'templates'     => array(
1118
+                'subtitle' => '{{id}}',
1119
+            ),
1120
+            'custom_fields' => array(
1121
+                self::FIELD_RECIPE_CUISINE          => array(
1122
+                    'predicate'   => 'http://schema.org/recipeCuisine',
1123
+                    'type'        => self::DATA_TYPE_STRING,
1124
+                    'export_type' => 'xsd:string',
1125
+                    'constraints' => '',
1126
+                    'metabox'     => array(
1127
+                        'label' => __( 'Recipe cuisine', 'wordlift' ),
1128
+                    ),
1129
+                ),
1130
+                self::FIELD_RECIPE_INGREDIENT       => array(
1131
+                    'predicate'   => 'http://schema.org/recipeIngredient',
1132
+                    'type'        => self::DATA_TYPE_STRING,
1133
+                    'export_type' => 'xsd:string',
1134
+                    'constraints' => array(
1135
+                        'cardinality' => INF,
1136
+                    ),
1137
+                    'metabox'     => array(
1138
+                        'label' => __( 'Recipe ingredient', 'wordlift' ),
1139
+                    ),
1140
+                ),
1141
+                self::FIELD_RECIPE_INSTRUCTIONS     => array(
1142
+                    'predicate'   => 'http://schema.org/recipeInstructions',
1143
+                    'type'        => self::DATA_TYPE_MULTILINE,
1144
+                    'export_type' => 'xsd:string',
1145
+                    'constraints' => '',
1146
+                    'metabox'     => array(
1147
+                        'class' => 'Wordlift_Metabox_Field_Multiline',
1148
+                        'label' => __( 'Recipe instructions', 'wordlift' ),
1149
+                    ),
1150
+                ),
1151
+                self::FIELD_RECIPE_YIELD            => array(
1152
+                    'predicate'   => 'http://schema.org/recipeYield',
1153
+                    'type'        => self::DATA_TYPE_STRING,
1154
+                    'export_type' => 'xsd:string',
1155
+                    'constraints' => '',
1156
+                    'metabox'     => array(
1157
+                        'label' => __( 'Recipe number of servings', 'wordlift' ),
1158
+                    ),
1159
+                ),
1160
+                self::FIELD_RECIPE_INGREDIENT       => array(
1161
+                    'predicate'   => 'http://schema.org/recipeIngredient',
1162
+                    'type'        => self::DATA_TYPE_STRING,
1163
+                    'export_type' => 'xsd:string',
1164
+                    'constraints' => array(
1165
+                        'cardinality' => INF,
1166
+                    ),
1167
+                    'metabox'     => array(
1168
+                        'label' => __( 'Recipe ingredient', 'wordlift' ),
1169
+                    ),
1170
+                ),
1171
+                self::FIELD_NUTRITION_INFO_CALORIES => array(
1172
+                    'predicate'   => 'http://schema.org/calories',
1173
+                    'type'        => self::DATA_TYPE_STRING,
1174
+                    'export_type' => 'xsd:string',
1175
+                    'constraints' => '',
1176
+                    'metabox'     => array(
1177
+                        'label' => __( 'Calories (e.g. 240 calories)', 'wordlift' ),
1178
+                    ),
1179
+                ),
1180
+                self::FIELD_PREP_TIME               => array(
1181
+                    'predicate'   => 'http://schema.org/prepTime',
1182
+                    'type'        => self::DATA_TYPE_DURATION,
1183
+                    'export_type' => 'xsd:time',
1184
+                    'constraints' => '',
1185
+                    'metabox'     => array(
1186
+                        'class' => 'Wordlift_Metabox_Field_Duration',
1187
+                        'label' => __( 'Recipe preparation time (e.g. 1:30)', 'wordlift' ),
1188
+                    ),
1189
+                ),
1190
+                self::FIELD_COOK_TIME               => array(
1191
+                    'predicate'   => 'http://schema.org/cookTime',
1192
+                    'type'        => self::DATA_TYPE_DURATION,
1193
+                    'export_type' => 'xsd:time',
1194
+                    'constraints' => '',
1195
+                    'metabox'     => array(
1196
+                        'class' => 'Wordlift_Metabox_Field_Duration',
1197
+                        'label' => __( 'Recipe cook time (e.g. 1:30)', 'wordlift' ),
1198
+                    ),
1199
+                ),
1200
+                self::FIELD_TOTAL_TIME              => array(
1201
+                    'predicate'   => 'http://schema.org/totalTime',
1202
+                    'type'        => self::DATA_TYPE_DURATION,
1203
+                    'export_type' => 'xsd:time',
1204
+                    'constraints' => '',
1205
+                    'metabox'     => array(
1206
+                        'class' => 'Wordlift_Metabox_Field_Duration',
1207
+                        'label' => __( 'Recipe total time (e.g. 1:30)', 'wordlift' ),
1208
+                    ),
1209
+                ),
1210
+            ),
1211
+            'linked_data'   => array(
1212
+                // ### schema:recipeCuisine.
1213
+                $this->rendition_factory->create(
1214
+                    $this->storage_factory->post_meta( self::FIELD_RECIPE_CUISINE ),
1215
+                    'http://schema.org/recipeCuisine'
1216
+                ),
1217
+                // ### schema:recipeIngredient.
1218
+                $this->rendition_factory->create(
1219
+                    $this->storage_factory->post_meta( self::FIELD_RECIPE_INGREDIENT ),
1220
+                    'http://schema.org/recipeIngredient'
1221
+                ),
1222
+                // ### schema:prepTime.
1223
+                $this->rendition_factory->create(
1224
+                    $this->storage_factory->post_meta( self::FIELD_PREP_TIME ),
1225
+                    'http://schema.org/prepTime',
1226
+                    self::DATA_TYPE_DURATION
1227
+                ),
1228
+                // ### schema:cookTime.
1229
+                $this->rendition_factory->create(
1230
+                    $this->storage_factory->post_meta( self::FIELD_COOK_TIME ),
1231
+                    'http://schema.org/cookTime',
1232
+                    self::DATA_TYPE_DURATION
1233
+                ),
1234
+                // ### schema:totalTime.
1235
+                $this->rendition_factory->create(
1236
+                    $this->storage_factory->post_meta( self::FIELD_TOTAL_TIME ),
1237
+                    'http://schema.org/totalTime',
1238
+                    self::DATA_TYPE_DURATION
1239
+                ),
1240
+            ),
1241
+        );
1242
+
1243
+        // Merge the custom fields with those provided by the parent schema.
1244
+        $parent_schema           = $this->get_creative_work_schema();
1245
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1246
+        $schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1247
+
1248
+        return $schema;
1249
+    }
1250
+
1251
+    /**
1252
+     * Get the 'article' schema.
1253
+     *
1254
+     * @return array An array with the schema configuration.
1255
+     *
1256
+     * @since 3.15.0
1257
+     */
1258
+    private function get_article_schema() {
1259
+
1260
+        $schema = array(
1261
+            'label'         => 'Article',
1262
+            'description'   => 'An Article.',
1263
+            'parents'       => array(),
1264
+            'css_class'     => 'wl-article',
1265
+            'uri'           => 'http://schema.org/Article',
1266
+            'same_as'       => array(),
1267
+            'templates'     => array(
1268
+                'subtitle' => '{{id}}',
1269
+            ),
1270
+            'custom_fields' => array(),
1271
+            'linked_data'   => array(),
1272
+        );
1273
+
1274
+        return $schema;
1275
+    }
1276
+
1277
+    /**
1278
+     * Get all the predicates.
1279
+     *
1280
+     * @since 3.15.0
1281
+     *
1282
+     * @return array An array of predicates.
1283
+     */
1284
+    public function get_all_predicates() {
1285
+
1286
+        // Get the custom fields.
1287
+        $renditions = array_reduce( $this->schema, function ( $carry, $item ) {
1288
+            return array_merge( $carry, $item['linked_data'] );
1289
+        }, array() );
1290
+
1291
+        // Create a new array of predicates from the custom fields. The initial
1292
+        // array contains just the `http://www.w3.org/1999/02/22-rdf-syntax-ns#type`
1293
+        // (a, rdf:type) predicate (use the full URI).
1294
+        $predicates = array_unique( array_reduce( $renditions, function ( $carry, $item ) {
1295
+            return array_merge( $carry, (array) $item->get_predicate() );
1296
+        }, array() ) );
1297
+
1298
+        /**
1299
+         * Filter: 'wl_schema_predicates' - Allow third parties to hook and add additional predicates.
1300
+         *
1301
+         * @since  3.17.0
1302
+         * @api arr $predicates Schema.org predicates.
1303
+         */
1304
+        return apply_filters( 'wl_schema_predicates', $predicates );
1305
+    }
1306 1306
 
1307 1307
 }
Please login to merge, or discard this patch.
Spacing   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -383,9 +383,9 @@  discard block
 block discarded – undo
383 383
 	 * @param \Wordlift_Sparql_Tuple_Rendition_Factory $rendition_factory     The {@link Wordlift_Sparql_Tuple_Rendition_Factory} instance.
384 384
 	 * @param \Wordlift_Configuration_Service          $configuration_service The {@link Wordlift_Configuration_Service} instance.
385 385
 	 */
386
-	public function __construct( $storage_factory, $rendition_factory, $configuration_service ) {
386
+	public function __construct($storage_factory, $rendition_factory, $configuration_service) {
387 387
 
388
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
388
+		$this->log = Wordlift_Log_Service::get_logger('Wordlift_Schema_Service');
389 389
 
390 390
 		$this->storage_factory       = $storage_factory;
391 391
 		$this->rendition_factory     = $rendition_factory;
@@ -433,18 +433,18 @@  discard block
 block discarded – undo
433 433
 	 *
434 434
 	 * @return null|array An array of field's properties or null if the field is not found.
435 435
 	 */
436
-	public function get_field( $key ) {
436
+	public function get_field($key) {
437 437
 
438 438
 		// Parse each schema's fields until we find the one we're looking for, then
439 439
 		// return its properties.
440
-		foreach ( $this->schema as $_ => $schema ) {
440
+		foreach ($this->schema as $_ => $schema) {
441 441
 
442
-			if ( ! isset( $schema['custom_fields'] ) ) {
442
+			if ( ! isset($schema['custom_fields'])) {
443 443
 				break;
444 444
 			}
445 445
 
446
-			foreach ( $schema['custom_fields'] as $field => $props ) {
447
-				if ( $key === $field ) {
446
+			foreach ($schema['custom_fields'] as $field => $props) {
447
+				if ($key === $field) {
448 448
 					return $props;
449 449
 				}
450 450
 			}
@@ -462,14 +462,14 @@  discard block
 block discarded – undo
462 462
 	 *
463 463
 	 * @since 3.1.0
464 464
 	 */
465
-	public function get_schema( $name ) {
465
+	public function get_schema($name) {
466 466
 		// Check if the schema exists and, if not, return NULL.
467
-		if ( ! isset( $this->schema[ $name ] ) ) {
467
+		if ( ! isset($this->schema[$name])) {
468 468
 			return null;
469 469
 		}
470 470
 
471 471
 		// Return the requested schema.
472
-		return $this->schema[ $name ];
472
+		return $this->schema[$name];
473 473
 	}
474 474
 
475 475
 	/**
@@ -481,10 +481,10 @@  discard block
 block discarded – undo
481 481
 	 *
482 482
 	 * @since 3.3.0
483 483
 	 */
484
-	public function get_schema_by_uri( $uri ) {
484
+	public function get_schema_by_uri($uri) {
485 485
 
486
-		foreach ( $this->schema as $name => $schema ) {
487
-			if ( $schema['uri'] === $uri ) {
486
+		foreach ($this->schema as $name => $schema) {
487
+			if ($schema['uri'] === $uri) {
488 488
 				return $schema;
489 489
 			}
490 490
 		}
@@ -504,7 +504,7 @@  discard block
 block discarded – undo
504 504
 		return array(
505 505
 			'css_class'     => 'wl-thing',
506 506
 			'uri'           => 'http://schema.org/Thing',
507
-			'same_as'       => array( '*' ),
507
+			'same_as'       => array('*'),
508 508
 			// set as default.
509 509
 			'custom_fields' => array(
510 510
 				self::FIELD_SAME_AS                            => array(
@@ -543,14 +543,14 @@  discard block
 block discarded – undo
543 543
 				),
544 544
 				// ### Alternative title to rdfs:label.
545 545
 				$this->rendition_factory->create(
546
-					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
546
+					$this->storage_factory->post_meta(Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY),
547 547
 					Wordlift_Query_Builder::RDFS_LABEL_URI,
548 548
 					null,
549 549
 					$this->language_code
550 550
 				),
551 551
 				// ### Alternative title to dct:title.
552 552
 				$this->rendition_factory->create(
553
-					$this->storage_factory->post_meta( Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY ),
553
+					$this->storage_factory->post_meta(Wordlift_Entity_Service::ALTERNATIVE_LABEL_META_KEY),
554 554
 					'http://purl.org/dc/terms/title',
555 555
 					null,
556 556
 					$this->language_code
@@ -570,13 +570,13 @@  discard block
 block discarded – undo
570 570
 				),
571 571
 				// ### owl:sameAs.
572 572
 				$this->rendition_factory->create(
573
-					$this->storage_factory->post_meta( self::FIELD_SAME_AS ),
573
+					$this->storage_factory->post_meta(self::FIELD_SAME_AS),
574 574
 					'http://www.w3.org/2002/07/owl#sameAs',
575 575
 					self::DATA_TYPE_URI
576 576
 				),
577 577
 				// ### rdf:type.
578 578
 				$this->rendition_factory->create(
579
-					$this->storage_factory->schema_class( $this ),
579
+					$this->storage_factory->schema_class($this),
580 580
 					Wordlift_Query_Builder::RDFS_TYPE_URI,
581 581
 					self::DATA_TYPE_URI
582 582
 				),
@@ -609,7 +609,7 @@  discard block
 block discarded – undo
609 609
 		$schema = array(
610 610
 			'label'         => 'CreativeWork',
611 611
 			'description'   => 'A creative work (or a Music Album).',
612
-			'parents'       => array( 'thing' ),
612
+			'parents'       => array('thing'),
613 613
 			// Give term slug as parent.
614 614
 			'css_class'     => 'wl-creative-work',
615 615
 			'uri'           => 'http://schema.org/CreativeWork',
@@ -623,7 +623,7 @@  discard block
 block discarded – undo
623 623
 					'type'        => self::DATA_TYPE_URI,
624 624
 					'export_type' => 'http://schema.org/Person',
625 625
 					'constraints' => array(
626
-						'uri_type'    => array( 'Person', 'Organization' ),
626
+						'uri_type'    => array('Person', 'Organization'),
627 627
 						'cardinality' => INF,
628 628
 					),
629 629
 				),
@@ -643,8 +643,8 @@  discard block
 block discarded – undo
643 643
 
644 644
 		// Merge the custom fields with those provided by the thing schema.
645 645
 		$parent_schema           = $this->get_thing_schema();
646
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
647
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
646
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $parent_schema['custom_fields']);
647
+		$schema['linked_data']   = array_merge($schema['linked_data'], $parent_schema['linked_data']);
648 648
 
649 649
 		return $schema;
650 650
 	}
@@ -661,10 +661,10 @@  discard block
 block discarded – undo
661 661
 		$schema = array(
662 662
 			'label'         => 'Event',
663 663
 			'description'   => 'An event . ',
664
-			'parents'       => array( 'thing' ),
664
+			'parents'       => array('thing'),
665 665
 			'css_class'     => 'wl-event',
666 666
 			'uri'           => self::SCHEMA_EVENT_TYPE,
667
-			'same_as'       => array( 'http://dbpedia.org/ontology/Event' ),
667
+			'same_as'       => array('http://dbpedia.org/ontology/Event'),
668 668
 			'custom_fields' => array(
669 669
 				self::FIELD_DATE_START => array(
670 670
 					'predicate'   => 'http://schema.org/startDate',
@@ -683,7 +683,7 @@  discard block
 block discarded – undo
683 683
 					'type'        => self::DATA_TYPE_URI,
684 684
 					'export_type' => 'http://schema.org/PostalAddress',
685 685
 					'constraints' => array(
686
-						'uri_type'    => array( 'Place', 'LocalBusiness' ),
686
+						'uri_type'    => array('Place', 'LocalBusiness'),
687 687
 						'cardinality' => INF,
688 688
 					),
689 689
 				),
@@ -691,19 +691,19 @@  discard block
 block discarded – undo
691 691
 			'linked_data'   => array(
692 692
 				// ### schema:startDate.
693 693
 				$this->rendition_factory->create(
694
-					$this->storage_factory->post_meta( self::FIELD_DATE_START ),
694
+					$this->storage_factory->post_meta(self::FIELD_DATE_START),
695 695
 					'http://schema.org/startDate',
696 696
 					self::DATA_TYPE_DATE_TIME
697 697
 				),
698 698
 				// ### schema:endDate.
699 699
 				$this->rendition_factory->create(
700
-					$this->storage_factory->post_meta( self::FIELD_DATE_END ),
700
+					$this->storage_factory->post_meta(self::FIELD_DATE_END),
701 701
 					'http://schema.org/endDate',
702 702
 					self::DATA_TYPE_DATE_TIME
703 703
 				),
704 704
 				// ### schema:location.
705 705
 				$this->rendition_factory->create(
706
-					$this->storage_factory->post_meta_to_uri( self::FIELD_LOCATION ),
706
+					$this->storage_factory->post_meta_to_uri(self::FIELD_LOCATION),
707 707
 					'http://schema.org/location',
708 708
 					self::DATA_TYPE_URI
709 709
 				),
@@ -715,8 +715,8 @@  discard block
 block discarded – undo
715 715
 
716 716
 		// Merge the custom fields with those provided by the thing schema.
717 717
 		$parent_schema           = $this->get_thing_schema();
718
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
719
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
718
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $parent_schema['custom_fields']);
719
+		$schema['linked_data']   = array_merge($schema['linked_data'], $parent_schema['linked_data']);
720 720
 
721 721
 		return $schema;
722 722
 	}
@@ -733,7 +733,7 @@  discard block
 block discarded – undo
733 733
 		$schema = array(
734 734
 			'label'         => 'Organization',
735 735
 			'description'   => 'An organization, including a government or a newspaper.',
736
-			'parents'       => array( 'thing' ),
736
+			'parents'       => array('thing'),
737 737
 			'css_class'     => 'wl-organization',
738 738
 			'uri'           => 'http://schema.org/Organization',
739 739
 			'same_as'       => array(
@@ -821,23 +821,23 @@  discard block
 block discarded – undo
821 821
 			'linked_data'   => array(
822 822
 				// ### schema:legalName.
823 823
 				$this->rendition_factory->create(
824
-					$this->storage_factory->post_meta( self::FIELD_LEGAL_NAME ),
824
+					$this->storage_factory->post_meta(self::FIELD_LEGAL_NAME),
825 825
 					'http://schema.org/legalName'
826 826
 				),
827 827
 				// ### schema:founder.
828 828
 				$this->rendition_factory->create(
829
-					$this->storage_factory->post_meta_to_uri( self::FIELD_FOUNDER ),
829
+					$this->storage_factory->post_meta_to_uri(self::FIELD_FOUNDER),
830 830
 					'http://schema.org/founder',
831 831
 					self::DATA_TYPE_URI
832 832
 				),
833 833
 				// ### schema:email.
834 834
 				$this->rendition_factory->create(
835
-					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
835
+					$this->storage_factory->post_meta(self::FIELD_EMAIL),
836 836
 					'http://schema.org/email'
837 837
 				),
838 838
 				// ### schema:telephone.
839 839
 				$this->rendition_factory->create(
840
-					$this->storage_factory->post_meta( self::FIELD_TELEPHONE ),
840
+					$this->storage_factory->post_meta(self::FIELD_TELEPHONE),
841 841
 					'http://schema.org/telephone'
842 842
 				),
843 843
 			),
@@ -848,8 +848,8 @@  discard block
 block discarded – undo
848 848
 
849 849
 		// Merge the custom fields with those provided by the thing schema.
850 850
 		$parent_schema           = $this->get_thing_schema();
851
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
852
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
851
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $parent_schema['custom_fields']);
852
+		$schema['linked_data']   = array_merge($schema['linked_data'], $parent_schema['linked_data']);
853 853
 
854 854
 		return $schema;
855 855
 	}
@@ -866,7 +866,7 @@  discard block
 block discarded – undo
866 866
 		$schema = array(
867 867
 			'label'         => 'Person',
868 868
 			'description'   => 'A person (or a music artist).',
869
-			'parents'       => array( 'thing' ),
869
+			'parents'       => array('thing'),
870 870
 			'css_class'     => 'wl-person',
871 871
 			'uri'           => 'http://schema.org/Person',
872 872
 			'same_as'       => array(
@@ -922,31 +922,31 @@  discard block
 block discarded – undo
922 922
 			'linked_data'   => array(
923 923
 				// ### schema:knows.
924 924
 				$this->rendition_factory->create(
925
-					$this->storage_factory->post_meta_to_uri( self::FIELD_KNOWS ),
925
+					$this->storage_factory->post_meta_to_uri(self::FIELD_KNOWS),
926 926
 					'http://schema.org/knows',
927 927
 					self::DATA_TYPE_URI
928 928
 				),
929 929
 				// ### schema:birthDate.
930 930
 				$this->rendition_factory->create(
931
-					$this->storage_factory->post_meta( self::FIELD_BIRTH_DATE ),
931
+					$this->storage_factory->post_meta(self::FIELD_BIRTH_DATE),
932 932
 					'http://schema.org/birthDate',
933 933
 					self::DATA_TYPE_DATE
934 934
 				),
935 935
 				// ### schema:birthPlace.
936 936
 				$this->rendition_factory->create(
937
-					$this->storage_factory->post_meta_to_uri( self::FIELD_BIRTH_PLACE ),
937
+					$this->storage_factory->post_meta_to_uri(self::FIELD_BIRTH_PLACE),
938 938
 					'http://schema.org/birthPlace',
939 939
 					self::DATA_TYPE_URI
940 940
 				),
941 941
 				// ### schema:affiliation.
942 942
 				$this->rendition_factory->create(
943
-					$this->storage_factory->post_meta_to_uri( self::FIELD_AFFILIATION ),
943
+					$this->storage_factory->post_meta_to_uri(self::FIELD_AFFILIATION),
944 944
 					'http://schema.org/affiliation',
945 945
 					self::DATA_TYPE_URI
946 946
 				),
947 947
 				// ### schema:email.
948 948
 				$this->rendition_factory->create(
949
-					$this->storage_factory->post_meta( self::FIELD_EMAIL ),
949
+					$this->storage_factory->post_meta(self::FIELD_EMAIL),
950 950
 					'http://schema.org/email'
951 951
 				),
952 952
 			),
@@ -957,8 +957,8 @@  discard block
 block discarded – undo
957 957
 
958 958
 		// Merge the custom fields with those provided by the thing schema.
959 959
 		$parent_schema           = $this->get_thing_schema();
960
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
961
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
960
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $parent_schema['custom_fields']);
961
+		$schema['linked_data']   = array_merge($schema['linked_data'], $parent_schema['linked_data']);
962 962
 
963 963
 		return $schema;
964 964
 
@@ -976,7 +976,7 @@  discard block
 block discarded – undo
976 976
 		$schema = array(
977 977
 			'label'         => 'Place',
978 978
 			'description'   => 'A place.',
979
-			'parents'       => array( 'thing' ),
979
+			'parents'       => array('thing'),
980 980
 			'css_class'     => 'wl-place',
981 981
 			'uri'           => 'http://schema.org/Place',
982 982
 			'same_as'       => array(
@@ -1057,8 +1057,8 @@  discard block
 block discarded – undo
1057 1057
 
1058 1058
 		// Merge the custom fields with those provided by the thing schema.
1059 1059
 		$parent_schema           = $this->get_thing_schema();
1060
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1061
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1060
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $parent_schema['custom_fields']);
1061
+		$schema['linked_data']   = array_merge($schema['linked_data'], $parent_schema['linked_data']);
1062 1062
 
1063 1063
 		return $schema;
1064 1064
 	}
@@ -1075,7 +1075,7 @@  discard block
 block discarded – undo
1075 1075
 		$schema = array(
1076 1076
 			'label'         => 'LocalBusiness',
1077 1077
 			'description'   => 'A local business.',
1078
-			'parents'       => array( 'place', 'organization' ),
1078
+			'parents'       => array('place', 'organization'),
1079 1079
 			'css_class'     => 'wl-local-business',
1080 1080
 			'uri'           => 'http://schema.org/LocalBusiness',
1081 1081
 			'same_as'       => array(
@@ -1092,8 +1092,8 @@  discard block
 block discarded – undo
1092 1092
 		// Merge the custom fields with those provided by the place and organization schema.
1093 1093
 		$place_schema            = $this->get_place_schema();
1094 1094
 		$organization_schema     = $this->get_organization_schema();
1095
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
1096
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $place_schema['linked_data'], $organization_schema['linked_data'] );
1095
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields']);
1096
+		$schema['linked_data']   = array_merge($schema['linked_data'], $place_schema['linked_data'], $organization_schema['linked_data']);
1097 1097
 
1098 1098
 		return $schema;
1099 1099
 	}
@@ -1110,7 +1110,7 @@  discard block
 block discarded – undo
1110 1110
 		$schema = array(
1111 1111
 			'label'         => 'Recipe',
1112 1112
 			'description'   => 'A Recipe.',
1113
-			'parents'       => array( 'CreativeWork' ),
1113
+			'parents'       => array('CreativeWork'),
1114 1114
 			'css_class'     => 'wl-recipe',
1115 1115
 			'uri'           => 'http://schema.org/Recipe',
1116 1116
 			'same_as'       => array(),
@@ -1124,7 +1124,7 @@  discard block
 block discarded – undo
1124 1124
 					'export_type' => 'xsd:string',
1125 1125
 					'constraints' => '',
1126 1126
 					'metabox'     => array(
1127
-						'label' => __( 'Recipe cuisine', 'wordlift' ),
1127
+						'label' => __('Recipe cuisine', 'wordlift'),
1128 1128
 					),
1129 1129
 				),
1130 1130
 				self::FIELD_RECIPE_INGREDIENT       => array(
@@ -1135,7 +1135,7 @@  discard block
 block discarded – undo
1135 1135
 						'cardinality' => INF,
1136 1136
 					),
1137 1137
 					'metabox'     => array(
1138
-						'label' => __( 'Recipe ingredient', 'wordlift' ),
1138
+						'label' => __('Recipe ingredient', 'wordlift'),
1139 1139
 					),
1140 1140
 				),
1141 1141
 				self::FIELD_RECIPE_INSTRUCTIONS     => array(
@@ -1145,7 +1145,7 @@  discard block
 block discarded – undo
1145 1145
 					'constraints' => '',
1146 1146
 					'metabox'     => array(
1147 1147
 						'class' => 'Wordlift_Metabox_Field_Multiline',
1148
-						'label' => __( 'Recipe instructions', 'wordlift' ),
1148
+						'label' => __('Recipe instructions', 'wordlift'),
1149 1149
 					),
1150 1150
 				),
1151 1151
 				self::FIELD_RECIPE_YIELD            => array(
@@ -1154,7 +1154,7 @@  discard block
 block discarded – undo
1154 1154
 					'export_type' => 'xsd:string',
1155 1155
 					'constraints' => '',
1156 1156
 					'metabox'     => array(
1157
-						'label' => __( 'Recipe number of servings', 'wordlift' ),
1157
+						'label' => __('Recipe number of servings', 'wordlift'),
1158 1158
 					),
1159 1159
 				),
1160 1160
 				self::FIELD_RECIPE_INGREDIENT       => array(
@@ -1165,7 +1165,7 @@  discard block
 block discarded – undo
1165 1165
 						'cardinality' => INF,
1166 1166
 					),
1167 1167
 					'metabox'     => array(
1168
-						'label' => __( 'Recipe ingredient', 'wordlift' ),
1168
+						'label' => __('Recipe ingredient', 'wordlift'),
1169 1169
 					),
1170 1170
 				),
1171 1171
 				self::FIELD_NUTRITION_INFO_CALORIES => array(
@@ -1174,7 +1174,7 @@  discard block
 block discarded – undo
1174 1174
 					'export_type' => 'xsd:string',
1175 1175
 					'constraints' => '',
1176 1176
 					'metabox'     => array(
1177
-						'label' => __( 'Calories (e.g. 240 calories)', 'wordlift' ),
1177
+						'label' => __('Calories (e.g. 240 calories)', 'wordlift'),
1178 1178
 					),
1179 1179
 				),
1180 1180
 				self::FIELD_PREP_TIME               => array(
@@ -1184,7 +1184,7 @@  discard block
 block discarded – undo
1184 1184
 					'constraints' => '',
1185 1185
 					'metabox'     => array(
1186 1186
 						'class' => 'Wordlift_Metabox_Field_Duration',
1187
-						'label' => __( 'Recipe preparation time (e.g. 1:30)', 'wordlift' ),
1187
+						'label' => __('Recipe preparation time (e.g. 1:30)', 'wordlift'),
1188 1188
 					),
1189 1189
 				),
1190 1190
 				self::FIELD_COOK_TIME               => array(
@@ -1194,7 +1194,7 @@  discard block
 block discarded – undo
1194 1194
 					'constraints' => '',
1195 1195
 					'metabox'     => array(
1196 1196
 						'class' => 'Wordlift_Metabox_Field_Duration',
1197
-						'label' => __( 'Recipe cook time (e.g. 1:30)', 'wordlift' ),
1197
+						'label' => __('Recipe cook time (e.g. 1:30)', 'wordlift'),
1198 1198
 					),
1199 1199
 				),
1200 1200
 				self::FIELD_TOTAL_TIME              => array(
@@ -1204,36 +1204,36 @@  discard block
 block discarded – undo
1204 1204
 					'constraints' => '',
1205 1205
 					'metabox'     => array(
1206 1206
 						'class' => 'Wordlift_Metabox_Field_Duration',
1207
-						'label' => __( 'Recipe total time (e.g. 1:30)', 'wordlift' ),
1207
+						'label' => __('Recipe total time (e.g. 1:30)', 'wordlift'),
1208 1208
 					),
1209 1209
 				),
1210 1210
 			),
1211 1211
 			'linked_data'   => array(
1212 1212
 				// ### schema:recipeCuisine.
1213 1213
 				$this->rendition_factory->create(
1214
-					$this->storage_factory->post_meta( self::FIELD_RECIPE_CUISINE ),
1214
+					$this->storage_factory->post_meta(self::FIELD_RECIPE_CUISINE),
1215 1215
 					'http://schema.org/recipeCuisine'
1216 1216
 				),
1217 1217
 				// ### schema:recipeIngredient.
1218 1218
 				$this->rendition_factory->create(
1219
-					$this->storage_factory->post_meta( self::FIELD_RECIPE_INGREDIENT ),
1219
+					$this->storage_factory->post_meta(self::FIELD_RECIPE_INGREDIENT),
1220 1220
 					'http://schema.org/recipeIngredient'
1221 1221
 				),
1222 1222
 				// ### schema:prepTime.
1223 1223
 				$this->rendition_factory->create(
1224
-					$this->storage_factory->post_meta( self::FIELD_PREP_TIME ),
1224
+					$this->storage_factory->post_meta(self::FIELD_PREP_TIME),
1225 1225
 					'http://schema.org/prepTime',
1226 1226
 					self::DATA_TYPE_DURATION
1227 1227
 				),
1228 1228
 				// ### schema:cookTime.
1229 1229
 				$this->rendition_factory->create(
1230
-					$this->storage_factory->post_meta( self::FIELD_COOK_TIME ),
1230
+					$this->storage_factory->post_meta(self::FIELD_COOK_TIME),
1231 1231
 					'http://schema.org/cookTime',
1232 1232
 					self::DATA_TYPE_DURATION
1233 1233
 				),
1234 1234
 				// ### schema:totalTime.
1235 1235
 				$this->rendition_factory->create(
1236
-					$this->storage_factory->post_meta( self::FIELD_TOTAL_TIME ),
1236
+					$this->storage_factory->post_meta(self::FIELD_TOTAL_TIME),
1237 1237
 					'http://schema.org/totalTime',
1238 1238
 					self::DATA_TYPE_DURATION
1239 1239
 				),
@@ -1242,8 +1242,8 @@  discard block
 block discarded – undo
1242 1242
 
1243 1243
 		// Merge the custom fields with those provided by the parent schema.
1244 1244
 		$parent_schema           = $this->get_creative_work_schema();
1245
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $parent_schema['custom_fields'] );
1246
-		$schema['linked_data']   = array_merge( $schema['linked_data'], $parent_schema['linked_data'] );
1245
+		$schema['custom_fields'] = array_merge($schema['custom_fields'], $parent_schema['custom_fields']);
1246
+		$schema['linked_data']   = array_merge($schema['linked_data'], $parent_schema['linked_data']);
1247 1247
 
1248 1248
 		return $schema;
1249 1249
 	}
@@ -1284,16 +1284,16 @@  discard block
 block discarded – undo
1284 1284
 	public function get_all_predicates() {
1285 1285
 
1286 1286
 		// Get the custom fields.
1287
-		$renditions = array_reduce( $this->schema, function ( $carry, $item ) {
1288
-			return array_merge( $carry, $item['linked_data'] );
1289
-		}, array() );
1287
+		$renditions = array_reduce($this->schema, function($carry, $item) {
1288
+			return array_merge($carry, $item['linked_data']);
1289
+		}, array());
1290 1290
 
1291 1291
 		// Create a new array of predicates from the custom fields. The initial
1292 1292
 		// array contains just the `http://www.w3.org/1999/02/22-rdf-syntax-ns#type`
1293 1293
 		// (a, rdf:type) predicate (use the full URI).
1294
-		$predicates = array_unique( array_reduce( $renditions, function ( $carry, $item ) {
1295
-			return array_merge( $carry, (array) $item->get_predicate() );
1296
-		}, array() ) );
1294
+		$predicates = array_unique(array_reduce($renditions, function($carry, $item) {
1295
+			return array_merge($carry, (array) $item->get_predicate());
1296
+		}, array()));
1297 1297
 
1298 1298
 		/**
1299 1299
 		 * Filter: 'wl_schema_predicates' - Allow third parties to hook and add additional predicates.
@@ -1301,7 +1301,7 @@  discard block
 block discarded – undo
1301 1301
 		 * @since  3.17.0
1302 1302
 		 * @api arr $predicates Schema.org predicates.
1303 1303
 		 */
1304
-		return apply_filters( 'wl_schema_predicates', $predicates );
1304
+		return apply_filters('wl_schema_predicates', $predicates);
1305 1305
 	}
1306 1306
 
1307 1307
 }
Please login to merge, or discard this patch.
src/includes/class-wordlift-linked-data-service.php 2 patches
Indentation   +282 added lines, -282 removed lines patch added patch discarded remove patch
@@ -18,287 +18,287 @@
 block discarded – undo
18 18
  */
19 19
 class Wordlift_Linked_Data_Service {
20 20
 
21
-	/**
22
-	 * A {@link Wordlift_Log_Service} instance.
23
-	 *
24
-	 * @since  3.15.0
25
-	 * @access private
26
-	 * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
27
-	 */
28
-	private $log;
29
-
30
-	/**
31
-	 * The {@link Wordlift_Entity_Service} instance.
32
-	 *
33
-	 * @since  3.15.0
34
-	 * @access private
35
-	 * @var \Wordlift_Entity_Service $entity_service The {@link Wordlift_Entity_Service} instance.
36
-	 */
37
-	private $entity_service;
38
-
39
-	/**
40
-	 * The {@link Wordlift_Entity_Type_Service} instance.
41
-	 *
42
-	 * @since  3.15.0
43
-	 * @access private
44
-	 * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
45
-	 */
46
-	private $entity_type_service;
47
-
48
-	/**
49
-	 * The {@link Wordlift_Schema_Service} instance.
50
-	 *
51
-	 * @since  3.15.0
52
-	 * @access private
53
-	 * @var \Wordlift_Schema_Service $schema_service The {@link Wordlift_Schema_Service} instance.
54
-	 */
55
-	private $schema_service;
56
-
57
-	/**
58
-	 * The {@link Wordlift_Linked_Data_Service} singleton instance.
59
-	 *
60
-	 * @since  3.15.0
61
-	 * @access private
62
-	 * @var \Wordlift_Linked_Data_Service $instance The {@link Wordlift_Linked_Data_Service} singleton instance.
63
-	 */
64
-	private static $instance;
65
-
66
-	/**
67
-	 * The {@link Wordlift_Sparql_Service} instance.
68
-	 *
69
-	 * @since  3.15.0
70
-	 * @access private
71
-	 * @var \Wordlift_Sparql_Service $sparql_service The {@link Wordlift_Sparql_Service} instance.
72
-	 */
73
-	private $sparql_service;
74
-
75
-	/**
76
-	 * Create a {@link Wordlift_Linked_Data_Service} instance.
77
-	 *
78
-	 * @since 3.15.0
79
-	 *
80
-	 * @param \Wordlift_Entity_Service      $entity_service      The {@link Wordlift_Entity_Service} instance.
81
-	 * @param \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
82
-	 * @param \Wordlift_Schema_Service      $schema_service      The {@link Wordlift_Schema_Service} instance.
83
-	 * @param \Wordlift_Sparql_Service      $sparql_service      The {@link Wordlift_Sparql_Service} instance.
84
-	 */
85
-	public function __construct( $entity_service, $entity_type_service, $schema_service, $sparql_service ) {
86
-
87
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Linked_Data_Service' );
88
-
89
-		$this->entity_service      = $entity_service;
90
-		$this->entity_type_service = $entity_type_service;
91
-		$this->schema_service      = $schema_service;
92
-		$this->sparql_service      = $sparql_service;
93
-
94
-		self::$instance = $this;
95
-
96
-	}
97
-
98
-	/**
99
-	 * Get the singleton instance of {@link Wordlift_Linked_Data_Service}.
100
-	 *
101
-	 * @since 3.15.0
102
-	 *
103
-	 * @return Wordlift_Linked_Data_Service The singleton instance of <a href='psi_element://Wordlift_Linked_Data_Service'>Wordlift_Linked_Data_Service</a>.
104
-	 */
105
-	public static function get_instance() {
106
-
107
-		return self::$instance;
108
-	}
109
-
110
-	/**
111
-	 * Push a {@link WP_Post} to the Linked Data store.
112
-	 *
113
-	 * If the {@link WP_Post} is an entity and it's not of the `Article` type,
114
-	 * then it is pushed to the remote Linked Data store.
115
-	 *
116
-	 * @since 3.15.0
117
-	 *
118
-	 * @param int $post_id The {@link WP_Post}'s id.
119
-	 */
120
-	public function push( $post_id ) {
121
-
122
-		$this->log->debug( "Pushing post $post_id..." );
123
-
124
-		// Bail out if it's not an entity: we do NOT publish non entities or
125
-		// entities of type `Article`s.
126
-		if ( ! $this->entity_service->is_entity( $post_id ) ) {
127
-			$this->log->debug( "Post $post_id is not an entity." );
128
-
129
-			return;
130
-		}
131
-
132
-		// Get the post and push it to the Linked Data store.
133
-		$this->do_push( $post_id );
134
-
135
-		// Reindex the triple store if buffering is turned off.
136
-		if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
137
-			wordlift_reindex_triple_store();
138
-		}
139
-
140
-	}
141
-
142
-	/**
143
-	 * Remove the specified {@link WP_Post} from the Linked Data.
144
-	 *
145
-	 * @since 3.15.0
146
-	 *
147
-	 * @param int $post_id The {@link WP_Post}'s id.
148
-	 */
149
-	public function remove( $post_id ) {
150
-
151
-		// Get the delete statements.
152
-		$deletes      = $this->get_delete_statements( $post_id );
153
-		$delete_query = implode( "\n", $deletes );
154
-		$this->sparql_service->execute( $delete_query );
155
-
156
-	}
157
-
158
-	/**
159
-	 * Push an entity to the Linked Data store.
160
-	 *
161
-	 * @since 3.15.0
162
-	 *
163
-	 * @param int $post_id The {@link WP_Post}'s id.
164
-	 */
165
-	private function do_push( $post_id ) {
166
-		$this->log->debug( "Doing post $post_id push..." );
167
-
168
-		// Get the post.
169
-		$post = get_post( $post_id );
170
-
171
-		// Bail out if the post isn't found.
172
-		if ( null === $post ) {
173
-			$this->log->warn( "Post $post_id not found." );
174
-
175
-			return;
176
-		}
177
-
178
-		// Bail out if the post isn't published.
179
-		if ( 'publish' !== $post->post_status ) {
180
-			$this->log->info( "Post $post_id not published." );
181
-
182
-			return;
183
-		}
184
-
185
-		// Bail out if the URI isn't valid.
186
-		if ( ! $this->has_valid_uri( $post_id ) ) {
187
-			$this->log->warn( "Post $post_id URI invalid." );
188
-
189
-			return;
190
-		}
191
-
192
-		// First remove the post data.
193
-		$this->remove( $post_id );
194
-
195
-		// Get the insert statements.
196
-		$insert_tuples     = $this->get_insert_tuples( $post_id );
197
-		$insert_query_body = implode( "\n", $insert_tuples );
198
-		$insert_query      = "INSERT DATA { $insert_query_body };";
199
-		$this->sparql_service->execute( $insert_query );
200
-
201
-	}
202
-
203
-	/**
204
-	 * Check if an entity's {@link WP_Post} has a valid URI.
205
-	 *
206
-	 * @since 3.15.0
207
-	 *
208
-	 * @param int $post_id The entity's {@link WP_Post}'s id.
209
-	 *
210
-	 * @return bool True if the URI is valid otherwise false.
211
-	 */
212
-	private function has_valid_uri( $post_id ) {
213
-
214
-		// Get the entity's URI.
215
-		$uri = $this->entity_service->get_uri( $post_id );
216
-
217
-		// If the URI isn't found, return false.
218
-		if ( null === $uri ) {
219
-			return false;
220
-		}
221
-
222
-		// If the URI ends with a trailing slash, return false.
223
-		if ( '/' === substr( $uri, - 1 ) ) {
224
-			return false;
225
-		}
226
-
227
-		// URI is valid.
228
-		return true;
229
-	}
230
-
231
-	/**
232
-	 * Get the delete statements.
233
-	 *
234
-	 * @since 3.15.0
235
-	 *
236
-	 * @param int $post_id The {@link WP_Post}'s id.
237
-	 *
238
-	 * @return array An array of delete statements.
239
-	 */
240
-	private function get_delete_statements( $post_id ) {
241
-
242
-		// Get the entity URI.
243
-		$uri = $this->entity_service->get_uri( $post_id );
244
-
245
-		// Prepare the delete statements with the entity as subject.
246
-		$as_subject = array_map( function ( $item ) use ( $uri ) {
247
-			return Wordlift_Query_Builder
248
-				::new_instance()
249
-				->delete()
250
-				->statement( $uri, $item, '?o' )
251
-				->build();
252
-		}, $this->schema_service->get_all_predicates() );
253
-
254
-		// Prepare the delete statements with the entity as object.
255
-		$as_object = array_map( function ( $item ) use ( $uri ) {
256
-			return Wordlift_Query_Builder
257
-				::new_instance()
258
-				->delete()
259
-				->statement( '?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI )
260
-				->build();
261
-		}, $this->schema_service->get_all_predicates() );
262
-
263
-		// Merge the delete statements and return them.
264
-		return array_merge( $as_subject, $as_object );
265
-	}
266
-
267
-	/**
268
-	 * Get the SPARQL insert tuples ( ?s ?p ?o ) for the specified {@link WP_Post}.
269
-	 *
270
-	 * @since 3.15.0
271
-	 *
272
-	 * @param int $post_id The {@link WP_Post}'s id.
273
-	 *
274
-	 * @return array An array of insert tuples.
275
-	 */
276
-	private function get_insert_tuples( $post_id ) {
277
-
278
-		// Get the entity type.
279
-		$type = $this->entity_type_service->get( $post_id );
280
-
281
-		/**
282
-		 * Filter: 'wl_tuple_properties' - Allow third parties to hook and add additional tuples.
283
-		 *
284
-		 * @since 3.17.0
285
-		 * @api   arr $type['linked_data'] A {@link Wordlift_Sparql_Tuple_Rendition} instances.
286
-		 * @api   \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
287
-		 * @api   int $post_id The {@link WP_Post}'s id.
288
-		 */
289
-		$properties = apply_filters( 'wl_tuple_properties', $type['linked_data'], $this->entity_service, $post_id );
290
-
291
-		// Accumulate the tuples.
292
-		$tuples = array();
293
-		/** @var Wordlift_Sparql_Tuple_Rendition $property A {@link Wordlift_Sparql_Tuple_Rendition} instance. */
294
-		foreach ( $properties as $property ) {
295
-			foreach ( $property->get( $post_id ) as $tuple ) {
296
-				$tuples[] = $tuple;
297
-			}
298
-		}
299
-
300
-		// Finally return the tuples.
301
-		return $tuples;
302
-	}
21
+    /**
22
+     * A {@link Wordlift_Log_Service} instance.
23
+     *
24
+     * @since  3.15.0
25
+     * @access private
26
+     * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
27
+     */
28
+    private $log;
29
+
30
+    /**
31
+     * The {@link Wordlift_Entity_Service} instance.
32
+     *
33
+     * @since  3.15.0
34
+     * @access private
35
+     * @var \Wordlift_Entity_Service $entity_service The {@link Wordlift_Entity_Service} instance.
36
+     */
37
+    private $entity_service;
38
+
39
+    /**
40
+     * The {@link Wordlift_Entity_Type_Service} instance.
41
+     *
42
+     * @since  3.15.0
43
+     * @access private
44
+     * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
45
+     */
46
+    private $entity_type_service;
47
+
48
+    /**
49
+     * The {@link Wordlift_Schema_Service} instance.
50
+     *
51
+     * @since  3.15.0
52
+     * @access private
53
+     * @var \Wordlift_Schema_Service $schema_service The {@link Wordlift_Schema_Service} instance.
54
+     */
55
+    private $schema_service;
56
+
57
+    /**
58
+     * The {@link Wordlift_Linked_Data_Service} singleton instance.
59
+     *
60
+     * @since  3.15.0
61
+     * @access private
62
+     * @var \Wordlift_Linked_Data_Service $instance The {@link Wordlift_Linked_Data_Service} singleton instance.
63
+     */
64
+    private static $instance;
65
+
66
+    /**
67
+     * The {@link Wordlift_Sparql_Service} instance.
68
+     *
69
+     * @since  3.15.0
70
+     * @access private
71
+     * @var \Wordlift_Sparql_Service $sparql_service The {@link Wordlift_Sparql_Service} instance.
72
+     */
73
+    private $sparql_service;
74
+
75
+    /**
76
+     * Create a {@link Wordlift_Linked_Data_Service} instance.
77
+     *
78
+     * @since 3.15.0
79
+     *
80
+     * @param \Wordlift_Entity_Service      $entity_service      The {@link Wordlift_Entity_Service} instance.
81
+     * @param \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
82
+     * @param \Wordlift_Schema_Service      $schema_service      The {@link Wordlift_Schema_Service} instance.
83
+     * @param \Wordlift_Sparql_Service      $sparql_service      The {@link Wordlift_Sparql_Service} instance.
84
+     */
85
+    public function __construct( $entity_service, $entity_type_service, $schema_service, $sparql_service ) {
86
+
87
+        $this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Linked_Data_Service' );
88
+
89
+        $this->entity_service      = $entity_service;
90
+        $this->entity_type_service = $entity_type_service;
91
+        $this->schema_service      = $schema_service;
92
+        $this->sparql_service      = $sparql_service;
93
+
94
+        self::$instance = $this;
95
+
96
+    }
97
+
98
+    /**
99
+     * Get the singleton instance of {@link Wordlift_Linked_Data_Service}.
100
+     *
101
+     * @since 3.15.0
102
+     *
103
+     * @return Wordlift_Linked_Data_Service The singleton instance of <a href='psi_element://Wordlift_Linked_Data_Service'>Wordlift_Linked_Data_Service</a>.
104
+     */
105
+    public static function get_instance() {
106
+
107
+        return self::$instance;
108
+    }
109
+
110
+    /**
111
+     * Push a {@link WP_Post} to the Linked Data store.
112
+     *
113
+     * If the {@link WP_Post} is an entity and it's not of the `Article` type,
114
+     * then it is pushed to the remote Linked Data store.
115
+     *
116
+     * @since 3.15.0
117
+     *
118
+     * @param int $post_id The {@link WP_Post}'s id.
119
+     */
120
+    public function push( $post_id ) {
121
+
122
+        $this->log->debug( "Pushing post $post_id..." );
123
+
124
+        // Bail out if it's not an entity: we do NOT publish non entities or
125
+        // entities of type `Article`s.
126
+        if ( ! $this->entity_service->is_entity( $post_id ) ) {
127
+            $this->log->debug( "Post $post_id is not an entity." );
128
+
129
+            return;
130
+        }
131
+
132
+        // Get the post and push it to the Linked Data store.
133
+        $this->do_push( $post_id );
134
+
135
+        // Reindex the triple store if buffering is turned off.
136
+        if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
137
+            wordlift_reindex_triple_store();
138
+        }
139
+
140
+    }
141
+
142
+    /**
143
+     * Remove the specified {@link WP_Post} from the Linked Data.
144
+     *
145
+     * @since 3.15.0
146
+     *
147
+     * @param int $post_id The {@link WP_Post}'s id.
148
+     */
149
+    public function remove( $post_id ) {
150
+
151
+        // Get the delete statements.
152
+        $deletes      = $this->get_delete_statements( $post_id );
153
+        $delete_query = implode( "\n", $deletes );
154
+        $this->sparql_service->execute( $delete_query );
155
+
156
+    }
157
+
158
+    /**
159
+     * Push an entity to the Linked Data store.
160
+     *
161
+     * @since 3.15.0
162
+     *
163
+     * @param int $post_id The {@link WP_Post}'s id.
164
+     */
165
+    private function do_push( $post_id ) {
166
+        $this->log->debug( "Doing post $post_id push..." );
167
+
168
+        // Get the post.
169
+        $post = get_post( $post_id );
170
+
171
+        // Bail out if the post isn't found.
172
+        if ( null === $post ) {
173
+            $this->log->warn( "Post $post_id not found." );
174
+
175
+            return;
176
+        }
177
+
178
+        // Bail out if the post isn't published.
179
+        if ( 'publish' !== $post->post_status ) {
180
+            $this->log->info( "Post $post_id not published." );
181
+
182
+            return;
183
+        }
184
+
185
+        // Bail out if the URI isn't valid.
186
+        if ( ! $this->has_valid_uri( $post_id ) ) {
187
+            $this->log->warn( "Post $post_id URI invalid." );
188
+
189
+            return;
190
+        }
191
+
192
+        // First remove the post data.
193
+        $this->remove( $post_id );
194
+
195
+        // Get the insert statements.
196
+        $insert_tuples     = $this->get_insert_tuples( $post_id );
197
+        $insert_query_body = implode( "\n", $insert_tuples );
198
+        $insert_query      = "INSERT DATA { $insert_query_body };";
199
+        $this->sparql_service->execute( $insert_query );
200
+
201
+    }
202
+
203
+    /**
204
+     * Check if an entity's {@link WP_Post} has a valid URI.
205
+     *
206
+     * @since 3.15.0
207
+     *
208
+     * @param int $post_id The entity's {@link WP_Post}'s id.
209
+     *
210
+     * @return bool True if the URI is valid otherwise false.
211
+     */
212
+    private function has_valid_uri( $post_id ) {
213
+
214
+        // Get the entity's URI.
215
+        $uri = $this->entity_service->get_uri( $post_id );
216
+
217
+        // If the URI isn't found, return false.
218
+        if ( null === $uri ) {
219
+            return false;
220
+        }
221
+
222
+        // If the URI ends with a trailing slash, return false.
223
+        if ( '/' === substr( $uri, - 1 ) ) {
224
+            return false;
225
+        }
226
+
227
+        // URI is valid.
228
+        return true;
229
+    }
230
+
231
+    /**
232
+     * Get the delete statements.
233
+     *
234
+     * @since 3.15.0
235
+     *
236
+     * @param int $post_id The {@link WP_Post}'s id.
237
+     *
238
+     * @return array An array of delete statements.
239
+     */
240
+    private function get_delete_statements( $post_id ) {
241
+
242
+        // Get the entity URI.
243
+        $uri = $this->entity_service->get_uri( $post_id );
244
+
245
+        // Prepare the delete statements with the entity as subject.
246
+        $as_subject = array_map( function ( $item ) use ( $uri ) {
247
+            return Wordlift_Query_Builder
248
+                ::new_instance()
249
+                ->delete()
250
+                ->statement( $uri, $item, '?o' )
251
+                ->build();
252
+        }, $this->schema_service->get_all_predicates() );
253
+
254
+        // Prepare the delete statements with the entity as object.
255
+        $as_object = array_map( function ( $item ) use ( $uri ) {
256
+            return Wordlift_Query_Builder
257
+                ::new_instance()
258
+                ->delete()
259
+                ->statement( '?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI )
260
+                ->build();
261
+        }, $this->schema_service->get_all_predicates() );
262
+
263
+        // Merge the delete statements and return them.
264
+        return array_merge( $as_subject, $as_object );
265
+    }
266
+
267
+    /**
268
+     * Get the SPARQL insert tuples ( ?s ?p ?o ) for the specified {@link WP_Post}.
269
+     *
270
+     * @since 3.15.0
271
+     *
272
+     * @param int $post_id The {@link WP_Post}'s id.
273
+     *
274
+     * @return array An array of insert tuples.
275
+     */
276
+    private function get_insert_tuples( $post_id ) {
277
+
278
+        // Get the entity type.
279
+        $type = $this->entity_type_service->get( $post_id );
280
+
281
+        /**
282
+         * Filter: 'wl_tuple_properties' - Allow third parties to hook and add additional tuples.
283
+         *
284
+         * @since 3.17.0
285
+         * @api   arr $type['linked_data'] A {@link Wordlift_Sparql_Tuple_Rendition} instances.
286
+         * @api   \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
287
+         * @api   int $post_id The {@link WP_Post}'s id.
288
+         */
289
+        $properties = apply_filters( 'wl_tuple_properties', $type['linked_data'], $this->entity_service, $post_id );
290
+
291
+        // Accumulate the tuples.
292
+        $tuples = array();
293
+        /** @var Wordlift_Sparql_Tuple_Rendition $property A {@link Wordlift_Sparql_Tuple_Rendition} instance. */
294
+        foreach ( $properties as $property ) {
295
+            foreach ( $property->get( $post_id ) as $tuple ) {
296
+                $tuples[] = $tuple;
297
+            }
298
+        }
299
+
300
+        // Finally return the tuples.
301
+        return $tuples;
302
+    }
303 303
 
304 304
 }
Please login to merge, or discard this patch.
Spacing   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -82,9 +82,9 @@  discard block
 block discarded – undo
82 82
 	 * @param \Wordlift_Schema_Service      $schema_service      The {@link Wordlift_Schema_Service} instance.
83 83
 	 * @param \Wordlift_Sparql_Service      $sparql_service      The {@link Wordlift_Sparql_Service} instance.
84 84
 	 */
85
-	public function __construct( $entity_service, $entity_type_service, $schema_service, $sparql_service ) {
85
+	public function __construct($entity_service, $entity_type_service, $schema_service, $sparql_service) {
86 86
 
87
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Linked_Data_Service' );
87
+		$this->log = Wordlift_Log_Service::get_logger('Wordlift_Linked_Data_Service');
88 88
 
89 89
 		$this->entity_service      = $entity_service;
90 90
 		$this->entity_type_service = $entity_type_service;
@@ -117,23 +117,23 @@  discard block
 block discarded – undo
117 117
 	 *
118 118
 	 * @param int $post_id The {@link WP_Post}'s id.
119 119
 	 */
120
-	public function push( $post_id ) {
120
+	public function push($post_id) {
121 121
 
122
-		$this->log->debug( "Pushing post $post_id..." );
122
+		$this->log->debug("Pushing post $post_id...");
123 123
 
124 124
 		// Bail out if it's not an entity: we do NOT publish non entities or
125 125
 		// entities of type `Article`s.
126
-		if ( ! $this->entity_service->is_entity( $post_id ) ) {
127
-			$this->log->debug( "Post $post_id is not an entity." );
126
+		if ( ! $this->entity_service->is_entity($post_id)) {
127
+			$this->log->debug("Post $post_id is not an entity.");
128 128
 
129 129
 			return;
130 130
 		}
131 131
 
132 132
 		// Get the post and push it to the Linked Data store.
133
-		$this->do_push( $post_id );
133
+		$this->do_push($post_id);
134 134
 
135 135
 		// Reindex the triple store if buffering is turned off.
136
-		if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
136
+		if (false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING) {
137 137
 			wordlift_reindex_triple_store();
138 138
 		}
139 139
 
@@ -146,12 +146,12 @@  discard block
 block discarded – undo
146 146
 	 *
147 147
 	 * @param int $post_id The {@link WP_Post}'s id.
148 148
 	 */
149
-	public function remove( $post_id ) {
149
+	public function remove($post_id) {
150 150
 
151 151
 		// Get the delete statements.
152
-		$deletes      = $this->get_delete_statements( $post_id );
153
-		$delete_query = implode( "\n", $deletes );
154
-		$this->sparql_service->execute( $delete_query );
152
+		$deletes      = $this->get_delete_statements($post_id);
153
+		$delete_query = implode("\n", $deletes);
154
+		$this->sparql_service->execute($delete_query);
155 155
 
156 156
 	}
157 157
 
@@ -162,41 +162,41 @@  discard block
 block discarded – undo
162 162
 	 *
163 163
 	 * @param int $post_id The {@link WP_Post}'s id.
164 164
 	 */
165
-	private function do_push( $post_id ) {
166
-		$this->log->debug( "Doing post $post_id push..." );
165
+	private function do_push($post_id) {
166
+		$this->log->debug("Doing post $post_id push...");
167 167
 
168 168
 		// Get the post.
169
-		$post = get_post( $post_id );
169
+		$post = get_post($post_id);
170 170
 
171 171
 		// Bail out if the post isn't found.
172
-		if ( null === $post ) {
173
-			$this->log->warn( "Post $post_id not found." );
172
+		if (null === $post) {
173
+			$this->log->warn("Post $post_id not found.");
174 174
 
175 175
 			return;
176 176
 		}
177 177
 
178 178
 		// Bail out if the post isn't published.
179
-		if ( 'publish' !== $post->post_status ) {
180
-			$this->log->info( "Post $post_id not published." );
179
+		if ('publish' !== $post->post_status) {
180
+			$this->log->info("Post $post_id not published.");
181 181
 
182 182
 			return;
183 183
 		}
184 184
 
185 185
 		// Bail out if the URI isn't valid.
186
-		if ( ! $this->has_valid_uri( $post_id ) ) {
187
-			$this->log->warn( "Post $post_id URI invalid." );
186
+		if ( ! $this->has_valid_uri($post_id)) {
187
+			$this->log->warn("Post $post_id URI invalid.");
188 188
 
189 189
 			return;
190 190
 		}
191 191
 
192 192
 		// First remove the post data.
193
-		$this->remove( $post_id );
193
+		$this->remove($post_id);
194 194
 
195 195
 		// Get the insert statements.
196
-		$insert_tuples     = $this->get_insert_tuples( $post_id );
197
-		$insert_query_body = implode( "\n", $insert_tuples );
196
+		$insert_tuples     = $this->get_insert_tuples($post_id);
197
+		$insert_query_body = implode("\n", $insert_tuples);
198 198
 		$insert_query      = "INSERT DATA { $insert_query_body };";
199
-		$this->sparql_service->execute( $insert_query );
199
+		$this->sparql_service->execute($insert_query);
200 200
 
201 201
 	}
202 202
 
@@ -209,18 +209,18 @@  discard block
 block discarded – undo
209 209
 	 *
210 210
 	 * @return bool True if the URI is valid otherwise false.
211 211
 	 */
212
-	private function has_valid_uri( $post_id ) {
212
+	private function has_valid_uri($post_id) {
213 213
 
214 214
 		// Get the entity's URI.
215
-		$uri = $this->entity_service->get_uri( $post_id );
215
+		$uri = $this->entity_service->get_uri($post_id);
216 216
 
217 217
 		// If the URI isn't found, return false.
218
-		if ( null === $uri ) {
218
+		if (null === $uri) {
219 219
 			return false;
220 220
 		}
221 221
 
222 222
 		// If the URI ends with a trailing slash, return false.
223
-		if ( '/' === substr( $uri, - 1 ) ) {
223
+		if ('/' === substr($uri, - 1)) {
224 224
 			return false;
225 225
 		}
226 226
 
@@ -237,31 +237,31 @@  discard block
 block discarded – undo
237 237
 	 *
238 238
 	 * @return array An array of delete statements.
239 239
 	 */
240
-	private function get_delete_statements( $post_id ) {
240
+	private function get_delete_statements($post_id) {
241 241
 
242 242
 		// Get the entity URI.
243
-		$uri = $this->entity_service->get_uri( $post_id );
243
+		$uri = $this->entity_service->get_uri($post_id);
244 244
 
245 245
 		// Prepare the delete statements with the entity as subject.
246
-		$as_subject = array_map( function ( $item ) use ( $uri ) {
246
+		$as_subject = array_map(function($item) use ($uri) {
247 247
 			return Wordlift_Query_Builder
248 248
 				::new_instance()
249 249
 				->delete()
250
-				->statement( $uri, $item, '?o' )
250
+				->statement($uri, $item, '?o')
251 251
 				->build();
252
-		}, $this->schema_service->get_all_predicates() );
252
+		}, $this->schema_service->get_all_predicates());
253 253
 
254 254
 		// Prepare the delete statements with the entity as object.
255
-		$as_object = array_map( function ( $item ) use ( $uri ) {
255
+		$as_object = array_map(function($item) use ($uri) {
256 256
 			return Wordlift_Query_Builder
257 257
 				::new_instance()
258 258
 				->delete()
259
-				->statement( '?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI )
259
+				->statement('?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI)
260 260
 				->build();
261
-		}, $this->schema_service->get_all_predicates() );
261
+		}, $this->schema_service->get_all_predicates());
262 262
 
263 263
 		// Merge the delete statements and return them.
264
-		return array_merge( $as_subject, $as_object );
264
+		return array_merge($as_subject, $as_object);
265 265
 	}
266 266
 
267 267
 	/**
@@ -273,10 +273,10 @@  discard block
 block discarded – undo
273 273
 	 *
274 274
 	 * @return array An array of insert tuples.
275 275
 	 */
276
-	private function get_insert_tuples( $post_id ) {
276
+	private function get_insert_tuples($post_id) {
277 277
 
278 278
 		// Get the entity type.
279
-		$type = $this->entity_type_service->get( $post_id );
279
+		$type = $this->entity_type_service->get($post_id);
280 280
 
281 281
 		/**
282 282
 		 * Filter: 'wl_tuple_properties' - Allow third parties to hook and add additional tuples.
@@ -286,13 +286,13 @@  discard block
 block discarded – undo
286 286
 		 * @api   \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
287 287
 		 * @api   int $post_id The {@link WP_Post}'s id.
288 288
 		 */
289
-		$properties = apply_filters( 'wl_tuple_properties', $type['linked_data'], $this->entity_service, $post_id );
289
+		$properties = apply_filters('wl_tuple_properties', $type['linked_data'], $this->entity_service, $post_id);
290 290
 
291 291
 		// Accumulate the tuples.
292 292
 		$tuples = array();
293 293
 		/** @var Wordlift_Sparql_Tuple_Rendition $property A {@link Wordlift_Sparql_Tuple_Rendition} instance. */
294
-		foreach ( $properties as $property ) {
295
-			foreach ( $property->get( $post_id ) as $tuple ) {
294
+		foreach ($properties as $property) {
295
+			foreach ($property->get($post_id) as $tuple) {
296 296
 				$tuples[] = $tuple;
297 297
 			}
298 298
 		}
Please login to merge, or discard this patch.
src/includes/class-wordlift-sparql-service.php 2 patches
Indentation   +290 added lines, -290 removed lines patch added patch discarded remove patch
@@ -18,298 +18,298 @@
 block discarded – undo
18 18
  */
19 19
 class Wordlift_Sparql_Service {
20 20
 
21
-	/**
22
-	 * A {@link Wordlift_Log_Service} instance.
23
-	 *
24
-	 * @since  3.6.0
25
-	 * @access private
26
-	 * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
27
-	 */
28
-	private static $log;
29
-
30
-	/**
31
-	 * The {@link Wordlift_Sparql_Service} singleton instance.
32
-	 *
33
-	 * @since  3.6.0
34
-	 * @access private
35
-	 * @var \Wordlift_Sparql_Service $instance The {@link Wordlift_Sparql_Service} singleton instance.
36
-	 */
37
-	private static $instance;
38
-
39
-	/**
40
-	 * Create a {@link Wordlift_Sparql_Service} instance.
41
-	 *
42
-	 * @since 3.6.0
43
-	 */
44
-	public function __construct() {
45
-
46
-		self::$log = Wordlift_Log_Service::get_logger( 'Wordlift_Sparql_Service' );
47
-
48
-		self::$instance = $this;
49
-
50
-	}
51
-
52
-	/**
53
-	 * Get the singleton instance of the {@link Wordlift_Sparql_Service}.
54
-	 *
55
-	 * @since 3.6.0
56
-	 * @return \Wordlift_Sparql_Service
57
-	 */
58
-	public static function get_instance() {
59
-
60
-		return self::$instance;
61
-	}
62
-
63
-	/**
64
-	 * Queue a SPARQL statement for execution.
65
-	 *
66
-	 * @since 3.6.0
67
-	 *
68
-	 * @param string $stmt  The SPARQL statement.
69
-	 * @param bool   $queue Whether to queue the statement for asynchronous
70
-	 *                      execution.
71
-	 */
72
-	public function execute( $stmt, $queue = WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
73
-
74
-		rl_execute_sparql_update_query( $stmt, $queue );
75
-
76
-	}
77
-
78
-	/**
79
-	 * Run the SPARQL queries buffered for the specified request id.
80
-	 *
81
-	 * @since 3.13.2
82
-	 *
83
-	 * @param string $request_id A unique request id.
84
-	 */
85
-	public function run_sparql_query( $request_id ) {
86
-
87
-		self::$log->debug( "Running SPARQL queries..." );
88
-
89
-		// Look for a free temporary filename.
90
-		for ( $index = 1; $index < PHP_INT_MAX; $index ++ ) {
91
-			$filename = WL_TEMP_DIR . $request_id . "-$index.sparql";
92
-
93
-			// Bail out if there are no files left.
94
-			if ( ! file_exists( $filename ) ) {
95
-				break;
96
-			}
97
-
98
-			self::$log->debug( "Running SPARQL from $filename..." );
99
-
100
-			// Get the query saved in the file.
101
-			$query = file_get_contents( $filename );
102
-
103
-			// Execute the SPARQL query.
104
-			rl_execute_sparql_update_query( $query, false );
105
-
106
-			// Delete the temporary file.
107
-			unlink( $filename );
108
-		}
109
-
110
-		// Reindex the triple store.
111
-		wordlift_reindex_triple_store();
112
-
113
-	}
114
-
115
-	/**
116
-	 * Queue a SPARQL statement for asynchronous execution.
117
-	 *
118
-	 * @since 3.13.2
119
-	 *
120
-	 * @param string $stmt The SPARQL statement.
121
-	 */
122
-	public function queue( $stmt ) {
123
-
124
-		// Get a temporary filename.
125
-		$filename = $this->get_temporary_file_for_sparql();
126
-
127
-		self::$log->debug( "Buffering SPARQL to file $filename..." );
128
-
129
-		// Write the contents to the temporary filename.
130
-		file_put_contents( $filename, $stmt . "\n", FILE_APPEND );
131
-
132
-	}
133
-
134
-	/**
135
-	 * Get a temporary filename where to store SPARQL queries.
136
-	 *
137
-	 * @since 3.13.2
138
-	 *
139
-	 * @return string The filename.
140
-	 * @throws Exception An exception is thrown if there are already 1.000
141
-	 *                   temporary files for this request.
142
-	 */
143
-	private function get_temporary_file_for_sparql() {
144
-
145
-		// Look for a free temporary filename.
146
-		for ( $index = 1; $index < PHP_INT_MAX; $index ++ ) {
147
-			$filename = WL_TEMP_DIR . WL_REQUEST_ID . "-$index.sparql";
148
-
149
-			if ( ! file_exists( $filename ) ) {
150
-
151
-				// Only if this it the first buffered SPARQL, then launch the
152
-				// action which will be handled by the Async Task. The Async
153
-				// Task will take care of all the buffered files _on shutdown_.
154
-				if ( 1 === $index ) {
155
-					do_action( 'wl_run_sparql_query', WL_REQUEST_ID );
156
-				}
157
-
158
-				// Return the temporary filename.
159
-				return $filename;
160
-			}
161
-		}
21
+    /**
22
+     * A {@link Wordlift_Log_Service} instance.
23
+     *
24
+     * @since  3.6.0
25
+     * @access private
26
+     * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
27
+     */
28
+    private static $log;
29
+
30
+    /**
31
+     * The {@link Wordlift_Sparql_Service} singleton instance.
32
+     *
33
+     * @since  3.6.0
34
+     * @access private
35
+     * @var \Wordlift_Sparql_Service $instance The {@link Wordlift_Sparql_Service} singleton instance.
36
+     */
37
+    private static $instance;
38
+
39
+    /**
40
+     * Create a {@link Wordlift_Sparql_Service} instance.
41
+     *
42
+     * @since 3.6.0
43
+     */
44
+    public function __construct() {
45
+
46
+        self::$log = Wordlift_Log_Service::get_logger( 'Wordlift_Sparql_Service' );
47
+
48
+        self::$instance = $this;
49
+
50
+    }
51
+
52
+    /**
53
+     * Get the singleton instance of the {@link Wordlift_Sparql_Service}.
54
+     *
55
+     * @since 3.6.0
56
+     * @return \Wordlift_Sparql_Service
57
+     */
58
+    public static function get_instance() {
59
+
60
+        return self::$instance;
61
+    }
62
+
63
+    /**
64
+     * Queue a SPARQL statement for execution.
65
+     *
66
+     * @since 3.6.0
67
+     *
68
+     * @param string $stmt  The SPARQL statement.
69
+     * @param bool   $queue Whether to queue the statement for asynchronous
70
+     *                      execution.
71
+     */
72
+    public function execute( $stmt, $queue = WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
73
+
74
+        rl_execute_sparql_update_query( $stmt, $queue );
75
+
76
+    }
77
+
78
+    /**
79
+     * Run the SPARQL queries buffered for the specified request id.
80
+     *
81
+     * @since 3.13.2
82
+     *
83
+     * @param string $request_id A unique request id.
84
+     */
85
+    public function run_sparql_query( $request_id ) {
86
+
87
+        self::$log->debug( "Running SPARQL queries..." );
88
+
89
+        // Look for a free temporary filename.
90
+        for ( $index = 1; $index < PHP_INT_MAX; $index ++ ) {
91
+            $filename = WL_TEMP_DIR . $request_id . "-$index.sparql";
92
+
93
+            // Bail out if there are no files left.
94
+            if ( ! file_exists( $filename ) ) {
95
+                break;
96
+            }
97
+
98
+            self::$log->debug( "Running SPARQL from $filename..." );
99
+
100
+            // Get the query saved in the file.
101
+            $query = file_get_contents( $filename );
102
+
103
+            // Execute the SPARQL query.
104
+            rl_execute_sparql_update_query( $query, false );
105
+
106
+            // Delete the temporary file.
107
+            unlink( $filename );
108
+        }
109
+
110
+        // Reindex the triple store.
111
+        wordlift_reindex_triple_store();
112
+
113
+    }
114
+
115
+    /**
116
+     * Queue a SPARQL statement for asynchronous execution.
117
+     *
118
+     * @since 3.13.2
119
+     *
120
+     * @param string $stmt The SPARQL statement.
121
+     */
122
+    public function queue( $stmt ) {
123
+
124
+        // Get a temporary filename.
125
+        $filename = $this->get_temporary_file_for_sparql();
126
+
127
+        self::$log->debug( "Buffering SPARQL to file $filename..." );
128
+
129
+        // Write the contents to the temporary filename.
130
+        file_put_contents( $filename, $stmt . "\n", FILE_APPEND );
131
+
132
+    }
133
+
134
+    /**
135
+     * Get a temporary filename where to store SPARQL queries.
136
+     *
137
+     * @since 3.13.2
138
+     *
139
+     * @return string The filename.
140
+     * @throws Exception An exception is thrown if there are already 1.000
141
+     *                   temporary files for this request.
142
+     */
143
+    private function get_temporary_file_for_sparql() {
144
+
145
+        // Look for a free temporary filename.
146
+        for ( $index = 1; $index < PHP_INT_MAX; $index ++ ) {
147
+            $filename = WL_TEMP_DIR . WL_REQUEST_ID . "-$index.sparql";
148
+
149
+            if ( ! file_exists( $filename ) ) {
150
+
151
+                // Only if this it the first buffered SPARQL, then launch the
152
+                // action which will be handled by the Async Task. The Async
153
+                // Task will take care of all the buffered files _on shutdown_.
154
+                if ( 1 === $index ) {
155
+                    do_action( 'wl_run_sparql_query', WL_REQUEST_ID );
156
+                }
157
+
158
+                // Return the temporary filename.
159
+                return $filename;
160
+            }
161
+        }
162 162
 
163
-		throw new Exception( 'Cannot create a temporary file [ ' . WL_TEMP_DIR . WL_REQUEST_ID . ' ].' );
164
-	}
165
-
166
-	/**
167
-	 * Execute the SELECT query.
168
-	 *
169
-	 * @since 3.12.2
170
-	 *
171
-	 * @param string $query The SELECT query to execute.
172
-	 *
173
-	 * @return WP_Error|array The response or WP_Error on failure.
174
-	 */
175
-	public function select( $query ) {
176
-
177
-		// Prepare the SPARQL statement by prepending the default namespaces.
178
-		$sparql = rl_sparql_prefixes() . "\n" . $query;
179
-
180
-		// Get the SPARQL SELECT URL.
181
-		$url = wl_configuration_get_query_select_url() . urlencode( $sparql );
163
+        throw new Exception( 'Cannot create a temporary file [ ' . WL_TEMP_DIR . WL_REQUEST_ID . ' ].' );
164
+    }
165
+
166
+    /**
167
+     * Execute the SELECT query.
168
+     *
169
+     * @since 3.12.2
170
+     *
171
+     * @param string $query The SELECT query to execute.
172
+     *
173
+     * @return WP_Error|array The response or WP_Error on failure.
174
+     */
175
+    public function select( $query ) {
176
+
177
+        // Prepare the SPARQL statement by prepending the default namespaces.
178
+        $sparql = rl_sparql_prefixes() . "\n" . $query;
179
+
180
+        // Get the SPARQL SELECT URL.
181
+        $url = wl_configuration_get_query_select_url() . urlencode( $sparql );
182 182
 
183
-		/**
184
-		 * Filter: 'wl_sparql_query_http_args' - Allow third parties to hook and add additional HTTP args.
185
-		 *
186
-		 * @since 3.17.0
187
-		 * @api   arr Current http options.
188
-		 */
189
-		$args = apply_filters( 'wl_sparql_query_http_args', unserialize( WL_REDLINK_API_HTTP_OPTIONS ) );
190
-
191
-		return wp_remote_get( $url, $args );
192
-	}
193
-
194
-	/**
195
-	 * Formats the provided value according to the specified type in order to
196
-	 * insert the value using SPARQL. The value is also escaped.
197
-	 *
198
-	 * @since 3.6.0
199
-	 *
200
-	 * @param string      $value    The value.
201
-	 * @param string      $type     The value type.
202
-	 * @param string|null $language The language tag or null if not set.
203
-	 *
204
-	 * @return string The formatted value for SPARQL statements.
205
-	 */
206
-	public static function format( $value, $type = null, $language = null ) {
207
-
208
-		// see https://www.w3.org/TR/sparql11-query/.
209
-
210
-		switch ( $type ) {
211
-
212
-			case Wordlift_Schema_Service::DATA_TYPE_BOOLEAN:
213
-				// SPARQL supports 'true' and 'false', so we evaluate the $value
214
-				// and return true/false accordingly.
215
-				return $value ? 'true' : 'false';
216
-
217
-			case Wordlift_Schema_Service::DATA_TYPE_DATE:
218
-				$date       = date_create_from_format( 'Y/m/d', $value );
219
-				$date_value = date_format( $date, 'Y-m-d' );
220
-
221
-				return sprintf( '"%s"^^xsd:date', self::escape( $date_value ) );
222
-
223
-			case Wordlift_Schema_Service::DATA_TYPE_DATE_TIME:
224
-				$date       = date_create_from_format( 'Y/m/d H:i', $value );
225
-				$date_value = date_format( $date, 'Y-m-d\TH:i:00' );
226
-
227
-				return sprintf( '"%s"^^xsd:dateTime', self::escape( $date_value ) );
228
-
229
-			case Wordlift_Schema_Service::DATA_TYPE_DURATION:
230
-				$time       = date_create_from_format( 'H:i', $value );
231
-				$time_value = sprintf( 'PT%dH%dM', date_format( $time, 'H' ), intval( date_format( $time, 'i' ) ) );
232
-
233
-				return sprintf( '"%s"^^xsd:duration', self::escape( $time_value ) );
234
-
235
-			case Wordlift_Schema_Service::DATA_TYPE_DOUBLE:
236
-				return sprintf( '"%s"^^xsd:double', self::escape( $value ) );
237
-
238
-			case Wordlift_Schema_Service::DATA_TYPE_INTEGER:
239
-				return sprintf( '"%s"^^xsd:integer', self::escape( $value ) );
240
-
241
-			case Wordlift_Schema_Service::DATA_TYPE_STRING:
242
-				return sprintf( '"%s"^^xsd:string', self::escape( $value ) );
243
-
244
-			case Wordlift_Schema_Service::DATA_TYPE_URI:
245
-				return sprintf( '<%s>', self::escape_uri( $value ) );
246
-
247
-			case null:
248
-				$language_tag = ( null !== $language ? "@$language" : '' );
249
-
250
-				return sprintf( '"%s"%s', self::escape( $value ), $language_tag );
251
-
252
-			default:
253
-
254
-				self::$log->warn( "Unknown data type [ type :: $type ]" );
255
-
256
-				// Try to insert the value anyway.
257
-				return sprintf( '"%s"', self::escape( $value ) );
258
-		}
259
-
260
-	}
261
-
262
-	/**
263
-	 * Escapes an URI for a SPARQL statement.
264
-	 *
265
-	 * @since 3.6.0
266
-	 *
267
-	 * @param string $uri The URI to escape.
268
-	 *
269
-	 * @return string The escaped URI.
270
-	 */
271
-	public static function escape_uri( $uri ) {
272
-
273
-		// Should we validate the IRI?
274
-		// http://www.w3.org/TR/sparql11-query/#QSynIRI
275
-
276
-		$uri = str_replace( '<', '\<', $uri );
277
-		$uri = str_replace( '>', '\>', $uri );
278
-
279
-		return $uri;
280
-	}
281
-
282
-	/**
283
-	 * Escapes a string for a SPARQL statement.
284
-	 *
285
-	 * @since 3.6.0
286
-	 *
287
-	 * @param string $string The string to escape.
288
-	 *
289
-	 * @return string The escaped string.
290
-	 */
291
-	public static function escape( $string ) {
292
-
293
-		// see http://www.w3.org/TR/rdf-sparql-query/
294
-		//    '\t'	U+0009 (tab)
295
-		//    '\n'	U+000A (line feed)
296
-		//    '\r'	U+000D (carriage return)
297
-		//    '\b'	U+0008 (backspace)
298
-		//    '\f'	U+000C (form feed)
299
-		//    '\"'	U+0022 (quotation mark, double quote mark)
300
-		//    "\'"	U+0027 (apostrophe-quote, single quote mark)
301
-		//    '\\'	U+005C (backslash)
302
-
303
-		$string = str_replace( '\\', '\\\\', $string );
304
-		$string = str_replace( '\'', '\\\'', $string );
305
-		$string = str_replace( '"', '\\"', $string );
306
-		$string = str_replace( "\f", '\\f', $string );
307
-		$string = str_replace( "\b", '\\b', $string );
308
-		$string = str_replace( "\r", '\\r', $string );
309
-		$string = str_replace( "\n", '\\n', $string );
310
-		$string = str_replace( "\t", '\\t', $string );
183
+        /**
184
+         * Filter: 'wl_sparql_query_http_args' - Allow third parties to hook and add additional HTTP args.
185
+         *
186
+         * @since 3.17.0
187
+         * @api   arr Current http options.
188
+         */
189
+        $args = apply_filters( 'wl_sparql_query_http_args', unserialize( WL_REDLINK_API_HTTP_OPTIONS ) );
190
+
191
+        return wp_remote_get( $url, $args );
192
+    }
193
+
194
+    /**
195
+     * Formats the provided value according to the specified type in order to
196
+     * insert the value using SPARQL. The value is also escaped.
197
+     *
198
+     * @since 3.6.0
199
+     *
200
+     * @param string      $value    The value.
201
+     * @param string      $type     The value type.
202
+     * @param string|null $language The language tag or null if not set.
203
+     *
204
+     * @return string The formatted value for SPARQL statements.
205
+     */
206
+    public static function format( $value, $type = null, $language = null ) {
207
+
208
+        // see https://www.w3.org/TR/sparql11-query/.
209
+
210
+        switch ( $type ) {
211
+
212
+            case Wordlift_Schema_Service::DATA_TYPE_BOOLEAN:
213
+                // SPARQL supports 'true' and 'false', so we evaluate the $value
214
+                // and return true/false accordingly.
215
+                return $value ? 'true' : 'false';
216
+
217
+            case Wordlift_Schema_Service::DATA_TYPE_DATE:
218
+                $date       = date_create_from_format( 'Y/m/d', $value );
219
+                $date_value = date_format( $date, 'Y-m-d' );
220
+
221
+                return sprintf( '"%s"^^xsd:date', self::escape( $date_value ) );
222
+
223
+            case Wordlift_Schema_Service::DATA_TYPE_DATE_TIME:
224
+                $date       = date_create_from_format( 'Y/m/d H:i', $value );
225
+                $date_value = date_format( $date, 'Y-m-d\TH:i:00' );
226
+
227
+                return sprintf( '"%s"^^xsd:dateTime', self::escape( $date_value ) );
228
+
229
+            case Wordlift_Schema_Service::DATA_TYPE_DURATION:
230
+                $time       = date_create_from_format( 'H:i', $value );
231
+                $time_value = sprintf( 'PT%dH%dM', date_format( $time, 'H' ), intval( date_format( $time, 'i' ) ) );
232
+
233
+                return sprintf( '"%s"^^xsd:duration', self::escape( $time_value ) );
234
+
235
+            case Wordlift_Schema_Service::DATA_TYPE_DOUBLE:
236
+                return sprintf( '"%s"^^xsd:double', self::escape( $value ) );
237
+
238
+            case Wordlift_Schema_Service::DATA_TYPE_INTEGER:
239
+                return sprintf( '"%s"^^xsd:integer', self::escape( $value ) );
240
+
241
+            case Wordlift_Schema_Service::DATA_TYPE_STRING:
242
+                return sprintf( '"%s"^^xsd:string', self::escape( $value ) );
243
+
244
+            case Wordlift_Schema_Service::DATA_TYPE_URI:
245
+                return sprintf( '<%s>', self::escape_uri( $value ) );
246
+
247
+            case null:
248
+                $language_tag = ( null !== $language ? "@$language" : '' );
249
+
250
+                return sprintf( '"%s"%s', self::escape( $value ), $language_tag );
251
+
252
+            default:
253
+
254
+                self::$log->warn( "Unknown data type [ type :: $type ]" );
255
+
256
+                // Try to insert the value anyway.
257
+                return sprintf( '"%s"', self::escape( $value ) );
258
+        }
259
+
260
+    }
261
+
262
+    /**
263
+     * Escapes an URI for a SPARQL statement.
264
+     *
265
+     * @since 3.6.0
266
+     *
267
+     * @param string $uri The URI to escape.
268
+     *
269
+     * @return string The escaped URI.
270
+     */
271
+    public static function escape_uri( $uri ) {
272
+
273
+        // Should we validate the IRI?
274
+        // http://www.w3.org/TR/sparql11-query/#QSynIRI
275
+
276
+        $uri = str_replace( '<', '\<', $uri );
277
+        $uri = str_replace( '>', '\>', $uri );
278
+
279
+        return $uri;
280
+    }
281
+
282
+    /**
283
+     * Escapes a string for a SPARQL statement.
284
+     *
285
+     * @since 3.6.0
286
+     *
287
+     * @param string $string The string to escape.
288
+     *
289
+     * @return string The escaped string.
290
+     */
291
+    public static function escape( $string ) {
292
+
293
+        // see http://www.w3.org/TR/rdf-sparql-query/
294
+        //    '\t'	U+0009 (tab)
295
+        //    '\n'	U+000A (line feed)
296
+        //    '\r'	U+000D (carriage return)
297
+        //    '\b'	U+0008 (backspace)
298
+        //    '\f'	U+000C (form feed)
299
+        //    '\"'	U+0022 (quotation mark, double quote mark)
300
+        //    "\'"	U+0027 (apostrophe-quote, single quote mark)
301
+        //    '\\'	U+005C (backslash)
302
+
303
+        $string = str_replace( '\\', '\\\\', $string );
304
+        $string = str_replace( '\'', '\\\'', $string );
305
+        $string = str_replace( '"', '\\"', $string );
306
+        $string = str_replace( "\f", '\\f', $string );
307
+        $string = str_replace( "\b", '\\b', $string );
308
+        $string = str_replace( "\r", '\\r', $string );
309
+        $string = str_replace( "\n", '\\n', $string );
310
+        $string = str_replace( "\t", '\\t', $string );
311 311
 
312
-		return $string;
313
-	}
312
+        return $string;
313
+    }
314 314
 
315 315
 }
Please login to merge, or discard this patch.
Spacing   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@  discard block
 block discarded – undo
43 43
 	 */
44 44
 	public function __construct() {
45 45
 
46
-		self::$log = Wordlift_Log_Service::get_logger( 'Wordlift_Sparql_Service' );
46
+		self::$log = Wordlift_Log_Service::get_logger('Wordlift_Sparql_Service');
47 47
 
48 48
 		self::$instance = $this;
49 49
 
@@ -69,9 +69,9 @@  discard block
 block discarded – undo
69 69
 	 * @param bool   $queue Whether to queue the statement for asynchronous
70 70
 	 *                      execution.
71 71
 	 */
72
-	public function execute( $stmt, $queue = WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
72
+	public function execute($stmt, $queue = WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING) {
73 73
 
74
-		rl_execute_sparql_update_query( $stmt, $queue );
74
+		rl_execute_sparql_update_query($stmt, $queue);
75 75
 
76 76
 	}
77 77
 
@@ -82,29 +82,29 @@  discard block
 block discarded – undo
82 82
 	 *
83 83
 	 * @param string $request_id A unique request id.
84 84
 	 */
85
-	public function run_sparql_query( $request_id ) {
85
+	public function run_sparql_query($request_id) {
86 86
 
87
-		self::$log->debug( "Running SPARQL queries..." );
87
+		self::$log->debug("Running SPARQL queries...");
88 88
 
89 89
 		// Look for a free temporary filename.
90
-		for ( $index = 1; $index < PHP_INT_MAX; $index ++ ) {
91
-			$filename = WL_TEMP_DIR . $request_id . "-$index.sparql";
90
+		for ($index = 1; $index < PHP_INT_MAX; $index++) {
91
+			$filename = WL_TEMP_DIR.$request_id."-$index.sparql";
92 92
 
93 93
 			// Bail out if there are no files left.
94
-			if ( ! file_exists( $filename ) ) {
94
+			if ( ! file_exists($filename)) {
95 95
 				break;
96 96
 			}
97 97
 
98
-			self::$log->debug( "Running SPARQL from $filename..." );
98
+			self::$log->debug("Running SPARQL from $filename...");
99 99
 
100 100
 			// Get the query saved in the file.
101
-			$query = file_get_contents( $filename );
101
+			$query = file_get_contents($filename);
102 102
 
103 103
 			// Execute the SPARQL query.
104
-			rl_execute_sparql_update_query( $query, false );
104
+			rl_execute_sparql_update_query($query, false);
105 105
 
106 106
 			// Delete the temporary file.
107
-			unlink( $filename );
107
+			unlink($filename);
108 108
 		}
109 109
 
110 110
 		// Reindex the triple store.
@@ -119,15 +119,15 @@  discard block
 block discarded – undo
119 119
 	 *
120 120
 	 * @param string $stmt The SPARQL statement.
121 121
 	 */
122
-	public function queue( $stmt ) {
122
+	public function queue($stmt) {
123 123
 
124 124
 		// Get a temporary filename.
125 125
 		$filename = $this->get_temporary_file_for_sparql();
126 126
 
127
-		self::$log->debug( "Buffering SPARQL to file $filename..." );
127
+		self::$log->debug("Buffering SPARQL to file $filename...");
128 128
 
129 129
 		// Write the contents to the temporary filename.
130
-		file_put_contents( $filename, $stmt . "\n", FILE_APPEND );
130
+		file_put_contents($filename, $stmt."\n", FILE_APPEND);
131 131
 
132 132
 	}
133 133
 
@@ -143,16 +143,16 @@  discard block
 block discarded – undo
143 143
 	private function get_temporary_file_for_sparql() {
144 144
 
145 145
 		// Look for a free temporary filename.
146
-		for ( $index = 1; $index < PHP_INT_MAX; $index ++ ) {
147
-			$filename = WL_TEMP_DIR . WL_REQUEST_ID . "-$index.sparql";
146
+		for ($index = 1; $index < PHP_INT_MAX; $index++) {
147
+			$filename = WL_TEMP_DIR.WL_REQUEST_ID."-$index.sparql";
148 148
 
149
-			if ( ! file_exists( $filename ) ) {
149
+			if ( ! file_exists($filename)) {
150 150
 
151 151
 				// Only if this it the first buffered SPARQL, then launch the
152 152
 				// action which will be handled by the Async Task. The Async
153 153
 				// Task will take care of all the buffered files _on shutdown_.
154
-				if ( 1 === $index ) {
155
-					do_action( 'wl_run_sparql_query', WL_REQUEST_ID );
154
+				if (1 === $index) {
155
+					do_action('wl_run_sparql_query', WL_REQUEST_ID);
156 156
 				}
157 157
 
158 158
 				// Return the temporary filename.
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
 			}
161 161
 		}
162 162
 
163
-		throw new Exception( 'Cannot create a temporary file [ ' . WL_TEMP_DIR . WL_REQUEST_ID . ' ].' );
163
+		throw new Exception('Cannot create a temporary file [ '.WL_TEMP_DIR.WL_REQUEST_ID.' ].');
164 164
 	}
165 165
 
166 166
 	/**
@@ -172,13 +172,13 @@  discard block
 block discarded – undo
172 172
 	 *
173 173
 	 * @return WP_Error|array The response or WP_Error on failure.
174 174
 	 */
175
-	public function select( $query ) {
175
+	public function select($query) {
176 176
 
177 177
 		// Prepare the SPARQL statement by prepending the default namespaces.
178
-		$sparql = rl_sparql_prefixes() . "\n" . $query;
178
+		$sparql = rl_sparql_prefixes()."\n".$query;
179 179
 
180 180
 		// Get the SPARQL SELECT URL.
181
-		$url = wl_configuration_get_query_select_url() . urlencode( $sparql );
181
+		$url = wl_configuration_get_query_select_url().urlencode($sparql);
182 182
 
183 183
 		/**
184 184
 		 * Filter: 'wl_sparql_query_http_args' - Allow third parties to hook and add additional HTTP args.
@@ -186,9 +186,9 @@  discard block
 block discarded – undo
186 186
 		 * @since 3.17.0
187 187
 		 * @api   arr Current http options.
188 188
 		 */
189
-		$args = apply_filters( 'wl_sparql_query_http_args', unserialize( WL_REDLINK_API_HTTP_OPTIONS ) );
189
+		$args = apply_filters('wl_sparql_query_http_args', unserialize(WL_REDLINK_API_HTTP_OPTIONS));
190 190
 
191
-		return wp_remote_get( $url, $args );
191
+		return wp_remote_get($url, $args);
192 192
 	}
193 193
 
194 194
 	/**
@@ -203,11 +203,11 @@  discard block
 block discarded – undo
203 203
 	 *
204 204
 	 * @return string The formatted value for SPARQL statements.
205 205
 	 */
206
-	public static function format( $value, $type = null, $language = null ) {
206
+	public static function format($value, $type = null, $language = null) {
207 207
 
208 208
 		// see https://www.w3.org/TR/sparql11-query/.
209 209
 
210
-		switch ( $type ) {
210
+		switch ($type) {
211 211
 
212 212
 			case Wordlift_Schema_Service::DATA_TYPE_BOOLEAN:
213 213
 				// SPARQL supports 'true' and 'false', so we evaluate the $value
@@ -215,46 +215,46 @@  discard block
 block discarded – undo
215 215
 				return $value ? 'true' : 'false';
216 216
 
217 217
 			case Wordlift_Schema_Service::DATA_TYPE_DATE:
218
-				$date       = date_create_from_format( 'Y/m/d', $value );
219
-				$date_value = date_format( $date, 'Y-m-d' );
218
+				$date       = date_create_from_format('Y/m/d', $value);
219
+				$date_value = date_format($date, 'Y-m-d');
220 220
 
221
-				return sprintf( '"%s"^^xsd:date', self::escape( $date_value ) );
221
+				return sprintf('"%s"^^xsd:date', self::escape($date_value));
222 222
 
223 223
 			case Wordlift_Schema_Service::DATA_TYPE_DATE_TIME:
224
-				$date       = date_create_from_format( 'Y/m/d H:i', $value );
225
-				$date_value = date_format( $date, 'Y-m-d\TH:i:00' );
224
+				$date       = date_create_from_format('Y/m/d H:i', $value);
225
+				$date_value = date_format($date, 'Y-m-d\TH:i:00');
226 226
 
227
-				return sprintf( '"%s"^^xsd:dateTime', self::escape( $date_value ) );
227
+				return sprintf('"%s"^^xsd:dateTime', self::escape($date_value));
228 228
 
229 229
 			case Wordlift_Schema_Service::DATA_TYPE_DURATION:
230
-				$time       = date_create_from_format( 'H:i', $value );
231
-				$time_value = sprintf( 'PT%dH%dM', date_format( $time, 'H' ), intval( date_format( $time, 'i' ) ) );
230
+				$time       = date_create_from_format('H:i', $value);
231
+				$time_value = sprintf('PT%dH%dM', date_format($time, 'H'), intval(date_format($time, 'i')));
232 232
 
233
-				return sprintf( '"%s"^^xsd:duration', self::escape( $time_value ) );
233
+				return sprintf('"%s"^^xsd:duration', self::escape($time_value));
234 234
 
235 235
 			case Wordlift_Schema_Service::DATA_TYPE_DOUBLE:
236
-				return sprintf( '"%s"^^xsd:double', self::escape( $value ) );
236
+				return sprintf('"%s"^^xsd:double', self::escape($value));
237 237
 
238 238
 			case Wordlift_Schema_Service::DATA_TYPE_INTEGER:
239
-				return sprintf( '"%s"^^xsd:integer', self::escape( $value ) );
239
+				return sprintf('"%s"^^xsd:integer', self::escape($value));
240 240
 
241 241
 			case Wordlift_Schema_Service::DATA_TYPE_STRING:
242
-				return sprintf( '"%s"^^xsd:string', self::escape( $value ) );
242
+				return sprintf('"%s"^^xsd:string', self::escape($value));
243 243
 
244 244
 			case Wordlift_Schema_Service::DATA_TYPE_URI:
245
-				return sprintf( '<%s>', self::escape_uri( $value ) );
245
+				return sprintf('<%s>', self::escape_uri($value));
246 246
 
247 247
 			case null:
248
-				$language_tag = ( null !== $language ? "@$language" : '' );
248
+				$language_tag = (null !== $language ? "@$language" : '');
249 249
 
250
-				return sprintf( '"%s"%s', self::escape( $value ), $language_tag );
250
+				return sprintf('"%s"%s', self::escape($value), $language_tag);
251 251
 
252 252
 			default:
253 253
 
254
-				self::$log->warn( "Unknown data type [ type :: $type ]" );
254
+				self::$log->warn("Unknown data type [ type :: $type ]");
255 255
 
256 256
 				// Try to insert the value anyway.
257
-				return sprintf( '"%s"', self::escape( $value ) );
257
+				return sprintf('"%s"', self::escape($value));
258 258
 		}
259 259
 
260 260
 	}
@@ -268,13 +268,13 @@  discard block
 block discarded – undo
268 268
 	 *
269 269
 	 * @return string The escaped URI.
270 270
 	 */
271
-	public static function escape_uri( $uri ) {
271
+	public static function escape_uri($uri) {
272 272
 
273 273
 		// Should we validate the IRI?
274 274
 		// http://www.w3.org/TR/sparql11-query/#QSynIRI
275 275
 
276
-		$uri = str_replace( '<', '\<', $uri );
277
-		$uri = str_replace( '>', '\>', $uri );
276
+		$uri = str_replace('<', '\<', $uri);
277
+		$uri = str_replace('>', '\>', $uri);
278 278
 
279 279
 		return $uri;
280 280
 	}
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
 	 *
289 289
 	 * @return string The escaped string.
290 290
 	 */
291
-	public static function escape( $string ) {
291
+	public static function escape($string) {
292 292
 
293 293
 		// see http://www.w3.org/TR/rdf-sparql-query/
294 294
 		//    '\t'	U+0009 (tab)
@@ -300,14 +300,14 @@  discard block
 block discarded – undo
300 300
 		//    "\'"	U+0027 (apostrophe-quote, single quote mark)
301 301
 		//    '\\'	U+005C (backslash)
302 302
 
303
-		$string = str_replace( '\\', '\\\\', $string );
304
-		$string = str_replace( '\'', '\\\'', $string );
305
-		$string = str_replace( '"', '\\"', $string );
306
-		$string = str_replace( "\f", '\\f', $string );
307
-		$string = str_replace( "\b", '\\b', $string );
308
-		$string = str_replace( "\r", '\\r', $string );
309
-		$string = str_replace( "\n", '\\n', $string );
310
-		$string = str_replace( "\t", '\\t', $string );
303
+		$string = str_replace('\\', '\\\\', $string);
304
+		$string = str_replace('\'', '\\\'', $string);
305
+		$string = str_replace('"', '\\"', $string);
306
+		$string = str_replace("\f", '\\f', $string);
307
+		$string = str_replace("\b", '\\b', $string);
308
+		$string = str_replace("\r", '\\r', $string);
309
+		$string = str_replace("\n", '\\n', $string);
310
+		$string = str_replace("\t", '\\t', $string);
311 311
 
312 312
 		return $string;
313 313
 	}
Please login to merge, or discard this patch.