Completed
Push — develop ( f65bd6...158ffc )
by David
08:55
created
src/wordlift.php 2 patches
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
 
27 27
 // If this file is called directly, abort.
28 28
 if ( ! defined( 'WPINC' ) ) {
29
-	die;
29
+    die;
30 30
 }
31 31
 
32 32
 // Include WordLift constants.
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
  */
49 49
 function wl_write_log( $log ) {
50 50
 
51
-	Wordlift_Log_Service::get_instance()->info( $log );
51
+    Wordlift_Log_Service::get_instance()->info( $log );
52 52
 
53 53
 }
54 54
 
@@ -64,20 +64,20 @@  discard block
 block discarded – undo
64 64
  */
65 65
 function wl_write_log_handler( $log, $caller = null ) {
66 66
 
67
-	global $wl_logger;
67
+    global $wl_logger;
68 68
 
69
-	if ( true === WP_DEBUG ) {
69
+    if ( true === WP_DEBUG ) {
70 70
 
71
-		$message = ( isset( $caller ) ? sprintf( '[%-40.40s] ', $caller ) : '' ) .
72
-		           ( is_array( $log ) || is_object( $log ) ? print_r( $log, true ) : wl_write_log_hide_key( $log ) );
71
+        $message = ( isset( $caller ) ? sprintf( '[%-40.40s] ', $caller ) : '' ) .
72
+                    ( is_array( $log ) || is_object( $log ) ? print_r( $log, true ) : wl_write_log_hide_key( $log ) );
73 73
 
74
-		if ( isset( $wl_logger ) ) {
75
-			$wl_logger->info( $message );
76
-		} else {
77
-			error_log( $message );
78
-		}
74
+        if ( isset( $wl_logger ) ) {
75
+            $wl_logger->info( $message );
76
+        } else {
77
+            error_log( $message );
78
+        }
79 79
 
80
-	}
80
+    }
81 81
 
82 82
 }
83 83
 
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
  */
95 95
 function wl_write_log_hide_key( $text ) {
96 96
 
97
-	return str_ireplace( wl_configuration_get_key(), '<hidden>', $text );
97
+    return str_ireplace( wl_configuration_get_key(), '<hidden>', $text );
98 98
 }
99 99
 
100 100
 /**
@@ -102,21 +102,21 @@  discard block
 block discarded – undo
102 102
  * see http://vip.wordpress.com/documentation/register-additional-html-attributes-for-tinymce-and-wp-kses/
103 103
  */
104 104
 function wordlift_allowed_post_tags() {
105
-	global $allowedposttags;
106
-
107
-	$tags           = array( 'span' );
108
-	$new_attributes = array(
109
-		'itemscope' => array(),
110
-		'itemtype'  => array(),
111
-		'itemprop'  => array(),
112
-		'itemid'    => array(),
113
-	);
114
-
115
-	foreach ( $tags as $tag ) {
116
-		if ( isset( $allowedposttags[ $tag ] ) && is_array( $allowedposttags[ $tag ] ) ) {
117
-			$allowedposttags[ $tag ] = array_merge( $allowedposttags[ $tag ], $new_attributes );
118
-		}
119
-	}
105
+    global $allowedposttags;
106
+
107
+    $tags           = array( 'span' );
108
+    $new_attributes = array(
109
+        'itemscope' => array(),
110
+        'itemtype'  => array(),
111
+        'itemprop'  => array(),
112
+        'itemid'    => array(),
113
+    );
114
+
115
+    foreach ( $tags as $tag ) {
116
+        if ( isset( $allowedposttags[ $tag ] ) && is_array( $allowedposttags[ $tag ] ) ) {
117
+            $allowedposttags[ $tag ] = array_merge( $allowedposttags[ $tag ], $new_attributes );
118
+        }
119
+    }
120 120
 }
121 121
 
122 122
 // add allowed post tags.
@@ -127,28 +127,28 @@  discard block
 block discarded – undo
127 127
  */
128 128
 function wordlift_admin_enqueue_scripts() {
129 129
 
130
-	// Added for compatibility with WordPress 3.9 (see http://make.wordpress.org/core/2014/04/16/jquery-ui-and-wpdialogs-in-wordpress-3-9/)
131
-	wp_enqueue_script( 'wpdialogs' );
132
-	wp_enqueue_style( 'wp-jquery-ui-dialog' );
130
+    // Added for compatibility with WordPress 3.9 (see http://make.wordpress.org/core/2014/04/16/jquery-ui-and-wpdialogs-in-wordpress-3-9/)
131
+    wp_enqueue_script( 'wpdialogs' );
132
+    wp_enqueue_style( 'wp-jquery-ui-dialog' );
133 133
 
134
-	wp_enqueue_style( 'wordlift-reloaded', plugin_dir_url( __FILE__ ) . 'css/wordlift-reloaded.min.css' );
134
+    wp_enqueue_style( 'wordlift-reloaded', plugin_dir_url( __FILE__ ) . 'css/wordlift-reloaded.min.css' );
135 135
 
136
-	wp_enqueue_script( 'jquery-ui-autocomplete' );
137
-	wp_enqueue_script( 'angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js' );
138
-	wp_enqueue_script( 'angularjs-geolocation', plugin_dir_url( __FILE__ ) . '/bower_components/angularjs-geolocation/dist/angularjs-geolocation.min.js' );
139
-	wp_enqueue_script( 'angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js' );
140
-	wp_enqueue_script( 'angularjs-animate', 'https://code.angularjs.org/1.3.11/angular-animate.min.js' );
136
+    wp_enqueue_script( 'jquery-ui-autocomplete' );
137
+    wp_enqueue_script( 'angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js' );
138
+    wp_enqueue_script( 'angularjs-geolocation', plugin_dir_url( __FILE__ ) . '/bower_components/angularjs-geolocation/dist/angularjs-geolocation.min.js' );
139
+    wp_enqueue_script( 'angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js' );
140
+    wp_enqueue_script( 'angularjs-animate', 'https://code.angularjs.org/1.3.11/angular-animate.min.js' );
141 141
 
142
-	// Disable auto-save for custom entity posts only
143
-	if ( Wordlift_Entity_Service::TYPE_NAME === get_post_type() ) {
144
-		wp_dequeue_script( 'autosave' );
145
-	}
142
+    // Disable auto-save for custom entity posts only
143
+    if ( Wordlift_Entity_Service::TYPE_NAME === get_post_type() ) {
144
+        wp_dequeue_script( 'autosave' );
145
+    }
146 146
 }
147 147
 
148 148
 add_action( 'admin_enqueue_scripts', 'wordlift_admin_enqueue_scripts' );
149 149
 
150 150
 function wl_enqueue_scripts() {
151
-	wp_enqueue_style( 'wordlift-ui', plugin_dir_url( __FILE__ ) . 'css/wordlift-ui.min.css' );
151
+    wp_enqueue_style( 'wordlift-ui', plugin_dir_url( __FILE__ ) . 'css/wordlift-ui.min.css' );
152 152
 }
153 153
 
154 154
 add_action( 'wp_enqueue_scripts', 'wl_enqueue_scripts' );
@@ -163,18 +163,18 @@  discard block
 block discarded – undo
163 163
  */
164 164
 function wordlift_allowed_html( $allowedtags, $context ) {
165 165
 
166
-	if ( 'post' !== $context ) {
167
-		return $allowedtags;
168
-	}
169
-
170
-	return array_merge_recursive( $allowedtags, array(
171
-		'span' => array(
172
-			'itemscope' => true,
173
-			'itemtype'  => true,
174
-			'itemid'    => true,
175
-			'itemprop'  => true,
176
-		),
177
-	) );
166
+    if ( 'post' !== $context ) {
167
+        return $allowedtags;
168
+    }
169
+
170
+    return array_merge_recursive( $allowedtags, array(
171
+        'span' => array(
172
+            'itemscope' => true,
173
+            'itemtype'  => true,
174
+            'itemid'    => true,
175
+            'itemprop'  => true,
176
+        ),
177
+    ) );
178 178
 }
179 179
 
180 180
 add_filter( 'wp_kses_allowed_html', 'wordlift_allowed_html', 10, 2 );
@@ -188,16 +188,16 @@  discard block
 block discarded – undo
188 188
  */
189 189
 function wl_get_coordinates( $post_id ) {
190 190
 
191
-	$latitude  = wl_schema_get_value( $post_id, 'latitude' );
192
-	$longitude = wl_schema_get_value( $post_id, 'longitude' );
191
+    $latitude  = wl_schema_get_value( $post_id, 'latitude' );
192
+    $longitude = wl_schema_get_value( $post_id, 'longitude' );
193 193
 
194
-	// DO NOT set latitude/longitude to 0/0 as default values. It's a specific
195
-	// place on the globe:"The zero/zero point of this system is located in the
196
-	// Gulf of Guinea about 625 km (390 mi) south of Tema, Ghana."
197
-	return array(
198
-		'latitude'  => isset( $latitude[0] ) && is_numeric( $latitude[0] ) ? $latitude[0] : '',
199
-		'longitude' => isset( $longitude[0] ) && is_numeric( $longitude[0] ) ? $longitude[0] : '',
200
-	);
194
+    // DO NOT set latitude/longitude to 0/0 as default values. It's a specific
195
+    // place on the globe:"The zero/zero point of this system is located in the
196
+    // Gulf of Guinea about 625 km (390 mi) south of Tema, Ghana."
197
+    return array(
198
+        'latitude'  => isset( $latitude[0] ) && is_numeric( $latitude[0] ) ? $latitude[0] : '',
199
+        'longitude' => isset( $longitude[0] ) && is_numeric( $longitude[0] ) ? $longitude[0] : '',
200
+    );
201 201
 }
202 202
 
203 203
 /**
@@ -211,9 +211,9 @@  discard block
 block discarded – undo
211 211
  */
212 212
 function wl_get_image_urls( $post_id ) {
213 213
 
214
-	return Wordlift_Storage_Factory::get_instance()
215
-	                               ->post_images()
216
-	                               ->get( $post_id );
214
+    return Wordlift_Storage_Factory::get_instance()
215
+                                    ->post_images()
216
+                                    ->get( $post_id );
217 217
 
218 218
 //	// If there is a featured image it has the priority.
219 219
 //	$featured_image_id = get_post_thumbnail_id( $post_id );
@@ -261,24 +261,24 @@  discard block
 block discarded – undo
261 261
  */
262 262
 function wl_get_attachment_for_source_url( $parent_post_id, $source_url ) {
263 263
 
264
-	// wl_write_log( "wl_get_attachment_for_source_url [ parent post id :: $parent_post_id ][ source url :: $source_url ]" );
264
+    // wl_write_log( "wl_get_attachment_for_source_url [ parent post id :: $parent_post_id ][ source url :: $source_url ]" );
265 265
 
266
-	$posts = get_posts( array(
267
-		'post_type'      => 'attachment',
268
-		'posts_per_page' => 1,
269
-		'post_status'    => 'any',
270
-		'post_parent'    => $parent_post_id,
271
-		'meta_key'       => 'wl_source_url',
272
-		'meta_value'     => $source_url,
273
-	) );
266
+    $posts = get_posts( array(
267
+        'post_type'      => 'attachment',
268
+        'posts_per_page' => 1,
269
+        'post_status'    => 'any',
270
+        'post_parent'    => $parent_post_id,
271
+        'meta_key'       => 'wl_source_url',
272
+        'meta_value'     => $source_url,
273
+    ) );
274 274
 
275
-	// Return the found post.
276
-	if ( 1 === count( $posts ) ) {
277
-		return $posts[0];
278
-	}
275
+    // Return the found post.
276
+    if ( 1 === count( $posts ) ) {
277
+        return $posts[0];
278
+    }
279 279
 
280
-	// Return null.
281
-	return null;
280
+    // Return null.
281
+    return null;
282 282
 }
283 283
 
284 284
 /**
@@ -289,8 +289,8 @@  discard block
 block discarded – undo
289 289
  */
290 290
 function wl_set_source_url( $post_id, $source_url ) {
291 291
 
292
-	delete_post_meta( $post_id, 'wl_source_url' );
293
-	add_post_meta( $post_id, 'wl_source_url', $source_url );
292
+    delete_post_meta( $post_id, 'wl_source_url' );
293
+    add_post_meta( $post_id, 'wl_source_url', $source_url );
294 294
 }
295 295
 
296 296
 
@@ -307,61 +307,61 @@  discard block
 block discarded – undo
307 307
  */
308 308
 function wl_flush_rewrite_rules_hard( $hard ) {
309 309
 
310
-	// If WL is not yet configured, we cannot perform any update, so we exit.
311
-	if ( '' === wl_configuration_get_key() ) {
312
-		return;
313
-	}
310
+    // If WL is not yet configured, we cannot perform any update, so we exit.
311
+    if ( '' === wl_configuration_get_key() ) {
312
+        return;
313
+    }
314 314
 
315
-	// Set the initial offset and limit each call to 100 posts to avoid memory errors.
316
-	$offset = 0;
317
-	$limit  = 100;
315
+    // Set the initial offset and limit each call to 100 posts to avoid memory errors.
316
+    $offset = 0;
317
+    $limit  = 100;
318 318
 
319
-	// Get more posts if the number of returned posts matches the limit.
320
-	while ( $limit === ( $posts = get_posts( array(
321
-			'offset'      => $offset,
322
-			'numberposts' => $limit,
323
-			'orderby'     => 'ID',
324
-			'post_type'   => 'any',
325
-			'post_status' => 'publish',
326
-		) ) ) ) {
319
+    // Get more posts if the number of returned posts matches the limit.
320
+    while ( $limit === ( $posts = get_posts( array(
321
+            'offset'      => $offset,
322
+            'numberposts' => $limit,
323
+            'orderby'     => 'ID',
324
+            'post_type'   => 'any',
325
+            'post_status' => 'publish',
326
+        ) ) ) ) {
327 327
 
328
-		// Holds the delete part of the query.
329
-		$delete_query = rl_sparql_prefixes();
328
+        // Holds the delete part of the query.
329
+        $delete_query = rl_sparql_prefixes();
330 330
 
331
-		// Holds the insert part of the query.
332
-		$insert_query = '';
331
+        // Holds the insert part of the query.
332
+        $insert_query = '';
333 333
 
334
-		// Cycle in each post to build the query.
335
-		foreach ( $posts as $post ) {
334
+        // Cycle in each post to build the query.
335
+        foreach ( $posts as $post ) {
336 336
 
337
-			// Ignore revisions.
338
-			if ( wp_is_post_revision( $post->ID ) ) {
339
-				continue;
340
-			}
337
+            // Ignore revisions.
338
+            if ( wp_is_post_revision( $post->ID ) ) {
339
+                continue;
340
+            }
341 341
 
342
-			// Get the entity URI.
343
-			$s = Wordlift_Sparql_Service::escape_uri( Wordlift_Entity_Service::get_instance()
344
-			                                                                 ->get_uri( $post->ID ) );
342
+            // Get the entity URI.
343
+            $s = Wordlift_Sparql_Service::escape_uri( Wordlift_Entity_Service::get_instance()
344
+                                                                                ->get_uri( $post->ID ) );
345 345
 
346
-			// Get the post URL.
347
-			// $url = wl_sparql_escape_uri( get_permalink( $post->ID ) );
346
+            // Get the post URL.
347
+            // $url = wl_sparql_escape_uri( get_permalink( $post->ID ) );
348 348
 
349
-			// Prepare the DELETE and INSERT commands.
350
-			$delete_query .= "DELETE { <$s> schema:url ?u . } WHERE  { <$s> schema:url ?u . };\n";
349
+            // Prepare the DELETE and INSERT commands.
350
+            $delete_query .= "DELETE { <$s> schema:url ?u . } WHERE  { <$s> schema:url ?u . };\n";
351 351
 
352
-			$insert_query .= Wordlift_Schema_Url_Property_Service::get_instance()
353
-			                                                     ->get_insert_query( $s, $post->ID );
352
+            $insert_query .= Wordlift_Schema_Url_Property_Service::get_instance()
353
+                                                                    ->get_insert_query( $s, $post->ID );
354 354
 
355
-		}
355
+        }
356 356
 
357 357
 
358
-		// Execute the query.
359
-		rl_execute_sparql_update_query( $delete_query . $insert_query );
358
+        // Execute the query.
359
+        rl_execute_sparql_update_query( $delete_query . $insert_query );
360 360
 
361
-		// Advance to the next posts.
362
-		$offset += $limit;
361
+        // Advance to the next posts.
362
+        $offset += $limit;
363 363
 
364
-	}
364
+    }
365 365
 
366 366
 }
367 367
 
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
  */
381 381
 function wl_sanitize_uri_path( $path, $char = '_' ) {
382 382
 
383
-	return Wordlift_Uri_Service::get_instance()->sanitize_path( $path, $char );
383
+    return Wordlift_Uri_Service::get_instance()->sanitize_path( $path, $char );
384 384
 }
385 385
 
386 386
 ///**
@@ -421,46 +421,46 @@  discard block
 block discarded – undo
421 421
  */
422 422
 function wl_replace_item_id_with_uri( $content ) {
423 423
 
424
-	// wl_write_log( "wl_replace_item_id_with_uri" );
424
+    // wl_write_log( "wl_replace_item_id_with_uri" );
425 425
 
426
-	// Strip slashes, see https://core.trac.wordpress.org/ticket/21767
427
-	$content = stripslashes( $content );
426
+    // Strip slashes, see https://core.trac.wordpress.org/ticket/21767
427
+    $content = stripslashes( $content );
428 428
 
429
-	// If any match are found.
430
-	$matches = array();
431
-	if ( 0 < preg_match_all( '/ itemid="([^"]+)"/i', $content, $matches, PREG_SET_ORDER ) ) {
429
+    // If any match are found.
430
+    $matches = array();
431
+    if ( 0 < preg_match_all( '/ itemid="([^"]+)"/i', $content, $matches, PREG_SET_ORDER ) ) {
432 432
 
433
-		foreach ( $matches as $match ) {
433
+        foreach ( $matches as $match ) {
434 434
 
435
-			// Get the item ID.
436
-			$item_id = $match[1];
435
+            // Get the item ID.
436
+            $item_id = $match[1];
437 437
 
438
-			// Get the post bound to that item ID (looking both in the 'official' URI and in the 'same-as' .
439
-			$post = Wordlift_Entity_Service::get_instance()
440
-			                               ->get_entity_post_by_uri( $item_id );
438
+            // Get the post bound to that item ID (looking both in the 'official' URI and in the 'same-as' .
439
+            $post = Wordlift_Entity_Service::get_instance()
440
+                                            ->get_entity_post_by_uri( $item_id );
441 441
 
442
-			// If no entity is found, continue to the next one.
443
-			if ( null === $post ) {
444
-				continue;
445
-			}
442
+            // If no entity is found, continue to the next one.
443
+            if ( null === $post ) {
444
+                continue;
445
+            }
446 446
 
447
-			// Get the URI for that post.
448
-			$uri = wl_get_entity_uri( $post->ID );
447
+            // Get the URI for that post.
448
+            $uri = wl_get_entity_uri( $post->ID );
449 449
 
450
-			// wl_write_log( "wl_replace_item_id_with_uri [ item id :: $item_id ][ uri :: $uri ]" );
450
+            // wl_write_log( "wl_replace_item_id_with_uri [ item id :: $item_id ][ uri :: $uri ]" );
451 451
 
452
-			// If the item ID and the URI differ, replace the item ID with the URI saved in WordPress.
453
-			if ( $item_id !== $uri ) {
454
-				$uri_e   = esc_html( $uri );
455
-				$content = str_replace( " itemid=\"$item_id\"", " itemid=\"$uri_e\"", $content );
456
-			}
457
-		}
458
-	}
452
+            // If the item ID and the URI differ, replace the item ID with the URI saved in WordPress.
453
+            if ( $item_id !== $uri ) {
454
+                $uri_e   = esc_html( $uri );
455
+                $content = str_replace( " itemid=\"$item_id\"", " itemid=\"$uri_e\"", $content );
456
+            }
457
+        }
458
+    }
459 459
 
460
-	// Reapply slashes.
461
-	$content = addslashes( $content );
460
+    // Reapply slashes.
461
+    $content = addslashes( $content );
462 462
 
463
-	return $content;
463
+    return $content;
464 464
 }
465 465
 
466 466
 add_filter( 'content_save_pre', 'wl_replace_item_id_with_uri', 1, 1 );
@@ -527,8 +527,8 @@  discard block
 block discarded – undo
527 527
  * This action is documented in includes/class-wordlift-activator.php
528 528
  */
529 529
 function activate_wordlift() {
530
-	require_once plugin_dir_path( __FILE__ ) . 'includes/class-wordlift-activator.php';
531
-	Wordlift_Activator::activate();
530
+    require_once plugin_dir_path( __FILE__ ) . 'includes/class-wordlift-activator.php';
531
+    Wordlift_Activator::activate();
532 532
 }
533 533
 
534 534
 /**
@@ -536,8 +536,8 @@  discard block
 block discarded – undo
536 536
  * This action is documented in includes/class-wordlift-deactivator.php
537 537
  */
538 538
 function deactivate_wordlift() {
539
-	require_once plugin_dir_path( __FILE__ ) . 'includes/class-wordlift-deactivator.php';
540
-	Wordlift_Deactivator::deactivate();
539
+    require_once plugin_dir_path( __FILE__ ) . 'includes/class-wordlift-deactivator.php';
540
+    Wordlift_Deactivator::deactivate();
541 541
 }
542 542
 
543 543
 register_activation_hook( __FILE__, 'activate_wordlift' );
@@ -560,8 +560,8 @@  discard block
 block discarded – undo
560 560
  */
561 561
 function run_wordlift() {
562 562
 
563
-	$plugin = new Wordlift();
564
-	$plugin->run();
563
+    $plugin = new Wordlift();
564
+    $plugin->run();
565 565
 
566 566
 }
567 567
 
Please login to merge, or discard this patch.
Spacing   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -25,15 +25,15 @@  discard block
 block discarded – undo
25 25
  */
26 26
 
27 27
 // If this file is called directly, abort.
28
-if ( ! defined( 'WPINC' ) ) {
28
+if ( ! defined('WPINC')) {
29 29
 	die;
30 30
 }
31 31
 
32 32
 // Include WordLift constants.
33
-require_once( 'wordlift_constants.php' );
33
+require_once('wordlift_constants.php');
34 34
 
35 35
 // Load modules.
36
-require_once( 'modules/core/wordlift_core.php' );
36
+require_once('modules/core/wordlift_core.php');
37 37
 
38 38
 /**
39 39
  * Log to the debug.log file.
@@ -46,9 +46,9 @@  discard block
 block discarded – undo
46 46
  *
47 47
  * @param string|mixed $log The log data.
48 48
  */
49
-function wl_write_log( $log ) {
49
+function wl_write_log($log) {
50 50
 
51
-	Wordlift_Log_Service::get_instance()->info( $log );
51
+	Wordlift_Log_Service::get_instance()->info($log);
52 52
 
53 53
 }
54 54
 
@@ -62,19 +62,19 @@  discard block
 block discarded – undo
62 62
  * @param string|array $log    The log data.
63 63
  * @param string       $caller The calling function.
64 64
  */
65
-function wl_write_log_handler( $log, $caller = null ) {
65
+function wl_write_log_handler($log, $caller = null) {
66 66
 
67 67
 	global $wl_logger;
68 68
 
69
-	if ( true === WP_DEBUG ) {
69
+	if (true === WP_DEBUG) {
70 70
 
71
-		$message = ( isset( $caller ) ? sprintf( '[%-40.40s] ', $caller ) : '' ) .
72
-		           ( is_array( $log ) || is_object( $log ) ? print_r( $log, true ) : wl_write_log_hide_key( $log ) );
71
+		$message = (isset($caller) ? sprintf('[%-40.40s] ', $caller) : '').
72
+		           (is_array($log) || is_object($log) ? print_r($log, true) : wl_write_log_hide_key($log));
73 73
 
74
-		if ( isset( $wl_logger ) ) {
75
-			$wl_logger->info( $message );
74
+		if (isset($wl_logger)) {
75
+			$wl_logger->info($message);
76 76
 		} else {
77
-			error_log( $message );
77
+			error_log($message);
78 78
 		}
79 79
 
80 80
 	}
@@ -92,9 +92,9 @@  discard block
 block discarded – undo
92 92
  *
93 93
  * @return string A text with the key hidden.
94 94
  */
95
-function wl_write_log_hide_key( $text ) {
95
+function wl_write_log_hide_key($text) {
96 96
 
97
-	return str_ireplace( wl_configuration_get_key(), '<hidden>', $text );
97
+	return str_ireplace(wl_configuration_get_key(), '<hidden>', $text);
98 98
 }
99 99
 
100 100
 /**
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
 function wordlift_allowed_post_tags() {
105 105
 	global $allowedposttags;
106 106
 
107
-	$tags           = array( 'span' );
107
+	$tags           = array('span');
108 108
 	$new_attributes = array(
109 109
 		'itemscope' => array(),
110 110
 		'itemtype'  => array(),
@@ -112,15 +112,15 @@  discard block
 block discarded – undo
112 112
 		'itemid'    => array(),
113 113
 	);
114 114
 
115
-	foreach ( $tags as $tag ) {
116
-		if ( isset( $allowedposttags[ $tag ] ) && is_array( $allowedposttags[ $tag ] ) ) {
117
-			$allowedposttags[ $tag ] = array_merge( $allowedposttags[ $tag ], $new_attributes );
115
+	foreach ($tags as $tag) {
116
+		if (isset($allowedposttags[$tag]) && is_array($allowedposttags[$tag])) {
117
+			$allowedposttags[$tag] = array_merge($allowedposttags[$tag], $new_attributes);
118 118
 		}
119 119
 	}
120 120
 }
121 121
 
122 122
 // add allowed post tags.
123
-add_action( 'init', 'wordlift_allowed_post_tags' );
123
+add_action('init', 'wordlift_allowed_post_tags');
124 124
 
125 125
 /**
126 126
  * Register additional scripts for the admin UI.
@@ -128,30 +128,30 @@  discard block
 block discarded – undo
128 128
 function wordlift_admin_enqueue_scripts() {
129 129
 
130 130
 	// Added for compatibility with WordPress 3.9 (see http://make.wordpress.org/core/2014/04/16/jquery-ui-and-wpdialogs-in-wordpress-3-9/)
131
-	wp_enqueue_script( 'wpdialogs' );
132
-	wp_enqueue_style( 'wp-jquery-ui-dialog' );
131
+	wp_enqueue_script('wpdialogs');
132
+	wp_enqueue_style('wp-jquery-ui-dialog');
133 133
 
134
-	wp_enqueue_style( 'wordlift-reloaded', plugin_dir_url( __FILE__ ) . 'css/wordlift-reloaded.min.css' );
134
+	wp_enqueue_style('wordlift-reloaded', plugin_dir_url(__FILE__).'css/wordlift-reloaded.min.css');
135 135
 
136
-	wp_enqueue_script( 'jquery-ui-autocomplete' );
137
-	wp_enqueue_script( 'angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js' );
138
-	wp_enqueue_script( 'angularjs-geolocation', plugin_dir_url( __FILE__ ) . '/bower_components/angularjs-geolocation/dist/angularjs-geolocation.min.js' );
139
-	wp_enqueue_script( 'angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js' );
140
-	wp_enqueue_script( 'angularjs-animate', 'https://code.angularjs.org/1.3.11/angular-animate.min.js' );
136
+	wp_enqueue_script('jquery-ui-autocomplete');
137
+	wp_enqueue_script('angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js');
138
+	wp_enqueue_script('angularjs-geolocation', plugin_dir_url(__FILE__).'/bower_components/angularjs-geolocation/dist/angularjs-geolocation.min.js');
139
+	wp_enqueue_script('angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js');
140
+	wp_enqueue_script('angularjs-animate', 'https://code.angularjs.org/1.3.11/angular-animate.min.js');
141 141
 
142 142
 	// Disable auto-save for custom entity posts only
143
-	if ( Wordlift_Entity_Service::TYPE_NAME === get_post_type() ) {
144
-		wp_dequeue_script( 'autosave' );
143
+	if (Wordlift_Entity_Service::TYPE_NAME === get_post_type()) {
144
+		wp_dequeue_script('autosave');
145 145
 	}
146 146
 }
147 147
 
148
-add_action( 'admin_enqueue_scripts', 'wordlift_admin_enqueue_scripts' );
148
+add_action('admin_enqueue_scripts', 'wordlift_admin_enqueue_scripts');
149 149
 
150 150
 function wl_enqueue_scripts() {
151
-	wp_enqueue_style( 'wordlift-ui', plugin_dir_url( __FILE__ ) . 'css/wordlift-ui.min.css' );
151
+	wp_enqueue_style('wordlift-ui', plugin_dir_url(__FILE__).'css/wordlift-ui.min.css');
152 152
 }
153 153
 
154
-add_action( 'wp_enqueue_scripts', 'wl_enqueue_scripts' );
154
+add_action('wp_enqueue_scripts', 'wl_enqueue_scripts');
155 155
 
156 156
 /**
157 157
  * Hooked to *wp_kses_allowed_html* filter, adds microdata attributes.
@@ -161,23 +161,23 @@  discard block
 block discarded – undo
161 161
  *
162 162
  * @return array An array which contains allowed microdata attributes.
163 163
  */
164
-function wordlift_allowed_html( $allowedtags, $context ) {
164
+function wordlift_allowed_html($allowedtags, $context) {
165 165
 
166
-	if ( 'post' !== $context ) {
166
+	if ('post' !== $context) {
167 167
 		return $allowedtags;
168 168
 	}
169 169
 
170
-	return array_merge_recursive( $allowedtags, array(
170
+	return array_merge_recursive($allowedtags, array(
171 171
 		'span' => array(
172 172
 			'itemscope' => true,
173 173
 			'itemtype'  => true,
174 174
 			'itemid'    => true,
175 175
 			'itemprop'  => true,
176 176
 		),
177
-	) );
177
+	));
178 178
 }
179 179
 
180
-add_filter( 'wp_kses_allowed_html', 'wordlift_allowed_html', 10, 2 );
180
+add_filter('wp_kses_allowed_html', 'wordlift_allowed_html', 10, 2);
181 181
 
182 182
 /**
183 183
  * Get the coordinates for the specified post ID.
@@ -186,17 +186,17 @@  discard block
 block discarded – undo
186 186
  *
187 187
  * @return array|null An array of coordinates or null.
188 188
  */
189
-function wl_get_coordinates( $post_id ) {
189
+function wl_get_coordinates($post_id) {
190 190
 
191
-	$latitude  = wl_schema_get_value( $post_id, 'latitude' );
192
-	$longitude = wl_schema_get_value( $post_id, 'longitude' );
191
+	$latitude  = wl_schema_get_value($post_id, 'latitude');
192
+	$longitude = wl_schema_get_value($post_id, 'longitude');
193 193
 
194 194
 	// DO NOT set latitude/longitude to 0/0 as default values. It's a specific
195 195
 	// place on the globe:"The zero/zero point of this system is located in the
196 196
 	// Gulf of Guinea about 625 km (390 mi) south of Tema, Ghana."
197 197
 	return array(
198
-		'latitude'  => isset( $latitude[0] ) && is_numeric( $latitude[0] ) ? $latitude[0] : '',
199
-		'longitude' => isset( $longitude[0] ) && is_numeric( $longitude[0] ) ? $longitude[0] : '',
198
+		'latitude'  => isset($latitude[0]) && is_numeric($latitude[0]) ? $latitude[0] : '',
199
+		'longitude' => isset($longitude[0]) && is_numeric($longitude[0]) ? $longitude[0] : '',
200 200
 	);
201 201
 }
202 202
 
@@ -209,11 +209,11 @@  discard block
 block discarded – undo
209 209
  *
210 210
  * @return array An array of image URLs.
211 211
  */
212
-function wl_get_image_urls( $post_id ) {
212
+function wl_get_image_urls($post_id) {
213 213
 
214 214
 	return Wordlift_Storage_Factory::get_instance()
215 215
 	                               ->post_images()
216
-	                               ->get( $post_id );
216
+	                               ->get($post_id);
217 217
 
218 218
 //	// If there is a featured image it has the priority.
219 219
 //	$featured_image_id = get_post_thumbnail_id( $post_id );
@@ -259,21 +259,21 @@  discard block
 block discarded – undo
259 259
  *
260 260
  * @return WP_Post|null A post instance or null if not found.
261 261
  */
262
-function wl_get_attachment_for_source_url( $parent_post_id, $source_url ) {
262
+function wl_get_attachment_for_source_url($parent_post_id, $source_url) {
263 263
 
264 264
 	// wl_write_log( "wl_get_attachment_for_source_url [ parent post id :: $parent_post_id ][ source url :: $source_url ]" );
265 265
 
266
-	$posts = get_posts( array(
266
+	$posts = get_posts(array(
267 267
 		'post_type'      => 'attachment',
268 268
 		'posts_per_page' => 1,
269 269
 		'post_status'    => 'any',
270 270
 		'post_parent'    => $parent_post_id,
271 271
 		'meta_key'       => 'wl_source_url',
272 272
 		'meta_value'     => $source_url,
273
-	) );
273
+	));
274 274
 
275 275
 	// Return the found post.
276
-	if ( 1 === count( $posts ) ) {
276
+	if (1 === count($posts)) {
277 277
 		return $posts[0];
278 278
 	}
279 279
 
@@ -287,10 +287,10 @@  discard block
 block discarded – undo
287 287
  * @param int    $post_id    The post ID.
288 288
  * @param string $source_url The source URL.
289 289
  */
290
-function wl_set_source_url( $post_id, $source_url ) {
290
+function wl_set_source_url($post_id, $source_url) {
291 291
 
292
-	delete_post_meta( $post_id, 'wl_source_url' );
293
-	add_post_meta( $post_id, 'wl_source_url', $source_url );
292
+	delete_post_meta($post_id, 'wl_source_url');
293
+	add_post_meta($post_id, 'wl_source_url', $source_url);
294 294
 }
295 295
 
296 296
 
@@ -305,10 +305,10 @@  discard block
 block discarded – undo
305 305
  *
306 306
  * @param bool $hard True if the rewrite involves configuration updates in Apache/IIS.
307 307
  */
308
-function wl_flush_rewrite_rules_hard( $hard ) {
308
+function wl_flush_rewrite_rules_hard($hard) {
309 309
 
310 310
 	// If WL is not yet configured, we cannot perform any update, so we exit.
311
-	if ( '' === wl_configuration_get_key() ) {
311
+	if ('' === wl_configuration_get_key()) {
312 312
 		return;
313 313
 	}
314 314
 
@@ -317,13 +317,13 @@  discard block
 block discarded – undo
317 317
 	$limit  = 100;
318 318
 
319 319
 	// Get more posts if the number of returned posts matches the limit.
320
-	while ( $limit === ( $posts = get_posts( array(
320
+	while ($limit === ($posts = get_posts(array(
321 321
 			'offset'      => $offset,
322 322
 			'numberposts' => $limit,
323 323
 			'orderby'     => 'ID',
324 324
 			'post_type'   => 'any',
325 325
 			'post_status' => 'publish',
326
-		) ) ) ) {
326
+		)))) {
327 327
 
328 328
 		// Holds the delete part of the query.
329 329
 		$delete_query = rl_sparql_prefixes();
@@ -332,16 +332,16 @@  discard block
 block discarded – undo
332 332
 		$insert_query = '';
333 333
 
334 334
 		// Cycle in each post to build the query.
335
-		foreach ( $posts as $post ) {
335
+		foreach ($posts as $post) {
336 336
 
337 337
 			// Ignore revisions.
338
-			if ( wp_is_post_revision( $post->ID ) ) {
338
+			if (wp_is_post_revision($post->ID)) {
339 339
 				continue;
340 340
 			}
341 341
 
342 342
 			// Get the entity URI.
343
-			$s = Wordlift_Sparql_Service::escape_uri( Wordlift_Entity_Service::get_instance()
344
-			                                                                 ->get_uri( $post->ID ) );
343
+			$s = Wordlift_Sparql_Service::escape_uri(Wordlift_Entity_Service::get_instance()
344
+			                                                                 ->get_uri($post->ID));
345 345
 
346 346
 			// Get the post URL.
347 347
 			// $url = wl_sparql_escape_uri( get_permalink( $post->ID ) );
@@ -350,13 +350,13 @@  discard block
 block discarded – undo
350 350
 			$delete_query .= "DELETE { <$s> schema:url ?u . } WHERE  { <$s> schema:url ?u . };\n";
351 351
 
352 352
 			$insert_query .= Wordlift_Schema_Url_Property_Service::get_instance()
353
-			                                                     ->get_insert_query( $s, $post->ID );
353
+			                                                     ->get_insert_query($s, $post->ID);
354 354
 
355 355
 		}
356 356
 
357 357
 
358 358
 		// Execute the query.
359
-		rl_execute_sparql_update_query( $delete_query . $insert_query );
359
+		rl_execute_sparql_update_query($delete_query.$insert_query);
360 360
 
361 361
 		// Advance to the next posts.
362 362
 		$offset += $limit;
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
 
366 366
 }
367 367
 
368
-add_filter( 'flush_rewrite_rules_hard', 'wl_flush_rewrite_rules_hard', 10, 1 );
368
+add_filter('flush_rewrite_rules_hard', 'wl_flush_rewrite_rules_hard', 10, 1);
369 369
 
370 370
 /**
371 371
  * Sanitizes an URI path by replacing the non allowed characters with an underscore.
@@ -378,9 +378,9 @@  discard block
 block discarded – undo
378 378
  *
379 379
  * @return string The sanitized path.
380 380
  */
381
-function wl_sanitize_uri_path( $path, $char = '_' ) {
381
+function wl_sanitize_uri_path($path, $char = '_') {
382 382
 
383
-	return Wordlift_Uri_Service::get_instance()->sanitize_path( $path, $char );
383
+	return Wordlift_Uri_Service::get_instance()->sanitize_path($path, $char);
384 384
 }
385 385
 
386 386
 ///**
@@ -419,107 +419,107 @@  discard block
 block discarded – undo
419 419
  *
420 420
  * @return string The updated post content.
421 421
  */
422
-function wl_replace_item_id_with_uri( $content ) {
422
+function wl_replace_item_id_with_uri($content) {
423 423
 
424 424
 	// wl_write_log( "wl_replace_item_id_with_uri" );
425 425
 
426 426
 	// Strip slashes, see https://core.trac.wordpress.org/ticket/21767
427
-	$content = stripslashes( $content );
427
+	$content = stripslashes($content);
428 428
 
429 429
 	// If any match are found.
430 430
 	$matches = array();
431
-	if ( 0 < preg_match_all( '/ itemid="([^"]+)"/i', $content, $matches, PREG_SET_ORDER ) ) {
431
+	if (0 < preg_match_all('/ itemid="([^"]+)"/i', $content, $matches, PREG_SET_ORDER)) {
432 432
 
433
-		foreach ( $matches as $match ) {
433
+		foreach ($matches as $match) {
434 434
 
435 435
 			// Get the item ID.
436 436
 			$item_id = $match[1];
437 437
 
438 438
 			// Get the post bound to that item ID (looking both in the 'official' URI and in the 'same-as' .
439 439
 			$post = Wordlift_Entity_Service::get_instance()
440
-			                               ->get_entity_post_by_uri( $item_id );
440
+			                               ->get_entity_post_by_uri($item_id);
441 441
 
442 442
 			// If no entity is found, continue to the next one.
443
-			if ( null === $post ) {
443
+			if (null === $post) {
444 444
 				continue;
445 445
 			}
446 446
 
447 447
 			// Get the URI for that post.
448
-			$uri = wl_get_entity_uri( $post->ID );
448
+			$uri = wl_get_entity_uri($post->ID);
449 449
 
450 450
 			// wl_write_log( "wl_replace_item_id_with_uri [ item id :: $item_id ][ uri :: $uri ]" );
451 451
 
452 452
 			// If the item ID and the URI differ, replace the item ID with the URI saved in WordPress.
453
-			if ( $item_id !== $uri ) {
454
-				$uri_e   = esc_html( $uri );
455
-				$content = str_replace( " itemid=\"$item_id\"", " itemid=\"$uri_e\"", $content );
453
+			if ($item_id !== $uri) {
454
+				$uri_e   = esc_html($uri);
455
+				$content = str_replace(" itemid=\"$item_id\"", " itemid=\"$uri_e\"", $content);
456 456
 			}
457 457
 		}
458 458
 	}
459 459
 
460 460
 	// Reapply slashes.
461
-	$content = addslashes( $content );
461
+	$content = addslashes($content);
462 462
 
463 463
 	return $content;
464 464
 }
465 465
 
466
-add_filter( 'content_save_pre', 'wl_replace_item_id_with_uri', 1, 1 );
466
+add_filter('content_save_pre', 'wl_replace_item_id_with_uri', 1, 1);
467 467
 
468
-require_once( 'wordlift_entity_functions.php' );
468
+require_once('wordlift_entity_functions.php');
469 469
 
470 470
 // add editor related methods.
471
-require_once( 'wordlift_editor.php' );
471
+require_once('wordlift_editor.php');
472 472
 
473 473
 // add the WordLift entity custom type.
474
-require_once( 'wordlift_entity_type.php' );
475
-require_once( 'wordlift_entity_type_taxonomy.php' );
474
+require_once('wordlift_entity_type.php');
475
+require_once('wordlift_entity_type_taxonomy.php');
476 476
 
477 477
 // add callbacks on post save to notify data changes from wp to redlink triple store
478
-require_once( 'wordlift_to_redlink_data_push_callbacks.php' );
478
+require_once('wordlift_to_redlink_data_push_callbacks.php');
479 479
 
480
-require_once( 'modules/configuration/wordlift_configuration_settings.php' );
480
+require_once('modules/configuration/wordlift_configuration_settings.php');
481 481
 
482 482
 // Load modules
483
-require_once( 'modules/analyzer/wordlift_analyzer.php' );
484
-require_once( 'modules/linked_data/wordlift_linked_data.php' );
485
-require_once( 'modules/prefixes/wordlift_prefixes.php' );
483
+require_once('modules/analyzer/wordlift_analyzer.php');
484
+require_once('modules/linked_data/wordlift_linked_data.php');
485
+require_once('modules/prefixes/wordlift_prefixes.php');
486 486
 
487 487
 // Shortcodes
488 488
 
489
-require_once( 'modules/geo_widget/wordlift_geo_widget.php' );
490
-require_once( 'shortcodes/wordlift_shortcode_chord.php' );
491
-require_once( 'shortcodes/wordlift_shortcode_geomap.php' );
492
-require_once( 'shortcodes/wordlift_shortcode_field.php' );
493
-require_once( 'shortcodes/wordlift_shortcode_faceted_search.php' );
494
-require_once( 'shortcodes/wordlift_shortcode_navigator.php' );
489
+require_once('modules/geo_widget/wordlift_geo_widget.php');
490
+require_once('shortcodes/wordlift_shortcode_chord.php');
491
+require_once('shortcodes/wordlift_shortcode_geomap.php');
492
+require_once('shortcodes/wordlift_shortcode_field.php');
493
+require_once('shortcodes/wordlift_shortcode_faceted_search.php');
494
+require_once('shortcodes/wordlift_shortcode_navigator.php');
495 495
 
496
-require_once( 'widgets/wordlift_widget_geo.php' );
497
-require_once( 'widgets/wordlift_widget_chord.php' );
498
-require_once( 'widgets/wordlift_widget_timeline.php' );
496
+require_once('widgets/wordlift_widget_geo.php');
497
+require_once('widgets/wordlift_widget_chord.php');
498
+require_once('widgets/wordlift_widget_timeline.php');
499 499
 
500
-require_once( 'wordlift_redlink.php' );
500
+require_once('wordlift_redlink.php');
501 501
 
502 502
 // Add admin functions.
503 503
 // TODO: find a way to make 'admin' UI tests work.
504 504
 //if ( is_admin() ) {
505 505
 
506
-require_once( 'admin/wordlift_admin.php' );
507
-require_once( 'admin/wordlift_admin_edit_post.php' );
508
-require_once( 'admin/wordlift_admin_save_post.php' );
506
+require_once('admin/wordlift_admin.php');
507
+require_once('admin/wordlift_admin_edit_post.php');
508
+require_once('admin/wordlift_admin_save_post.php');
509 509
 
510 510
 // add the entities meta box.
511
-require_once( 'admin/wordlift_admin_meta_box_entities.php' );
511
+require_once('admin/wordlift_admin_meta_box_entities.php');
512 512
 
513 513
 // add the entity creation AJAX.
514
-require_once( 'admin/wordlift_admin_ajax_related_posts.php' );
514
+require_once('admin/wordlift_admin_ajax_related_posts.php');
515 515
 
516 516
 // Load the wl_chord TinyMCE button and configuration dialog.
517
-require_once( 'admin/wordlift_admin_shortcodes.php' );
517
+require_once('admin/wordlift_admin_shortcodes.php');
518 518
 
519 519
 // load languages.
520 520
 // TODO: the following call gives for granted that the plugin is in the wordlift directory,
521 521
 //       we're currently doing this because wordlift is symbolic linked.
522
-load_plugin_textdomain( 'wordlift', false, '/wordlift/languages' );
522
+load_plugin_textdomain('wordlift', false, '/wordlift/languages');
523 523
 
524 524
 
525 525
 /**
@@ -527,7 +527,7 @@  discard block
 block discarded – undo
527 527
  * This action is documented in includes/class-wordlift-activator.php
528 528
  */
529 529
 function activate_wordlift() {
530
-	require_once plugin_dir_path( __FILE__ ) . 'includes/class-wordlift-activator.php';
530
+	require_once plugin_dir_path(__FILE__).'includes/class-wordlift-activator.php';
531 531
 	Wordlift_Activator::activate();
532 532
 }
533 533
 
@@ -536,18 +536,18 @@  discard block
 block discarded – undo
536 536
  * This action is documented in includes/class-wordlift-deactivator.php
537 537
  */
538 538
 function deactivate_wordlift() {
539
-	require_once plugin_dir_path( __FILE__ ) . 'includes/class-wordlift-deactivator.php';
539
+	require_once plugin_dir_path(__FILE__).'includes/class-wordlift-deactivator.php';
540 540
 	Wordlift_Deactivator::deactivate();
541 541
 }
542 542
 
543
-register_activation_hook( __FILE__, 'activate_wordlift' );
544
-register_deactivation_hook( __FILE__, 'deactivate_wordlift' );
543
+register_activation_hook(__FILE__, 'activate_wordlift');
544
+register_deactivation_hook(__FILE__, 'deactivate_wordlift');
545 545
 
546 546
 /**
547 547
  * The core plugin class that is used to define internationalization,
548 548
  * admin-specific hooks, and public-facing site hooks.
549 549
  */
550
-require plugin_dir_path( __FILE__ ) . 'includes/class-wordlift.php';
550
+require plugin_dir_path(__FILE__).'includes/class-wordlift.php';
551 551
 
552 552
 /**
553 553
  * Begins execution of the plugin.
Please login to merge, or discard this patch.
src/wordlift_entity_type.php 2 patches
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -10,8 +10,8 @@  discard block
 block discarded – undo
10 10
  */
11 11
 function wl_set_entity_main_type( $post_id, $type_uri ) {
12 12
 
13
-	Wordlift_Entity_Type_Service::get_instance()
14
-	                            ->set( $post_id, $type_uri );
13
+    Wordlift_Entity_Type_Service::get_instance()
14
+                                ->set( $post_id, $type_uri );
15 15
 
16 16
 }
17 17
 
@@ -20,47 +20,47 @@  discard block
 block discarded – undo
20 20
  */
21 21
 function wl_print_entity_type_inline_js() {
22 22
 
23
-	$terms = get_terms( Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
24
-		'hide_empty' => FALSE,
25
-	) );
23
+    $terms = get_terms( Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
24
+        'hide_empty' => FALSE,
25
+    ) );
26 26
 
27
-	echo <<<EOF
27
+    echo <<<EOF
28 28
     <script type="text/javascript">
29 29
         (function() {
30 30
         var t = [];
31 31
 
32 32
 EOF;
33 33
 
34
-	// Cycle in each WordLift term and get its metadata. The metadata will be printed as a global object in JavaScript
35
-	// to be used by the JavaScript client library.
36
-	foreach ( $terms as $term ) {
34
+    // Cycle in each WordLift term and get its metadata. The metadata will be printed as a global object in JavaScript
35
+    // to be used by the JavaScript client library.
36
+    foreach ( $terms as $term ) {
37 37
 
38
-		$term_name = $term->name;
38
+        $term_name = $term->name;
39 39
 
40
-		// Load the type data.
41
-		$type = Wordlift_Schema_Service::get_instance()
42
-		                               ->get_schema( $term->slug );
40
+        // Load the type data.
41
+        $type = Wordlift_Schema_Service::get_instance()
42
+                                        ->get_schema( $term->slug );
43 43
 
44
-		// Skip types that are not defined.
45
-		if ( ! empty( $type['uri'] ) ) {
44
+        // Skip types that are not defined.
45
+        if ( ! empty( $type['uri'] ) ) {
46 46
 
47
-			// Prepare the JSON output then print it to the browser.
48
-			$json = json_encode( array(
49
-				'label'     => $term_name,
50
-				'uri'       => $type['uri'],
51
-				'css'       => $type['css_class'],
52
-				'sameAs'    => $type['same_as'],
53
-				'templates' => ( isset( $type['templates'] ) ? $type['templates'] : array() ),
54
-			) );
47
+            // Prepare the JSON output then print it to the browser.
48
+            $json = json_encode( array(
49
+                'label'     => $term_name,
50
+                'uri'       => $type['uri'],
51
+                'css'       => $type['css_class'],
52
+                'sameAs'    => $type['same_as'],
53
+                'templates' => ( isset( $type['templates'] ) ? $type['templates'] : array() ),
54
+            ) );
55 55
 
56
-			// Output the type data.
57
-			echo "t.push($json);\n";
56
+            // Output the type data.
57
+            echo "t.push($json);\n";
58 58
 
59
-		}
59
+        }
60 60
 
61
-	}
61
+    }
62 62
 
63
-	echo <<<EOF
63
+    echo <<<EOF
64 64
             if ('undefined' == typeof window.wordlift) {
65 65
                 window.wordlift = {}
66 66
             }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -8,10 +8,10 @@  discard block
 block discarded – undo
8 8
  * @param int    $post_id  The numeric post ID.
9 9
  * @param string $type_uri A type URI.
10 10
  */
11
-function wl_set_entity_main_type( $post_id, $type_uri ) {
11
+function wl_set_entity_main_type($post_id, $type_uri) {
12 12
 
13 13
 	Wordlift_Entity_Type_Service::get_instance()
14
-	                            ->set( $post_id, $type_uri );
14
+	                            ->set($post_id, $type_uri);
15 15
 
16 16
 }
17 17
 
@@ -20,9 +20,9 @@  discard block
 block discarded – undo
20 20
  */
21 21
 function wl_print_entity_type_inline_js() {
22 22
 
23
-	$terms = get_terms( Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
23
+	$terms = get_terms(Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
24 24
 		'hide_empty' => FALSE,
25
-	) );
25
+	));
26 26
 
27 27
 	echo <<<EOF
28 28
     <script type="text/javascript">
@@ -33,25 +33,25 @@  discard block
 block discarded – undo
33 33
 
34 34
 	// Cycle in each WordLift term and get its metadata. The metadata will be printed as a global object in JavaScript
35 35
 	// to be used by the JavaScript client library.
36
-	foreach ( $terms as $term ) {
36
+	foreach ($terms as $term) {
37 37
 
38 38
 		$term_name = $term->name;
39 39
 
40 40
 		// Load the type data.
41 41
 		$type = Wordlift_Schema_Service::get_instance()
42
-		                               ->get_schema( $term->slug );
42
+		                               ->get_schema($term->slug);
43 43
 
44 44
 		// Skip types that are not defined.
45
-		if ( ! empty( $type['uri'] ) ) {
45
+		if ( ! empty($type['uri'])) {
46 46
 
47 47
 			// Prepare the JSON output then print it to the browser.
48
-			$json = json_encode( array(
48
+			$json = json_encode(array(
49 49
 				'label'     => $term_name,
50 50
 				'uri'       => $type['uri'],
51 51
 				'css'       => $type['css_class'],
52 52
 				'sameAs'    => $type['same_as'],
53
-				'templates' => ( isset( $type['templates'] ) ? $type['templates'] : array() ),
54
-			) );
53
+				'templates' => (isset($type['templates']) ? $type['templates'] : array()),
54
+			));
55 55
 
56 56
 			// Output the type data.
57 57
 			echo "t.push($json);\n";
@@ -72,5 +72,5 @@  discard block
 block discarded – undo
72 72
 
73 73
 }
74 74
 
75
-add_action( 'admin_print_scripts', 'wl_print_entity_type_inline_js' );
76
-add_action( 'init', 'wl_entity_type_taxonomy_register', 0 );
75
+add_action('admin_print_scripts', 'wl_print_entity_type_inline_js');
76
+add_action('init', 'wl_entity_type_taxonomy_register', 0);
Please login to merge, or discard this patch.
src/includes/class-wordlift-linked-data-service.php 2 patches
Indentation   +280 added lines, -280 removed lines patch added patch discarded remove patch
@@ -18,285 +18,285 @@
 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
-		// Bail out if the entity type is `Article`.
133
-		if ( $this->entity_type_service->has_entity_type( $post_id, 'http://schema.org/Article' ) ) {
134
-			$this->log->debug( "Post $post_id is an `Article`." );
135
-
136
-			return;
137
-		}
138
-
139
-		// Get the post and push it to the Linked Data store.
140
-		$this->do_push( $post_id );
141
-
142
-		// Reindex the triple store if buffering is turned off.
143
-		if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
144
-			wordlift_reindex_triple_store();
145
-		}
146
-
147
-	}
148
-
149
-	/**
150
-	 * Remove the specified {@link WP_Post} from the Linked Data.
151
-	 *
152
-	 * @since 3.15.0
153
-	 *
154
-	 * @param int $post_id The {@link WP_Post}'s id.
155
-	 */
156
-	public function remove( $post_id ) {
157
-
158
-		// Get the delete statements.
159
-		$deletes      = $this->get_delete_statements( $post_id );
160
-		$delete_query = implode( "\n", $deletes );
161
-		$this->sparql_service->execute( $delete_query );
162
-
163
-	}
164
-
165
-	/**
166
-	 * Push an entity to the Linked Data store.
167
-	 *
168
-	 * @since 3.15.0
169
-	 *
170
-	 * @param int $post_id The {@link WP_Post}'s id.
171
-	 */
172
-	private function do_push( $post_id ) {
173
-		$this->log->debug( "Doing post $post_id push..." );
174
-
175
-		// Get the post.
176
-		$post = get_post( $post_id );
177
-
178
-		// Bail out if the post isn't found.
179
-		if ( null === $post ) {
180
-			$this->log->debug( "Post $post_id not found." );
181
-
182
-			return;
183
-		}
184
-
185
-		// Bail out if the post isn't published.
186
-		if ( 'publish' !== $post->post_status ) {
187
-			$this->log->debug( "Post $post_id not published." );
188
-
189
-			return;
190
-		}
191
-
192
-		// Bail out if the URI isn't valid.
193
-		if ( ! $this->has_valid_uri( $post_id ) ) {
194
-			$this->log->debug( "Post $post_id URI invalid." );
195
-
196
-			return;
197
-		}
198
-
199
-		// First remove the post data.
200
-		$this->remove( $post_id );
201
-
202
-		// Get the insert statements.
203
-		$insert_tuples     = $this->get_insert_tuples( $post_id );
204
-		$insert_query_body = implode( "\n", $insert_tuples );
205
-		$insert_query      = "INSERT DATA { $insert_query_body };";
206
-		$this->sparql_service->execute( $insert_query );
207
-
208
-	}
209
-
210
-	/**
211
-	 * Check if an entity's {@link WP_Post} has a valid URI.
212
-	 *
213
-	 * @since 3.15.0
214
-	 *
215
-	 * @param int $post_id The entity's {@link WP_Post}'s id.
216
-	 *
217
-	 * @return bool True if the URI is valid otherwise false.
218
-	 */
219
-	private function has_valid_uri( $post_id ) {
220
-
221
-		// Get the entity's URI.
222
-		$uri = $this->entity_service->get_uri( $post_id );
223
-
224
-		// If the URI isn't found, return false.
225
-		if ( null === $uri ) {
226
-			return false;
227
-		}
228
-
229
-		// If the URI ends with a trailing slash, return false.
230
-		if ( '/' === substr( $uri, - 1 ) ) {
231
-			return false;
232
-		}
233
-
234
-		// URI is valid.
235
-		return true;
236
-	}
237
-
238
-	/**
239
-	 * Get the delete statements.
240
-	 *
241
-	 * @since 3.15.0
242
-	 *
243
-	 * @param int $post_id The {@link WP_Post}'s id.
244
-	 *
245
-	 * @return array An array of delete statements.
246
-	 */
247
-	private function get_delete_statements( $post_id ) {
248
-
249
-		// Get the entity URI.
250
-		$uri = $this->entity_service->get_uri( $post_id );
251
-
252
-		// Prepare the delete statements with the entity as subject.
253
-		$as_subject = array_map( function ( $item ) use ( $uri ) {
254
-			return Wordlift_Query_Builder::new_instance()
255
-			                             ->delete()
256
-			                             ->statement( $uri, $item, '?o' )
257
-			                             ->build();
258
-		}, $this->schema_service->get_all_predicates() );
259
-
260
-		// Prepare the delete statements with the entity as object.
261
-		$as_object = array_map( function ( $item ) use ( $uri ) {
262
-			return Wordlift_Query_Builder::new_instance()
263
-			                             ->delete()
264
-			                             ->statement( '?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI )
265
-			                             ->build();
266
-		}, $this->schema_service->get_all_predicates() );
267
-
268
-		// Merge the delete statements and return them.
269
-		return array_merge( $as_subject, $as_object );
270
-	}
271
-
272
-	/**
273
-	 * Get the SPARQL insert tuples ( ?s ?p ?o ) for the specified {@link WP_Post}.
274
-	 *
275
-	 * @since 3.15.0
276
-	 *
277
-	 * @param int $post_id The {@link WP_Post}'s id.
278
-	 *
279
-	 * @return array An array of insert tuples.
280
-	 */
281
-	private function get_insert_tuples( $post_id ) {
282
-
283
-		// Get the entity type.
284
-		$type = $this->entity_type_service->get( $post_id );
285
-
286
-		// Get the Linked Data properties.
287
-		$properties = $type['linked_data'];
288
-
289
-		// Accumulate the tuples.
290
-		$tuples = array();
291
-		/** @var Wordlift_Sparql_Tuple_Rendition $property */
292
-		foreach ( $properties as $property ) {
293
-			foreach ( $property->get( $post_id ) as $tuple ) {
294
-				$tuples[] = $tuple;
295
-			}
296
-		}
297
-
298
-		// Finally return the tuples.
299
-		return $tuples;
300
-	}
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
+        // Bail out if the entity type is `Article`.
133
+        if ( $this->entity_type_service->has_entity_type( $post_id, 'http://schema.org/Article' ) ) {
134
+            $this->log->debug( "Post $post_id is an `Article`." );
135
+
136
+            return;
137
+        }
138
+
139
+        // Get the post and push it to the Linked Data store.
140
+        $this->do_push( $post_id );
141
+
142
+        // Reindex the triple store if buffering is turned off.
143
+        if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
144
+            wordlift_reindex_triple_store();
145
+        }
146
+
147
+    }
148
+
149
+    /**
150
+     * Remove the specified {@link WP_Post} from the Linked Data.
151
+     *
152
+     * @since 3.15.0
153
+     *
154
+     * @param int $post_id The {@link WP_Post}'s id.
155
+     */
156
+    public function remove( $post_id ) {
157
+
158
+        // Get the delete statements.
159
+        $deletes      = $this->get_delete_statements( $post_id );
160
+        $delete_query = implode( "\n", $deletes );
161
+        $this->sparql_service->execute( $delete_query );
162
+
163
+    }
164
+
165
+    /**
166
+     * Push an entity to the Linked Data store.
167
+     *
168
+     * @since 3.15.0
169
+     *
170
+     * @param int $post_id The {@link WP_Post}'s id.
171
+     */
172
+    private function do_push( $post_id ) {
173
+        $this->log->debug( "Doing post $post_id push..." );
174
+
175
+        // Get the post.
176
+        $post = get_post( $post_id );
177
+
178
+        // Bail out if the post isn't found.
179
+        if ( null === $post ) {
180
+            $this->log->debug( "Post $post_id not found." );
181
+
182
+            return;
183
+        }
184
+
185
+        // Bail out if the post isn't published.
186
+        if ( 'publish' !== $post->post_status ) {
187
+            $this->log->debug( "Post $post_id not published." );
188
+
189
+            return;
190
+        }
191
+
192
+        // Bail out if the URI isn't valid.
193
+        if ( ! $this->has_valid_uri( $post_id ) ) {
194
+            $this->log->debug( "Post $post_id URI invalid." );
195
+
196
+            return;
197
+        }
198
+
199
+        // First remove the post data.
200
+        $this->remove( $post_id );
201
+
202
+        // Get the insert statements.
203
+        $insert_tuples     = $this->get_insert_tuples( $post_id );
204
+        $insert_query_body = implode( "\n", $insert_tuples );
205
+        $insert_query      = "INSERT DATA { $insert_query_body };";
206
+        $this->sparql_service->execute( $insert_query );
207
+
208
+    }
209
+
210
+    /**
211
+     * Check if an entity's {@link WP_Post} has a valid URI.
212
+     *
213
+     * @since 3.15.0
214
+     *
215
+     * @param int $post_id The entity's {@link WP_Post}'s id.
216
+     *
217
+     * @return bool True if the URI is valid otherwise false.
218
+     */
219
+    private function has_valid_uri( $post_id ) {
220
+
221
+        // Get the entity's URI.
222
+        $uri = $this->entity_service->get_uri( $post_id );
223
+
224
+        // If the URI isn't found, return false.
225
+        if ( null === $uri ) {
226
+            return false;
227
+        }
228
+
229
+        // If the URI ends with a trailing slash, return false.
230
+        if ( '/' === substr( $uri, - 1 ) ) {
231
+            return false;
232
+        }
233
+
234
+        // URI is valid.
235
+        return true;
236
+    }
237
+
238
+    /**
239
+     * Get the delete statements.
240
+     *
241
+     * @since 3.15.0
242
+     *
243
+     * @param int $post_id The {@link WP_Post}'s id.
244
+     *
245
+     * @return array An array of delete statements.
246
+     */
247
+    private function get_delete_statements( $post_id ) {
248
+
249
+        // Get the entity URI.
250
+        $uri = $this->entity_service->get_uri( $post_id );
251
+
252
+        // Prepare the delete statements with the entity as subject.
253
+        $as_subject = array_map( function ( $item ) use ( $uri ) {
254
+            return Wordlift_Query_Builder::new_instance()
255
+                                            ->delete()
256
+                                            ->statement( $uri, $item, '?o' )
257
+                                            ->build();
258
+        }, $this->schema_service->get_all_predicates() );
259
+
260
+        // Prepare the delete statements with the entity as object.
261
+        $as_object = array_map( function ( $item ) use ( $uri ) {
262
+            return Wordlift_Query_Builder::new_instance()
263
+                                            ->delete()
264
+                                            ->statement( '?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI )
265
+                                            ->build();
266
+        }, $this->schema_service->get_all_predicates() );
267
+
268
+        // Merge the delete statements and return them.
269
+        return array_merge( $as_subject, $as_object );
270
+    }
271
+
272
+    /**
273
+     * Get the SPARQL insert tuples ( ?s ?p ?o ) for the specified {@link WP_Post}.
274
+     *
275
+     * @since 3.15.0
276
+     *
277
+     * @param int $post_id The {@link WP_Post}'s id.
278
+     *
279
+     * @return array An array of insert tuples.
280
+     */
281
+    private function get_insert_tuples( $post_id ) {
282
+
283
+        // Get the entity type.
284
+        $type = $this->entity_type_service->get( $post_id );
285
+
286
+        // Get the Linked Data properties.
287
+        $properties = $type['linked_data'];
288
+
289
+        // Accumulate the tuples.
290
+        $tuples = array();
291
+        /** @var Wordlift_Sparql_Tuple_Rendition $property */
292
+        foreach ( $properties as $property ) {
293
+            foreach ( $property->get( $post_id ) as $tuple ) {
294
+                $tuples[] = $tuple;
295
+            }
296
+        }
297
+
298
+        // Finally return the tuples.
299
+        return $tuples;
300
+    }
301 301
 
302 302
 }
Please login to merge, or discard this patch.
Spacing   +44 added lines, -44 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,30 +117,30 @@  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
 		// Bail out if the entity type is `Article`.
133
-		if ( $this->entity_type_service->has_entity_type( $post_id, 'http://schema.org/Article' ) ) {
134
-			$this->log->debug( "Post $post_id is an `Article`." );
133
+		if ($this->entity_type_service->has_entity_type($post_id, 'http://schema.org/Article')) {
134
+			$this->log->debug("Post $post_id is an `Article`.");
135 135
 
136 136
 			return;
137 137
 		}
138 138
 
139 139
 		// Get the post and push it to the Linked Data store.
140
-		$this->do_push( $post_id );
140
+		$this->do_push($post_id);
141 141
 
142 142
 		// Reindex the triple store if buffering is turned off.
143
-		if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
143
+		if (false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING) {
144 144
 			wordlift_reindex_triple_store();
145 145
 		}
146 146
 
@@ -153,12 +153,12 @@  discard block
 block discarded – undo
153 153
 	 *
154 154
 	 * @param int $post_id The {@link WP_Post}'s id.
155 155
 	 */
156
-	public function remove( $post_id ) {
156
+	public function remove($post_id) {
157 157
 
158 158
 		// Get the delete statements.
159
-		$deletes      = $this->get_delete_statements( $post_id );
160
-		$delete_query = implode( "\n", $deletes );
161
-		$this->sparql_service->execute( $delete_query );
159
+		$deletes      = $this->get_delete_statements($post_id);
160
+		$delete_query = implode("\n", $deletes);
161
+		$this->sparql_service->execute($delete_query);
162 162
 
163 163
 	}
164 164
 
@@ -169,41 +169,41 @@  discard block
 block discarded – undo
169 169
 	 *
170 170
 	 * @param int $post_id The {@link WP_Post}'s id.
171 171
 	 */
172
-	private function do_push( $post_id ) {
173
-		$this->log->debug( "Doing post $post_id push..." );
172
+	private function do_push($post_id) {
173
+		$this->log->debug("Doing post $post_id push...");
174 174
 
175 175
 		// Get the post.
176
-		$post = get_post( $post_id );
176
+		$post = get_post($post_id);
177 177
 
178 178
 		// Bail out if the post isn't found.
179
-		if ( null === $post ) {
180
-			$this->log->debug( "Post $post_id not found." );
179
+		if (null === $post) {
180
+			$this->log->debug("Post $post_id not found.");
181 181
 
182 182
 			return;
183 183
 		}
184 184
 
185 185
 		// Bail out if the post isn't published.
186
-		if ( 'publish' !== $post->post_status ) {
187
-			$this->log->debug( "Post $post_id not published." );
186
+		if ('publish' !== $post->post_status) {
187
+			$this->log->debug("Post $post_id not published.");
188 188
 
189 189
 			return;
190 190
 		}
191 191
 
192 192
 		// Bail out if the URI isn't valid.
193
-		if ( ! $this->has_valid_uri( $post_id ) ) {
194
-			$this->log->debug( "Post $post_id URI invalid." );
193
+		if ( ! $this->has_valid_uri($post_id)) {
194
+			$this->log->debug("Post $post_id URI invalid.");
195 195
 
196 196
 			return;
197 197
 		}
198 198
 
199 199
 		// First remove the post data.
200
-		$this->remove( $post_id );
200
+		$this->remove($post_id);
201 201
 
202 202
 		// Get the insert statements.
203
-		$insert_tuples     = $this->get_insert_tuples( $post_id );
204
-		$insert_query_body = implode( "\n", $insert_tuples );
203
+		$insert_tuples     = $this->get_insert_tuples($post_id);
204
+		$insert_query_body = implode("\n", $insert_tuples);
205 205
 		$insert_query      = "INSERT DATA { $insert_query_body };";
206
-		$this->sparql_service->execute( $insert_query );
206
+		$this->sparql_service->execute($insert_query);
207 207
 
208 208
 	}
209 209
 
@@ -216,18 +216,18 @@  discard block
 block discarded – undo
216 216
 	 *
217 217
 	 * @return bool True if the URI is valid otherwise false.
218 218
 	 */
219
-	private function has_valid_uri( $post_id ) {
219
+	private function has_valid_uri($post_id) {
220 220
 
221 221
 		// Get the entity's URI.
222
-		$uri = $this->entity_service->get_uri( $post_id );
222
+		$uri = $this->entity_service->get_uri($post_id);
223 223
 
224 224
 		// If the URI isn't found, return false.
225
-		if ( null === $uri ) {
225
+		if (null === $uri) {
226 226
 			return false;
227 227
 		}
228 228
 
229 229
 		// If the URI ends with a trailing slash, return false.
230
-		if ( '/' === substr( $uri, - 1 ) ) {
230
+		if ('/' === substr($uri, - 1)) {
231 231
 			return false;
232 232
 		}
233 233
 
@@ -244,29 +244,29 @@  discard block
 block discarded – undo
244 244
 	 *
245 245
 	 * @return array An array of delete statements.
246 246
 	 */
247
-	private function get_delete_statements( $post_id ) {
247
+	private function get_delete_statements($post_id) {
248 248
 
249 249
 		// Get the entity URI.
250
-		$uri = $this->entity_service->get_uri( $post_id );
250
+		$uri = $this->entity_service->get_uri($post_id);
251 251
 
252 252
 		// Prepare the delete statements with the entity as subject.
253
-		$as_subject = array_map( function ( $item ) use ( $uri ) {
253
+		$as_subject = array_map(function($item) use ($uri) {
254 254
 			return Wordlift_Query_Builder::new_instance()
255 255
 			                             ->delete()
256
-			                             ->statement( $uri, $item, '?o' )
256
+			                             ->statement($uri, $item, '?o')
257 257
 			                             ->build();
258
-		}, $this->schema_service->get_all_predicates() );
258
+		}, $this->schema_service->get_all_predicates());
259 259
 
260 260
 		// Prepare the delete statements with the entity as object.
261
-		$as_object = array_map( function ( $item ) use ( $uri ) {
261
+		$as_object = array_map(function($item) use ($uri) {
262 262
 			return Wordlift_Query_Builder::new_instance()
263 263
 			                             ->delete()
264
-			                             ->statement( '?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI )
264
+			                             ->statement('?s', $item, $uri, Wordlift_Query_Builder::OBJECT_URI)
265 265
 			                             ->build();
266
-		}, $this->schema_service->get_all_predicates() );
266
+		}, $this->schema_service->get_all_predicates());
267 267
 
268 268
 		// Merge the delete statements and return them.
269
-		return array_merge( $as_subject, $as_object );
269
+		return array_merge($as_subject, $as_object);
270 270
 	}
271 271
 
272 272
 	/**
@@ -278,10 +278,10 @@  discard block
 block discarded – undo
278 278
 	 *
279 279
 	 * @return array An array of insert tuples.
280 280
 	 */
281
-	private function get_insert_tuples( $post_id ) {
281
+	private function get_insert_tuples($post_id) {
282 282
 
283 283
 		// Get the entity type.
284
-		$type = $this->entity_type_service->get( $post_id );
284
+		$type = $this->entity_type_service->get($post_id);
285 285
 
286 286
 		// Get the Linked Data properties.
287 287
 		$properties = $type['linked_data'];
@@ -289,8 +289,8 @@  discard block
 block discarded – undo
289 289
 		// Accumulate the tuples.
290 290
 		$tuples = array();
291 291
 		/** @var Wordlift_Sparql_Tuple_Rendition $property */
292
-		foreach ( $properties as $property ) {
293
-			foreach ( $property->get( $post_id ) as $tuple ) {
292
+		foreach ($properties as $property) {
293
+			foreach ($property->get($post_id) as $tuple) {
294 294
 				$tuples[] = $tuple;
295 295
 			}
296 296
 		}
Please login to merge, or discard this patch.
src/includes/class-wordlift-sample-data-service.php 2 patches
Indentation   +272 added lines, -272 removed lines patch added patch discarded remove patch
@@ -17,93 +17,93 @@  discard block
 block discarded – undo
17 17
  */
18 18
 class Wordlift_Sample_Data_Service {
19 19
 
20
-	/**
21
-	 * An array of sample data.
22
-	 *
23
-	 * @since 3.12.0
24
-	 * @var array $samples An array of sample data.
25
-	 */
26
-	private $samples = array(
27
-		array(
28
-			'post'            => array(
29
-				'post_name'    => 'praesent_imperdiet_odio_sed_lectus_vulputate_finibus',
30
-				'post_title'   => 'Praesent imperdiet odio sed lectus vulputate finibus',
31
-				'post_content' => 'Praesent imperdiet odio sed lectus vulputate finibus. Donec placerat ex arcu, eget fermentum metus ullamcorper vitae. Cras interdum libero a tellus sagittis, sed ultricies sapien tincidunt. Aliquam sit amet vehicula sem. Mauris neque nisl, pellentesque ut molestie id, laoreet nec tortor. Sed tempus ornare est, nec dapibus enim ornare eu. Cras risus ligula, blandit ut faucibus ut, vulputate id ipsum. In vel purus at orci hendrerit cursus. Aliquam interdum lorem id dui maximus volutpat. Vestibulum mi velit, efficitur nec neque eu, posuere porta risus.',
32
-				'post_type'    => 'entity',
33
-				'post_status'  => 'publish',
34
-			),
35
-			'entity_type_uri' => 'http://schema.org/Event',
36
-		),
37
-		array(
38
-			'post'            => array(
39
-				'post_name'    => 'nullam_tempor_lectus_sit_amet_tincidunt_euismod',
40
-				'post_title'   => 'Nullam tempor lectus sit amet tincidunt euismod',
41
-				'post_content' => 'Nullam tempor lectus sit amet tincidunt euismod. Nunc posuere libero augue, eu pretium erat interdum id. Vivamus aliquam dui in mauris tempor, vitae vestibulum odio aliquet. Proin quis bibendum diam, nec tempus dui. Pellentesque sit amet justo vitae urna ornare volutpat quis consectetur nisl. Sed hendrerit purus et magna varius, sodales tincidunt velit finibus. Donec malesuada faucibus mattis. Morbi viverra sagittis justo nec luctus. Nullam et justo sed nisi fringilla rutrum sit amet a urna. Integer elementum, risus in condimentum rhoncus, nisi velit cursus tellus, sed sagittis ante tellus hendrerit ante. Donec et semper libero, vitae imperdiet ligula. Donec eleifend iaculis nisi sed mollis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin faucibus magna ac lectus tempor iaculis quis in nisi. Mauris ac nibh lacinia, ultrices erat quis, rhoncus lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.',
42
-				'post_type'    => 'entity',
43
-				'post_status'  => 'publish',
44
-			),
45
-			'entity_type_uri' => 'http://schema.org/Place',
46
-		),
47
-		array(
48
-			'post'            => array(
49
-				'post_name'    => 'praesent_luctus_tincidunt_odio_quis_aliquam',
50
-				'post_title'   => 'Praesent luctus tincidunt odio quis aliquam',
51
-				'post_content' => 'Praesent luctus tincidunt odio quis aliquam. Ut pellentesque odio nec turpis placerat, at rhoncus mauris elementum. Proin vehicula lectus a dolor bibendum, ut pretium lacus volutpat. Integer luctus enim sed odio dapibus tempus. Fusce elementum purus in diam dictum, sit amet ultricies leo molestie. Etiam id nunc tincidunt sapien tristique interdum ac at purus. Nulla eget laoreet turpis. Nullam id cursus nulla.',
52
-				'post_type'    => 'entity',
53
-				'post_status'  => 'publish',
54
-			),
55
-			'entity_type_uri' => 'http://schema.org/Organization',
56
-		),
57
-		array(
58
-			'post'            => array(
59
-				'post_name'    => 'lorem_ipsum_dolor_sit_amet__consectetur_adipiscing_elit',
60
-				'post_title'   => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
61
-				'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
62
-				'post_type'    => 'entity',
63
-				'post_status'  => 'publish',
64
-			),
65
-			'entity_type_uri' => 'http://schema.org/CreativeWork',
66
-		),
67
-		array(
68
-			'post' =>
69
-				array(
70
-					'post_title'   => 'Praesent imperdiet odio sed lectus vulputate finibus',
71
-					'post_content' => '<span><span id="urn:enhancement-da554278-9522-2d83-76ad-8129d2292cb3" class="textannotation disambiguated wl-event" itemid="{dataset-uri}/entity/praesent_imperdiet_odio_sed_lectus_vulputate_finibus">Praesent imperdiet odio sed lectus vulputate finibus</span>. Donec placerat ex arcu, eget fermentum metus ullamcorper vitae. Cras interdum libero a tellus sagittis, sed ultricies sapien tincidunt. Aliquam sit amet vehicula sem. Mauris neque nisl, pellentesque ut molestie id, laoreet nec tortor. Sed tempus ornare est, nec dapibus enim ornare eu. Cras risus ligula, blandit ut faucibus ut, vulputate id ipsum. In vel purus at orci hendrerit cursus. Aliquam interdum lorem id dui maximus volutpat. Vestibulum mi velit, efficitur nec neque eu, posuere porta risus.</span>',
72
-					'post_type'    => 'post',
73
-					'post_status'  => 'publish',
74
-				),
75
-		),
76
-		array(
77
-			'post' =>
78
-				array(
79
-					'post_title'   => 'Nullam tempor lectus sit amet tincidunt euismod',
80
-					'post_content' => '<span><span id="urn:local-text-annotation-p8i5o4279ex3rsbwqkrx9z5mh1ox91ae" class="textannotation disambiguated wl-place" itemid="{dataset-uri}/entity/nullam_tempor_lectus_sit_amet_tincidunt_euismod">Nullam tempor lectus sit amet tincidunt euismod</span>. Nunc posuere libero augue, eu pretium erat interdum id. Vivamus aliquam dui in mauris tempor, vitae vestibulum odio aliquet. Proin quis bibendum diam, nec tempus dui. Pellentesque sit amet justo vitae urna ornare volutpat quis consectetur nisl. Sed hendrerit purus et magna varius, sodales tincidunt velit finibus. Donec malesuada faucibus mattis. Morbi viverra sagittis justo nec luctus. Nullam et justo sed nisi fringilla rutrum sit amet a urna. Integer elementum, risus in condimentum rhoncus, nisi velit cursus tellus, sed sagittis ante tellus hendrerit ante. Donec et semper libero, vitae imperdiet ligula. Donec eleifend iaculis nisi sed mollis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin faucibus magna ac lectus tempor iaculis quis in nisi. Mauris ac nibh lacinia, ultrices erat quis, rhoncus lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</span>',
81
-					'post_type'    => 'post',
82
-					'post_status'  => 'publish',
83
-				),
84
-		),
85
-		array(
86
-			'post' =>
87
-				array(
88
-					'post_title'   => 'Praesent luctus tincidunt odio quis aliquam',
89
-					'post_content' => '<span><span id="urn:enhancement-b3487a20-4696-b6d9-6c55-842445f5c263" class="textannotation disambiguated wl-organization" itemid="{dataset-uri}/entity/praesent_luctus_tincidunt_odio_quis_aliquam">Praesent luctus tincidunt odio quis aliquam</span>. Ut pellentesque odio nec turpis placerat, at rhoncus mauris elementum. Proin vehicula lectus a dolor bibendum, ut pretium lacus volutpat. Integer luctus enim sed odio dapibus tempus. Fusce elementum purus in diam dictum, sit amet ultricies leo molestie. Etiam id nunc tincidunt sapien tristique interdum ac at purus. Nulla eget laoreet turpis. Nullam id cursus nulla.</span>',
90
-					'post_type'    => 'post',
91
-					'post_status'  => 'publish',
92
-				),
93
-		),
94
-		array(
95
-			'post' =>
96
-				array(
97
-					'post_title'   => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
98
-					'post_content' => '<span><span id="urn:enhancement-4edc3bde-d275-22f9-8d50-0b707596b292" class="textannotation disambiguated wl-thing" itemid="{dataset-uri}/entity/lorem_ipsum_dolor_sit_amet__consectetur_adipiscing_elit">Lorem ipsum dolor sit amet, consectetur adipiscing elit</span>. Proin rutrum ultrices nulla ut elementum. Nunc nec lacus tortor. Curabitur bibendum imperdiet luctus. Vivamus a faucibus dolor. Donec blandit malesuada risus. Vestibulum volutpat ut tellus sed tincidunt. Sed id tincidunt velit. Integer sed felis id libero fringilla molestie vitae id orci. Ut vel purus ullamcorper, feugiat tortor non, iaculis neque. Vivamus vitae vehicula sem. Mauris fermentum, metus id vestibulum sodales, lorem lacus efficitur ante, non vestibulum ligula ligula a turpis. Vivamus quis scelerisque massa.</span>',
99
-					'post_type'    => 'post',
100
-					'post_status'  => 'publish',
101
-				),
102
-		),
103
-		array(
104
-			'post' => array(
105
-				'post_title'   => 'Lorem ipsum',
106
-				'post_content' => "
20
+    /**
21
+     * An array of sample data.
22
+     *
23
+     * @since 3.12.0
24
+     * @var array $samples An array of sample data.
25
+     */
26
+    private $samples = array(
27
+        array(
28
+            'post'            => array(
29
+                'post_name'    => 'praesent_imperdiet_odio_sed_lectus_vulputate_finibus',
30
+                'post_title'   => 'Praesent imperdiet odio sed lectus vulputate finibus',
31
+                'post_content' => 'Praesent imperdiet odio sed lectus vulputate finibus. Donec placerat ex arcu, eget fermentum metus ullamcorper vitae. Cras interdum libero a tellus sagittis, sed ultricies sapien tincidunt. Aliquam sit amet vehicula sem. Mauris neque nisl, pellentesque ut molestie id, laoreet nec tortor. Sed tempus ornare est, nec dapibus enim ornare eu. Cras risus ligula, blandit ut faucibus ut, vulputate id ipsum. In vel purus at orci hendrerit cursus. Aliquam interdum lorem id dui maximus volutpat. Vestibulum mi velit, efficitur nec neque eu, posuere porta risus.',
32
+                'post_type'    => 'entity',
33
+                'post_status'  => 'publish',
34
+            ),
35
+            'entity_type_uri' => 'http://schema.org/Event',
36
+        ),
37
+        array(
38
+            'post'            => array(
39
+                'post_name'    => 'nullam_tempor_lectus_sit_amet_tincidunt_euismod',
40
+                'post_title'   => 'Nullam tempor lectus sit amet tincidunt euismod',
41
+                'post_content' => 'Nullam tempor lectus sit amet tincidunt euismod. Nunc posuere libero augue, eu pretium erat interdum id. Vivamus aliquam dui in mauris tempor, vitae vestibulum odio aliquet. Proin quis bibendum diam, nec tempus dui. Pellentesque sit amet justo vitae urna ornare volutpat quis consectetur nisl. Sed hendrerit purus et magna varius, sodales tincidunt velit finibus. Donec malesuada faucibus mattis. Morbi viverra sagittis justo nec luctus. Nullam et justo sed nisi fringilla rutrum sit amet a urna. Integer elementum, risus in condimentum rhoncus, nisi velit cursus tellus, sed sagittis ante tellus hendrerit ante. Donec et semper libero, vitae imperdiet ligula. Donec eleifend iaculis nisi sed mollis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin faucibus magna ac lectus tempor iaculis quis in nisi. Mauris ac nibh lacinia, ultrices erat quis, rhoncus lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.',
42
+                'post_type'    => 'entity',
43
+                'post_status'  => 'publish',
44
+            ),
45
+            'entity_type_uri' => 'http://schema.org/Place',
46
+        ),
47
+        array(
48
+            'post'            => array(
49
+                'post_name'    => 'praesent_luctus_tincidunt_odio_quis_aliquam',
50
+                'post_title'   => 'Praesent luctus tincidunt odio quis aliquam',
51
+                'post_content' => 'Praesent luctus tincidunt odio quis aliquam. Ut pellentesque odio nec turpis placerat, at rhoncus mauris elementum. Proin vehicula lectus a dolor bibendum, ut pretium lacus volutpat. Integer luctus enim sed odio dapibus tempus. Fusce elementum purus in diam dictum, sit amet ultricies leo molestie. Etiam id nunc tincidunt sapien tristique interdum ac at purus. Nulla eget laoreet turpis. Nullam id cursus nulla.',
52
+                'post_type'    => 'entity',
53
+                'post_status'  => 'publish',
54
+            ),
55
+            'entity_type_uri' => 'http://schema.org/Organization',
56
+        ),
57
+        array(
58
+            'post'            => array(
59
+                'post_name'    => 'lorem_ipsum_dolor_sit_amet__consectetur_adipiscing_elit',
60
+                'post_title'   => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
61
+                'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
62
+                'post_type'    => 'entity',
63
+                'post_status'  => 'publish',
64
+            ),
65
+            'entity_type_uri' => 'http://schema.org/CreativeWork',
66
+        ),
67
+        array(
68
+            'post' =>
69
+                array(
70
+                    'post_title'   => 'Praesent imperdiet odio sed lectus vulputate finibus',
71
+                    'post_content' => '<span><span id="urn:enhancement-da554278-9522-2d83-76ad-8129d2292cb3" class="textannotation disambiguated wl-event" itemid="{dataset-uri}/entity/praesent_imperdiet_odio_sed_lectus_vulputate_finibus">Praesent imperdiet odio sed lectus vulputate finibus</span>. Donec placerat ex arcu, eget fermentum metus ullamcorper vitae. Cras interdum libero a tellus sagittis, sed ultricies sapien tincidunt. Aliquam sit amet vehicula sem. Mauris neque nisl, pellentesque ut molestie id, laoreet nec tortor. Sed tempus ornare est, nec dapibus enim ornare eu. Cras risus ligula, blandit ut faucibus ut, vulputate id ipsum. In vel purus at orci hendrerit cursus. Aliquam interdum lorem id dui maximus volutpat. Vestibulum mi velit, efficitur nec neque eu, posuere porta risus.</span>',
72
+                    'post_type'    => 'post',
73
+                    'post_status'  => 'publish',
74
+                ),
75
+        ),
76
+        array(
77
+            'post' =>
78
+                array(
79
+                    'post_title'   => 'Nullam tempor lectus sit amet tincidunt euismod',
80
+                    'post_content' => '<span><span id="urn:local-text-annotation-p8i5o4279ex3rsbwqkrx9z5mh1ox91ae" class="textannotation disambiguated wl-place" itemid="{dataset-uri}/entity/nullam_tempor_lectus_sit_amet_tincidunt_euismod">Nullam tempor lectus sit amet tincidunt euismod</span>. Nunc posuere libero augue, eu pretium erat interdum id. Vivamus aliquam dui in mauris tempor, vitae vestibulum odio aliquet. Proin quis bibendum diam, nec tempus dui. Pellentesque sit amet justo vitae urna ornare volutpat quis consectetur nisl. Sed hendrerit purus et magna varius, sodales tincidunt velit finibus. Donec malesuada faucibus mattis. Morbi viverra sagittis justo nec luctus. Nullam et justo sed nisi fringilla rutrum sit amet a urna. Integer elementum, risus in condimentum rhoncus, nisi velit cursus tellus, sed sagittis ante tellus hendrerit ante. Donec et semper libero, vitae imperdiet ligula. Donec eleifend iaculis nisi sed mollis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin faucibus magna ac lectus tempor iaculis quis in nisi. Mauris ac nibh lacinia, ultrices erat quis, rhoncus lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</span>',
81
+                    'post_type'    => 'post',
82
+                    'post_status'  => 'publish',
83
+                ),
84
+        ),
85
+        array(
86
+            'post' =>
87
+                array(
88
+                    'post_title'   => 'Praesent luctus tincidunt odio quis aliquam',
89
+                    'post_content' => '<span><span id="urn:enhancement-b3487a20-4696-b6d9-6c55-842445f5c263" class="textannotation disambiguated wl-organization" itemid="{dataset-uri}/entity/praesent_luctus_tincidunt_odio_quis_aliquam">Praesent luctus tincidunt odio quis aliquam</span>. Ut pellentesque odio nec turpis placerat, at rhoncus mauris elementum. Proin vehicula lectus a dolor bibendum, ut pretium lacus volutpat. Integer luctus enim sed odio dapibus tempus. Fusce elementum purus in diam dictum, sit amet ultricies leo molestie. Etiam id nunc tincidunt sapien tristique interdum ac at purus. Nulla eget laoreet turpis. Nullam id cursus nulla.</span>',
90
+                    'post_type'    => 'post',
91
+                    'post_status'  => 'publish',
92
+                ),
93
+        ),
94
+        array(
95
+            'post' =>
96
+                array(
97
+                    'post_title'   => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
98
+                    'post_content' => '<span><span id="urn:enhancement-4edc3bde-d275-22f9-8d50-0b707596b292" class="textannotation disambiguated wl-thing" itemid="{dataset-uri}/entity/lorem_ipsum_dolor_sit_amet__consectetur_adipiscing_elit">Lorem ipsum dolor sit amet, consectetur adipiscing elit</span>. Proin rutrum ultrices nulla ut elementum. Nunc nec lacus tortor. Curabitur bibendum imperdiet luctus. Vivamus a faucibus dolor. Donec blandit malesuada risus. Vestibulum volutpat ut tellus sed tincidunt. Sed id tincidunt velit. Integer sed felis id libero fringilla molestie vitae id orci. Ut vel purus ullamcorper, feugiat tortor non, iaculis neque. Vivamus vitae vehicula sem. Mauris fermentum, metus id vestibulum sodales, lorem lacus efficitur ante, non vestibulum ligula ligula a turpis. Vivamus quis scelerisque massa.</span>',
99
+                    'post_type'    => 'post',
100
+                    'post_status'  => 'publish',
101
+                ),
102
+        ),
103
+        array(
104
+            'post' => array(
105
+                'post_title'   => 'Lorem ipsum',
106
+                'post_content' => "
107 107
 					<span id=\"urn:enhancement-28cb4112-64cf-bd49-ef97-a2ee54727de7\" class=\"textannotation disambiguated wl-thing\" itemid=\"{dataset-uri}/entity/lorem_ipsum_dolor_sit_amet__consectetur_adipiscing_elit\">Lorem ipsum</span> dolor sit amet, consectetur adipiscing elit. Proin rutrum ultrices nulla ut elementum. Nunc nec lacus tortor. Curabitur bibendum imperdiet luctus. Vivamus a faucibus dolor. Donec blandit malesuada risus. Vestibulum volutpat ut tellus sed tincidunt. Sed id tincidunt velit. Integer sed felis id libero fringilla molestie vitae id orci. Ut vel purus ullamcorper, feugiat tortor non, iaculis neque. Vivamus vitae vehicula sem. Mauris fermentum, metus id vestibulum sodales, lorem lacus efficitur ante, non vestibulum ligula ligula a turpis. Vivamus quis scelerisque massa.
108 108
 					
109 109
 					[wl_navigator]
@@ -118,190 +118,190 @@  discard block
 block discarded – undo
118 118
 					
119 119
 					<span id=\"urn:local-text-annotation-v0kqdtx685n6cg9jrfvl67amkhm28hxh\" class=\"textannotation disambiguated wl-event\" itemid=\"{dataset-uri}/entity/praesent_imperdiet_odio_sed_lectus_vulputate_finibus\">Praesent imperdiet odio sed lectus vulputate finibus</span>. Donec placerat ex arcu, eget fermentum metus ullamcorper vitae. Cras interdum libero a tellus sagittis, sed ultricies sapien tincidunt. Aliquam sit amet vehicula sem. Mauris neque nisl, pellentesque ut molestie id, laoreet nec tortor. Sed tempus ornare est, nec dapibus enim ornare eu. Cras risus ligula, blandit ut faucibus ut, vulputate id ipsum. In vel purus at orci hendrerit cursus. Aliquam interdum lorem id dui maximus volutpat. Vestibulum mi velit, efficitur nec neque eu, posuere porta risus.
120 120
 					",
121
-				'post_type'    => 'post',
122
-				'post_status'  => 'publish',
123
-			),
124
-		),
125
-	);
126
-
127
-	/**
128
-	 * The {@link Wordlift_Entity_Type_Service} instance.
129
-	 *
130
-	 * @since  3.12.0
131
-	 * @access private
132
-	 * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
133
-	 */
134
-	private $entity_type_service;
135
-
136
-	/**
137
-	 * The {@link Wordlift_Configuration_Service} instance.
138
-	 *
139
-	 * @since  3.12.0
140
-	 * @access private
141
-	 * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
142
-	 */
143
-	private $configuration_service;
144
-
145
-	/**
146
-	 * Create a {@link Wordlift_Sample_Data_Service} instance.
147
-	 *
148
-	 * @since 3.12.0
149
-	 *
150
-	 * @param \Wordlift_Entity_Type_Service   $entity_type_service   The {@link Wordlift_Entity_Type_Service} instance.
151
-	 * @param \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
152
-	 */
153
-	function __construct( $entity_type_service, $configuration_service ) {
154
-
155
-		$this->entity_type_service   = $entity_type_service;
156
-		$this->configuration_service = $configuration_service;
157
-	}
158
-
159
-	/**
160
-	 * Create sample data in this WordPress instance.
161
-	 *
162
-	 * @since 3.12.0
163
-	 */
164
-	function create() {
165
-
166
-		// Get the source image path.
167
-		$source = plugin_dir_path( dirname( __FILE__ ) ) . 'images/rome.png';
168
-
169
-		// Create an attachment with the local file.
170
-		$attachment_id = $this->create_attachment_from_local_file( $source );
171
-
172
-		// Add a flag to signal the attachment is sample data and allow easy delete
173
-		// afterwards.
174
-		add_post_meta( $attachment_id, '_wl_sample_data', 1, true );
175
-
176
-		// Get the dataset URI, used for replacements in the `post_content`.
177
-		$dataset_uri = $this->configuration_service->get_dataset_uri();
178
-
179
-		// Create 4 entities.
180
-		// Create 4 posts referencing each one entity.
181
-		// Create 1 post referencing all the entities.
182
-		foreach ( $this->samples as $sample ) {
183
-
184
-			// Get the post data.
185
-			$post = array_replace_recursive( $sample['post'], array( 'post_content' => str_replace( '{dataset-uri}', $dataset_uri, $sample['post']['post_content'] ) ) );
186
-
187
-			// Insert the post.
188
-			$post_id = wp_insert_post( $post );
189
-
190
-			// Add a flag to signal the post is sample data and allow easy delete
191
-			// afterwards.
192
-			add_post_meta( $post_id, '_wl_sample_data', 1, true );
193
-
194
-			// Set the psot thumbnail.
195
-			set_post_thumbnail( $post_id, $attachment_id );
196
-
197
-			// If the `entity_type_uri` property is set, set it on the post.
198
-			if ( isset( $sample['entity_type_uri'] ) ) {
199
-				$this->entity_type_service->set( $post_id, $sample['entity_type_uri'] );
200
-			}
201
-
202
-		}
203
-
204
-
205
-	}
206
-
207
-	/**
208
-	 * Remove the sample data from this WordPress instance.
209
-	 *
210
-	 * @since 3.12.0
211
-	 */
212
-	function delete() {
213
-
214
-		$this->delete_by_type( 'post' );
215
-		$this->delete_by_type( 'entity' );
216
-		$this->delete_by_type( 'attachment' );
217
-
218
-	}
219
-
220
-	/**
221
-	 * Remove the sample data of the specified type (e.g. `post`, `entity`, `attachment`)
222
-	 * from the local WordPress instance.
223
-	 *
224
-	 * @since 3.12.0
225
-	 *
226
-	 * @param string $type WordPress {@link WP_Post}'s type, e.g. `post`, `entity`, `attachment`.
227
-	 */
228
-	private function delete_by_type( $type ) {
229
-
230
-		$posts = get_posts( array(
231
-			'meta_key'    => '_wl_sample_data',
232
-			'meta_value'  => 1,
233
-			'post_status' => 'any',
234
-			'post_type'   => $type,
235
-		) );
236
-
237
-		foreach ( $posts as $post ) {
238
-			wp_delete_post( $post->ID, true );
239
-		}
240
-
241
-	}
242
-
243
-	/**
244
-	 * Create a WordPress' attachment using the specified file.
245
-	 *
246
-	 * @since 3.12.0
247
-	 *
248
-	 * @param string $source The source file path.
249
-	 *
250
-	 * @return int WordPress' attachment's id.
251
-	 */
252
-	private function create_attachment_from_local_file( $source ) {
253
-
254
-		// Get the path to the upload directory.
255
-		$upload_dir  = wp_upload_dir();
256
-		$upload_path = $upload_dir['path'];
257
-
258
-		// Get the destination image path.
259
-		$destination = $upload_path . '/wl-sample-data.png';
260
-
261
-		// Copy the source file to the destination.
262
-		@copy( $source, $destination );
263
-
264
-		return $this->create_attachment( $destination );
265
-	}
266
-
267
-	/**
268
-	 * Create a WordPress attachment using the specified file in the upload folder.
269
-	 *
270
-	 * @see   https://codex.wordpress.org/Function_Reference/wp_insert_attachment
271
-	 *
272
-	 * @since 3.12.0
273
-	 *
274
-	 * @param string $filename The image filename.
275
-	 *
276
-	 * @return int The attachment id.
277
-	 */
278
-	private function create_attachment( $filename ) {
279
-
280
-		// Check the type of file. We'll use this as the 'post_mime_type'.
281
-		$filetype = wp_check_filetype( basename( $filename ), null );
282
-
283
-		// Get the path to the upload directory.
284
-		$wp_upload_dir = wp_upload_dir();
285
-
286
-		// Prepare an array of post data for the attachment.
287
-		$attachment = array(
288
-			'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ),
289
-			'post_mime_type' => $filetype['type'],
290
-			'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
291
-			'post_content'   => '',
292
-			'post_status'    => 'inherit',
293
-		);
294
-
295
-		// Insert the attachment.
296
-		$attachment_id = wp_insert_attachment( $attachment, $filename );
297
-
298
-		// Generate the metadata for the attachment, and update the database record.
299
-		$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
300
-
301
-		// Update the attachment metadata.
302
-		wp_update_attachment_metadata( $attachment_id, $attachment_data );
303
-
304
-		return $attachment_id;
305
-	}
121
+                'post_type'    => 'post',
122
+                'post_status'  => 'publish',
123
+            ),
124
+        ),
125
+    );
126
+
127
+    /**
128
+     * The {@link Wordlift_Entity_Type_Service} instance.
129
+     *
130
+     * @since  3.12.0
131
+     * @access private
132
+     * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
133
+     */
134
+    private $entity_type_service;
135
+
136
+    /**
137
+     * The {@link Wordlift_Configuration_Service} instance.
138
+     *
139
+     * @since  3.12.0
140
+     * @access private
141
+     * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
142
+     */
143
+    private $configuration_service;
144
+
145
+    /**
146
+     * Create a {@link Wordlift_Sample_Data_Service} instance.
147
+     *
148
+     * @since 3.12.0
149
+     *
150
+     * @param \Wordlift_Entity_Type_Service   $entity_type_service   The {@link Wordlift_Entity_Type_Service} instance.
151
+     * @param \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
152
+     */
153
+    function __construct( $entity_type_service, $configuration_service ) {
154
+
155
+        $this->entity_type_service   = $entity_type_service;
156
+        $this->configuration_service = $configuration_service;
157
+    }
158
+
159
+    /**
160
+     * Create sample data in this WordPress instance.
161
+     *
162
+     * @since 3.12.0
163
+     */
164
+    function create() {
165
+
166
+        // Get the source image path.
167
+        $source = plugin_dir_path( dirname( __FILE__ ) ) . 'images/rome.png';
168
+
169
+        // Create an attachment with the local file.
170
+        $attachment_id = $this->create_attachment_from_local_file( $source );
171
+
172
+        // Add a flag to signal the attachment is sample data and allow easy delete
173
+        // afterwards.
174
+        add_post_meta( $attachment_id, '_wl_sample_data', 1, true );
175
+
176
+        // Get the dataset URI, used for replacements in the `post_content`.
177
+        $dataset_uri = $this->configuration_service->get_dataset_uri();
178
+
179
+        // Create 4 entities.
180
+        // Create 4 posts referencing each one entity.
181
+        // Create 1 post referencing all the entities.
182
+        foreach ( $this->samples as $sample ) {
183
+
184
+            // Get the post data.
185
+            $post = array_replace_recursive( $sample['post'], array( 'post_content' => str_replace( '{dataset-uri}', $dataset_uri, $sample['post']['post_content'] ) ) );
186
+
187
+            // Insert the post.
188
+            $post_id = wp_insert_post( $post );
189
+
190
+            // Add a flag to signal the post is sample data and allow easy delete
191
+            // afterwards.
192
+            add_post_meta( $post_id, '_wl_sample_data', 1, true );
193
+
194
+            // Set the psot thumbnail.
195
+            set_post_thumbnail( $post_id, $attachment_id );
196
+
197
+            // If the `entity_type_uri` property is set, set it on the post.
198
+            if ( isset( $sample['entity_type_uri'] ) ) {
199
+                $this->entity_type_service->set( $post_id, $sample['entity_type_uri'] );
200
+            }
201
+
202
+        }
203
+
204
+
205
+    }
206
+
207
+    /**
208
+     * Remove the sample data from this WordPress instance.
209
+     *
210
+     * @since 3.12.0
211
+     */
212
+    function delete() {
213
+
214
+        $this->delete_by_type( 'post' );
215
+        $this->delete_by_type( 'entity' );
216
+        $this->delete_by_type( 'attachment' );
217
+
218
+    }
219
+
220
+    /**
221
+     * Remove the sample data of the specified type (e.g. `post`, `entity`, `attachment`)
222
+     * from the local WordPress instance.
223
+     *
224
+     * @since 3.12.0
225
+     *
226
+     * @param string $type WordPress {@link WP_Post}'s type, e.g. `post`, `entity`, `attachment`.
227
+     */
228
+    private function delete_by_type( $type ) {
229
+
230
+        $posts = get_posts( array(
231
+            'meta_key'    => '_wl_sample_data',
232
+            'meta_value'  => 1,
233
+            'post_status' => 'any',
234
+            'post_type'   => $type,
235
+        ) );
236
+
237
+        foreach ( $posts as $post ) {
238
+            wp_delete_post( $post->ID, true );
239
+        }
240
+
241
+    }
242
+
243
+    /**
244
+     * Create a WordPress' attachment using the specified file.
245
+     *
246
+     * @since 3.12.0
247
+     *
248
+     * @param string $source The source file path.
249
+     *
250
+     * @return int WordPress' attachment's id.
251
+     */
252
+    private function create_attachment_from_local_file( $source ) {
253
+
254
+        // Get the path to the upload directory.
255
+        $upload_dir  = wp_upload_dir();
256
+        $upload_path = $upload_dir['path'];
257
+
258
+        // Get the destination image path.
259
+        $destination = $upload_path . '/wl-sample-data.png';
260
+
261
+        // Copy the source file to the destination.
262
+        @copy( $source, $destination );
263
+
264
+        return $this->create_attachment( $destination );
265
+    }
266
+
267
+    /**
268
+     * Create a WordPress attachment using the specified file in the upload folder.
269
+     *
270
+     * @see   https://codex.wordpress.org/Function_Reference/wp_insert_attachment
271
+     *
272
+     * @since 3.12.0
273
+     *
274
+     * @param string $filename The image filename.
275
+     *
276
+     * @return int The attachment id.
277
+     */
278
+    private function create_attachment( $filename ) {
279
+
280
+        // Check the type of file. We'll use this as the 'post_mime_type'.
281
+        $filetype = wp_check_filetype( basename( $filename ), null );
282
+
283
+        // Get the path to the upload directory.
284
+        $wp_upload_dir = wp_upload_dir();
285
+
286
+        // Prepare an array of post data for the attachment.
287
+        $attachment = array(
288
+            'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ),
289
+            'post_mime_type' => $filetype['type'],
290
+            'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
291
+            'post_content'   => '',
292
+            'post_status'    => 'inherit',
293
+        );
294
+
295
+        // Insert the attachment.
296
+        $attachment_id = wp_insert_attachment( $attachment, $filename );
297
+
298
+        // Generate the metadata for the attachment, and update the database record.
299
+        $attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
300
+
301
+        // Update the attachment metadata.
302
+        wp_update_attachment_metadata( $attachment_id, $attachment_data );
303
+
304
+        return $attachment_id;
305
+    }
306 306
 
307 307
 }
Please login to merge, or discard this patch.
Spacing   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
 	 * @param \Wordlift_Entity_Type_Service   $entity_type_service   The {@link Wordlift_Entity_Type_Service} instance.
151 151
 	 * @param \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
152 152
 	 */
153
-	function __construct( $entity_type_service, $configuration_service ) {
153
+	function __construct($entity_type_service, $configuration_service) {
154 154
 
155 155
 		$this->entity_type_service   = $entity_type_service;
156 156
 		$this->configuration_service = $configuration_service;
@@ -164,14 +164,14 @@  discard block
 block discarded – undo
164 164
 	function create() {
165 165
 
166 166
 		// Get the source image path.
167
-		$source = plugin_dir_path( dirname( __FILE__ ) ) . 'images/rome.png';
167
+		$source = plugin_dir_path(dirname(__FILE__)).'images/rome.png';
168 168
 
169 169
 		// Create an attachment with the local file.
170
-		$attachment_id = $this->create_attachment_from_local_file( $source );
170
+		$attachment_id = $this->create_attachment_from_local_file($source);
171 171
 
172 172
 		// Add a flag to signal the attachment is sample data and allow easy delete
173 173
 		// afterwards.
174
-		add_post_meta( $attachment_id, '_wl_sample_data', 1, true );
174
+		add_post_meta($attachment_id, '_wl_sample_data', 1, true);
175 175
 
176 176
 		// Get the dataset URI, used for replacements in the `post_content`.
177 177
 		$dataset_uri = $this->configuration_service->get_dataset_uri();
@@ -179,24 +179,24 @@  discard block
 block discarded – undo
179 179
 		// Create 4 entities.
180 180
 		// Create 4 posts referencing each one entity.
181 181
 		// Create 1 post referencing all the entities.
182
-		foreach ( $this->samples as $sample ) {
182
+		foreach ($this->samples as $sample) {
183 183
 
184 184
 			// Get the post data.
185
-			$post = array_replace_recursive( $sample['post'], array( 'post_content' => str_replace( '{dataset-uri}', $dataset_uri, $sample['post']['post_content'] ) ) );
185
+			$post = array_replace_recursive($sample['post'], array('post_content' => str_replace('{dataset-uri}', $dataset_uri, $sample['post']['post_content'])));
186 186
 
187 187
 			// Insert the post.
188
-			$post_id = wp_insert_post( $post );
188
+			$post_id = wp_insert_post($post);
189 189
 
190 190
 			// Add a flag to signal the post is sample data and allow easy delete
191 191
 			// afterwards.
192
-			add_post_meta( $post_id, '_wl_sample_data', 1, true );
192
+			add_post_meta($post_id, '_wl_sample_data', 1, true);
193 193
 
194 194
 			// Set the psot thumbnail.
195
-			set_post_thumbnail( $post_id, $attachment_id );
195
+			set_post_thumbnail($post_id, $attachment_id);
196 196
 
197 197
 			// If the `entity_type_uri` property is set, set it on the post.
198
-			if ( isset( $sample['entity_type_uri'] ) ) {
199
-				$this->entity_type_service->set( $post_id, $sample['entity_type_uri'] );
198
+			if (isset($sample['entity_type_uri'])) {
199
+				$this->entity_type_service->set($post_id, $sample['entity_type_uri']);
200 200
 			}
201 201
 
202 202
 		}
@@ -211,9 +211,9 @@  discard block
 block discarded – undo
211 211
 	 */
212 212
 	function delete() {
213 213
 
214
-		$this->delete_by_type( 'post' );
215
-		$this->delete_by_type( 'entity' );
216
-		$this->delete_by_type( 'attachment' );
214
+		$this->delete_by_type('post');
215
+		$this->delete_by_type('entity');
216
+		$this->delete_by_type('attachment');
217 217
 
218 218
 	}
219 219
 
@@ -225,17 +225,17 @@  discard block
 block discarded – undo
225 225
 	 *
226 226
 	 * @param string $type WordPress {@link WP_Post}'s type, e.g. `post`, `entity`, `attachment`.
227 227
 	 */
228
-	private function delete_by_type( $type ) {
228
+	private function delete_by_type($type) {
229 229
 
230
-		$posts = get_posts( array(
230
+		$posts = get_posts(array(
231 231
 			'meta_key'    => '_wl_sample_data',
232 232
 			'meta_value'  => 1,
233 233
 			'post_status' => 'any',
234 234
 			'post_type'   => $type,
235
-		) );
235
+		));
236 236
 
237
-		foreach ( $posts as $post ) {
238
-			wp_delete_post( $post->ID, true );
237
+		foreach ($posts as $post) {
238
+			wp_delete_post($post->ID, true);
239 239
 		}
240 240
 
241 241
 	}
@@ -249,19 +249,19 @@  discard block
 block discarded – undo
249 249
 	 *
250 250
 	 * @return int WordPress' attachment's id.
251 251
 	 */
252
-	private function create_attachment_from_local_file( $source ) {
252
+	private function create_attachment_from_local_file($source) {
253 253
 
254 254
 		// Get the path to the upload directory.
255 255
 		$upload_dir  = wp_upload_dir();
256 256
 		$upload_path = $upload_dir['path'];
257 257
 
258 258
 		// Get the destination image path.
259
-		$destination = $upload_path . '/wl-sample-data.png';
259
+		$destination = $upload_path.'/wl-sample-data.png';
260 260
 
261 261
 		// Copy the source file to the destination.
262
-		@copy( $source, $destination );
262
+		@copy($source, $destination);
263 263
 
264
-		return $this->create_attachment( $destination );
264
+		return $this->create_attachment($destination);
265 265
 	}
266 266
 
267 267
 	/**
@@ -275,31 +275,31 @@  discard block
 block discarded – undo
275 275
 	 *
276 276
 	 * @return int The attachment id.
277 277
 	 */
278
-	private function create_attachment( $filename ) {
278
+	private function create_attachment($filename) {
279 279
 
280 280
 		// Check the type of file. We'll use this as the 'post_mime_type'.
281
-		$filetype = wp_check_filetype( basename( $filename ), null );
281
+		$filetype = wp_check_filetype(basename($filename), null);
282 282
 
283 283
 		// Get the path to the upload directory.
284 284
 		$wp_upload_dir = wp_upload_dir();
285 285
 
286 286
 		// Prepare an array of post data for the attachment.
287 287
 		$attachment = array(
288
-			'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ),
288
+			'guid'           => $wp_upload_dir['url'].'/'.basename($filename),
289 289
 			'post_mime_type' => $filetype['type'],
290
-			'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
290
+			'post_title'     => preg_replace('/\.[^.]+$/', '', basename($filename)),
291 291
 			'post_content'   => '',
292 292
 			'post_status'    => 'inherit',
293 293
 		);
294 294
 
295 295
 		// Insert the attachment.
296
-		$attachment_id = wp_insert_attachment( $attachment, $filename );
296
+		$attachment_id = wp_insert_attachment($attachment, $filename);
297 297
 
298 298
 		// Generate the metadata for the attachment, and update the database record.
299
-		$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
299
+		$attachment_data = wp_generate_attachment_metadata($attachment_id, $filename);
300 300
 
301 301
 		// Update the attachment metadata.
302
-		wp_update_attachment_metadata( $attachment_id, $attachment_data );
302
+		wp_update_attachment_metadata($attachment_id, $attachment_data);
303 303
 
304 304
 		return $attachment_id;
305 305
 	}
Please login to merge, or discard this patch.
src/includes/class-wordlift-rating-service.php 2 patches
Indentation   +369 added lines, -369 removed lines patch added patch discarded remove patch
@@ -14,374 +14,374 @@
 block discarded – undo
14 14
  */
15 15
 class Wordlift_Rating_Service {
16 16
 
17
-	/**
18
-	 * Entity rating max.
19
-	 *
20
-	 * @since 3.3.0
21
-	 */
22
-	const RATING_MAX = 7;
23
-
24
-	/**
25
-	 * Entity rating score meta key.
26
-	 *
27
-	 * @since 3.3.0
28
-	 */
29
-	const RATING_RAW_SCORE_META_KEY = '_wl_entity_rating_raw_score';
30
-
31
-	/**
32
-	 * Entity rating warnings meta key.
33
-	 *
34
-	 * @since 3.3.0
35
-	 */
36
-	const RATING_WARNINGS_META_KEY = '_wl_entity_rating_warnings';
37
-
38
-	/**
39
-	 * Entity warning has related post identifier.
40
-	 *
41
-	 * @since 3.3.0
42
-	 */
43
-	const RATING_WARNING_HAS_RELATED_POSTS = 'There are no related posts for the current entity.';
44
-
45
-	/**
46
-	 * Entity warning has content post identifier.
47
-	 *
48
-	 * @since 3.3.0
49
-	 */
50
-	const RATING_WARNING_HAS_CONTENT_POST = 'This entity has not description.';
51
-
52
-	/**
53
-	 * Entity warning has related entities identifier.
54
-	 *
55
-	 * @since 3.3.0
56
-	 */
57
-	const RATING_WARNING_HAS_RELATED_ENTITIES = 'There are no related entities for the current entity.';
58
-
59
-	/**
60
-	 * Entity warning is published identifier.
61
-	 *
62
-	 * @since 3.3.0
63
-	 */
64
-	const RATING_WARNING_IS_PUBLISHED = 'This entity is not published. It will not appear within analysis results.';
65
-
66
-	/**
67
-	 * Entity warning has thumbnail identifier.
68
-	 *
69
-	 * @since 3.3.0
70
-	 */
71
-	const RATING_WARNING_HAS_THUMBNAIL = 'This entity has no featured image yet.';
72
-
73
-	/**
74
-	 * Entity warning has same as identifier.
75
-	 *
76
-	 * @since 3.3.0
77
-	 */
78
-	const RATING_WARNING_HAS_SAME_AS = 'There are no sameAs configured for this entity.';
79
-
80
-	/**
81
-	 * Entity warning has completed metadata identifier.
82
-	 *
83
-	 * @since 3.3.0
84
-	 */
85
-	const RATING_WARNING_HAS_COMPLETED_METADATA = 'Schema.org metadata for this entity are not completed.';
86
-
87
-	/**
88
-	 * A {@link Wordlift_Entity_Service} instance.
89
-	 *
90
-	 * @since  3.10.0
91
-	 * @access private
92
-	 * @var Wordlift_Entity_Service $entity_service A {@link Wordlift_Entity_Service} instance.
93
-	 */
94
-	private $entity_service;
95
-
96
-	/**
97
-	 *  A {@link Wordlift_Entity_Type_Service} instance.
98
-	 *
99
-	 * @since  3.10.0
100
-	 * @access private
101
-	 * @var Wordlift_Entity_Type_Service $entity_type_service A {@link Wordlift_Entity_Type_Service} instance.
102
-	 */
103
-	private $entity_type_service;
104
-
105
-	/**
106
-	 * The Notice service.
107
-	 *
108
-	 * @since  3.3.0
109
-	 * @access private
110
-	 * @var \Wordlift_Notice_Service $notice_service The Notice service.
111
-	 */
112
-	private $notice_service;
113
-
114
-	/**
115
-	 * A {@link Wordlift_Log_Service} instance.
116
-	 *
117
-	 * @since  3.10.0
118
-	 * @access private
119
-	 * @var Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
120
-	 */
121
-	private $log;
122
-
123
-	/**
124
-	 * Create a {@link Wordlift_Rating_Service} instance.
125
-	 *
126
-	 * @since 3.10.0
127
-	 *
128
-	 * @param \Wordlift_Entity_Service      $entity_service      A {@link Wordlift_Entity_Service} instance.
129
-	 * @param \Wordlift_Entity_Type_Service $entity_type_service A {@link Wordlift_Entity_Type_Service} instance.
130
-	 * @param \Wordlift_Notice_Service      $notice_service      A {@link Wordlift_Notice_Service} instance.
131
-	 */
132
-	public function __construct( $entity_service, $entity_type_service, $notice_service ) {
133
-
134
-		$this->entity_service      = $entity_service;
135
-		$this->entity_type_service = $entity_type_service;
136
-		$this->notice_service      = $notice_service;
137
-
138
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Rating_Service' );
139
-
140
-	}
141
-
142
-	/**
143
-	 * Set rating for a given entity.
144
-	 *
145
-	 * @since 3.3.0
146
-	 *
147
-	 * @param int $post_id The entity post id.
148
-	 *
149
-	 * @return array An array representing the rating obj.
150
-	 */
151
-	public function set_rating_for( $post_id ) {
152
-
153
-		if ( ! $this->entity_service->is_entity( $post_id ) ) {
154
-			return;
155
-		}
156
-
157
-		// Calculate rating for the given post.
158
-		$rating = $this->calculate_rating_for( $post_id );
159
-
160
-		// Store the rating on db as post meta. Please notice that RATING_RAW_SCORE_META_KEY
161
-		// is saved on a different meta to allow score sorting. Both meta are managed as unique.
162
-		//
163
-		// See https://codex.wordpress.org/Function_Reference/update_post_meta
164
-		update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
165
-		update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
166
-
167
-		$this->log->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
168
-
169
-		// Finally returns the rating
170
-		return $rating;
171
-	}
172
-
173
-
174
-	/**
175
-	 * Get or calculate rating for a given entity
176
-	 *
177
-	 * @since 3.3.0
178
-	 *
179
-	 * @param int $post_id      The entity post id.
180
-	 * @param     $force_reload $warnings_needed If true, detailed warnings collection is provided with the rating obj.
181
-	 *
182
-	 * @return array An array representing the rating obj.
183
-	 */
184
-	public function get_rating_for( $post_id, $force_reload = false ) {
185
-
186
-		// If forced reload is required or rating is missing.
187
-		if ( $force_reload ) {
188
-			$this->log->trace( "Force rating reload [ post_id :: $post_id ]" );
189
-
190
-			return $this->set_rating_for( $post_id );
191
-		}
192
-
193
-		$current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, true );
194
-
195
-		if ( ! is_numeric( $current_raw_score ) ) {
196
-			$this->log->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
197
-
198
-			return $this->set_rating_for( $post_id );
199
-		}
200
-
201
-		$current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, true );
202
-
203
-		// Finally return score and warnings
204
-		return array(
205
-			'raw_score'           => $current_raw_score,
206
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
207
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
208
-			'warnings'            => $current_warnings,
209
-		);
210
-
211
-	}
212
-
213
-	/**
214
-	 * Calculate rating for a given entity.
215
-	 *
216
-	 * Rating depends from following criteria:
217
-	 *
218
-	 * 1. Is the current entity related to at least 1 post?
219
-	 * 2. Is the current entity content post not empty?
220
-	 * 3. Is the current entity related to at least 1 entity?
221
-	 * 4. Is the entity published?
222
-	 * 5. There is a a thumbnail associated to the entity?
223
-	 * 6. Has the entity a sameas defined?
224
-	 * 7. Are all schema.org required metadata compiled?
225
-	 *
226
-	 * Each positive check means +1 in terms of rating score.
227
-	 *
228
-	 * @since 3.3.0
229
-	 *
230
-	 * @param int $post_id The entity post id.
231
-	 *
232
-	 * @return array An array representing the rating obj.
233
-	 */
234
-	private function calculate_rating_for( $post_id ) {
235
-
236
-		// If it's not an entity, return.
237
-		if ( ! $this->entity_service->is_entity( $post_id ) ) {
238
-			return array();
239
-		}
240
-		// Retrieve the post object.
241
-		$post = get_post( $post_id );
242
-
243
-		// Rating value.
244
-		$score = 0;
245
-
246
-		// Store warning messages.
247
-		$warnings = array();
248
-
249
-		// Is the current entity related to at least 1 post?
250
-		( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
251
-			$score ++ :
252
-			array_push( $warnings, __( 'There are no related posts for the current entity.', 'wordlift' ) );
253
-
254
-		// Is the post content not empty?
255
-		( ! empty( $post->post_content ) ) ?
256
-			$score ++ :
257
-			array_push( $warnings, __( 'This entity has not description.', 'wordlift' ) );
258
-
259
-		// Is the current entity related to at least 1 entity?
260
-		// Was the current entity already disambiguated?
261
-		( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
262
-			$score ++ :
263
-			array_push( $warnings, __( 'There are no related entities for the current entity.', 'wordlift' ) );
264
-
265
-		// Is the entity published?
266
-		( 'publish' === get_post_status( $post->ID ) ) ?
267
-			$score ++ :
268
-			array_push( $warnings, __( 'This entity is not published. It will not appear within analysis results.', 'wordlift' ) );
269
-
270
-		// Has a thumbnail?
271
-		( has_post_thumbnail( $post->ID ) ) ?
272
-			$score ++ :
273
-			array_push( $warnings, __( 'This entity has no featured image yet.', 'wordlift' ) );
274
-
275
-		// Get all post meta keys for the current post
276
-		global $wpdb;
277
-
278
-		$query = $wpdb->prepare(
279
-			"SELECT DISTINCT (meta_key) FROM $wpdb->postmeta  WHERE post_id = %d", $post->ID
280
-		);
281
-
282
-		// Check intersection between available meta keys and expected ones
283
-		// arrays to detect missing values.
284
-		$available_meta_keys = $wpdb->get_col( $query );
285
-
286
-		// If each expected key is contained in available keys array ...
287
-		( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
288
-			$score ++ :
289
-			array_push( $warnings, __( 'There are no sameAs configured for this entity.', 'wordlift' ) );
290
-
291
-		$schema = $this->entity_type_service->get( $post_id );
292
-
293
-		$expected_meta_keys = ( null === $schema['custom_fields'] ) ?
294
-			array() :
295
-			array_keys( $schema['custom_fields'] );
296
-
297
-		$intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
298
-		// If each expected key is contained in available keys array ...
299
-		( count( $intersection ) === count( $expected_meta_keys ) ) ?
300
-			$score ++ :
301
-			array_push( $warnings, __( 'Schema.org metadata for this entity are not completed.', 'wordlift' ) );
302
-
303
-		// Finally return score and warnings
304
-		return array(
305
-			'raw_score'           => $score,
306
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
307
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
308
-			'warnings'            => $warnings,
309
-		);
310
-
311
-	}
312
-
313
-	/**
314
-	 * Get as rating as input and convert in a traffic-light rating
315
-	 *
316
-	 * @since 3.3.0
317
-	 *
318
-	 * @param int $score The rating score for a given entity.
319
-	 *
320
-	 * @return string The input HTML code.
321
-	 */
322
-	private function convert_raw_score_to_traffic_light( $score ) {
323
-		// RATING_MAX : $score = 3 : x
324
-		// See http://php.net/manual/en/function.round.php
325
-		$rating = round( ( $score * 3 ) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP );
326
-
327
-		// If rating is 0, return 1, otherwise return rating
328
-		return ( 0 == $rating ) ? 1 : $rating;
329
-
330
-	}
331
-
332
-	/**
333
-	 * Get as rating as input and convert in a traffic-light rating
334
-	 *
335
-	 * @since 3.3.0
336
-	 *
337
-	 * @param int $score The rating score for a given entity.
338
-	 *
339
-	 * @return string The input HTML code.
340
-	 */
341
-	public function convert_raw_score_to_percentage( $score ) {
342
-
343
-		// RATING_MAX : $score = 100 : x
344
-		return round( ( $score * 100 ) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP );
345
-	}
346
-
347
-
348
-	/**
349
-	 * Add admin notices for the current entity depending on the current rating.
350
-	 *
351
-	 * @since 3.3.0
352
-	 */
353
-	public function in_admin_header() {
354
-
355
-		// Return safely if get_current_screen() is not defined (yet)
356
-		if ( false === function_exists( 'get_current_screen' ) ) {
357
-			return;
358
-		}
359
-
360
-		$screen = get_current_screen();
361
-		// If there is any valid screen nothing to do
362
-		if ( null === $screen ) {
363
-			return;
364
-		}
365
-
366
-		// If you're not in the entity post edit page, return.
367
-		if ( Wordlift_Entity_Service::TYPE_NAME !== $screen->id ) {
368
-			return;
369
-		}
370
-		// Retrieve the current global post
371
-		global $post;
372
-		// If it's not an entity, return.
373
-		if ( ! $this->entity_service->is_entity( $post->ID ) ) {
374
-			return;
375
-		}
376
-		// Retrieve an updated rating for the current entity
377
-		$rating = $this->get_rating_for( $post->ID, true );
378
-
379
-		// If there is at least 1 warning
380
-		if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
381
-			// TODO - Pass Wordlift_Notice_Service trough the service constructor
382
-			$this->notice_service->add_suggestion( $rating['warnings'] );
383
-		}
384
-
385
-	}
17
+    /**
18
+     * Entity rating max.
19
+     *
20
+     * @since 3.3.0
21
+     */
22
+    const RATING_MAX = 7;
23
+
24
+    /**
25
+     * Entity rating score meta key.
26
+     *
27
+     * @since 3.3.0
28
+     */
29
+    const RATING_RAW_SCORE_META_KEY = '_wl_entity_rating_raw_score';
30
+
31
+    /**
32
+     * Entity rating warnings meta key.
33
+     *
34
+     * @since 3.3.0
35
+     */
36
+    const RATING_WARNINGS_META_KEY = '_wl_entity_rating_warnings';
37
+
38
+    /**
39
+     * Entity warning has related post identifier.
40
+     *
41
+     * @since 3.3.0
42
+     */
43
+    const RATING_WARNING_HAS_RELATED_POSTS = 'There are no related posts for the current entity.';
44
+
45
+    /**
46
+     * Entity warning has content post identifier.
47
+     *
48
+     * @since 3.3.0
49
+     */
50
+    const RATING_WARNING_HAS_CONTENT_POST = 'This entity has not description.';
51
+
52
+    /**
53
+     * Entity warning has related entities identifier.
54
+     *
55
+     * @since 3.3.0
56
+     */
57
+    const RATING_WARNING_HAS_RELATED_ENTITIES = 'There are no related entities for the current entity.';
58
+
59
+    /**
60
+     * Entity warning is published identifier.
61
+     *
62
+     * @since 3.3.0
63
+     */
64
+    const RATING_WARNING_IS_PUBLISHED = 'This entity is not published. It will not appear within analysis results.';
65
+
66
+    /**
67
+     * Entity warning has thumbnail identifier.
68
+     *
69
+     * @since 3.3.0
70
+     */
71
+    const RATING_WARNING_HAS_THUMBNAIL = 'This entity has no featured image yet.';
72
+
73
+    /**
74
+     * Entity warning has same as identifier.
75
+     *
76
+     * @since 3.3.0
77
+     */
78
+    const RATING_WARNING_HAS_SAME_AS = 'There are no sameAs configured for this entity.';
79
+
80
+    /**
81
+     * Entity warning has completed metadata identifier.
82
+     *
83
+     * @since 3.3.0
84
+     */
85
+    const RATING_WARNING_HAS_COMPLETED_METADATA = 'Schema.org metadata for this entity are not completed.';
86
+
87
+    /**
88
+     * A {@link Wordlift_Entity_Service} instance.
89
+     *
90
+     * @since  3.10.0
91
+     * @access private
92
+     * @var Wordlift_Entity_Service $entity_service A {@link Wordlift_Entity_Service} instance.
93
+     */
94
+    private $entity_service;
95
+
96
+    /**
97
+     *  A {@link Wordlift_Entity_Type_Service} instance.
98
+     *
99
+     * @since  3.10.0
100
+     * @access private
101
+     * @var Wordlift_Entity_Type_Service $entity_type_service A {@link Wordlift_Entity_Type_Service} instance.
102
+     */
103
+    private $entity_type_service;
104
+
105
+    /**
106
+     * The Notice service.
107
+     *
108
+     * @since  3.3.0
109
+     * @access private
110
+     * @var \Wordlift_Notice_Service $notice_service The Notice service.
111
+     */
112
+    private $notice_service;
113
+
114
+    /**
115
+     * A {@link Wordlift_Log_Service} instance.
116
+     *
117
+     * @since  3.10.0
118
+     * @access private
119
+     * @var Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
120
+     */
121
+    private $log;
122
+
123
+    /**
124
+     * Create a {@link Wordlift_Rating_Service} instance.
125
+     *
126
+     * @since 3.10.0
127
+     *
128
+     * @param \Wordlift_Entity_Service      $entity_service      A {@link Wordlift_Entity_Service} instance.
129
+     * @param \Wordlift_Entity_Type_Service $entity_type_service A {@link Wordlift_Entity_Type_Service} instance.
130
+     * @param \Wordlift_Notice_Service      $notice_service      A {@link Wordlift_Notice_Service} instance.
131
+     */
132
+    public function __construct( $entity_service, $entity_type_service, $notice_service ) {
133
+
134
+        $this->entity_service      = $entity_service;
135
+        $this->entity_type_service = $entity_type_service;
136
+        $this->notice_service      = $notice_service;
137
+
138
+        $this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Rating_Service' );
139
+
140
+    }
141
+
142
+    /**
143
+     * Set rating for a given entity.
144
+     *
145
+     * @since 3.3.0
146
+     *
147
+     * @param int $post_id The entity post id.
148
+     *
149
+     * @return array An array representing the rating obj.
150
+     */
151
+    public function set_rating_for( $post_id ) {
152
+
153
+        if ( ! $this->entity_service->is_entity( $post_id ) ) {
154
+            return;
155
+        }
156
+
157
+        // Calculate rating for the given post.
158
+        $rating = $this->calculate_rating_for( $post_id );
159
+
160
+        // Store the rating on db as post meta. Please notice that RATING_RAW_SCORE_META_KEY
161
+        // is saved on a different meta to allow score sorting. Both meta are managed as unique.
162
+        //
163
+        // See https://codex.wordpress.org/Function_Reference/update_post_meta
164
+        update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
165
+        update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
166
+
167
+        $this->log->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
168
+
169
+        // Finally returns the rating
170
+        return $rating;
171
+    }
172
+
173
+
174
+    /**
175
+     * Get or calculate rating for a given entity
176
+     *
177
+     * @since 3.3.0
178
+     *
179
+     * @param int $post_id      The entity post id.
180
+     * @param     $force_reload $warnings_needed If true, detailed warnings collection is provided with the rating obj.
181
+     *
182
+     * @return array An array representing the rating obj.
183
+     */
184
+    public function get_rating_for( $post_id, $force_reload = false ) {
185
+
186
+        // If forced reload is required or rating is missing.
187
+        if ( $force_reload ) {
188
+            $this->log->trace( "Force rating reload [ post_id :: $post_id ]" );
189
+
190
+            return $this->set_rating_for( $post_id );
191
+        }
192
+
193
+        $current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, true );
194
+
195
+        if ( ! is_numeric( $current_raw_score ) ) {
196
+            $this->log->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
197
+
198
+            return $this->set_rating_for( $post_id );
199
+        }
200
+
201
+        $current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, true );
202
+
203
+        // Finally return score and warnings
204
+        return array(
205
+            'raw_score'           => $current_raw_score,
206
+            'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
207
+            'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
208
+            'warnings'            => $current_warnings,
209
+        );
210
+
211
+    }
212
+
213
+    /**
214
+     * Calculate rating for a given entity.
215
+     *
216
+     * Rating depends from following criteria:
217
+     *
218
+     * 1. Is the current entity related to at least 1 post?
219
+     * 2. Is the current entity content post not empty?
220
+     * 3. Is the current entity related to at least 1 entity?
221
+     * 4. Is the entity published?
222
+     * 5. There is a a thumbnail associated to the entity?
223
+     * 6. Has the entity a sameas defined?
224
+     * 7. Are all schema.org required metadata compiled?
225
+     *
226
+     * Each positive check means +1 in terms of rating score.
227
+     *
228
+     * @since 3.3.0
229
+     *
230
+     * @param int $post_id The entity post id.
231
+     *
232
+     * @return array An array representing the rating obj.
233
+     */
234
+    private function calculate_rating_for( $post_id ) {
235
+
236
+        // If it's not an entity, return.
237
+        if ( ! $this->entity_service->is_entity( $post_id ) ) {
238
+            return array();
239
+        }
240
+        // Retrieve the post object.
241
+        $post = get_post( $post_id );
242
+
243
+        // Rating value.
244
+        $score = 0;
245
+
246
+        // Store warning messages.
247
+        $warnings = array();
248
+
249
+        // Is the current entity related to at least 1 post?
250
+        ( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
251
+            $score ++ :
252
+            array_push( $warnings, __( 'There are no related posts for the current entity.', 'wordlift' ) );
253
+
254
+        // Is the post content not empty?
255
+        ( ! empty( $post->post_content ) ) ?
256
+            $score ++ :
257
+            array_push( $warnings, __( 'This entity has not description.', 'wordlift' ) );
258
+
259
+        // Is the current entity related to at least 1 entity?
260
+        // Was the current entity already disambiguated?
261
+        ( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
262
+            $score ++ :
263
+            array_push( $warnings, __( 'There are no related entities for the current entity.', 'wordlift' ) );
264
+
265
+        // Is the entity published?
266
+        ( 'publish' === get_post_status( $post->ID ) ) ?
267
+            $score ++ :
268
+            array_push( $warnings, __( 'This entity is not published. It will not appear within analysis results.', 'wordlift' ) );
269
+
270
+        // Has a thumbnail?
271
+        ( has_post_thumbnail( $post->ID ) ) ?
272
+            $score ++ :
273
+            array_push( $warnings, __( 'This entity has no featured image yet.', 'wordlift' ) );
274
+
275
+        // Get all post meta keys for the current post
276
+        global $wpdb;
277
+
278
+        $query = $wpdb->prepare(
279
+            "SELECT DISTINCT (meta_key) FROM $wpdb->postmeta  WHERE post_id = %d", $post->ID
280
+        );
281
+
282
+        // Check intersection between available meta keys and expected ones
283
+        // arrays to detect missing values.
284
+        $available_meta_keys = $wpdb->get_col( $query );
285
+
286
+        // If each expected key is contained in available keys array ...
287
+        ( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
288
+            $score ++ :
289
+            array_push( $warnings, __( 'There are no sameAs configured for this entity.', 'wordlift' ) );
290
+
291
+        $schema = $this->entity_type_service->get( $post_id );
292
+
293
+        $expected_meta_keys = ( null === $schema['custom_fields'] ) ?
294
+            array() :
295
+            array_keys( $schema['custom_fields'] );
296
+
297
+        $intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
298
+        // If each expected key is contained in available keys array ...
299
+        ( count( $intersection ) === count( $expected_meta_keys ) ) ?
300
+            $score ++ :
301
+            array_push( $warnings, __( 'Schema.org metadata for this entity are not completed.', 'wordlift' ) );
302
+
303
+        // Finally return score and warnings
304
+        return array(
305
+            'raw_score'           => $score,
306
+            'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
307
+            'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
308
+            'warnings'            => $warnings,
309
+        );
310
+
311
+    }
312
+
313
+    /**
314
+     * Get as rating as input and convert in a traffic-light rating
315
+     *
316
+     * @since 3.3.0
317
+     *
318
+     * @param int $score The rating score for a given entity.
319
+     *
320
+     * @return string The input HTML code.
321
+     */
322
+    private function convert_raw_score_to_traffic_light( $score ) {
323
+        // RATING_MAX : $score = 3 : x
324
+        // See http://php.net/manual/en/function.round.php
325
+        $rating = round( ( $score * 3 ) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP );
326
+
327
+        // If rating is 0, return 1, otherwise return rating
328
+        return ( 0 == $rating ) ? 1 : $rating;
329
+
330
+    }
331
+
332
+    /**
333
+     * Get as rating as input and convert in a traffic-light rating
334
+     *
335
+     * @since 3.3.0
336
+     *
337
+     * @param int $score The rating score for a given entity.
338
+     *
339
+     * @return string The input HTML code.
340
+     */
341
+    public function convert_raw_score_to_percentage( $score ) {
342
+
343
+        // RATING_MAX : $score = 100 : x
344
+        return round( ( $score * 100 ) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP );
345
+    }
346
+
347
+
348
+    /**
349
+     * Add admin notices for the current entity depending on the current rating.
350
+     *
351
+     * @since 3.3.0
352
+     */
353
+    public function in_admin_header() {
354
+
355
+        // Return safely if get_current_screen() is not defined (yet)
356
+        if ( false === function_exists( 'get_current_screen' ) ) {
357
+            return;
358
+        }
359
+
360
+        $screen = get_current_screen();
361
+        // If there is any valid screen nothing to do
362
+        if ( null === $screen ) {
363
+            return;
364
+        }
365
+
366
+        // If you're not in the entity post edit page, return.
367
+        if ( Wordlift_Entity_Service::TYPE_NAME !== $screen->id ) {
368
+            return;
369
+        }
370
+        // Retrieve the current global post
371
+        global $post;
372
+        // If it's not an entity, return.
373
+        if ( ! $this->entity_service->is_entity( $post->ID ) ) {
374
+            return;
375
+        }
376
+        // Retrieve an updated rating for the current entity
377
+        $rating = $this->get_rating_for( $post->ID, true );
378
+
379
+        // If there is at least 1 warning
380
+        if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
381
+            // TODO - Pass Wordlift_Notice_Service trough the service constructor
382
+            $this->notice_service->add_suggestion( $rating['warnings'] );
383
+        }
384
+
385
+    }
386 386
 
387 387
 }
Please login to merge, or discard this patch.
Spacing   +55 added lines, -63 removed lines patch added patch discarded remove patch
@@ -129,13 +129,13 @@  discard block
 block discarded – undo
129 129
 	 * @param \Wordlift_Entity_Type_Service $entity_type_service A {@link Wordlift_Entity_Type_Service} instance.
130 130
 	 * @param \Wordlift_Notice_Service      $notice_service      A {@link Wordlift_Notice_Service} instance.
131 131
 	 */
132
-	public function __construct( $entity_service, $entity_type_service, $notice_service ) {
132
+	public function __construct($entity_service, $entity_type_service, $notice_service) {
133 133
 
134 134
 		$this->entity_service      = $entity_service;
135 135
 		$this->entity_type_service = $entity_type_service;
136 136
 		$this->notice_service      = $notice_service;
137 137
 
138
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Rating_Service' );
138
+		$this->log = Wordlift_Log_Service::get_logger('Wordlift_Rating_Service');
139 139
 
140 140
 	}
141 141
 
@@ -148,23 +148,23 @@  discard block
 block discarded – undo
148 148
 	 *
149 149
 	 * @return array An array representing the rating obj.
150 150
 	 */
151
-	public function set_rating_for( $post_id ) {
151
+	public function set_rating_for($post_id) {
152 152
 
153
-		if ( ! $this->entity_service->is_entity( $post_id ) ) {
153
+		if ( ! $this->entity_service->is_entity($post_id)) {
154 154
 			return;
155 155
 		}
156 156
 
157 157
 		// Calculate rating for the given post.
158
-		$rating = $this->calculate_rating_for( $post_id );
158
+		$rating = $this->calculate_rating_for($post_id);
159 159
 
160 160
 		// Store the rating on db as post meta. Please notice that RATING_RAW_SCORE_META_KEY
161 161
 		// is saved on a different meta to allow score sorting. Both meta are managed as unique.
162 162
 		//
163 163
 		// See https://codex.wordpress.org/Function_Reference/update_post_meta
164
-		update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
165
-		update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
164
+		update_post_meta($post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score']);
165
+		update_post_meta($post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings']);
166 166
 
167
-		$this->log->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
167
+		$this->log->trace(sprintf("Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score']));
168 168
 
169 169
 		// Finally returns the rating
170 170
 		return $rating;
@@ -181,30 +181,30 @@  discard block
 block discarded – undo
181 181
 	 *
182 182
 	 * @return array An array representing the rating obj.
183 183
 	 */
184
-	public function get_rating_for( $post_id, $force_reload = false ) {
184
+	public function get_rating_for($post_id, $force_reload = false) {
185 185
 
186 186
 		// If forced reload is required or rating is missing.
187
-		if ( $force_reload ) {
188
-			$this->log->trace( "Force rating reload [ post_id :: $post_id ]" );
187
+		if ($force_reload) {
188
+			$this->log->trace("Force rating reload [ post_id :: $post_id ]");
189 189
 
190
-			return $this->set_rating_for( $post_id );
190
+			return $this->set_rating_for($post_id);
191 191
 		}
192 192
 
193
-		$current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, true );
193
+		$current_raw_score = get_post_meta($post_id, self::RATING_RAW_SCORE_META_KEY, true);
194 194
 
195
-		if ( ! is_numeric( $current_raw_score ) ) {
196
-			$this->log->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
195
+		if ( ! is_numeric($current_raw_score)) {
196
+			$this->log->trace("Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]");
197 197
 
198
-			return $this->set_rating_for( $post_id );
198
+			return $this->set_rating_for($post_id);
199 199
 		}
200 200
 
201
-		$current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, true );
201
+		$current_warnings = get_post_meta($post_id, self::RATING_WARNINGS_META_KEY, true);
202 202
 
203 203
 		// Finally return score and warnings
204 204
 		return array(
205 205
 			'raw_score'           => $current_raw_score,
206
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
207
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
206
+			'traffic_light_score' => $this->convert_raw_score_to_traffic_light($current_raw_score),
207
+			'percentage_score'    => $this->convert_raw_score_to_percentage($current_raw_score),
208 208
 			'warnings'            => $current_warnings,
209 209
 		);
210 210
 
@@ -231,14 +231,14 @@  discard block
 block discarded – undo
231 231
 	 *
232 232
 	 * @return array An array representing the rating obj.
233 233
 	 */
234
-	private function calculate_rating_for( $post_id ) {
234
+	private function calculate_rating_for($post_id) {
235 235
 
236 236
 		// If it's not an entity, return.
237
-		if ( ! $this->entity_service->is_entity( $post_id ) ) {
237
+		if ( ! $this->entity_service->is_entity($post_id)) {
238 238
 			return array();
239 239
 		}
240 240
 		// Retrieve the post object.
241
-		$post = get_post( $post_id );
241
+		$post = get_post($post_id);
242 242
 
243 243
 		// Rating value.
244 244
 		$score = 0;
@@ -247,30 +247,25 @@  discard block
 block discarded – undo
247 247
 		$warnings = array();
248 248
 
249 249
 		// Is the current entity related to at least 1 post?
250
-		( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
251
-			$score ++ :
252
-			array_push( $warnings, __( 'There are no related posts for the current entity.', 'wordlift' ) );
250
+		(0 < count(wl_core_get_related_post_ids($post->ID))) ?
251
+			$score++ : array_push($warnings, __('There are no related posts for the current entity.', 'wordlift'));
253 252
 
254 253
 		// Is the post content not empty?
255
-		( ! empty( $post->post_content ) ) ?
256
-			$score ++ :
257
-			array_push( $warnings, __( 'This entity has not description.', 'wordlift' ) );
254
+		( ! empty($post->post_content)) ?
255
+			$score++ : array_push($warnings, __('This entity has not description.', 'wordlift'));
258 256
 
259 257
 		// Is the current entity related to at least 1 entity?
260 258
 		// Was the current entity already disambiguated?
261
-		( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
262
-			$score ++ :
263
-			array_push( $warnings, __( 'There are no related entities for the current entity.', 'wordlift' ) );
259
+		(0 < count(wl_core_get_related_entity_ids($post->ID))) ?
260
+			$score++ : array_push($warnings, __('There are no related entities for the current entity.', 'wordlift'));
264 261
 
265 262
 		// Is the entity published?
266
-		( 'publish' === get_post_status( $post->ID ) ) ?
267
-			$score ++ :
268
-			array_push( $warnings, __( 'This entity is not published. It will not appear within analysis results.', 'wordlift' ) );
263
+		('publish' === get_post_status($post->ID)) ?
264
+			$score++ : array_push($warnings, __('This entity is not published. It will not appear within analysis results.', 'wordlift'));
269 265
 
270 266
 		// Has a thumbnail?
271
-		( has_post_thumbnail( $post->ID ) ) ?
272
-			$score ++ :
273
-			array_push( $warnings, __( 'This entity has no featured image yet.', 'wordlift' ) );
267
+		(has_post_thumbnail($post->ID)) ?
268
+			$score++ : array_push($warnings, __('This entity has no featured image yet.', 'wordlift'));
274 269
 
275 270
 		// Get all post meta keys for the current post
276 271
 		global $wpdb;
@@ -281,30 +276,27 @@  discard block
 block discarded – undo
281 276
 
282 277
 		// Check intersection between available meta keys and expected ones
283 278
 		// arrays to detect missing values.
284
-		$available_meta_keys = $wpdb->get_col( $query );
279
+		$available_meta_keys = $wpdb->get_col($query);
285 280
 
286 281
 		// If each expected key is contained in available keys array ...
287
-		( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
288
-			$score ++ :
289
-			array_push( $warnings, __( 'There are no sameAs configured for this entity.', 'wordlift' ) );
282
+		(in_array(Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys)) ?
283
+			$score++ : array_push($warnings, __('There are no sameAs configured for this entity.', 'wordlift'));
290 284
 
291
-		$schema = $this->entity_type_service->get( $post_id );
285
+		$schema = $this->entity_type_service->get($post_id);
292 286
 
293
-		$expected_meta_keys = ( null === $schema['custom_fields'] ) ?
294
-			array() :
295
-			array_keys( $schema['custom_fields'] );
287
+		$expected_meta_keys = (null === $schema['custom_fields']) ?
288
+			array() : array_keys($schema['custom_fields']);
296 289
 
297
-		$intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
290
+		$intersection = array_intersect($expected_meta_keys, $available_meta_keys);
298 291
 		// If each expected key is contained in available keys array ...
299
-		( count( $intersection ) === count( $expected_meta_keys ) ) ?
300
-			$score ++ :
301
-			array_push( $warnings, __( 'Schema.org metadata for this entity are not completed.', 'wordlift' ) );
292
+		(count($intersection) === count($expected_meta_keys)) ?
293
+			$score++ : array_push($warnings, __('Schema.org metadata for this entity are not completed.', 'wordlift'));
302 294
 
303 295
 		// Finally return score and warnings
304 296
 		return array(
305 297
 			'raw_score'           => $score,
306
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
307
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
298
+			'traffic_light_score' => $this->convert_raw_score_to_traffic_light($score),
299
+			'percentage_score'    => $this->convert_raw_score_to_percentage($score),
308 300
 			'warnings'            => $warnings,
309 301
 		);
310 302
 
@@ -319,13 +311,13 @@  discard block
 block discarded – undo
319 311
 	 *
320 312
 	 * @return string The input HTML code.
321 313
 	 */
322
-	private function convert_raw_score_to_traffic_light( $score ) {
314
+	private function convert_raw_score_to_traffic_light($score) {
323 315
 		// RATING_MAX : $score = 3 : x
324 316
 		// See http://php.net/manual/en/function.round.php
325
-		$rating = round( ( $score * 3 ) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP );
317
+		$rating = round(($score * 3) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP);
326 318
 
327 319
 		// If rating is 0, return 1, otherwise return rating
328
-		return ( 0 == $rating ) ? 1 : $rating;
320
+		return (0 == $rating) ? 1 : $rating;
329 321
 
330 322
 	}
331 323
 
@@ -338,10 +330,10 @@  discard block
 block discarded – undo
338 330
 	 *
339 331
 	 * @return string The input HTML code.
340 332
 	 */
341
-	public function convert_raw_score_to_percentage( $score ) {
333
+	public function convert_raw_score_to_percentage($score) {
342 334
 
343 335
 		// RATING_MAX : $score = 100 : x
344
-		return round( ( $score * 100 ) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP );
336
+		return round(($score * 100) / self::RATING_MAX, 0, PHP_ROUND_HALF_UP);
345 337
 	}
346 338
 
347 339
 
@@ -353,33 +345,33 @@  discard block
 block discarded – undo
353 345
 	public function in_admin_header() {
354 346
 
355 347
 		// Return safely if get_current_screen() is not defined (yet)
356
-		if ( false === function_exists( 'get_current_screen' ) ) {
348
+		if (false === function_exists('get_current_screen')) {
357 349
 			return;
358 350
 		}
359 351
 
360 352
 		$screen = get_current_screen();
361 353
 		// If there is any valid screen nothing to do
362
-		if ( null === $screen ) {
354
+		if (null === $screen) {
363 355
 			return;
364 356
 		}
365 357
 
366 358
 		// If you're not in the entity post edit page, return.
367
-		if ( Wordlift_Entity_Service::TYPE_NAME !== $screen->id ) {
359
+		if (Wordlift_Entity_Service::TYPE_NAME !== $screen->id) {
368 360
 			return;
369 361
 		}
370 362
 		// Retrieve the current global post
371 363
 		global $post;
372 364
 		// If it's not an entity, return.
373
-		if ( ! $this->entity_service->is_entity( $post->ID ) ) {
365
+		if ( ! $this->entity_service->is_entity($post->ID)) {
374 366
 			return;
375 367
 		}
376 368
 		// Retrieve an updated rating for the current entity
377
-		$rating = $this->get_rating_for( $post->ID, true );
369
+		$rating = $this->get_rating_for($post->ID, true);
378 370
 
379 371
 		// If there is at least 1 warning
380
-		if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
372
+		if (isset($rating['warnings']) && 0 < count($rating['warnings'])) {
381 373
 			// TODO - Pass Wordlift_Notice_Service trough the service constructor
382
-			$this->notice_service->add_suggestion( $rating['warnings'] );
374
+			$this->notice_service->add_suggestion($rating['warnings']);
383 375
 		}
384 376
 
385 377
 	}
Please login to merge, or discard this patch.
src/includes/class-wordlift-entity-service.php 2 patches
Indentation   +597 added lines, -597 removed lines patch added patch discarded remove patch
@@ -7,608 +7,608 @@
 block discarded – undo
7 7
  */
8 8
 class Wordlift_Entity_Service {
9 9
 
10
-	/**
11
-	 * The Log service.
12
-	 *
13
-	 * @since  3.2.0
14
-	 * @access private
15
-	 * @var \Wordlift_Log_Service $log The Log service.
16
-	 */
17
-	private $log;
18
-
19
-	/**
20
-	 * The UI service.
21
-	 *
22
-	 * @since  3.2.0
23
-	 * @access private
24
-	 * @var \Wordlift_UI_Service $ui_service The UI service.
25
-	 */
26
-	private $ui_service;
27
-
28
-	/**
29
-	 *The {@link Wordlift_Relation_Service} instance.
30
-	 *
31
-	 * @since  3.15.0
32
-	 * @access private
33
-	 * @var \Wordlift_Relation_Service $relation_service The {@link Wordlift_Relation_Service} instance.
34
-	 */
35
-	private $relation_service;
36
-
37
-	/**
38
-	 * The entity post type name.
39
-	 *
40
-	 * @since 3.1.0
41
-	 */
42
-	const TYPE_NAME = 'entity';
43
-
44
-	/**
45
-	 * The alternative label meta key.
46
-	 *
47
-	 * @since 3.2.0
48
-	 */
49
-	const ALTERNATIVE_LABEL_META_KEY = '_wl_alt_label';
50
-
51
-	/**
52
-	 * The alternative label input template.
53
-	 *
54
-	 * @since 3.2.0
55
-	 */
56
-	// TODO: this should be moved to a class that deals with HTML code.
57
-	const ALTERNATIVE_LABEL_INPUT_TEMPLATE = '<div class="wl-alternative-label">
10
+    /**
11
+     * The Log service.
12
+     *
13
+     * @since  3.2.0
14
+     * @access private
15
+     * @var \Wordlift_Log_Service $log The Log service.
16
+     */
17
+    private $log;
18
+
19
+    /**
20
+     * The UI service.
21
+     *
22
+     * @since  3.2.0
23
+     * @access private
24
+     * @var \Wordlift_UI_Service $ui_service The UI service.
25
+     */
26
+    private $ui_service;
27
+
28
+    /**
29
+     *The {@link Wordlift_Relation_Service} instance.
30
+     *
31
+     * @since  3.15.0
32
+     * @access private
33
+     * @var \Wordlift_Relation_Service $relation_service The {@link Wordlift_Relation_Service} instance.
34
+     */
35
+    private $relation_service;
36
+
37
+    /**
38
+     * The entity post type name.
39
+     *
40
+     * @since 3.1.0
41
+     */
42
+    const TYPE_NAME = 'entity';
43
+
44
+    /**
45
+     * The alternative label meta key.
46
+     *
47
+     * @since 3.2.0
48
+     */
49
+    const ALTERNATIVE_LABEL_META_KEY = '_wl_alt_label';
50
+
51
+    /**
52
+     * The alternative label input template.
53
+     *
54
+     * @since 3.2.0
55
+     */
56
+    // TODO: this should be moved to a class that deals with HTML code.
57
+    const ALTERNATIVE_LABEL_INPUT_TEMPLATE = '<div class="wl-alternative-label">
58 58
                 <label class="screen-reader-text" id="wl-alternative-label-prompt-text" for="wl-alternative-label">Enter alternative label here</label>
59 59
                 <input name="wl_alternative_label[]" size="30" value="%s" id="wl-alternative-label" type="text">
60 60
                 <button class="button wl-delete-button">%s</button>
61 61
                 </div>';
62 62
 
63
-	/**
64
-	 * A singleton instance of the Entity service.
65
-	 *
66
-	 * @since  3.2.0
67
-	 * @access private
68
-	 * @var \Wordlift_Entity_Service $instance A singleton instance of the Entity service.
69
-	 */
70
-	private static $instance;
71
-
72
-	/**
73
-	 * Create a Wordlift_Entity_Service instance.
74
-	 *
75
-	 * @since 3.2.0
76
-	 *
77
-	 * @param \Wordlift_UI_Service       $ui_service       The UI service.
78
-	 * @param \Wordlift_Relation_Service $relation_service The {@link Wordlift_Relation_Service} instance.
79
-	 */
80
-	public function __construct( $ui_service, $relation_service ) {
81
-
82
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
83
-
84
-		$this->ui_service       = $ui_service;
85
-		$this->relation_service = $relation_service;
86
-
87
-		// Set the singleton instance.
88
-		self::$instance = $this;
89
-	}
90
-
91
-	/**
92
-	 * Get the singleton instance of the Entity service.
93
-	 *
94
-	 * @since 3.2.0
95
-	 * @return \Wordlift_Entity_Service The singleton instance of the Entity service.
96
-	 */
97
-	public static function get_instance() {
98
-
99
-		return self::$instance;
100
-	}
101
-
102
-	/**
103
-	 * Determines whether a post is an entity or not. Entity is in this context
104
-	 * something which is not an article.
105
-	 *
106
-	 * @since 3.1.0
107
-	 *
108
-	 * @param int $post_id A post id.
109
-	 *
110
-	 * @return bool Return true if the post is an entity otherwise false.
111
-	 */
112
-	public function is_entity( $post_id ) {
113
-
114
-		$terms = wp_get_object_terms( $post_id, Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME );
115
-
116
-		if ( 0 === count( $terms ) ) {
117
-			return false;
118
-		}
119
-
120
-		// We don't consider an `article` to be an entity.
121
-		if ( 'article' !== $terms[0]->slug ) {
122
-			return true;
123
-		}
124
-
125
-		return false;
126
-	}
127
-
128
-	/**
129
-	 * Get the proper classification scope for a given entity post
130
-	 *
131
-	 * @since 3.5.0
132
-	 *
133
-	 * @param integer $post_id An entity post id.
134
-	 *
135
-	 * @param string  $default The default classification scope, `what` if not
136
-	 *                         provided.
137
-	 *
138
-	 * @return string Returns a classification scope (e.g. 'what').
139
-	 */
140
-	public function get_classification_scope_for( $post_id, $default = WL_WHAT_RELATION ) {
141
-
142
-		if ( false === $this->is_entity( $post_id ) ) {
143
-			return $default;
144
-		}
145
-
146
-		// Retrieve the entity type
147
-		$entity_type_arr = Wordlift_Entity_Type_Service::get_instance()->get( $post_id );
148
-		$entity_type     = str_replace( 'wl-', '', $entity_type_arr['css_class'] );
149
-		// Retrieve classification boxes configuration
150
-		$classification_boxes = unserialize( WL_CORE_POST_CLASSIFICATION_BOXES );
151
-		foreach ( $classification_boxes as $cb ) {
152
-			if ( in_array( $entity_type, $cb['registeredTypes'] ) ) {
153
-				return $cb['id'];
154
-			}
155
-		}
156
-
157
-		return $default;
158
-	}
159
-
160
-
161
-	public function is_used( $post_id ) {
162
-
163
-		if ( false === $this->is_entity( $post_id ) ) {
164
-			return null;
165
-		}
166
-		// Retrieve the post
167
-		$entity = get_post( $post_id );
168
-
169
-		global $wpdb;
170
-		// Retrieve Wordlift relation instances table name
171
-		$table_name = wl_core_get_relation_instances_table_name();
172
-
173
-		// Check is it's referenced / related to another post / entity
174
-		$stmt = $wpdb->prepare(
175
-			"SELECT COUNT(*) FROM $table_name WHERE  object_id = %d",
176
-			$entity->ID
177
-		);
178
-
179
-		// Perform the query
180
-		$relation_instances = (int) $wpdb->get_var( $stmt );
181
-		// If there is at least one relation instance for the current entity, then it's used
182
-		if ( 0 < $relation_instances ) {
183
-			return true;
184
-		}
185
-
186
-		// Check if the entity uri is used as meta_value
187
-		$stmt = $wpdb->prepare(
188
-			"SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id != %d AND meta_value = %s",
189
-			$entity->ID,
190
-			wl_get_entity_uri( $entity->ID )
191
-		);
192
-		// Perform the query
193
-		$meta_instances = (int) $wpdb->get_var( $stmt );
194
-
195
-		// If there is at least one meta that refers the current entity uri, then current entity is used
196
-		if ( 0 < $meta_instances ) {
197
-			return true;
198
-		}
199
-
200
-		// If we are here, it means the current entity is not used at the moment
201
-		return false;
202
-	}
203
-
204
-	/**
205
-	 * Determines whether a given uri is an internal uri or not.
206
-	 *
207
-	 * @since 3.3.2
208
-	 *
209
-	 * @param int $uri An uri.
210
-	 *
211
-	 * @return true if the uri internal to the current dataset otherwise false.
212
-	 */
213
-	public function is_internal_uri( $uri ) {
214
-
215
-		return ( 0 === strrpos( $uri, wl_configuration_get_redlink_dataset_uri() ) );
216
-	}
217
-
218
-	/**
219
-	 * Find entity posts by the entity URI. Entity as searched by their entity URI or same as.
220
-	 *
221
-	 * @since 3.2.0
222
-	 *
223
-	 * @param string $uri The entity URI.
224
-	 *
225
-	 * @return WP_Post|null A WP_Post instance or null if not found.
226
-	 */
227
-	public function get_entity_post_by_uri( $uri ) {
228
-
229
-		// Check if we've been provided with a value otherwise return null.
230
-		if ( empty( $uri ) ) {
231
-			return null;
232
-		}
233
-
234
-		$query_args = array(
235
-			'posts_per_page' => 1,
236
-			'post_status'    => 'any',
237
-			'post_type'      => Wordlift_Entity_Service::valid_entity_post_types(),
238
-			'meta_query'     => array(
239
-				array(
240
-					'key'     => WL_ENTITY_URL_META_NAME,
241
-					'value'   => $uri,
242
-					'compare' => '=',
243
-				),
244
-			),
245
-			$tax_query = array(
246
-				array(
247
-					'taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME,
248
-					'field'    => 'slug',
249
-					'terms'    => 'article',
250
-					'operator' => 'NOT IN',
251
-				),
252
-			),
253
-		);
254
-
255
-		// Only if the current uri is not an internal uri, entity search is
256
-		// performed also looking at sameAs values.
257
-		//
258
-		// This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237
259
-		if ( ! $this->is_internal_uri( $uri ) ) {
260
-
261
-			$query_args['meta_query']['relation'] = 'OR';
262
-			$query_args['meta_query'][]           = array(
263
-				'key'     => Wordlift_Schema_Service::FIELD_SAME_AS,
264
-				'value'   => $uri,
265
-				'compare' => '=',
266
-			);
267
-		}
268
-
269
-		$query = new WP_Query( $query_args );
270
-
271
-		// Get the matching entity posts.
272
-		$posts = $query->get_posts();
273
-
274
-		// Return null if no post is found.
275
-		if ( 0 === count( $posts ) ) {
276
-			return null;
277
-		}
278
-
279
-		// Return the found post.
280
-		return $posts[0];
281
-	}
282
-
283
-	/**
284
-	 * Fires once a post has been saved. This function uses the $_REQUEST, therefore
285
-	 * we check that the post we're saving is the current post.
286
-	 *
287
-	 * @see   https://github.com/insideout10/wordlift-plugin/issues/363
288
-	 *
289
-	 * @since 3.2.0
290
-	 *
291
-	 * @param int     $post_id Post ID.
292
-	 * @param WP_Post $post    Post object.
293
-	 * @param bool    $update  Whether this is an existing post being updated or not.
294
-	 */
295
-	public function save_post( $post_id, $post, $update ) {
296
-
297
-		// Avoid doing anything if post is autosave or a revision.
298
-		if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) {
299
-			return;
300
-		}
301
-
302
-		// We're setting the alternative label that have been provided via the UI
303
-		// (in fact we're using $_REQUEST), while save_post may be also called
304
-		// programmatically by some other function: we need to check therefore if
305
-		// the $post_id in the save_post call matches the post id set in the request.
306
-		//
307
-		// If this is not the current post being saved or if it's not an entity, return.
308
-		if ( ! isset( $_REQUEST['post_ID'] ) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity( $post_id ) ) {
309
-			return;
310
-		}
311
-
312
-		// Get the alt labels from the request (or empty array).
313
-		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
314
-
315
-		// Set the alternative labels.
316
-		$this->set_alternative_labels( $post_id, $alt_labels );
317
-
318
-	}
319
-
320
-	/**
321
-	 * Set the alternative labels.
322
-	 *
323
-	 * @since 3.2.0
324
-	 *
325
-	 * @param int   $post_id    The post id.
326
-	 * @param array $alt_labels An array of labels.
327
-	 */
328
-	public function set_alternative_labels( $post_id, $alt_labels ) {
329
-
330
-		// Force $alt_labels to be an array
331
-		if ( ! is_array( $alt_labels ) ) {
332
-			$alt_labels = array( $alt_labels );
333
-		}
334
-
335
-		$this->log->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
336
-
337
-		// Delete all the existing alternate labels.
338
-		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
339
-
340
-		// Set the alternative labels.
341
-		foreach ( $alt_labels as $alt_label ) {
342
-			if ( ! empty( $alt_label ) ) {
343
-				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
344
-			}
345
-		}
346
-
347
-	}
348
-
349
-	/**
350
-	 * Retrieve the alternate labels.
351
-	 *
352
-	 * @since 3.2.0
353
-	 *
354
-	 * @param int $post_id Post id.
355
-	 *
356
-	 * @return mixed An array  of alternative labels.
357
-	 */
358
-	public function get_alternative_labels( $post_id ) {
359
-
360
-		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
361
-	}
362
-
363
-	/**
364
-	 * Retrieve the labels for an entity, i.e. the title + the synonyms.
365
-	 *
366
-	 * @since 3.12.0
367
-	 *
368
-	 * @param int $post_id The entity {@link WP_Post} id.
369
-	 *
370
-	 * @return array An array with the entity title and labels.
371
-	 */
372
-	public function get_labels( $post_id ) {
373
-
374
-		return array_merge( (array) get_the_title( $post_id ), $this->get_alternative_labels( $post_id ) );
375
-	}
376
-
377
-	/**
378
-	 * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
379
-	 *
380
-	 * @since 3.2.0
381
-	 *
382
-	 * @param WP_Post $post Post object.
383
-	 */
384
-	public function edit_form_before_permalink( $post ) {
385
-
386
-		// If it's not an entity, return.
387
-		if ( ! $this->is_entity( $post->ID ) ) {
388
-			return;
389
-		}
390
-
391
-		// Print the input template.
392
-		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
393
-
394
-		// Print all the currently set alternative labels.
395
-		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
396
-
397
-			echo $this->get_alternative_label_input( $alt_label );
398
-
399
-		};
400
-
401
-		// Print the button.
402
-		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
403
-
404
-	}
405
-
406
-	/**
407
-	 * Get the URI for the entity with the specified post id.
408
-	 *
409
-	 * @since 3.6.0
410
-	 *
411
-	 * @param int $post_id The entity post id.
412
-	 *
413
-	 * @return null|string The entity URI or NULL if not found or the dataset URI is not configured.
414
-	 */
415
-	public function get_uri( $post_id ) {
416
-
417
-		// If a null is given, nothing to do
418
-		if ( null == $post_id ) {
419
-			return null;
420
-		}
421
-
422
-		$uri = get_post_meta( $post_id, WL_ENTITY_URL_META_NAME, true );
423
-
424
-		// If the dataset uri is not properly configured, null is returned
425
-		if ( '' === wl_configuration_get_redlink_dataset_uri() ) {
426
-			return null;
427
-		}
428
-
429
-		// Set the URI if it isn't set yet.
430
-		$post_status = get_post_status( $post_id );
431
-		if ( empty( $uri ) && 'auto-draft' !== $post_status && 'revision' !== $post_status ) {
432
-			$uri = wl_build_entity_uri( $post_id );
433
-			wl_set_entity_uri( $post_id, $uri );
434
-		}
435
-
436
-		return $uri;
437
-	}
438
-
439
-
440
-	/**
441
-	 * Get the alternative label input HTML code.
442
-	 *
443
-	 * @since 3.2.0
444
-	 *
445
-	 * @param string $value The input value.
446
-	 *
447
-	 * @return string The input HTML code.
448
-	 */
449
-	private function get_alternative_label_input( $value = '' ) {
450
-
451
-		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
452
-	}
453
-
454
-	/**
455
-	 * Get the number of entity posts published in this blog.
456
-	 *
457
-	 * @since 3.6.0
458
-	 *
459
-	 * @return int The number of published entity posts.
460
-	 */
461
-	public function count() {
462
-
463
-		$posts = get_posts( $this->add_criterias( array(
464
-			'post_status' => 'any',
465
-			'numberposts' => - 1,
466
-		) ) );
467
-
468
-		return count( $posts );
469
-	}
470
-
471
-	/**
472
-	 * Add the entity filtering criterias to the arguments for a `get_posts`
473
-	 * call.
474
-	 *
475
-	 * @since 3.15.0
476
-	 *
477
-	 * @param array $args The arguments for a `get_posts` call.
478
-	 *
479
-	 * @return array The arguments for a `get_posts` call.
480
-	 */
481
-	public static function add_criterias( $args ) {
482
-
483
-		return $args + array(
484
-				'post_type' => Wordlift_Entity_Service::valid_entity_post_types(),
485
-				'tax_query' => array(
486
-					array(
487
-						'taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME,
488
-						'terms'    => self::get_entity_terms(),
489
-					),
490
-				),
491
-			);
492
-	}
493
-
494
-	/**
495
-	 * Get the entity terms IDs which represent an entity.
496
-	 *
497
-	 * @since 3.15.0
498
-	 *
499
-	 * @return array An array of terms' ids.
500
-	 */
501
-	public static function get_entity_terms() {
502
-
503
-		$terms = get_terms( Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
504
-			'hide_empty' => false,
505
-			// Because of #334 (and the AAM plugin) we changed fields from 'id=>slug' to 'all'.
506
-			// An issue has been opened with the AAM plugin author as well.
507
-			//
508
-			// see https://github.com/insideout10/wordlift-plugin/issues/334
509
-			// see https://wordpress.org/support/topic/idslug-not-working-anymore?replies=1#post-8806863
510
-			'fields'     => 'all',
511
-		) );
512
-
513
-		return array_map( function ( $term ) {
514
-			return $term->term_id;
515
-		}, array_filter( $terms, function ( $term ) {
516
-			return 'article' !== $term->slug;
517
-		} ) );
518
-	}
519
-
520
-	/**
521
-	 * Create a new entity.
522
-	 *
523
-	 * @since 3.9.0
524
-	 *
525
-	 * @param string $name     The entity name.
526
-	 * @param string $type_uri The entity's type URI.
527
-	 * @param null   $logo     The entity logo id (or NULL if none).
528
-	 * @param string $status   The post status, by default 'publish'.
529
-	 *
530
-	 * @return int|WP_Error The entity post id or a {@link WP_Error} in case the `wp_insert_post` call fails.
531
-	 */
532
-	public function create( $name, $type_uri, $logo = null, $status = 'publish' ) {
533
-
534
-		// Create an entity for the publisher.
535
-		$post_id = wp_insert_post( array(
536
-			'post_type'    => self::TYPE_NAME,
537
-			'post_title'   => $name,
538
-			'post_status'  => $status,
539
-			'post_content' => '',
540
-		) );
541
-
542
-		// Return the error if any.
543
-		if ( is_wp_error( $post_id ) ) {
544
-			return $post_id;
545
-		}
546
-
547
-		// Set the entity logo.
548
-		if ( $logo && is_numeric( $logo ) ) {
549
-			set_post_thumbnail( $post_id, $logo );
550
-		}
551
-
552
-		// Set the entity type.
553
-		Wordlift_Entity_Type_Service::get_instance()->set( $post_id, $type_uri );
554
-
555
-		return $post_id;
556
-	}
557
-
558
-	/**
559
-	 * Get the entities related to the one with the specified id. By default only
560
-	 * published entities will be returned.
561
-	 *
562
-	 * @since 3.10.0
563
-	 *
564
-	 * @param int    $id          The post id.
565
-	 * @param string $post_status The target post status (default = publish).
566
-	 *
567
-	 * @return array An array of post ids.
568
-	 */
569
-	public function get_related_entities( $id, $post_status = 'publish' ) {
570
-
571
-		return $this->relation_service->get_objects( $id, 'ids', null, $post_status );
63
+    /**
64
+     * A singleton instance of the Entity service.
65
+     *
66
+     * @since  3.2.0
67
+     * @access private
68
+     * @var \Wordlift_Entity_Service $instance A singleton instance of the Entity service.
69
+     */
70
+    private static $instance;
71
+
72
+    /**
73
+     * Create a Wordlift_Entity_Service instance.
74
+     *
75
+     * @since 3.2.0
76
+     *
77
+     * @param \Wordlift_UI_Service       $ui_service       The UI service.
78
+     * @param \Wordlift_Relation_Service $relation_service The {@link Wordlift_Relation_Service} instance.
79
+     */
80
+    public function __construct( $ui_service, $relation_service ) {
81
+
82
+        $this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
83
+
84
+        $this->ui_service       = $ui_service;
85
+        $this->relation_service = $relation_service;
86
+
87
+        // Set the singleton instance.
88
+        self::$instance = $this;
89
+    }
90
+
91
+    /**
92
+     * Get the singleton instance of the Entity service.
93
+     *
94
+     * @since 3.2.0
95
+     * @return \Wordlift_Entity_Service The singleton instance of the Entity service.
96
+     */
97
+    public static function get_instance() {
98
+
99
+        return self::$instance;
100
+    }
101
+
102
+    /**
103
+     * Determines whether a post is an entity or not. Entity is in this context
104
+     * something which is not an article.
105
+     *
106
+     * @since 3.1.0
107
+     *
108
+     * @param int $post_id A post id.
109
+     *
110
+     * @return bool Return true if the post is an entity otherwise false.
111
+     */
112
+    public function is_entity( $post_id ) {
113
+
114
+        $terms = wp_get_object_terms( $post_id, Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME );
115
+
116
+        if ( 0 === count( $terms ) ) {
117
+            return false;
118
+        }
119
+
120
+        // We don't consider an `article` to be an entity.
121
+        if ( 'article' !== $terms[0]->slug ) {
122
+            return true;
123
+        }
124
+
125
+        return false;
126
+    }
127
+
128
+    /**
129
+     * Get the proper classification scope for a given entity post
130
+     *
131
+     * @since 3.5.0
132
+     *
133
+     * @param integer $post_id An entity post id.
134
+     *
135
+     * @param string  $default The default classification scope, `what` if not
136
+     *                         provided.
137
+     *
138
+     * @return string Returns a classification scope (e.g. 'what').
139
+     */
140
+    public function get_classification_scope_for( $post_id, $default = WL_WHAT_RELATION ) {
141
+
142
+        if ( false === $this->is_entity( $post_id ) ) {
143
+            return $default;
144
+        }
145
+
146
+        // Retrieve the entity type
147
+        $entity_type_arr = Wordlift_Entity_Type_Service::get_instance()->get( $post_id );
148
+        $entity_type     = str_replace( 'wl-', '', $entity_type_arr['css_class'] );
149
+        // Retrieve classification boxes configuration
150
+        $classification_boxes = unserialize( WL_CORE_POST_CLASSIFICATION_BOXES );
151
+        foreach ( $classification_boxes as $cb ) {
152
+            if ( in_array( $entity_type, $cb['registeredTypes'] ) ) {
153
+                return $cb['id'];
154
+            }
155
+        }
156
+
157
+        return $default;
158
+    }
159
+
160
+
161
+    public function is_used( $post_id ) {
162
+
163
+        if ( false === $this->is_entity( $post_id ) ) {
164
+            return null;
165
+        }
166
+        // Retrieve the post
167
+        $entity = get_post( $post_id );
168
+
169
+        global $wpdb;
170
+        // Retrieve Wordlift relation instances table name
171
+        $table_name = wl_core_get_relation_instances_table_name();
172
+
173
+        // Check is it's referenced / related to another post / entity
174
+        $stmt = $wpdb->prepare(
175
+            "SELECT COUNT(*) FROM $table_name WHERE  object_id = %d",
176
+            $entity->ID
177
+        );
178
+
179
+        // Perform the query
180
+        $relation_instances = (int) $wpdb->get_var( $stmt );
181
+        // If there is at least one relation instance for the current entity, then it's used
182
+        if ( 0 < $relation_instances ) {
183
+            return true;
184
+        }
185
+
186
+        // Check if the entity uri is used as meta_value
187
+        $stmt = $wpdb->prepare(
188
+            "SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id != %d AND meta_value = %s",
189
+            $entity->ID,
190
+            wl_get_entity_uri( $entity->ID )
191
+        );
192
+        // Perform the query
193
+        $meta_instances = (int) $wpdb->get_var( $stmt );
194
+
195
+        // If there is at least one meta that refers the current entity uri, then current entity is used
196
+        if ( 0 < $meta_instances ) {
197
+            return true;
198
+        }
199
+
200
+        // If we are here, it means the current entity is not used at the moment
201
+        return false;
202
+    }
203
+
204
+    /**
205
+     * Determines whether a given uri is an internal uri or not.
206
+     *
207
+     * @since 3.3.2
208
+     *
209
+     * @param int $uri An uri.
210
+     *
211
+     * @return true if the uri internal to the current dataset otherwise false.
212
+     */
213
+    public function is_internal_uri( $uri ) {
214
+
215
+        return ( 0 === strrpos( $uri, wl_configuration_get_redlink_dataset_uri() ) );
216
+    }
217
+
218
+    /**
219
+     * Find entity posts by the entity URI. Entity as searched by their entity URI or same as.
220
+     *
221
+     * @since 3.2.0
222
+     *
223
+     * @param string $uri The entity URI.
224
+     *
225
+     * @return WP_Post|null A WP_Post instance or null if not found.
226
+     */
227
+    public function get_entity_post_by_uri( $uri ) {
228
+
229
+        // Check if we've been provided with a value otherwise return null.
230
+        if ( empty( $uri ) ) {
231
+            return null;
232
+        }
233
+
234
+        $query_args = array(
235
+            'posts_per_page' => 1,
236
+            'post_status'    => 'any',
237
+            'post_type'      => Wordlift_Entity_Service::valid_entity_post_types(),
238
+            'meta_query'     => array(
239
+                array(
240
+                    'key'     => WL_ENTITY_URL_META_NAME,
241
+                    'value'   => $uri,
242
+                    'compare' => '=',
243
+                ),
244
+            ),
245
+            $tax_query = array(
246
+                array(
247
+                    'taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME,
248
+                    'field'    => 'slug',
249
+                    'terms'    => 'article',
250
+                    'operator' => 'NOT IN',
251
+                ),
252
+            ),
253
+        );
254
+
255
+        // Only if the current uri is not an internal uri, entity search is
256
+        // performed also looking at sameAs values.
257
+        //
258
+        // This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237
259
+        if ( ! $this->is_internal_uri( $uri ) ) {
260
+
261
+            $query_args['meta_query']['relation'] = 'OR';
262
+            $query_args['meta_query'][]           = array(
263
+                'key'     => Wordlift_Schema_Service::FIELD_SAME_AS,
264
+                'value'   => $uri,
265
+                'compare' => '=',
266
+            );
267
+        }
268
+
269
+        $query = new WP_Query( $query_args );
270
+
271
+        // Get the matching entity posts.
272
+        $posts = $query->get_posts();
273
+
274
+        // Return null if no post is found.
275
+        if ( 0 === count( $posts ) ) {
276
+            return null;
277
+        }
278
+
279
+        // Return the found post.
280
+        return $posts[0];
281
+    }
282
+
283
+    /**
284
+     * Fires once a post has been saved. This function uses the $_REQUEST, therefore
285
+     * we check that the post we're saving is the current post.
286
+     *
287
+     * @see   https://github.com/insideout10/wordlift-plugin/issues/363
288
+     *
289
+     * @since 3.2.0
290
+     *
291
+     * @param int     $post_id Post ID.
292
+     * @param WP_Post $post    Post object.
293
+     * @param bool    $update  Whether this is an existing post being updated or not.
294
+     */
295
+    public function save_post( $post_id, $post, $update ) {
296
+
297
+        // Avoid doing anything if post is autosave or a revision.
298
+        if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) {
299
+            return;
300
+        }
301
+
302
+        // We're setting the alternative label that have been provided via the UI
303
+        // (in fact we're using $_REQUEST), while save_post may be also called
304
+        // programmatically by some other function: we need to check therefore if
305
+        // the $post_id in the save_post call matches the post id set in the request.
306
+        //
307
+        // If this is not the current post being saved or if it's not an entity, return.
308
+        if ( ! isset( $_REQUEST['post_ID'] ) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity( $post_id ) ) {
309
+            return;
310
+        }
311
+
312
+        // Get the alt labels from the request (or empty array).
313
+        $alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
314
+
315
+        // Set the alternative labels.
316
+        $this->set_alternative_labels( $post_id, $alt_labels );
317
+
318
+    }
319
+
320
+    /**
321
+     * Set the alternative labels.
322
+     *
323
+     * @since 3.2.0
324
+     *
325
+     * @param int   $post_id    The post id.
326
+     * @param array $alt_labels An array of labels.
327
+     */
328
+    public function set_alternative_labels( $post_id, $alt_labels ) {
329
+
330
+        // Force $alt_labels to be an array
331
+        if ( ! is_array( $alt_labels ) ) {
332
+            $alt_labels = array( $alt_labels );
333
+        }
334
+
335
+        $this->log->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
336
+
337
+        // Delete all the existing alternate labels.
338
+        delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
339
+
340
+        // Set the alternative labels.
341
+        foreach ( $alt_labels as $alt_label ) {
342
+            if ( ! empty( $alt_label ) ) {
343
+                add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
344
+            }
345
+        }
346
+
347
+    }
348
+
349
+    /**
350
+     * Retrieve the alternate labels.
351
+     *
352
+     * @since 3.2.0
353
+     *
354
+     * @param int $post_id Post id.
355
+     *
356
+     * @return mixed An array  of alternative labels.
357
+     */
358
+    public function get_alternative_labels( $post_id ) {
359
+
360
+        return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
361
+    }
362
+
363
+    /**
364
+     * Retrieve the labels for an entity, i.e. the title + the synonyms.
365
+     *
366
+     * @since 3.12.0
367
+     *
368
+     * @param int $post_id The entity {@link WP_Post} id.
369
+     *
370
+     * @return array An array with the entity title and labels.
371
+     */
372
+    public function get_labels( $post_id ) {
373
+
374
+        return array_merge( (array) get_the_title( $post_id ), $this->get_alternative_labels( $post_id ) );
375
+    }
376
+
377
+    /**
378
+     * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
379
+     *
380
+     * @since 3.2.0
381
+     *
382
+     * @param WP_Post $post Post object.
383
+     */
384
+    public function edit_form_before_permalink( $post ) {
385
+
386
+        // If it's not an entity, return.
387
+        if ( ! $this->is_entity( $post->ID ) ) {
388
+            return;
389
+        }
390
+
391
+        // Print the input template.
392
+        $this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
393
+
394
+        // Print all the currently set alternative labels.
395
+        foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
396
+
397
+            echo $this->get_alternative_label_input( $alt_label );
398
+
399
+        };
400
+
401
+        // Print the button.
402
+        $this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
403
+
404
+    }
405
+
406
+    /**
407
+     * Get the URI for the entity with the specified post id.
408
+     *
409
+     * @since 3.6.0
410
+     *
411
+     * @param int $post_id The entity post id.
412
+     *
413
+     * @return null|string The entity URI or NULL if not found or the dataset URI is not configured.
414
+     */
415
+    public function get_uri( $post_id ) {
416
+
417
+        // If a null is given, nothing to do
418
+        if ( null == $post_id ) {
419
+            return null;
420
+        }
421
+
422
+        $uri = get_post_meta( $post_id, WL_ENTITY_URL_META_NAME, true );
423
+
424
+        // If the dataset uri is not properly configured, null is returned
425
+        if ( '' === wl_configuration_get_redlink_dataset_uri() ) {
426
+            return null;
427
+        }
428
+
429
+        // Set the URI if it isn't set yet.
430
+        $post_status = get_post_status( $post_id );
431
+        if ( empty( $uri ) && 'auto-draft' !== $post_status && 'revision' !== $post_status ) {
432
+            $uri = wl_build_entity_uri( $post_id );
433
+            wl_set_entity_uri( $post_id, $uri );
434
+        }
435
+
436
+        return $uri;
437
+    }
438
+
439
+
440
+    /**
441
+     * Get the alternative label input HTML code.
442
+     *
443
+     * @since 3.2.0
444
+     *
445
+     * @param string $value The input value.
446
+     *
447
+     * @return string The input HTML code.
448
+     */
449
+    private function get_alternative_label_input( $value = '' ) {
450
+
451
+        return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
452
+    }
453
+
454
+    /**
455
+     * Get the number of entity posts published in this blog.
456
+     *
457
+     * @since 3.6.0
458
+     *
459
+     * @return int The number of published entity posts.
460
+     */
461
+    public function count() {
462
+
463
+        $posts = get_posts( $this->add_criterias( array(
464
+            'post_status' => 'any',
465
+            'numberposts' => - 1,
466
+        ) ) );
467
+
468
+        return count( $posts );
469
+    }
470
+
471
+    /**
472
+     * Add the entity filtering criterias to the arguments for a `get_posts`
473
+     * call.
474
+     *
475
+     * @since 3.15.0
476
+     *
477
+     * @param array $args The arguments for a `get_posts` call.
478
+     *
479
+     * @return array The arguments for a `get_posts` call.
480
+     */
481
+    public static function add_criterias( $args ) {
482
+
483
+        return $args + array(
484
+                'post_type' => Wordlift_Entity_Service::valid_entity_post_types(),
485
+                'tax_query' => array(
486
+                    array(
487
+                        'taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME,
488
+                        'terms'    => self::get_entity_terms(),
489
+                    ),
490
+                ),
491
+            );
492
+    }
493
+
494
+    /**
495
+     * Get the entity terms IDs which represent an entity.
496
+     *
497
+     * @since 3.15.0
498
+     *
499
+     * @return array An array of terms' ids.
500
+     */
501
+    public static function get_entity_terms() {
502
+
503
+        $terms = get_terms( Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
504
+            'hide_empty' => false,
505
+            // Because of #334 (and the AAM plugin) we changed fields from 'id=>slug' to 'all'.
506
+            // An issue has been opened with the AAM plugin author as well.
507
+            //
508
+            // see https://github.com/insideout10/wordlift-plugin/issues/334
509
+            // see https://wordpress.org/support/topic/idslug-not-working-anymore?replies=1#post-8806863
510
+            'fields'     => 'all',
511
+        ) );
512
+
513
+        return array_map( function ( $term ) {
514
+            return $term->term_id;
515
+        }, array_filter( $terms, function ( $term ) {
516
+            return 'article' !== $term->slug;
517
+        } ) );
518
+    }
519
+
520
+    /**
521
+     * Create a new entity.
522
+     *
523
+     * @since 3.9.0
524
+     *
525
+     * @param string $name     The entity name.
526
+     * @param string $type_uri The entity's type URI.
527
+     * @param null   $logo     The entity logo id (or NULL if none).
528
+     * @param string $status   The post status, by default 'publish'.
529
+     *
530
+     * @return int|WP_Error The entity post id or a {@link WP_Error} in case the `wp_insert_post` call fails.
531
+     */
532
+    public function create( $name, $type_uri, $logo = null, $status = 'publish' ) {
533
+
534
+        // Create an entity for the publisher.
535
+        $post_id = wp_insert_post( array(
536
+            'post_type'    => self::TYPE_NAME,
537
+            'post_title'   => $name,
538
+            'post_status'  => $status,
539
+            'post_content' => '',
540
+        ) );
541
+
542
+        // Return the error if any.
543
+        if ( is_wp_error( $post_id ) ) {
544
+            return $post_id;
545
+        }
546
+
547
+        // Set the entity logo.
548
+        if ( $logo && is_numeric( $logo ) ) {
549
+            set_post_thumbnail( $post_id, $logo );
550
+        }
551
+
552
+        // Set the entity type.
553
+        Wordlift_Entity_Type_Service::get_instance()->set( $post_id, $type_uri );
554
+
555
+        return $post_id;
556
+    }
557
+
558
+    /**
559
+     * Get the entities related to the one with the specified id. By default only
560
+     * published entities will be returned.
561
+     *
562
+     * @since 3.10.0
563
+     *
564
+     * @param int    $id          The post id.
565
+     * @param string $post_status The target post status (default = publish).
566
+     *
567
+     * @return array An array of post ids.
568
+     */
569
+    public function get_related_entities( $id, $post_status = 'publish' ) {
570
+
571
+        return $this->relation_service->get_objects( $id, 'ids', null, $post_status );
572 572
 //		return wl_core_inner_get_related_entities( 'post_ids', $id, null, $post_status );
573
-	}
574
-
575
-	/**
576
-	 * Get the list of entities.
577
-	 *
578
-	 * @since 3.12.2
579
-	 *
580
-	 * @param array $params Custom parameters for WordPress' own {@link get_posts} function.
581
-	 *
582
-	 * @return array An array of entity posts.
583
-	 */
584
-	public function get( $params = array() ) {
585
-
586
-		// Set the defaults.
587
-		$defaults = array( 'post_type' => 'entity' );
588
-
589
-		// Merge the defaults with the provided parameters.
590
-		$args = wp_parse_args( $params, $defaults );
591
-
592
-		// Call the `get_posts` function.
593
-		return get_posts( $args );
594
-	}
595
-
596
-	/**
597
-	 * The list of post type names which can be used for entities
598
-	 *
599
-	 * Criteria is that the post type is public. The list of valid post types
600
-	 * can be overridden with a filter.
601
-	 *
602
-	 * @since 3.15.0
603
-	 *
604
-	 * @return array Array containing the names of the valid post types.
605
-	 */
606
-	static function valid_entity_post_types() {
607
-
608
-		// Ignore builtins in the call to avoid getting attachments.
609
-		$post_types = array( 'post', 'page', self::TYPE_NAME );
610
-
611
-		return apply_filters( 'wl_valid_entity_post_types', $post_types );
612
-	}
573
+    }
574
+
575
+    /**
576
+     * Get the list of entities.
577
+     *
578
+     * @since 3.12.2
579
+     *
580
+     * @param array $params Custom parameters for WordPress' own {@link get_posts} function.
581
+     *
582
+     * @return array An array of entity posts.
583
+     */
584
+    public function get( $params = array() ) {
585
+
586
+        // Set the defaults.
587
+        $defaults = array( 'post_type' => 'entity' );
588
+
589
+        // Merge the defaults with the provided parameters.
590
+        $args = wp_parse_args( $params, $defaults );
591
+
592
+        // Call the `get_posts` function.
593
+        return get_posts( $args );
594
+    }
595
+
596
+    /**
597
+     * The list of post type names which can be used for entities
598
+     *
599
+     * Criteria is that the post type is public. The list of valid post types
600
+     * can be overridden with a filter.
601
+     *
602
+     * @since 3.15.0
603
+     *
604
+     * @return array Array containing the names of the valid post types.
605
+     */
606
+    static function valid_entity_post_types() {
607
+
608
+        // Ignore builtins in the call to avoid getting attachments.
609
+        $post_types = array( 'post', 'page', self::TYPE_NAME );
610
+
611
+        return apply_filters( 'wl_valid_entity_post_types', $post_types );
612
+    }
613 613
 
614 614
 }
Please login to merge, or discard this patch.
Spacing   +86 added lines, -86 removed lines patch added patch discarded remove patch
@@ -77,9 +77,9 @@  discard block
 block discarded – undo
77 77
 	 * @param \Wordlift_UI_Service       $ui_service       The UI service.
78 78
 	 * @param \Wordlift_Relation_Service $relation_service The {@link Wordlift_Relation_Service} instance.
79 79
 	 */
80
-	public function __construct( $ui_service, $relation_service ) {
80
+	public function __construct($ui_service, $relation_service) {
81 81
 
82
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
82
+		$this->log = Wordlift_Log_Service::get_logger('Wordlift_Entity_Service');
83 83
 
84 84
 		$this->ui_service       = $ui_service;
85 85
 		$this->relation_service = $relation_service;
@@ -109,16 +109,16 @@  discard block
 block discarded – undo
109 109
 	 *
110 110
 	 * @return bool Return true if the post is an entity otherwise false.
111 111
 	 */
112
-	public function is_entity( $post_id ) {
112
+	public function is_entity($post_id) {
113 113
 
114
-		$terms = wp_get_object_terms( $post_id, Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME );
114
+		$terms = wp_get_object_terms($post_id, Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME);
115 115
 
116
-		if ( 0 === count( $terms ) ) {
116
+		if (0 === count($terms)) {
117 117
 			return false;
118 118
 		}
119 119
 
120 120
 		// We don't consider an `article` to be an entity.
121
-		if ( 'article' !== $terms[0]->slug ) {
121
+		if ('article' !== $terms[0]->slug) {
122 122
 			return true;
123 123
 		}
124 124
 
@@ -137,19 +137,19 @@  discard block
 block discarded – undo
137 137
 	 *
138 138
 	 * @return string Returns a classification scope (e.g. 'what').
139 139
 	 */
140
-	public function get_classification_scope_for( $post_id, $default = WL_WHAT_RELATION ) {
140
+	public function get_classification_scope_for($post_id, $default = WL_WHAT_RELATION) {
141 141
 
142
-		if ( false === $this->is_entity( $post_id ) ) {
142
+		if (false === $this->is_entity($post_id)) {
143 143
 			return $default;
144 144
 		}
145 145
 
146 146
 		// Retrieve the entity type
147
-		$entity_type_arr = Wordlift_Entity_Type_Service::get_instance()->get( $post_id );
148
-		$entity_type     = str_replace( 'wl-', '', $entity_type_arr['css_class'] );
147
+		$entity_type_arr = Wordlift_Entity_Type_Service::get_instance()->get($post_id);
148
+		$entity_type     = str_replace('wl-', '', $entity_type_arr['css_class']);
149 149
 		// Retrieve classification boxes configuration
150
-		$classification_boxes = unserialize( WL_CORE_POST_CLASSIFICATION_BOXES );
151
-		foreach ( $classification_boxes as $cb ) {
152
-			if ( in_array( $entity_type, $cb['registeredTypes'] ) ) {
150
+		$classification_boxes = unserialize(WL_CORE_POST_CLASSIFICATION_BOXES);
151
+		foreach ($classification_boxes as $cb) {
152
+			if (in_array($entity_type, $cb['registeredTypes'])) {
153 153
 				return $cb['id'];
154 154
 			}
155 155
 		}
@@ -158,13 +158,13 @@  discard block
 block discarded – undo
158 158
 	}
159 159
 
160 160
 
161
-	public function is_used( $post_id ) {
161
+	public function is_used($post_id) {
162 162
 
163
-		if ( false === $this->is_entity( $post_id ) ) {
163
+		if (false === $this->is_entity($post_id)) {
164 164
 			return null;
165 165
 		}
166 166
 		// Retrieve the post
167
-		$entity = get_post( $post_id );
167
+		$entity = get_post($post_id);
168 168
 
169 169
 		global $wpdb;
170 170
 		// Retrieve Wordlift relation instances table name
@@ -177,9 +177,9 @@  discard block
 block discarded – undo
177 177
 		);
178 178
 
179 179
 		// Perform the query
180
-		$relation_instances = (int) $wpdb->get_var( $stmt );
180
+		$relation_instances = (int) $wpdb->get_var($stmt);
181 181
 		// If there is at least one relation instance for the current entity, then it's used
182
-		if ( 0 < $relation_instances ) {
182
+		if (0 < $relation_instances) {
183 183
 			return true;
184 184
 		}
185 185
 
@@ -187,13 +187,13 @@  discard block
 block discarded – undo
187 187
 		$stmt = $wpdb->prepare(
188 188
 			"SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id != %d AND meta_value = %s",
189 189
 			$entity->ID,
190
-			wl_get_entity_uri( $entity->ID )
190
+			wl_get_entity_uri($entity->ID)
191 191
 		);
192 192
 		// Perform the query
193
-		$meta_instances = (int) $wpdb->get_var( $stmt );
193
+		$meta_instances = (int) $wpdb->get_var($stmt);
194 194
 
195 195
 		// If there is at least one meta that refers the current entity uri, then current entity is used
196
-		if ( 0 < $meta_instances ) {
196
+		if (0 < $meta_instances) {
197 197
 			return true;
198 198
 		}
199 199
 
@@ -210,9 +210,9 @@  discard block
 block discarded – undo
210 210
 	 *
211 211
 	 * @return true if the uri internal to the current dataset otherwise false.
212 212
 	 */
213
-	public function is_internal_uri( $uri ) {
213
+	public function is_internal_uri($uri) {
214 214
 
215
-		return ( 0 === strrpos( $uri, wl_configuration_get_redlink_dataset_uri() ) );
215
+		return (0 === strrpos($uri, wl_configuration_get_redlink_dataset_uri()));
216 216
 	}
217 217
 
218 218
 	/**
@@ -224,10 +224,10 @@  discard block
 block discarded – undo
224 224
 	 *
225 225
 	 * @return WP_Post|null A WP_Post instance or null if not found.
226 226
 	 */
227
-	public function get_entity_post_by_uri( $uri ) {
227
+	public function get_entity_post_by_uri($uri) {
228 228
 
229 229
 		// Check if we've been provided with a value otherwise return null.
230
-		if ( empty( $uri ) ) {
230
+		if (empty($uri)) {
231 231
 			return null;
232 232
 		}
233 233
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 		// performed also looking at sameAs values.
257 257
 		//
258 258
 		// This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237
259
-		if ( ! $this->is_internal_uri( $uri ) ) {
259
+		if ( ! $this->is_internal_uri($uri)) {
260 260
 
261 261
 			$query_args['meta_query']['relation'] = 'OR';
262 262
 			$query_args['meta_query'][]           = array(
@@ -266,13 +266,13 @@  discard block
 block discarded – undo
266 266
 			);
267 267
 		}
268 268
 
269
-		$query = new WP_Query( $query_args );
269
+		$query = new WP_Query($query_args);
270 270
 
271 271
 		// Get the matching entity posts.
272 272
 		$posts = $query->get_posts();
273 273
 
274 274
 		// Return null if no post is found.
275
-		if ( 0 === count( $posts ) ) {
275
+		if (0 === count($posts)) {
276 276
 			return null;
277 277
 		}
278 278
 
@@ -292,10 +292,10 @@  discard block
 block discarded – undo
292 292
 	 * @param WP_Post $post    Post object.
293 293
 	 * @param bool    $update  Whether this is an existing post being updated or not.
294 294
 	 */
295
-	public function save_post( $post_id, $post, $update ) {
295
+	public function save_post($post_id, $post, $update) {
296 296
 
297 297
 		// Avoid doing anything if post is autosave or a revision.
298
-		if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) {
298
+		if (wp_is_post_autosave($post) || wp_is_post_revision($post)) {
299 299
 			return;
300 300
 		}
301 301
 
@@ -305,15 +305,15 @@  discard block
 block discarded – undo
305 305
 		// the $post_id in the save_post call matches the post id set in the request.
306 306
 		//
307 307
 		// If this is not the current post being saved or if it's not an entity, return.
308
-		if ( ! isset( $_REQUEST['post_ID'] ) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity( $post_id ) ) {
308
+		if ( ! isset($_REQUEST['post_ID']) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity($post_id)) {
309 309
 			return;
310 310
 		}
311 311
 
312 312
 		// Get the alt labels from the request (or empty array).
313
-		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
313
+		$alt_labels = isset($_REQUEST['wl_alternative_label']) ? $_REQUEST['wl_alternative_label'] : array();
314 314
 
315 315
 		// Set the alternative labels.
316
-		$this->set_alternative_labels( $post_id, $alt_labels );
316
+		$this->set_alternative_labels($post_id, $alt_labels);
317 317
 
318 318
 	}
319 319
 
@@ -325,22 +325,22 @@  discard block
 block discarded – undo
325 325
 	 * @param int   $post_id    The post id.
326 326
 	 * @param array $alt_labels An array of labels.
327 327
 	 */
328
-	public function set_alternative_labels( $post_id, $alt_labels ) {
328
+	public function set_alternative_labels($post_id, $alt_labels) {
329 329
 
330 330
 		// Force $alt_labels to be an array
331
-		if ( ! is_array( $alt_labels ) ) {
332
-			$alt_labels = array( $alt_labels );
331
+		if ( ! is_array($alt_labels)) {
332
+			$alt_labels = array($alt_labels);
333 333
 		}
334 334
 
335
-		$this->log->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
335
+		$this->log->debug("Setting alternative labels [ post id :: $post_id ][ alt labels :: ".implode(',', $alt_labels)." ]");
336 336
 
337 337
 		// Delete all the existing alternate labels.
338
-		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
338
+		delete_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY);
339 339
 
340 340
 		// Set the alternative labels.
341
-		foreach ( $alt_labels as $alt_label ) {
342
-			if ( ! empty( $alt_label ) ) {
343
-				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
341
+		foreach ($alt_labels as $alt_label) {
342
+			if ( ! empty($alt_label)) {
343
+				add_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label);
344 344
 			}
345 345
 		}
346 346
 
@@ -355,9 +355,9 @@  discard block
 block discarded – undo
355 355
 	 *
356 356
 	 * @return mixed An array  of alternative labels.
357 357
 	 */
358
-	public function get_alternative_labels( $post_id ) {
358
+	public function get_alternative_labels($post_id) {
359 359
 
360
-		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
360
+		return get_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY);
361 361
 	}
362 362
 
363 363
 	/**
@@ -369,9 +369,9 @@  discard block
 block discarded – undo
369 369
 	 *
370 370
 	 * @return array An array with the entity title and labels.
371 371
 	 */
372
-	public function get_labels( $post_id ) {
372
+	public function get_labels($post_id) {
373 373
 
374
-		return array_merge( (array) get_the_title( $post_id ), $this->get_alternative_labels( $post_id ) );
374
+		return array_merge((array) get_the_title($post_id), $this->get_alternative_labels($post_id));
375 375
 	}
376 376
 
377 377
 	/**
@@ -381,25 +381,25 @@  discard block
 block discarded – undo
381 381
 	 *
382 382
 	 * @param WP_Post $post Post object.
383 383
 	 */
384
-	public function edit_form_before_permalink( $post ) {
384
+	public function edit_form_before_permalink($post) {
385 385
 
386 386
 		// If it's not an entity, return.
387
-		if ( ! $this->is_entity( $post->ID ) ) {
387
+		if ( ! $this->is_entity($post->ID)) {
388 388
 			return;
389 389
 		}
390 390
 
391 391
 		// Print the input template.
392
-		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
392
+		$this->ui_service->print_template('wl-tmpl-alternative-label-input', $this->get_alternative_label_input());
393 393
 
394 394
 		// Print all the currently set alternative labels.
395
-		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
395
+		foreach ($this->get_alternative_labels($post->ID) as $alt_label) {
396 396
 
397
-			echo $this->get_alternative_label_input( $alt_label );
397
+			echo $this->get_alternative_label_input($alt_label);
398 398
 
399 399
 		};
400 400
 
401 401
 		// Print the button.
402
-		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
402
+		$this->ui_service->print_button('wl-add-alternative-labels-button', __('Add more titles', 'wordlift'));
403 403
 
404 404
 	}
405 405
 
@@ -412,25 +412,25 @@  discard block
 block discarded – undo
412 412
 	 *
413 413
 	 * @return null|string The entity URI or NULL if not found or the dataset URI is not configured.
414 414
 	 */
415
-	public function get_uri( $post_id ) {
415
+	public function get_uri($post_id) {
416 416
 
417 417
 		// If a null is given, nothing to do
418
-		if ( null == $post_id ) {
418
+		if (null == $post_id) {
419 419
 			return null;
420 420
 		}
421 421
 
422
-		$uri = get_post_meta( $post_id, WL_ENTITY_URL_META_NAME, true );
422
+		$uri = get_post_meta($post_id, WL_ENTITY_URL_META_NAME, true);
423 423
 
424 424
 		// If the dataset uri is not properly configured, null is returned
425
-		if ( '' === wl_configuration_get_redlink_dataset_uri() ) {
425
+		if ('' === wl_configuration_get_redlink_dataset_uri()) {
426 426
 			return null;
427 427
 		}
428 428
 
429 429
 		// Set the URI if it isn't set yet.
430
-		$post_status = get_post_status( $post_id );
431
-		if ( empty( $uri ) && 'auto-draft' !== $post_status && 'revision' !== $post_status ) {
432
-			$uri = wl_build_entity_uri( $post_id );
433
-			wl_set_entity_uri( $post_id, $uri );
430
+		$post_status = get_post_status($post_id);
431
+		if (empty($uri) && 'auto-draft' !== $post_status && 'revision' !== $post_status) {
432
+			$uri = wl_build_entity_uri($post_id);
433
+			wl_set_entity_uri($post_id, $uri);
434 434
 		}
435 435
 
436 436
 		return $uri;
@@ -446,9 +446,9 @@  discard block
 block discarded – undo
446 446
 	 *
447 447
 	 * @return string The input HTML code.
448 448
 	 */
449
-	private function get_alternative_label_input( $value = '' ) {
449
+	private function get_alternative_label_input($value = '') {
450 450
 
451
-		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
451
+		return sprintf(self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr($value), __('Delete', 'wordlift'));
452 452
 	}
453 453
 
454 454
 	/**
@@ -460,12 +460,12 @@  discard block
 block discarded – undo
460 460
 	 */
461 461
 	public function count() {
462 462
 
463
-		$posts = get_posts( $this->add_criterias( array(
463
+		$posts = get_posts($this->add_criterias(array(
464 464
 			'post_status' => 'any',
465
-			'numberposts' => - 1,
466
-		) ) );
465
+			'numberposts' => -1,
466
+		)));
467 467
 
468
-		return count( $posts );
468
+		return count($posts);
469 469
 	}
470 470
 
471 471
 	/**
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
 	 *
479 479
 	 * @return array The arguments for a `get_posts` call.
480 480
 	 */
481
-	public static function add_criterias( $args ) {
481
+	public static function add_criterias($args) {
482 482
 
483 483
 		return $args + array(
484 484
 				'post_type' => Wordlift_Entity_Service::valid_entity_post_types(),
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
 	 */
501 501
 	public static function get_entity_terms() {
502 502
 
503
-		$terms = get_terms( Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
503
+		$terms = get_terms(Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, array(
504 504
 			'hide_empty' => false,
505 505
 			// Because of #334 (and the AAM plugin) we changed fields from 'id=>slug' to 'all'.
506 506
 			// An issue has been opened with the AAM plugin author as well.
@@ -508,13 +508,13 @@  discard block
 block discarded – undo
508 508
 			// see https://github.com/insideout10/wordlift-plugin/issues/334
509 509
 			// see https://wordpress.org/support/topic/idslug-not-working-anymore?replies=1#post-8806863
510 510
 			'fields'     => 'all',
511
-		) );
511
+		));
512 512
 
513
-		return array_map( function ( $term ) {
513
+		return array_map(function($term) {
514 514
 			return $term->term_id;
515
-		}, array_filter( $terms, function ( $term ) {
515
+		}, array_filter($terms, function($term) {
516 516
 			return 'article' !== $term->slug;
517
-		} ) );
517
+		} ));
518 518
 	}
519 519
 
520 520
 	/**
@@ -529,28 +529,28 @@  discard block
 block discarded – undo
529 529
 	 *
530 530
 	 * @return int|WP_Error The entity post id or a {@link WP_Error} in case the `wp_insert_post` call fails.
531 531
 	 */
532
-	public function create( $name, $type_uri, $logo = null, $status = 'publish' ) {
532
+	public function create($name, $type_uri, $logo = null, $status = 'publish') {
533 533
 
534 534
 		// Create an entity for the publisher.
535
-		$post_id = wp_insert_post( array(
535
+		$post_id = wp_insert_post(array(
536 536
 			'post_type'    => self::TYPE_NAME,
537 537
 			'post_title'   => $name,
538 538
 			'post_status'  => $status,
539 539
 			'post_content' => '',
540
-		) );
540
+		));
541 541
 
542 542
 		// Return the error if any.
543
-		if ( is_wp_error( $post_id ) ) {
543
+		if (is_wp_error($post_id)) {
544 544
 			return $post_id;
545 545
 		}
546 546
 
547 547
 		// Set the entity logo.
548
-		if ( $logo && is_numeric( $logo ) ) {
549
-			set_post_thumbnail( $post_id, $logo );
548
+		if ($logo && is_numeric($logo)) {
549
+			set_post_thumbnail($post_id, $logo);
550 550
 		}
551 551
 
552 552
 		// Set the entity type.
553
-		Wordlift_Entity_Type_Service::get_instance()->set( $post_id, $type_uri );
553
+		Wordlift_Entity_Type_Service::get_instance()->set($post_id, $type_uri);
554 554
 
555 555
 		return $post_id;
556 556
 	}
@@ -566,9 +566,9 @@  discard block
 block discarded – undo
566 566
 	 *
567 567
 	 * @return array An array of post ids.
568 568
 	 */
569
-	public function get_related_entities( $id, $post_status = 'publish' ) {
569
+	public function get_related_entities($id, $post_status = 'publish') {
570 570
 
571
-		return $this->relation_service->get_objects( $id, 'ids', null, $post_status );
571
+		return $this->relation_service->get_objects($id, 'ids', null, $post_status);
572 572
 //		return wl_core_inner_get_related_entities( 'post_ids', $id, null, $post_status );
573 573
 	}
574 574
 
@@ -581,16 +581,16 @@  discard block
 block discarded – undo
581 581
 	 *
582 582
 	 * @return array An array of entity posts.
583 583
 	 */
584
-	public function get( $params = array() ) {
584
+	public function get($params = array()) {
585 585
 
586 586
 		// Set the defaults.
587
-		$defaults = array( 'post_type' => 'entity' );
587
+		$defaults = array('post_type' => 'entity');
588 588
 
589 589
 		// Merge the defaults with the provided parameters.
590
-		$args = wp_parse_args( $params, $defaults );
590
+		$args = wp_parse_args($params, $defaults);
591 591
 
592 592
 		// Call the `get_posts` function.
593
-		return get_posts( $args );
593
+		return get_posts($args);
594 594
 	}
595 595
 
596 596
 	/**
@@ -606,9 +606,9 @@  discard block
 block discarded – undo
606 606
 	static function valid_entity_post_types() {
607 607
 
608 608
 		// Ignore builtins in the call to avoid getting attachments.
609
-		$post_types = array( 'post', 'page', self::TYPE_NAME );
609
+		$post_types = array('post', 'page', self::TYPE_NAME);
610 610
 
611
-		return apply_filters( 'wl_valid_entity_post_types', $post_types );
611
+		return apply_filters('wl_valid_entity_post_types', $post_types);
612 612
 	}
613 613
 
614 614
 }
Please login to merge, or discard this patch.
src/includes/class-wordlift-schema-service.php 2 patches
Indentation   +1280 added lines, -1280 removed lines patch added patch discarded remove patch
@@ -18,1285 +18,1285 @@
 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_END ),
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
-		// Finally return the predicates array.
1299
-		return $predicates;
1300
-	}
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_END ),
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
+        // Finally return the predicates array.
1299
+        return $predicates;
1300
+    }
1301 1301
 
1302 1302
 }
Please login to merge, or discard this patch.
Spacing   +74 added lines, -74 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_END ),
694
+					$this->storage_factory->post_meta(self::FIELD_DATE_END),
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
 		// Finally return the predicates array.
1299 1299
 		return $predicates;
Please login to merge, or discard this patch.
src/includes/class-wordlift-entity-link-service.php 2 patches
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -26,180 +26,180 @@
 block discarded – undo
26 26
  */
27 27
 class Wordlift_Entity_Link_Service {
28 28
 
29
-	/**
30
-	 * The entity type service.
31
-	 *
32
-	 * @since  3.6.0
33
-	 * @access private
34
-	 * @var Wordlift_Entity_Post_Type_Service $entity_type_service The entity type service.
35
-	 */
36
-	private $entity_type_service;
37
-
38
-	/**
39
-	 * The entity post type slug.
40
-	 *
41
-	 * @since  3.6.0
42
-	 * @access private
43
-	 * @var string $slug The entity post type slug.
44
-	 */
45
-	private $slug;
46
-
47
-	/**
48
-	 * A logger instance.
49
-	 *
50
-	 * @since  3.6.0
51
-	 * @access private
52
-	 * @var Wordlift_Log_Service
53
-	 */
54
-	private $log;
55
-
56
-	/**
57
-	 * Wordlift_Entity_Link_Service constructor.
58
-	 *
59
-	 * @since 3.6.0
60
-	 *
61
-	 * @param Wordlift_Entity_Post_Type_Service $entity_type_service
62
-	 * @param string                            $slug The entity post type slug.
63
-	 */
64
-	public function __construct( $entity_type_service, $slug ) {
65
-
66
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Link_Service' );
67
-
68
-		$this->entity_type_service = $entity_type_service;
69
-		$this->slug                = $slug;
70
-
71
-	}
72
-
73
-	/**
74
-	 * Intercept link generation to posts in order to customize links to entities.
75
-	 *
76
-	 * @since 3.6.0
77
-	 *
78
-	 * @param string  $post_link The post's permalink.
79
-	 * @param WP_Post $post      The post in question.
80
-	 * @param bool    $leavename Whether to keep the post name.
81
-	 * @param bool    $sample    Is it a sample permalink.
82
-	 *
83
-	 * @return string The link to the post.
84
-	 */
85
-	public function post_type_link( $post_link, $post, $leavename, $sample ) {
86
-
87
-		// Return the post link if this is not our post type.
88
-		if ( ! empty( $this->slug ) || $this->entity_type_service->get_post_type() !== get_post_type( $post ) ) {
89
-			return $post_link;
90
-		}
91
-
92
-		// Replace /slug/post_name/ with /post_name/
93
-		// The slug comes from the Entity Type Service since that service is responsible for registering the default
94
-		// slug.
95
-		return str_replace( "/{$this->entity_type_service->get_slug()}/$post->post_name/", "/$post->post_name/", $post_link );
96
-	}
97
-
98
-	/**
99
-	 * Alter the query to look for our own custom type.
100
-	 *
101
-	 * @since 3.6.0
102
-	 *
103
-	 * @param WP_Query $query
104
-	 */
105
-	public function pre_get_posts( $query ) {
106
-
107
-		// If a slug has been set, we don't need to alter the query.
108
-		if ( ! empty( $this->slug ) ) {
109
-			return;
110
-		}
111
-
112
-		// Check if it's a query we should extend with our own custom post type.
113
-		//
114
-		// The `$query->query` count could be > 2 if the preview parameter is passed too.
115
-		//
116
-		// See https://github.com/insideout10/wordlift-plugin/issues/439
117
-		if ( ! $query->is_main_query() || 2 > count( $query->query ) || ! isset( $query->query['page'] ) || empty( $query->query['name'] ) ) {
118
-			return;
119
-		}
120
-
121
-		// Add our own post type to the query.
122
-		$post_types = '' === $query->get( 'post_type' )
123
-			? Wordlift_Entity_Service::valid_entity_post_types()
124
-			: array_merge( (array) $query->get( 'post_type' ), (array) $this->entity_type_service->get_post_type() );
125
-		$query->set( 'post_type', $post_types );
126
-
127
-	}
128
-
129
-	/**
130
-	 * Hook to WordPress' wp_unique_post_slug_is_bad_flat_slug filter. This is called when a page is saved.
131
-	 *
132
-	 * @since 3.6.0
133
-	 *
134
-	 * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
135
-	 * @param string $slug      The post slug.
136
-	 * @param string $post_type Post type.
137
-	 *
138
-	 * @return bool Whether the slug is bad.
139
-	 */
140
-	public function wp_unique_post_slug_is_bad_flat_slug( $bad_slug, $slug, $post_type ) {
141
-
142
-		// The list of post types that might have conflicting slugs.
143
-		$post_types = array(
144
-			'post',
145
-			'page',
146
-			$this->entity_type_service->get_post_type(),
147
-		);
148
-
149
-		// Ignore post types different from the ones we need to check.
150
-		if ( ! in_array( $post_type, $post_types ) ) {
151
-			return $bad_slug;
152
-		}
153
-
154
-		$exists = $this->slug_exists( $slug, array_diff( $post_types, array( $post_type ) ) );
155
-
156
-		$this->log->debug( "Checking if a slug exists [ post type :: $post_type ][ slug :: $slug ][ exists :: " . ( $exists ? "yes" : "no" ) . " ]" );
157
-
158
-		return $exists;
159
-	}
160
-
161
-	/**
162
-	 * Hook to WordPress' wp_unique_post_slug_is_bad_hierarchical_slug filter. This is called when a page is saved.
163
-	 *
164
-	 * @since 3.6.0
165
-	 *
166
-	 * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
167
-	 * @param string $slug      The post slug.
168
-	 * @param string $post_type Post type.
169
-	 * @param int    $post_parent
170
-	 *
171
-	 * @return bool Whether the slug is bad.
172
-	 */
173
-	public function wp_unique_post_slug_is_bad_hierarchical_slug( $bad_slug, $slug, $post_type, $post_parent ) {
174
-
175
-		// We only care about pages here.
176
-		if ( 'page' !== $post_type ) {
177
-			return $bad_slug;
178
-		}
179
-
180
-		// We redirect the call to the flat hook, this means that this check is going to solve also the 6-years old issue
181
-		// about overlapping slugs among pages and posts:
182
-		//  https://core.trac.wordpress.org/ticket/13459
183
-		return $this->wp_unique_post_slug_is_bad_flat_slug( $bad_slug, $slug, $post_type );
184
-	}
185
-
186
-	/**
187
-	 * Check whether a slug exists already for the specified post types.
188
-	 *
189
-	 * @since 3.6.0
190
-	 *
191
-	 * @param string $slug       The slug.
192
-	 * @param array  $post_types An array of post types.
193
-	 *
194
-	 * @return bool True if the slug exists, otherwise false.
195
-	 */
196
-	private function slug_exists( $slug, $post_types ) {
197
-		global $wpdb;
198
-
199
-		// Post slugs must be unique across all posts.
200
-		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ('" . implode( "', '", array_map( 'esc_sql', $post_types ) ) . "') LIMIT 1";
201
-
202
-		return null !== $wpdb->get_var( $wpdb->prepare( $check_sql, $slug ) );
203
-	}
29
+    /**
30
+     * The entity type service.
31
+     *
32
+     * @since  3.6.0
33
+     * @access private
34
+     * @var Wordlift_Entity_Post_Type_Service $entity_type_service The entity type service.
35
+     */
36
+    private $entity_type_service;
37
+
38
+    /**
39
+     * The entity post type slug.
40
+     *
41
+     * @since  3.6.0
42
+     * @access private
43
+     * @var string $slug The entity post type slug.
44
+     */
45
+    private $slug;
46
+
47
+    /**
48
+     * A logger instance.
49
+     *
50
+     * @since  3.6.0
51
+     * @access private
52
+     * @var Wordlift_Log_Service
53
+     */
54
+    private $log;
55
+
56
+    /**
57
+     * Wordlift_Entity_Link_Service constructor.
58
+     *
59
+     * @since 3.6.0
60
+     *
61
+     * @param Wordlift_Entity_Post_Type_Service $entity_type_service
62
+     * @param string                            $slug The entity post type slug.
63
+     */
64
+    public function __construct( $entity_type_service, $slug ) {
65
+
66
+        $this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Link_Service' );
67
+
68
+        $this->entity_type_service = $entity_type_service;
69
+        $this->slug                = $slug;
70
+
71
+    }
72
+
73
+    /**
74
+     * Intercept link generation to posts in order to customize links to entities.
75
+     *
76
+     * @since 3.6.0
77
+     *
78
+     * @param string  $post_link The post's permalink.
79
+     * @param WP_Post $post      The post in question.
80
+     * @param bool    $leavename Whether to keep the post name.
81
+     * @param bool    $sample    Is it a sample permalink.
82
+     *
83
+     * @return string The link to the post.
84
+     */
85
+    public function post_type_link( $post_link, $post, $leavename, $sample ) {
86
+
87
+        // Return the post link if this is not our post type.
88
+        if ( ! empty( $this->slug ) || $this->entity_type_service->get_post_type() !== get_post_type( $post ) ) {
89
+            return $post_link;
90
+        }
91
+
92
+        // Replace /slug/post_name/ with /post_name/
93
+        // The slug comes from the Entity Type Service since that service is responsible for registering the default
94
+        // slug.
95
+        return str_replace( "/{$this->entity_type_service->get_slug()}/$post->post_name/", "/$post->post_name/", $post_link );
96
+    }
97
+
98
+    /**
99
+     * Alter the query to look for our own custom type.
100
+     *
101
+     * @since 3.6.0
102
+     *
103
+     * @param WP_Query $query
104
+     */
105
+    public function pre_get_posts( $query ) {
106
+
107
+        // If a slug has been set, we don't need to alter the query.
108
+        if ( ! empty( $this->slug ) ) {
109
+            return;
110
+        }
111
+
112
+        // Check if it's a query we should extend with our own custom post type.
113
+        //
114
+        // The `$query->query` count could be > 2 if the preview parameter is passed too.
115
+        //
116
+        // See https://github.com/insideout10/wordlift-plugin/issues/439
117
+        if ( ! $query->is_main_query() || 2 > count( $query->query ) || ! isset( $query->query['page'] ) || empty( $query->query['name'] ) ) {
118
+            return;
119
+        }
120
+
121
+        // Add our own post type to the query.
122
+        $post_types = '' === $query->get( 'post_type' )
123
+            ? Wordlift_Entity_Service::valid_entity_post_types()
124
+            : array_merge( (array) $query->get( 'post_type' ), (array) $this->entity_type_service->get_post_type() );
125
+        $query->set( 'post_type', $post_types );
126
+
127
+    }
128
+
129
+    /**
130
+     * Hook to WordPress' wp_unique_post_slug_is_bad_flat_slug filter. This is called when a page is saved.
131
+     *
132
+     * @since 3.6.0
133
+     *
134
+     * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
135
+     * @param string $slug      The post slug.
136
+     * @param string $post_type Post type.
137
+     *
138
+     * @return bool Whether the slug is bad.
139
+     */
140
+    public function wp_unique_post_slug_is_bad_flat_slug( $bad_slug, $slug, $post_type ) {
141
+
142
+        // The list of post types that might have conflicting slugs.
143
+        $post_types = array(
144
+            'post',
145
+            'page',
146
+            $this->entity_type_service->get_post_type(),
147
+        );
148
+
149
+        // Ignore post types different from the ones we need to check.
150
+        if ( ! in_array( $post_type, $post_types ) ) {
151
+            return $bad_slug;
152
+        }
153
+
154
+        $exists = $this->slug_exists( $slug, array_diff( $post_types, array( $post_type ) ) );
155
+
156
+        $this->log->debug( "Checking if a slug exists [ post type :: $post_type ][ slug :: $slug ][ exists :: " . ( $exists ? "yes" : "no" ) . " ]" );
157
+
158
+        return $exists;
159
+    }
160
+
161
+    /**
162
+     * Hook to WordPress' wp_unique_post_slug_is_bad_hierarchical_slug filter. This is called when a page is saved.
163
+     *
164
+     * @since 3.6.0
165
+     *
166
+     * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
167
+     * @param string $slug      The post slug.
168
+     * @param string $post_type Post type.
169
+     * @param int    $post_parent
170
+     *
171
+     * @return bool Whether the slug is bad.
172
+     */
173
+    public function wp_unique_post_slug_is_bad_hierarchical_slug( $bad_slug, $slug, $post_type, $post_parent ) {
174
+
175
+        // We only care about pages here.
176
+        if ( 'page' !== $post_type ) {
177
+            return $bad_slug;
178
+        }
179
+
180
+        // We redirect the call to the flat hook, this means that this check is going to solve also the 6-years old issue
181
+        // about overlapping slugs among pages and posts:
182
+        //  https://core.trac.wordpress.org/ticket/13459
183
+        return $this->wp_unique_post_slug_is_bad_flat_slug( $bad_slug, $slug, $post_type );
184
+    }
185
+
186
+    /**
187
+     * Check whether a slug exists already for the specified post types.
188
+     *
189
+     * @since 3.6.0
190
+     *
191
+     * @param string $slug       The slug.
192
+     * @param array  $post_types An array of post types.
193
+     *
194
+     * @return bool True if the slug exists, otherwise false.
195
+     */
196
+    private function slug_exists( $slug, $post_types ) {
197
+        global $wpdb;
198
+
199
+        // Post slugs must be unique across all posts.
200
+        $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ('" . implode( "', '", array_map( 'esc_sql', $post_types ) ) . "') LIMIT 1";
201
+
202
+        return null !== $wpdb->get_var( $wpdb->prepare( $check_sql, $slug ) );
203
+    }
204 204
 
205 205
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -61,9 +61,9 @@  discard block
 block discarded – undo
61 61
 	 * @param Wordlift_Entity_Post_Type_Service $entity_type_service
62 62
 	 * @param string                            $slug The entity post type slug.
63 63
 	 */
64
-	public function __construct( $entity_type_service, $slug ) {
64
+	public function __construct($entity_type_service, $slug) {
65 65
 
66
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Link_Service' );
66
+		$this->log = Wordlift_Log_Service::get_logger('Wordlift_Entity_Link_Service');
67 67
 
68 68
 		$this->entity_type_service = $entity_type_service;
69 69
 		$this->slug                = $slug;
@@ -82,17 +82,17 @@  discard block
 block discarded – undo
82 82
 	 *
83 83
 	 * @return string The link to the post.
84 84
 	 */
85
-	public function post_type_link( $post_link, $post, $leavename, $sample ) {
85
+	public function post_type_link($post_link, $post, $leavename, $sample) {
86 86
 
87 87
 		// Return the post link if this is not our post type.
88
-		if ( ! empty( $this->slug ) || $this->entity_type_service->get_post_type() !== get_post_type( $post ) ) {
88
+		if ( ! empty($this->slug) || $this->entity_type_service->get_post_type() !== get_post_type($post)) {
89 89
 			return $post_link;
90 90
 		}
91 91
 
92 92
 		// Replace /slug/post_name/ with /post_name/
93 93
 		// The slug comes from the Entity Type Service since that service is responsible for registering the default
94 94
 		// slug.
95
-		return str_replace( "/{$this->entity_type_service->get_slug()}/$post->post_name/", "/$post->post_name/", $post_link );
95
+		return str_replace("/{$this->entity_type_service->get_slug()}/$post->post_name/", "/$post->post_name/", $post_link);
96 96
 	}
97 97
 
98 98
 	/**
@@ -102,10 +102,10 @@  discard block
 block discarded – undo
102 102
 	 *
103 103
 	 * @param WP_Query $query
104 104
 	 */
105
-	public function pre_get_posts( $query ) {
105
+	public function pre_get_posts($query) {
106 106
 
107 107
 		// If a slug has been set, we don't need to alter the query.
108
-		if ( ! empty( $this->slug ) ) {
108
+		if ( ! empty($this->slug)) {
109 109
 			return;
110 110
 		}
111 111
 
@@ -114,15 +114,15 @@  discard block
 block discarded – undo
114 114
 		// The `$query->query` count could be > 2 if the preview parameter is passed too.
115 115
 		//
116 116
 		// See https://github.com/insideout10/wordlift-plugin/issues/439
117
-		if ( ! $query->is_main_query() || 2 > count( $query->query ) || ! isset( $query->query['page'] ) || empty( $query->query['name'] ) ) {
117
+		if ( ! $query->is_main_query() || 2 > count($query->query) || ! isset($query->query['page']) || empty($query->query['name'])) {
118 118
 			return;
119 119
 		}
120 120
 
121 121
 		// Add our own post type to the query.
122
-		$post_types = '' === $query->get( 'post_type' )
122
+		$post_types = '' === $query->get('post_type')
123 123
 			? Wordlift_Entity_Service::valid_entity_post_types()
124
-			: array_merge( (array) $query->get( 'post_type' ), (array) $this->entity_type_service->get_post_type() );
125
-		$query->set( 'post_type', $post_types );
124
+			: array_merge((array) $query->get('post_type'), (array) $this->entity_type_service->get_post_type());
125
+		$query->set('post_type', $post_types);
126 126
 
127 127
 	}
128 128
 
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
 	 *
138 138
 	 * @return bool Whether the slug is bad.
139 139
 	 */
140
-	public function wp_unique_post_slug_is_bad_flat_slug( $bad_slug, $slug, $post_type ) {
140
+	public function wp_unique_post_slug_is_bad_flat_slug($bad_slug, $slug, $post_type) {
141 141
 
142 142
 		// The list of post types that might have conflicting slugs.
143 143
 		$post_types = array(
@@ -147,13 +147,13 @@  discard block
 block discarded – undo
147 147
 		);
148 148
 
149 149
 		// Ignore post types different from the ones we need to check.
150
-		if ( ! in_array( $post_type, $post_types ) ) {
150
+		if ( ! in_array($post_type, $post_types)) {
151 151
 			return $bad_slug;
152 152
 		}
153 153
 
154
-		$exists = $this->slug_exists( $slug, array_diff( $post_types, array( $post_type ) ) );
154
+		$exists = $this->slug_exists($slug, array_diff($post_types, array($post_type)));
155 155
 
156
-		$this->log->debug( "Checking if a slug exists [ post type :: $post_type ][ slug :: $slug ][ exists :: " . ( $exists ? "yes" : "no" ) . " ]" );
156
+		$this->log->debug("Checking if a slug exists [ post type :: $post_type ][ slug :: $slug ][ exists :: ".($exists ? "yes" : "no")." ]");
157 157
 
158 158
 		return $exists;
159 159
 	}
@@ -170,17 +170,17 @@  discard block
 block discarded – undo
170 170
 	 *
171 171
 	 * @return bool Whether the slug is bad.
172 172
 	 */
173
-	public function wp_unique_post_slug_is_bad_hierarchical_slug( $bad_slug, $slug, $post_type, $post_parent ) {
173
+	public function wp_unique_post_slug_is_bad_hierarchical_slug($bad_slug, $slug, $post_type, $post_parent) {
174 174
 
175 175
 		// We only care about pages here.
176
-		if ( 'page' !== $post_type ) {
176
+		if ('page' !== $post_type) {
177 177
 			return $bad_slug;
178 178
 		}
179 179
 
180 180
 		// We redirect the call to the flat hook, this means that this check is going to solve also the 6-years old issue
181 181
 		// about overlapping slugs among pages and posts:
182 182
 		//  https://core.trac.wordpress.org/ticket/13459
183
-		return $this->wp_unique_post_slug_is_bad_flat_slug( $bad_slug, $slug, $post_type );
183
+		return $this->wp_unique_post_slug_is_bad_flat_slug($bad_slug, $slug, $post_type);
184 184
 	}
185 185
 
186 186
 	/**
@@ -193,13 +193,13 @@  discard block
 block discarded – undo
193 193
 	 *
194 194
 	 * @return bool True if the slug exists, otherwise false.
195 195
 	 */
196
-	private function slug_exists( $slug, $post_types ) {
196
+	private function slug_exists($slug, $post_types) {
197 197
 		global $wpdb;
198 198
 
199 199
 		// Post slugs must be unique across all posts.
200
-		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ('" . implode( "', '", array_map( 'esc_sql', $post_types ) ) . "') LIMIT 1";
200
+		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ('".implode("', '", array_map('esc_sql', $post_types))."') LIMIT 1";
201 201
 
202
-		return null !== $wpdb->get_var( $wpdb->prepare( $check_sql, $slug ) );
202
+		return null !== $wpdb->get_var($wpdb->prepare($check_sql, $slug));
203 203
 	}
204 204
 
205 205
 }
Please login to merge, or discard this patch.
src/includes/class-wordlift-query-builder.php 1 patch
Indentation   +310 added lines, -310 removed lines patch added patch discarded remove patch
@@ -7,315 +7,315 @@
 block discarded – undo
7 7
  */
8 8
 class Wordlift_Query_Builder {
9 9
 
10
-	/**
11
-	 * The INSERT statement template.
12
-	 *
13
-	 * @since 3.1.7
14
-	 */
15
-	const INSERT = 'INSERT DATA { %s };';
16
-
17
-	/**
18
-	 * The DELETE statement template (it repeats the statements in the WHERE clause.
19
-	 *
20
-	 * @since 3.1.7
21
-	 */
22
-	const DELETE = 'DELETE { %s } WHERE { %1$s };';
23
-
24
-	/**
25
-	 * Tell the statement function to guess the object type (URI, value or parameter).
26
-	 *
27
-	 * @since 3.1.7
28
-	 */
29
-	const OBJECT_AUTO = - 1;
30
-
31
-	/**
32
-	 * Tell the statement function that the object is a URI.
33
-	 *
34
-	 * @since 3.1.7
35
-	 */
36
-	const OBJECT_URI = 0;
37
-
38
-	/**
39
-	 * Tell the statement function that the object is a value.
40
-	 *
41
-	 * @since 3.1.7
42
-	 */
43
-	const OBJECT_VALUE = 1;
44
-
45
-	/**
46
-	 * Tell the statement function that the object is a parameter.
47
-	 *
48
-	 * @since 3.1.7
49
-	 */
50
-	const OBJECT_PARAMETER = 2;
51
-
52
-	/**
53
-	 * The RDFS type.
54
-	 *
55
-	 * @since 3.1.7
56
-	 */
57
-	const RDFS_TYPE_URI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
58
-
59
-	/**
60
-	 * The schema.org/Person type.
61
-	 *
62
-	 * @since 3.1.7
63
-	 */
64
-	const SCHEMA_PERSON_URI = 'http://schema.org/Person';
65
-
66
-	/**
67
-	 * The schema.org given name predicate.
68
-	 *
69
-	 * @since 3.1.7
70
-	 */
71
-	const SCHEMA_GIVEN_NAME_URI = 'http://schema.org/givenName';
72
-
73
-	/**
74
-	 * The schema.org family name predicate.
75
-	 *
76
-	 * @since 3.1.7
77
-	 */
78
-	const SCHEMA_FAMILY_NAME_URI = 'http://schema.org/familyName';
79
-
80
-	/**
81
-	 * The schema.org url predicate.
82
-	 *
83
-	 * @since 3.1.7
84
-	 */
85
-	const SCHEMA_URL_URI = 'http://schema.org/url';
86
-
87
-	/**
88
-	 * @since 3.14.0
89
-	 */
90
-	const SCHEMA_IMAGE_URI = 'http://schema.org/image';
91
-
92
-	/**
93
-	 * The location created predicate.
94
-	 *
95
-	 * @since 3.14.0
96
-	 */
97
-	const SCHEMA_LOCATION_CREATED_URI = 'http://schema.org/locationCreated';
98
-
99
-	/**
100
-	 * @since 3.14.0
101
-	 */
102
-	const SCHEMA_AUTHOR_URI = 'http://schema.org/author';
103
-
104
-	/**
105
-	 * @since 3.14.0
106
-	 */
107
-	const SCHEMA_INTERACTION_COUNT_URI = 'http://schema.org/interactionCount';
108
-
109
-	/**
110
-	 * @since 3.14.0
111
-	 */
112
-	const DCTERMS_SUBJECT_URI = 'http://purl.org/dc/terms/subject';
113
-
114
-	/**
115
-	 * @since 3.14.0
116
-	 */
117
-	const DCTERMS_REFERENCES_URI = 'http://purl.org/dc/terms/references';
118
-
119
-	/**
120
-	 * @since 3.15.0
121
-	 */
122
-	const DCTERMS_RELATION_URI = 'http://purl.org/dc/terms/relation';
123
-
124
-	/**
125
-	 * The RDF label.
126
-	 *
127
-	 * @since 3.1.7
128
-	 */
129
-	const RDFS_LABEL_URI = 'http://www.w3.org/2000/01/rdf-schema#label';
130
-
131
-	/**
132
-	 * Hold the template (INSERT or DELETE).
133
-	 *
134
-	 * @since  3.1.7
135
-	 * @access private
136
-	 * @var string $template The query template.
137
-	 */
138
-	private $template;
139
-
140
-	/**
141
-	 * An array of statements (in the form of subject, predicate, object).
142
-	 *
143
-	 * @since  3.1.7
144
-	 * @access private
145
-	 * @var array $statements An array of statements.
146
-	 */
147
-	private $statements = array();
148
-
149
-	/**
150
-	 * Create a new instance of the Query builder (compatible with PHP 5.3).
151
-	 *
152
-	 * @since 3.1.7
153
-	 * @return Wordlift_Query_Builder A new instance of the Query builder.
154
-	 */
155
-	public static function new_instance() {
156
-
157
-		return new Wordlift_Query_Builder();
158
-	}
159
-
160
-	/**
161
-	 * Set the query to INSERT.
162
-	 *
163
-	 * @since 3.1.7
164
-	 * @return Wordlift_Query_Builder The Query builder.
165
-	 */
166
-	public function insert() {
167
-
168
-		$this->template = self::INSERT;
169
-
170
-		return $this;
171
-	}
172
-
173
-	/**
174
-	 * Set the query to DELETE.
175
-	 *
176
-	 * @since 3.1.7
177
-	 * @return $this \Wordlift_Query_Builder The Query builder.
178
-	 */
179
-	public function delete() {
180
-
181
-		$this->template = self::DELETE;
182
-
183
-		return $this;
184
-	}
185
-
186
-	/**
187
-	 * Set the query to SELECT.
188
-	 *
189
-	 * @since 3.12.2
190
-	 *
191
-	 * @param string $props The list of properties to read.
192
-	 *
193
-	 * @return $this \Wordlift_Query_Builder The Query builder.
194
-	 */
195
-	public function select( $props = '*' ) {
196
-
197
-		$this->template = "SELECT $props WHERE { %s }";
198
-
199
-		return $this;
200
-	}
201
-
202
-	/**
203
-	 * Add a statement.
204
-	 *
205
-	 * @since 3.1.7
206
-	 *
207
-	 * @param string      $subject     The subject of the statement (must be a URI).
208
-	 * @param string      $predicate   The predicate (must be a URI).
209
-	 * @param string      $object      The object, can be a URI or a value.
210
-	 * @param int         $object_type The object type, either a {@link OBJECT_URI} or a value {@link OBJECT_VALUE}. If set to {@link OBJECT_AUTO}, the Query builder will try to guess.
211
-	 * @param string|null $data_type   The data type (or null).
212
-	 * @param string|null $language    The language code (or null).
213
-	 *
214
-	 * @return $this \Wordlift_Query_Builder The Query builder.
215
-	 */
216
-	public function statement( $subject, $predicate, $object, $object_type = self::OBJECT_AUTO, $data_type = null, $language = null ) {
217
-
218
-		// If no value has been provided, we don't set any statement.
219
-		if ( empty( $object ) ) {
220
-			return $this;
221
-		}
222
-
223
-		// Guess the subject type.
224
-		$subject_value_type = $this->guess_subject_type( $subject );
225
-
226
-		// Get the object type if set, otherwise try to guess it.
227
-		$object_value_type = ( self::OBJECT_AUTO === $object_type ? $this->guess_object_type( $predicate, $object ) : $object_type );
228
-
229
-		// Prepare the statement template.
230
-		$template =
231
-			// Subject as a parameter, no `<`, `>`.
232
-			( self::OBJECT_PARAMETER === $subject_value_type ? '%1$s' : '<%1$s>' ) .
233
-			// Predicate.
234
-			' <%2$s> ' .
235
-			// Object.
236
-			( self::OBJECT_URI === $object_value_type ? '<%3$s>' :
237
-				( self::OBJECT_PARAMETER === $object_value_type ? '%3$s' :
238
-					// self::OBJECT_VALUE === $object_value_type
239
-					'"%3$s"' . ( isset( $data_type ) ? '^^%4$s' : '' ) . ( isset( $language ) ? '@%5$s' : '' ) ) );
240
-
241
-		// Escape the subject, predicate and object.
242
-		$escaped_subject   = Wordlift_Sparql_Service::escape_uri( $subject );
243
-		$escaped_predicate = Wordlift_Sparql_Service::escape_uri( $predicate );
244
-		$escaped_object    = ( self::OBJECT_URI === $object_value_type ? Wordlift_Sparql_Service::escape_uri( $object ) : Wordlift_Sparql_Service::escape( $object ) );
245
-
246
-		// Prepare the statement and add it to the list of statements.
247
-		$this->statements[] = sprintf( $template, $escaped_subject, $escaped_predicate, $escaped_object, $data_type, $language );
248
-
249
-		return $this;
250
-	}
251
-
252
-	/**
253
-	 * Build the query.
254
-	 *
255
-	 * @since 3.1.7
256
-	 * @return string The query string.
257
-	 */
258
-	public function build() {
259
-
260
-		// If there are no statements return an empty string.
261
-		if ( 0 === count( $this->statements ) ) {
262
-			return '';
263
-		}
264
-
265
-		return sprintf( $this->template, implode( ' . ', $this->statements ) ) . "\n";
266
-	}
267
-
268
-	/**
269
-	 * Guess the statement object type.
270
-	 *
271
-	 * @since 3.1.7
272
-	 *
273
-	 * @param string $predicate The predicate.
274
-	 * @param string $object    The object.
275
-	 *
276
-	 * @return int {@link Wordlift_Query_Builder::OBJECT_URI} if the Query builder thinks the object must be an URI, {@link Wordlift_Query_Builder::OBJECT_VALUE} otherwise.
277
-	 */
278
-	private function guess_object_type( $predicate, $object ) {
279
-
280
-		// If the object starts with a question mark, it's a parameter.
281
-		if ( 0 === strpos( $object, '?' ) ) {
282
-			return self::OBJECT_PARAMETER;
283
-		}
284
-
285
-		// Guess based on the predicate.
286
-		switch ( $predicate ) {
287
-
288
-			case self::DCTERMS_REFERENCES_URI:
289
-			case self::DCTERMS_SUBJECT_URI:
290
-			case self::RDFS_TYPE_URI:
291
-			case self::SCHEMA_AUTHOR_URI:
292
-			case self::SCHEMA_LOCATION_CREATED_URI:
293
-			case self::SCHEMA_URL_URI:
294
-			case self::SCHEMA_IMAGE_URI:
295
-				return self::OBJECT_URI;
296
-
297
-		}
298
-
299
-		return self::OBJECT_VALUE;
300
-	}
301
-
302
-	/**
303
-	 * Guess the subject type.
304
-	 *
305
-	 * @since 3.12.3
306
-	 *
307
-	 * @param string $subject The subject string.
308
-	 *
309
-	 * @return int {@link Wordlift_Query_Builder::OBJECT_PARAMETER} if the Query builder thinks the subject is a parameter (starts with ?), otherwise {@link Wordlift_Query_Builder::OBJECT_URI}.
310
-	 */
311
-	private function guess_subject_type( $subject ) {
312
-
313
-		// If the object starts with a question mark, it's a parameter.
314
-		if ( 0 === strpos( $subject, '?' ) ) {
315
-			return self::OBJECT_PARAMETER;
316
-		}
317
-
318
-		return self::OBJECT_URI;
319
-	}
10
+    /**
11
+     * The INSERT statement template.
12
+     *
13
+     * @since 3.1.7
14
+     */
15
+    const INSERT = 'INSERT DATA { %s };';
16
+
17
+    /**
18
+     * The DELETE statement template (it repeats the statements in the WHERE clause.
19
+     *
20
+     * @since 3.1.7
21
+     */
22
+    const DELETE = 'DELETE { %s } WHERE { %1$s };';
23
+
24
+    /**
25
+     * Tell the statement function to guess the object type (URI, value or parameter).
26
+     *
27
+     * @since 3.1.7
28
+     */
29
+    const OBJECT_AUTO = - 1;
30
+
31
+    /**
32
+     * Tell the statement function that the object is a URI.
33
+     *
34
+     * @since 3.1.7
35
+     */
36
+    const OBJECT_URI = 0;
37
+
38
+    /**
39
+     * Tell the statement function that the object is a value.
40
+     *
41
+     * @since 3.1.7
42
+     */
43
+    const OBJECT_VALUE = 1;
44
+
45
+    /**
46
+     * Tell the statement function that the object is a parameter.
47
+     *
48
+     * @since 3.1.7
49
+     */
50
+    const OBJECT_PARAMETER = 2;
51
+
52
+    /**
53
+     * The RDFS type.
54
+     *
55
+     * @since 3.1.7
56
+     */
57
+    const RDFS_TYPE_URI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
58
+
59
+    /**
60
+     * The schema.org/Person type.
61
+     *
62
+     * @since 3.1.7
63
+     */
64
+    const SCHEMA_PERSON_URI = 'http://schema.org/Person';
65
+
66
+    /**
67
+     * The schema.org given name predicate.
68
+     *
69
+     * @since 3.1.7
70
+     */
71
+    const SCHEMA_GIVEN_NAME_URI = 'http://schema.org/givenName';
72
+
73
+    /**
74
+     * The schema.org family name predicate.
75
+     *
76
+     * @since 3.1.7
77
+     */
78
+    const SCHEMA_FAMILY_NAME_URI = 'http://schema.org/familyName';
79
+
80
+    /**
81
+     * The schema.org url predicate.
82
+     *
83
+     * @since 3.1.7
84
+     */
85
+    const SCHEMA_URL_URI = 'http://schema.org/url';
86
+
87
+    /**
88
+     * @since 3.14.0
89
+     */
90
+    const SCHEMA_IMAGE_URI = 'http://schema.org/image';
91
+
92
+    /**
93
+     * The location created predicate.
94
+     *
95
+     * @since 3.14.0
96
+     */
97
+    const SCHEMA_LOCATION_CREATED_URI = 'http://schema.org/locationCreated';
98
+
99
+    /**
100
+     * @since 3.14.0
101
+     */
102
+    const SCHEMA_AUTHOR_URI = 'http://schema.org/author';
103
+
104
+    /**
105
+     * @since 3.14.0
106
+     */
107
+    const SCHEMA_INTERACTION_COUNT_URI = 'http://schema.org/interactionCount';
108
+
109
+    /**
110
+     * @since 3.14.0
111
+     */
112
+    const DCTERMS_SUBJECT_URI = 'http://purl.org/dc/terms/subject';
113
+
114
+    /**
115
+     * @since 3.14.0
116
+     */
117
+    const DCTERMS_REFERENCES_URI = 'http://purl.org/dc/terms/references';
118
+
119
+    /**
120
+     * @since 3.15.0
121
+     */
122
+    const DCTERMS_RELATION_URI = 'http://purl.org/dc/terms/relation';
123
+
124
+    /**
125
+     * The RDF label.
126
+     *
127
+     * @since 3.1.7
128
+     */
129
+    const RDFS_LABEL_URI = 'http://www.w3.org/2000/01/rdf-schema#label';
130
+
131
+    /**
132
+     * Hold the template (INSERT or DELETE).
133
+     *
134
+     * @since  3.1.7
135
+     * @access private
136
+     * @var string $template The query template.
137
+     */
138
+    private $template;
139
+
140
+    /**
141
+     * An array of statements (in the form of subject, predicate, object).
142
+     *
143
+     * @since  3.1.7
144
+     * @access private
145
+     * @var array $statements An array of statements.
146
+     */
147
+    private $statements = array();
148
+
149
+    /**
150
+     * Create a new instance of the Query builder (compatible with PHP 5.3).
151
+     *
152
+     * @since 3.1.7
153
+     * @return Wordlift_Query_Builder A new instance of the Query builder.
154
+     */
155
+    public static function new_instance() {
156
+
157
+        return new Wordlift_Query_Builder();
158
+    }
159
+
160
+    /**
161
+     * Set the query to INSERT.
162
+     *
163
+     * @since 3.1.7
164
+     * @return Wordlift_Query_Builder The Query builder.
165
+     */
166
+    public function insert() {
167
+
168
+        $this->template = self::INSERT;
169
+
170
+        return $this;
171
+    }
172
+
173
+    /**
174
+     * Set the query to DELETE.
175
+     *
176
+     * @since 3.1.7
177
+     * @return $this \Wordlift_Query_Builder The Query builder.
178
+     */
179
+    public function delete() {
180
+
181
+        $this->template = self::DELETE;
182
+
183
+        return $this;
184
+    }
185
+
186
+    /**
187
+     * Set the query to SELECT.
188
+     *
189
+     * @since 3.12.2
190
+     *
191
+     * @param string $props The list of properties to read.
192
+     *
193
+     * @return $this \Wordlift_Query_Builder The Query builder.
194
+     */
195
+    public function select( $props = '*' ) {
196
+
197
+        $this->template = "SELECT $props WHERE { %s }";
198
+
199
+        return $this;
200
+    }
201
+
202
+    /**
203
+     * Add a statement.
204
+     *
205
+     * @since 3.1.7
206
+     *
207
+     * @param string      $subject     The subject of the statement (must be a URI).
208
+     * @param string      $predicate   The predicate (must be a URI).
209
+     * @param string      $object      The object, can be a URI or a value.
210
+     * @param int         $object_type The object type, either a {@link OBJECT_URI} or a value {@link OBJECT_VALUE}. If set to {@link OBJECT_AUTO}, the Query builder will try to guess.
211
+     * @param string|null $data_type   The data type (or null).
212
+     * @param string|null $language    The language code (or null).
213
+     *
214
+     * @return $this \Wordlift_Query_Builder The Query builder.
215
+     */
216
+    public function statement( $subject, $predicate, $object, $object_type = self::OBJECT_AUTO, $data_type = null, $language = null ) {
217
+
218
+        // If no value has been provided, we don't set any statement.
219
+        if ( empty( $object ) ) {
220
+            return $this;
221
+        }
222
+
223
+        // Guess the subject type.
224
+        $subject_value_type = $this->guess_subject_type( $subject );
225
+
226
+        // Get the object type if set, otherwise try to guess it.
227
+        $object_value_type = ( self::OBJECT_AUTO === $object_type ? $this->guess_object_type( $predicate, $object ) : $object_type );
228
+
229
+        // Prepare the statement template.
230
+        $template =
231
+            // Subject as a parameter, no `<`, `>`.
232
+            ( self::OBJECT_PARAMETER === $subject_value_type ? '%1$s' : '<%1$s>' ) .
233
+            // Predicate.
234
+            ' <%2$s> ' .
235
+            // Object.
236
+            ( self::OBJECT_URI === $object_value_type ? '<%3$s>' :
237
+                ( self::OBJECT_PARAMETER === $object_value_type ? '%3$s' :
238
+                    // self::OBJECT_VALUE === $object_value_type
239
+                    '"%3$s"' . ( isset( $data_type ) ? '^^%4$s' : '' ) . ( isset( $language ) ? '@%5$s' : '' ) ) );
240
+
241
+        // Escape the subject, predicate and object.
242
+        $escaped_subject   = Wordlift_Sparql_Service::escape_uri( $subject );
243
+        $escaped_predicate = Wordlift_Sparql_Service::escape_uri( $predicate );
244
+        $escaped_object    = ( self::OBJECT_URI === $object_value_type ? Wordlift_Sparql_Service::escape_uri( $object ) : Wordlift_Sparql_Service::escape( $object ) );
245
+
246
+        // Prepare the statement and add it to the list of statements.
247
+        $this->statements[] = sprintf( $template, $escaped_subject, $escaped_predicate, $escaped_object, $data_type, $language );
248
+
249
+        return $this;
250
+    }
251
+
252
+    /**
253
+     * Build the query.
254
+     *
255
+     * @since 3.1.7
256
+     * @return string The query string.
257
+     */
258
+    public function build() {
259
+
260
+        // If there are no statements return an empty string.
261
+        if ( 0 === count( $this->statements ) ) {
262
+            return '';
263
+        }
264
+
265
+        return sprintf( $this->template, implode( ' . ', $this->statements ) ) . "\n";
266
+    }
267
+
268
+    /**
269
+     * Guess the statement object type.
270
+     *
271
+     * @since 3.1.7
272
+     *
273
+     * @param string $predicate The predicate.
274
+     * @param string $object    The object.
275
+     *
276
+     * @return int {@link Wordlift_Query_Builder::OBJECT_URI} if the Query builder thinks the object must be an URI, {@link Wordlift_Query_Builder::OBJECT_VALUE} otherwise.
277
+     */
278
+    private function guess_object_type( $predicate, $object ) {
279
+
280
+        // If the object starts with a question mark, it's a parameter.
281
+        if ( 0 === strpos( $object, '?' ) ) {
282
+            return self::OBJECT_PARAMETER;
283
+        }
284
+
285
+        // Guess based on the predicate.
286
+        switch ( $predicate ) {
287
+
288
+            case self::DCTERMS_REFERENCES_URI:
289
+            case self::DCTERMS_SUBJECT_URI:
290
+            case self::RDFS_TYPE_URI:
291
+            case self::SCHEMA_AUTHOR_URI:
292
+            case self::SCHEMA_LOCATION_CREATED_URI:
293
+            case self::SCHEMA_URL_URI:
294
+            case self::SCHEMA_IMAGE_URI:
295
+                return self::OBJECT_URI;
296
+
297
+        }
298
+
299
+        return self::OBJECT_VALUE;
300
+    }
301
+
302
+    /**
303
+     * Guess the subject type.
304
+     *
305
+     * @since 3.12.3
306
+     *
307
+     * @param string $subject The subject string.
308
+     *
309
+     * @return int {@link Wordlift_Query_Builder::OBJECT_PARAMETER} if the Query builder thinks the subject is a parameter (starts with ?), otherwise {@link Wordlift_Query_Builder::OBJECT_URI}.
310
+     */
311
+    private function guess_subject_type( $subject ) {
312
+
313
+        // If the object starts with a question mark, it's a parameter.
314
+        if ( 0 === strpos( $subject, '?' ) ) {
315
+            return self::OBJECT_PARAMETER;
316
+        }
317
+
318
+        return self::OBJECT_URI;
319
+    }
320 320
 
321 321
 }
Please login to merge, or discard this patch.