Completed
Push — develop ( df3f0b...88eeb8 )
by David
07:56 queued 02:04
created
src/wordlift_constants.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -5,14 +5,14 @@  discard block
 block discarded – undo
5 5
 
6 6
 // Define the basic options for HTTP calls to REDLINK.
7 7
 define( 'WL_REDLINK_API_HTTP_OPTIONS', serialize( array(
8
-	'timeout'         => 300,
9
-	'redirection'     => 5,
10
-	'httpversion'     => '1.1',
11
-	'blocking'        => true,
12
-	'cookies'         => array(),
13
-	'sslverify'       => ( 'false' === getenv( 'WL_SSL_VERIFY_ENABLED' ) ) ? false : true,
14
-	'sslcertificates' => dirname( __FILE__ ) . '/ssl/ca-bundle.crt',
15
-	'decompress'      => false
8
+    'timeout'         => 300,
9
+    'redirection'     => 5,
10
+    'httpversion'     => '1.1',
11
+    'blocking'        => true,
12
+    'cookies'         => array(),
13
+    'sslverify'       => ( 'false' === getenv( 'WL_SSL_VERIFY_ENABLED' ) ) ? false : true,
14
+    'sslcertificates' => dirname( __FILE__ ) . '/ssl/ca-bundle.crt',
15
+    'decompress'      => false
16 16
 ) ) );
17 17
 
18 18
 // Create a unique ID for this request, useful to hook async HTTP requests.
@@ -36,14 +36,14 @@  discard block
 block discarded – undo
36 36
  */
37 37
 function wl_prefixes() {
38 38
 
39
-	$items    = wl_prefixes_list();
40
-	$prefixes = array();
39
+    $items    = wl_prefixes_list();
40
+    $prefixes = array();
41 41
 
42
-	foreach ( $items as $item ) {
43
-		$prefixes[ $item['prefix'] ] = $item['namespace'];
44
-	}
42
+    foreach ( $items as $item ) {
43
+        $prefixes[ $item['prefix'] ] = $item['namespace'];
44
+    }
45 45
 
46
-	return $prefixes;
46
+    return $prefixes;
47 47
 
48 48
 }
49 49
 
@@ -56,22 +56,22 @@  discard block
 block discarded – undo
56 56
  */
57 57
 function wl_predicates() {
58 58
 
59
-	return array(
60
-		'a',
61
-		'dct:references',
62
-		'dct:relation',
63
-		'dct:title',
64
-		'dct:subject',
65
-		'owl:sameAs',
66
-		'rdfs:label',
67
-		'schema:author',
68
-		'schema:dateModified',
69
-		'schema:datePublished',
70
-		'schema:locationCreated',
71
-		'schema:description',
72
-		'schema:image',
73
-		'schema:interactionCount',
74
-		'schema:url'
75
-	);
59
+    return array(
60
+        'a',
61
+        'dct:references',
62
+        'dct:relation',
63
+        'dct:title',
64
+        'dct:subject',
65
+        'owl:sameAs',
66
+        'rdfs:label',
67
+        'schema:author',
68
+        'schema:dateModified',
69
+        'schema:datePublished',
70
+        'schema:locationCreated',
71
+        'schema:description',
72
+        'schema:image',
73
+        'schema:interactionCount',
74
+        'schema:url'
75
+    );
76 76
 
77 77
 }
Please login to merge, or discard this patch.
src/modules/analyzer/wordlift_analyzer.php 2 patches
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -10,14 +10,14 @@  discard block
 block discarded – undo
10 10
  */
11 11
 function wl_ajax_analyze_action() {
12 12
 
13
-	if ( $analysis = wl_analyze_content( file_get_contents( "php://input" ) ) ) {
14
-		header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
15
-		echo( $analysis );
16
-		wp_die();
17
-	}
13
+    if ( $analysis = wl_analyze_content( file_get_contents( "php://input" ) ) ) {
14
+        header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
15
+        echo( $analysis );
16
+        wp_die();
17
+    }
18 18
 
19
-	status_header( 500 );
20
-	wp_send_json( __( 'An error occurred while request an analysis to the remote service. Please try again later.', 'wordlift' ) );
19
+    status_header( 500 );
20
+    wp_send_json( __( 'An error occurred while request an analysis to the remote service. Please try again later.', 'wordlift' ) );
21 21
 
22 22
 }
23 23
 
@@ -37,43 +37,43 @@  discard block
 block discarded – undo
37 37
  */
38 38
 function wl_analyze_content( $content ) {
39 39
 
40
-	// Get the analyzer URL.
41
-	$url = wl_configuration_get_analyzer_url();
40
+    // Get the analyzer URL.
41
+    $url = wl_configuration_get_analyzer_url();
42 42
 
43
-	// Set the content type to the request content type or to text/plain by default.
44
-	$content_type = isset( $_SERVER['CONTENT_TYPE'] ) ? $_SERVER['CONTENT_TYPE'] : 'text/plain';
43
+    // Set the content type to the request content type or to text/plain by default.
44
+    $content_type = isset( $_SERVER['CONTENT_TYPE'] ) ? $_SERVER['CONTENT_TYPE'] : 'text/plain';
45 45
 
46
-	// Prepare the request.
47
-	$args = array_merge_recursive( unserialize( WL_REDLINK_API_HTTP_OPTIONS ), array(
48
-		'method'      => 'POST',
49
-		'headers'     => array(
50
-			'Accept'       => 'application/json',
51
-			'Content-type' => $content_type
52
-		),
53
-		// we need to downgrade the HTTP version in this case since chunked encoding is dumping numbers in the response.
54
-		'httpversion' => '1.0',
55
-		'body'        => $content
56
-	) );
46
+    // Prepare the request.
47
+    $args = array_merge_recursive( unserialize( WL_REDLINK_API_HTTP_OPTIONS ), array(
48
+        'method'      => 'POST',
49
+        'headers'     => array(
50
+            'Accept'       => 'application/json',
51
+            'Content-type' => $content_type
52
+        ),
53
+        // we need to downgrade the HTTP version in this case since chunked encoding is dumping numbers in the response.
54
+        'httpversion' => '1.0',
55
+        'body'        => $content
56
+    ) );
57 57
 
58
-	$response = wp_remote_post( $url, $args );
58
+    $response = wp_remote_post( $url, $args );
59 59
 
60
-	// If an error has been raised, return the error.
61
-	if ( is_wp_error( $response ) || 200 !== (int) $response['response']['code'] ) {
60
+    // If an error has been raised, return the error.
61
+    if ( is_wp_error( $response ) || 200 !== (int) $response['response']['code'] ) {
62 62
 
63
-		$body = ( is_wp_error( $response ) ? $response->get_error_message() : $response['body'] );
63
+        $body = ( is_wp_error( $response ) ? $response->get_error_message() : $response['body'] );
64 64
 
65
-		wl_write_log( "error [ url :: $url ][ args :: " );
66
-		wl_write_log( var_export( $args, TRUE ) );
67
-		wl_write_log( '][ response :: ' );
68
-		wl_write_log( "\n" . var_export( $response, TRUE ) );
69
-		wl_write_log( "][ body :: " );
70
-		wl_write_log( "\n" . $body );
71
-		wl_write_log( "]" );
65
+        wl_write_log( "error [ url :: $url ][ args :: " );
66
+        wl_write_log( var_export( $args, TRUE ) );
67
+        wl_write_log( '][ response :: ' );
68
+        wl_write_log( "\n" . var_export( $response, TRUE ) );
69
+        wl_write_log( "][ body :: " );
70
+        wl_write_log( "\n" . $body );
71
+        wl_write_log( "]" );
72 72
 
73
-		return NULL;
74
-	}
73
+        return NULL;
74
+    }
75 75
 
76
-	wl_write_log( "[ url :: $url ][ response code :: " . $response['response']['code'] . " ]" );
76
+    wl_write_log( "[ url :: $url ][ response code :: " . $response['response']['code'] . " ]" );
77 77
 
78
-	return $response['body'];
78
+    return $response['body'];
79 79
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -10,18 +10,18 @@  discard block
 block discarded – undo
10 10
  */
11 11
 function wl_ajax_analyze_action() {
12 12
 
13
-	if ( $analysis = wl_analyze_content( file_get_contents( "php://input" ) ) ) {
14
-		header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
15
-		echo( $analysis );
13
+	if ($analysis = wl_analyze_content(file_get_contents("php://input"))) {
14
+		header('Content-Type: application/json; charset='.get_option('blog_charset'));
15
+		echo($analysis);
16 16
 		wp_die();
17 17
 	}
18 18
 
19
-	status_header( 500 );
20
-	wp_send_json( __( 'An error occurred while request an analysis to the remote service. Please try again later.', 'wordlift' ) );
19
+	status_header(500);
20
+	wp_send_json(__('An error occurred while request an analysis to the remote service. Please try again later.', 'wordlift'));
21 21
 
22 22
 }
23 23
 
24
-add_action( 'wp_ajax_wordlift_analyze', 'wl_ajax_analyze_action' );
24
+add_action('wp_ajax_wordlift_analyze', 'wl_ajax_analyze_action');
25 25
 
26 26
 /**
27 27
  * Analyze the provided content. The analysis will make use of the method *wl_ajax_analyze_action*
@@ -35,16 +35,16 @@  discard block
 block discarded – undo
35 35
  *
36 36
  * @return string Returns null on failure, or the WP_Error, or a WP_Response with the response.
37 37
  */
38
-function wl_analyze_content( $content ) {
38
+function wl_analyze_content($content) {
39 39
 
40 40
 	// Get the analyzer URL.
41 41
 	$url = wl_configuration_get_analyzer_url();
42 42
 
43 43
 	// Set the content type to the request content type or to text/plain by default.
44
-	$content_type = isset( $_SERVER['CONTENT_TYPE'] ) ? $_SERVER['CONTENT_TYPE'] : 'text/plain';
44
+	$content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : 'text/plain';
45 45
 
46 46
 	// Prepare the request.
47
-	$args = array_merge_recursive( unserialize( WL_REDLINK_API_HTTP_OPTIONS ), array(
47
+	$args = array_merge_recursive(unserialize(WL_REDLINK_API_HTTP_OPTIONS), array(
48 48
 		'method'      => 'POST',
49 49
 		'headers'     => array(
50 50
 			'Accept'       => 'application/json',
@@ -53,27 +53,27 @@  discard block
 block discarded – undo
53 53
 		// we need to downgrade the HTTP version in this case since chunked encoding is dumping numbers in the response.
54 54
 		'httpversion' => '1.0',
55 55
 		'body'        => $content
56
-	) );
56
+	));
57 57
 
58
-	$response = wp_remote_post( $url, $args );
58
+	$response = wp_remote_post($url, $args);
59 59
 
60 60
 	// If an error has been raised, return the error.
61
-	if ( is_wp_error( $response ) || 200 !== (int) $response['response']['code'] ) {
61
+	if (is_wp_error($response) || 200 !== (int) $response['response']['code']) {
62 62
 
63
-		$body = ( is_wp_error( $response ) ? $response->get_error_message() : $response['body'] );
63
+		$body = (is_wp_error($response) ? $response->get_error_message() : $response['body']);
64 64
 
65
-		wl_write_log( "error [ url :: $url ][ args :: " );
66
-		wl_write_log( var_export( $args, TRUE ) );
67
-		wl_write_log( '][ response :: ' );
68
-		wl_write_log( "\n" . var_export( $response, TRUE ) );
69
-		wl_write_log( "][ body :: " );
70
-		wl_write_log( "\n" . $body );
71
-		wl_write_log( "]" );
65
+		wl_write_log("error [ url :: $url ][ args :: ");
66
+		wl_write_log(var_export($args, TRUE));
67
+		wl_write_log('][ response :: ');
68
+		wl_write_log("\n".var_export($response, TRUE));
69
+		wl_write_log("][ body :: ");
70
+		wl_write_log("\n".$body);
71
+		wl_write_log("]");
72 72
 
73 73
 		return NULL;
74 74
 	}
75 75
 
76
-	wl_write_log( "[ url :: $url ][ response code :: " . $response['response']['code'] . " ]" );
76
+	wl_write_log("[ url :: $url ][ response code :: ".$response['response']['code']." ]");
77 77
 
78 78
 	return $response['body'];
79 79
 }
Please login to merge, or discard this patch.
src/includes/class-wordlift-schema-service.php 1 patch
Indentation   +782 added lines, -782 removed lines patch added patch discarded remove patch
@@ -7,789 +7,789 @@
 block discarded – undo
7 7
  */
8 8
 class Wordlift_Schema_Service {
9 9
 
10
-	/**
11
-	 * The 'location created' field name.
12
-	 *
13
-	 * @since 3.5.0
14
-	 */
15
-	const FIELD_LOCATION_CREATED = 'wl_location_created';
16
-
17
-	/**
18
-	 * The 'topic' field name.
19
-	 *
20
-	 * @since 3.5.0
21
-	 */
22
-	const FIELD_TOPIC = 'wl_topic';
23
-
24
-	/**
25
-	 * The 'author' field name.
26
-	 *
27
-	 * @since 3.1.0
28
-	 */
29
-	const FIELD_AUTHOR = 'wl_author';
30
-
31
-	/**
32
-	 * The 'same as' field name.
33
-	 *
34
-	 * @since 3.1.0
35
-	 */
36
-	const FIELD_SAME_AS = 'entity_same_as';
37
-
38
-	/**
39
-	 * The 'date start' field name.
40
-	 *
41
-	 * @since 3.1.0
42
-	 */
43
-	const FIELD_DATE_START = 'wl_cal_date_start';
44
-
45
-	/**
46
-	 * The 'date end' field name.
47
-	 *
48
-	 * @since 3.1.0
49
-	 */
50
-	const FIELD_DATE_END = 'wl_cal_date_end';
51
-
52
-	/**
53
-	 * The 'location' field name.
54
-	 *
55
-	 * @since 3.1.0
56
-	 */
57
-	const FIELD_LOCATION = 'wl_location';
58
-
59
-	/**
60
-	 * The 'founder' field name.
61
-	 *
62
-	 * @since 3.1.0
63
-	 */
64
-	const FIELD_FOUNDER = 'wl_founder';
65
-
66
-	/**
67
-	 * The 'knows' field name.
68
-	 *
69
-	 * @since 3.1.0
70
-	 */
71
-	const FIELD_KNOWS = 'wl_knows';
72
-
73
-	/**
74
-	 * The 'birth date' field name.
75
-	 *
76
-	 * @since 3.1.0
77
-	 */
78
-	const FIELD_BIRTH_DATE = 'wl_birth_date';
79
-
80
-	/**
81
-	 * The 'birth place' field name.
82
-	 *
83
-	 * @since 3.1.0
84
-	 */
85
-	const FIELD_BIRTH_PLACE = 'wl_birth_place';
86
-
87
-	/**
88
-	 * The 'latitude' field name.
89
-	 *
90
-	 * @since 3.1.0
91
-	 */
92
-	const FIELD_GEO_LATITUDE = 'wl_geo_latitude';
93
-
94
-	/**
95
-	 * The 'longitude' field name.
96
-	 *
97
-	 * @since 3.1.0
98
-	 */
99
-	const FIELD_GEO_LONGITUDE = 'wl_geo_longitude';
100
-
101
-	/**
102
-	 * The 'streetAddress' field name.
103
-	 *
104
-	 * @since 3.1.0
105
-	 */
106
-	const FIELD_ADDRESS = 'wl_address';
107
-
108
-	/**
109
-	 * The 'postOfficeBoxNumber' field name.
110
-	 *
111
-	 * @since 3.3.0
112
-	 */
113
-	const FIELD_ADDRESS_PO_BOX = 'wl_address_post_office_box';
114
-
115
-	/**
116
-	 * The 'postalCode' field name.
117
-	 *
118
-	 * @since 3.3.0
119
-	 */
120
-	const FIELD_ADDRESS_POSTAL_CODE = 'wl_address_postal_code';
121
-
122
-	/**
123
-	 * The 'addressLocality' field name.
124
-	 *
125
-	 * @since 3.3.0
126
-	 */
127
-	const FIELD_ADDRESS_LOCALITY = 'wl_address_locality';
128
-	/**
129
-	 * The 'addressRegion' field name.
130
-	 *
131
-	 * @since 3.3.0
132
-	 */
133
-	const FIELD_ADDRESS_REGION = 'wl_address_region';
134
-
135
-	/**
136
-	 * The 'addressCountry' field name.
137
-	 *
138
-	 * @since 3.3.0
139
-	 */
140
-	const FIELD_ADDRESS_COUNTRY = 'wl_address_country';
141
-
142
-	/**
143
-	 * The 'entity type' field name.
144
-	 *
145
-	 * @since 3.1.0
146
-	 */
147
-	const FIELD_ENTITY_TYPE = 'wl_entity_type_uri';
148
-
149
-	/**
150
-	 * The 'email' field name.
151
-	 *
152
-	 * @since 3.2.0
153
-	 */
154
-	const FIELD_EMAIL = 'wl_email';
155
-
156
-	/**
157
-	 * The 'affiliation' field name.
158
-	 *
159
-	 * @since 3.2.0
160
-	 */
161
-	const FIELD_AFFILIATION = 'wl_affiliation';
162
-
163
-	/**
164
-	 * The 'URI' data type name.
165
-	 *
166
-	 * @since 3.1.0
167
-	 */
168
-	const DATA_TYPE_URI = 'uri';
169
-
170
-	/**
171
-	 * The 'date' data type name.
172
-	 *
173
-	 * @since 3.1.0
174
-	 */
175
-	const DATA_TYPE_DATE = 'date';
176
-
177
-	/**
178
-	 * The 'double' data type name.
179
-	 *
180
-	 * @since 3.1.0
181
-	 */
182
-	const DATA_TYPE_DOUBLE = 'double';
183
-
184
-	/**
185
-	 * The 'string' data type name.
186
-	 *
187
-	 * @since 3.1.0
188
-	 */
189
-	const DATA_TYPE_STRING = 'string';
190
-
191
-	/**
192
-	 * The 'integer' data type name.
193
-	 *
194
-	 * @since 3.1.0
195
-	 */
196
-	const DATA_TYPE_INTEGER = 'int';
197
-
198
-	/**
199
-	 * The 'boolean' data type name.
200
-	 *
201
-	 * @since 3.1.0
202
-	 */
203
-	const DATA_TYPE_BOOLEAN = 'bool';
204
-
205
-	/**
206
-	 * The schema.org Event type URI.
207
-	 *
208
-	 * @since 3.1.0
209
-	 */
210
-	const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
211
-
212
-	/**
213
-	 * The Schema service singleton instance.
214
-	 *
215
-	 * @since 3.1.0
216
-	 * @access private
217
-	 * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
218
-	 */
219
-	private static $instance;
220
-
221
-	/**
222
-	 * WordLift's schema.
223
-	 *
224
-	 * @since 3.1.0
225
-	 * @access private
226
-	 * @var array $schema WordLift's schema.
227
-	 */
228
-	private $schema;
229
-
230
-	/**
231
-	 * The Log service.
232
-	 *
233
-	 * @since 3.1.0
234
-	 * @access private
235
-	 * @var \Wordlift_Log_Service $log_service The Log service.
236
-	 */
237
-	private $log_service;
238
-
239
-	/**
240
-	 * Wordlift_Schema_Service constructor.
241
-	 *
242
-	 * @since 3.1.0
243
-	 */
244
-	public function __construct() {
245
-
246
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
247
-
248
-		// Create a singleton instance of the Schema service, useful to provide static functions to global functions.
249
-		self::$instance = $this;
250
-
251
-		// Set the taxonomy data.
252
-		// Note: parent types must be defined before child types.
253
-		$this->schema = array(
254
-			'thing'         => $this->get_thing_schema(),
255
-			'creative-work' => $this->get_creative_work_schema(),
256
-			'event'         => $this->get_event_schema(),
257
-			'organization'  => $this->get_organization_schema(),
258
-			'person'        => $this->get_person_schema(),
259
-			'place'         => $this->get_place_schema(),
260
-			'localbusiness' => $this->get_local_business_schema()
261
-		);
262
-
263
-	}
264
-
265
-	/**
266
-	 * Get a reference to the Schema service.
267
-	 *
268
-	 * @since 3.1.0
269
-	 *
270
-	 * @return Wordlift_Schema_Service A reference to the Schema service.
271
-	 */
272
-	public static function get_instance() {
273
-
274
-		return self::$instance;
275
-	}
276
-
277
-	/**
278
-	 * Get the properties for a field with the specified key. The key is used as
279
-	 * meta key when the field's value is stored in WordPress meta data table.
280
-	 *
281
-	 * @since 3.6.0
282
-	 *
283
-	 * @param string $key The field's key.
284
-	 *
285
-	 * @return null|array An array of field's properties or null if the field is not found.
286
-	 */
287
-	public function get_field( $key ) {
288
-
289
-		// Parse each schema's fields until we find the one we're looking for, then
290
-		// return its properties.
291
-		foreach ( $this->schema as $_ => $schema ) {
292
-
293
-			if ( ! isset( $schema['custom_fields'] ) ) {
294
-				break;
295
-			}
296
-
297
-			foreach ( $schema['custom_fields'] as $field => $props ) {
298
-				if ( $key === $field ) {
299
-					return $props;
300
-				}
301
-			}
302
-		}
303
-
304
-		return NULL;
305
-	}
306
-
307
-	/**
308
-	 * Get the WordLift's schema.
309
-	 *
310
-	 * @param string $name The schema name.
311
-	 *
312
-	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
313
-	 *
314
-	 * @since 3.1.0
315
-	 */
316
-	public function get_schema( $name ) {
317
-
318
-		// $this->log_service->trace( "Get schema [ name :: $name ]" );
319
-
320
-		// Check if the schema exists and, if not, return NULL.
321
-		if ( ! isset( $this->schema[ $name ] ) ) {
322
-			return NULL;
323
-		}
324
-
325
-		// Return the requested schema.
326
-		return $this->schema[ $name ];
327
-	}
328
-
329
-	/**
330
-	 * Get the WordLift's schema trough schema type uri.
331
-	 *
332
-	 * @param string $uri The schema uri.
333
-	 *
334
-	 * @return array|null An array with the schema configuration or NULL if the schema is not found.
335
-	 *
336
-	 * @since 3.3.0
337
-	 */
338
-	public function get_schema_by_uri( $uri ) {
339
-
340
-		foreach ( $this->schema as $name => $schema ) {
341
-			if ( $schema['uri'] === $uri ) {
342
-				return $schema;
343
-			}
344
-		}
345
-
346
-		return NULL;
347
-
348
-		// Return the requested schema.
349
-		return $this->schema[ $name ];
350
-	}
351
-
352
-	/**
353
-	 * Get the 'thing' schema.
354
-	 *
355
-	 * @return array An array with the schema configuration.
356
-	 *
357
-	 * @since 3.1.0
358
-	 */
359
-	private function get_thing_schema() {
360
-
361
-		return array(
362
-			'css_class'          => 'wl-thing',
363
-			'uri'                => 'http://schema.org/Thing',
364
-			'same_as'            => array( '*' ),
365
-			// set as default.
366
-			'custom_fields'      => array(
367
-				self::FIELD_SAME_AS                            => array(
368
-					'predicate'   => 'http://schema.org/sameAs',
369
-					'type'        => self::DATA_TYPE_URI,
370
-					'export_type' => 'http://schema.org/Thing',
371
-					'constraints' => array(
372
-						'cardinality' => INF
373
-					),
374
-					'input_field' => 'sameas'   // we need a custom metabox
375
-				),
376
-				// Add the schema:url property.
377
-				Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
378
-				                                                                                      ->get_compat_definition()
379
-			),
380
-			// {{sameAs}} not present in the microdata template,
381
-			// because it is treated separately in *wl_content_embed_item_microdata*
382
-			'microdata_template' => '',
383
-			'templates'          => array(
384
-				'subtitle' => '{{id}}'
385
-			)
386
-		);
387
-
388
-	}
389
-
390
-	/**
391
-	 * Get the 'creative work' schema.
392
-	 *
393
-	 * @return array An array with the schema configuration.
394
-	 *
395
-	 * @since 3.1.0
396
-	 */
397
-	private function get_creative_work_schema() {
398
-
399
-		$schema = array(
400
-			'label'              => 'CreativeWork',
401
-			'description'        => 'A creative work (or a Music Album).',
402
-			'parents'            => array( 'thing' ),
403
-			// give term slug as parent
404
-			'css_class'          => 'wl-creative-work',
405
-			'uri'                => 'http://schema.org/CreativeWork',
406
-			'same_as'            => array(
407
-				'http://schema.org/MusicAlbum',
408
-				'http://schema.org/Product'
409
-			),
410
-			'custom_fields'      => array(
411
-				self::FIELD_AUTHOR => array(
412
-					'predicate'   => 'http://schema.org/author',
413
-					'type'        => self::DATA_TYPE_URI,
414
-					'export_type' => 'http://schema.org/Person',
415
-					'constraints' => array(
416
-						'uri_type'    => array( 'Person', 'Organization' ),
417
-						'cardinality' => INF
418
-					)
419
-				),
420
-			),
421
-			'microdata_template' => '{{author}}',
422
-			'templates'          => array(
423
-				'subtitle' => '{{id}}'
424
-			)
425
-		);
426
-
427
-		// Merge the custom fields with those provided by the thing schema.
428
-		$thing_schema            = $this->get_thing_schema();
429
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
430
-
431
-		return $schema;
432
-	}
433
-
434
-	/**
435
-	 * Get the 'event' schema.
436
-	 *
437
-	 * @return array An array with the schema configuration.
438
-	 *
439
-	 * @since 3.1.0
440
-	 */
441
-	private function get_event_schema() {
442
-
443
-		$schema = array(
444
-			'label'              => 'Event',
445
-			'description'        => 'An event . ',
446
-			'parents'            => array( 'thing' ),
447
-			'css_class'          => 'wl-event',
448
-			'uri'                => self::SCHEMA_EVENT_TYPE,
449
-			'same_as'            => array( 'http://dbpedia.org/ontology/Event' ),
450
-			'custom_fields'      => array(
451
-				self::FIELD_DATE_START => array(
452
-					'predicate'   => 'http://schema.org/startDate',
453
-					'type'        => self::DATA_TYPE_DATE,
454
-					'export_type' => 'xsd:datetime',
455
-					'constraints' => ''
456
-				),
457
-				self::FIELD_DATE_END   => array(
458
-					'predicate'   => 'http://schema.org/endDate',
459
-					'type'        => self::DATA_TYPE_DATE,
460
-					'export_type' => 'xsd:datetime',
461
-					'constraints' => ''
462
-				),
463
-				self::FIELD_LOCATION   => array(
464
-					'predicate'   => 'http://schema.org/location',
465
-					'type'        => self::DATA_TYPE_URI,
466
-					'export_type' => 'http://schema.org/PostalAddress',
467
-					'constraints' => array(
468
-						'uri_type'    => array( 'Place', 'LocalBusiness' ),
469
-						'cardinality' => INF
470
-					)
471
-				)
472
-			),
473
-			'microdata_template' =>
474
-				'{{startDate}}
10
+    /**
11
+     * The 'location created' field name.
12
+     *
13
+     * @since 3.5.0
14
+     */
15
+    const FIELD_LOCATION_CREATED = 'wl_location_created';
16
+
17
+    /**
18
+     * The 'topic' field name.
19
+     *
20
+     * @since 3.5.0
21
+     */
22
+    const FIELD_TOPIC = 'wl_topic';
23
+
24
+    /**
25
+     * The 'author' field name.
26
+     *
27
+     * @since 3.1.0
28
+     */
29
+    const FIELD_AUTHOR = 'wl_author';
30
+
31
+    /**
32
+     * The 'same as' field name.
33
+     *
34
+     * @since 3.1.0
35
+     */
36
+    const FIELD_SAME_AS = 'entity_same_as';
37
+
38
+    /**
39
+     * The 'date start' field name.
40
+     *
41
+     * @since 3.1.0
42
+     */
43
+    const FIELD_DATE_START = 'wl_cal_date_start';
44
+
45
+    /**
46
+     * The 'date end' field name.
47
+     *
48
+     * @since 3.1.0
49
+     */
50
+    const FIELD_DATE_END = 'wl_cal_date_end';
51
+
52
+    /**
53
+     * The 'location' field name.
54
+     *
55
+     * @since 3.1.0
56
+     */
57
+    const FIELD_LOCATION = 'wl_location';
58
+
59
+    /**
60
+     * The 'founder' field name.
61
+     *
62
+     * @since 3.1.0
63
+     */
64
+    const FIELD_FOUNDER = 'wl_founder';
65
+
66
+    /**
67
+     * The 'knows' field name.
68
+     *
69
+     * @since 3.1.0
70
+     */
71
+    const FIELD_KNOWS = 'wl_knows';
72
+
73
+    /**
74
+     * The 'birth date' field name.
75
+     *
76
+     * @since 3.1.0
77
+     */
78
+    const FIELD_BIRTH_DATE = 'wl_birth_date';
79
+
80
+    /**
81
+     * The 'birth place' field name.
82
+     *
83
+     * @since 3.1.0
84
+     */
85
+    const FIELD_BIRTH_PLACE = 'wl_birth_place';
86
+
87
+    /**
88
+     * The 'latitude' field name.
89
+     *
90
+     * @since 3.1.0
91
+     */
92
+    const FIELD_GEO_LATITUDE = 'wl_geo_latitude';
93
+
94
+    /**
95
+     * The 'longitude' field name.
96
+     *
97
+     * @since 3.1.0
98
+     */
99
+    const FIELD_GEO_LONGITUDE = 'wl_geo_longitude';
100
+
101
+    /**
102
+     * The 'streetAddress' field name.
103
+     *
104
+     * @since 3.1.0
105
+     */
106
+    const FIELD_ADDRESS = 'wl_address';
107
+
108
+    /**
109
+     * The 'postOfficeBoxNumber' field name.
110
+     *
111
+     * @since 3.3.0
112
+     */
113
+    const FIELD_ADDRESS_PO_BOX = 'wl_address_post_office_box';
114
+
115
+    /**
116
+     * The 'postalCode' field name.
117
+     *
118
+     * @since 3.3.0
119
+     */
120
+    const FIELD_ADDRESS_POSTAL_CODE = 'wl_address_postal_code';
121
+
122
+    /**
123
+     * The 'addressLocality' field name.
124
+     *
125
+     * @since 3.3.0
126
+     */
127
+    const FIELD_ADDRESS_LOCALITY = 'wl_address_locality';
128
+    /**
129
+     * The 'addressRegion' field name.
130
+     *
131
+     * @since 3.3.0
132
+     */
133
+    const FIELD_ADDRESS_REGION = 'wl_address_region';
134
+
135
+    /**
136
+     * The 'addressCountry' field name.
137
+     *
138
+     * @since 3.3.0
139
+     */
140
+    const FIELD_ADDRESS_COUNTRY = 'wl_address_country';
141
+
142
+    /**
143
+     * The 'entity type' field name.
144
+     *
145
+     * @since 3.1.0
146
+     */
147
+    const FIELD_ENTITY_TYPE = 'wl_entity_type_uri';
148
+
149
+    /**
150
+     * The 'email' field name.
151
+     *
152
+     * @since 3.2.0
153
+     */
154
+    const FIELD_EMAIL = 'wl_email';
155
+
156
+    /**
157
+     * The 'affiliation' field name.
158
+     *
159
+     * @since 3.2.0
160
+     */
161
+    const FIELD_AFFILIATION = 'wl_affiliation';
162
+
163
+    /**
164
+     * The 'URI' data type name.
165
+     *
166
+     * @since 3.1.0
167
+     */
168
+    const DATA_TYPE_URI = 'uri';
169
+
170
+    /**
171
+     * The 'date' data type name.
172
+     *
173
+     * @since 3.1.0
174
+     */
175
+    const DATA_TYPE_DATE = 'date';
176
+
177
+    /**
178
+     * The 'double' data type name.
179
+     *
180
+     * @since 3.1.0
181
+     */
182
+    const DATA_TYPE_DOUBLE = 'double';
183
+
184
+    /**
185
+     * The 'string' data type name.
186
+     *
187
+     * @since 3.1.0
188
+     */
189
+    const DATA_TYPE_STRING = 'string';
190
+
191
+    /**
192
+     * The 'integer' data type name.
193
+     *
194
+     * @since 3.1.0
195
+     */
196
+    const DATA_TYPE_INTEGER = 'int';
197
+
198
+    /**
199
+     * The 'boolean' data type name.
200
+     *
201
+     * @since 3.1.0
202
+     */
203
+    const DATA_TYPE_BOOLEAN = 'bool';
204
+
205
+    /**
206
+     * The schema.org Event type URI.
207
+     *
208
+     * @since 3.1.0
209
+     */
210
+    const SCHEMA_EVENT_TYPE = 'http://schema.org/Event';
211
+
212
+    /**
213
+     * The Schema service singleton instance.
214
+     *
215
+     * @since 3.1.0
216
+     * @access private
217
+     * @var \Wordlift_Schema_Service $instance The Schema service singleton instance.
218
+     */
219
+    private static $instance;
220
+
221
+    /**
222
+     * WordLift's schema.
223
+     *
224
+     * @since 3.1.0
225
+     * @access private
226
+     * @var array $schema WordLift's schema.
227
+     */
228
+    private $schema;
229
+
230
+    /**
231
+     * The Log service.
232
+     *
233
+     * @since 3.1.0
234
+     * @access private
235
+     * @var \Wordlift_Log_Service $log_service The Log service.
236
+     */
237
+    private $log_service;
238
+
239
+    /**
240
+     * Wordlift_Schema_Service constructor.
241
+     *
242
+     * @since 3.1.0
243
+     */
244
+    public function __construct() {
245
+
246
+        $this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Schema_Service' );
247
+
248
+        // Create a singleton instance of the Schema service, useful to provide static functions to global functions.
249
+        self::$instance = $this;
250
+
251
+        // Set the taxonomy data.
252
+        // Note: parent types must be defined before child types.
253
+        $this->schema = array(
254
+            'thing'         => $this->get_thing_schema(),
255
+            'creative-work' => $this->get_creative_work_schema(),
256
+            'event'         => $this->get_event_schema(),
257
+            'organization'  => $this->get_organization_schema(),
258
+            'person'        => $this->get_person_schema(),
259
+            'place'         => $this->get_place_schema(),
260
+            'localbusiness' => $this->get_local_business_schema()
261
+        );
262
+
263
+    }
264
+
265
+    /**
266
+     * Get a reference to the Schema service.
267
+     *
268
+     * @since 3.1.0
269
+     *
270
+     * @return Wordlift_Schema_Service A reference to the Schema service.
271
+     */
272
+    public static function get_instance() {
273
+
274
+        return self::$instance;
275
+    }
276
+
277
+    /**
278
+     * Get the properties for a field with the specified key. The key is used as
279
+     * meta key when the field's value is stored in WordPress meta data table.
280
+     *
281
+     * @since 3.6.0
282
+     *
283
+     * @param string $key The field's key.
284
+     *
285
+     * @return null|array An array of field's properties or null if the field is not found.
286
+     */
287
+    public function get_field( $key ) {
288
+
289
+        // Parse each schema's fields until we find the one we're looking for, then
290
+        // return its properties.
291
+        foreach ( $this->schema as $_ => $schema ) {
292
+
293
+            if ( ! isset( $schema['custom_fields'] ) ) {
294
+                break;
295
+            }
296
+
297
+            foreach ( $schema['custom_fields'] as $field => $props ) {
298
+                if ( $key === $field ) {
299
+                    return $props;
300
+                }
301
+            }
302
+        }
303
+
304
+        return NULL;
305
+    }
306
+
307
+    /**
308
+     * Get the WordLift's schema.
309
+     *
310
+     * @param string $name The schema name.
311
+     *
312
+     * @return array|null An array with the schema configuration or NULL if the schema is not found.
313
+     *
314
+     * @since 3.1.0
315
+     */
316
+    public function get_schema( $name ) {
317
+
318
+        // $this->log_service->trace( "Get schema [ name :: $name ]" );
319
+
320
+        // Check if the schema exists and, if not, return NULL.
321
+        if ( ! isset( $this->schema[ $name ] ) ) {
322
+            return NULL;
323
+        }
324
+
325
+        // Return the requested schema.
326
+        return $this->schema[ $name ];
327
+    }
328
+
329
+    /**
330
+     * Get the WordLift's schema trough schema type uri.
331
+     *
332
+     * @param string $uri The schema uri.
333
+     *
334
+     * @return array|null An array with the schema configuration or NULL if the schema is not found.
335
+     *
336
+     * @since 3.3.0
337
+     */
338
+    public function get_schema_by_uri( $uri ) {
339
+
340
+        foreach ( $this->schema as $name => $schema ) {
341
+            if ( $schema['uri'] === $uri ) {
342
+                return $schema;
343
+            }
344
+        }
345
+
346
+        return NULL;
347
+
348
+        // Return the requested schema.
349
+        return $this->schema[ $name ];
350
+    }
351
+
352
+    /**
353
+     * Get the 'thing' schema.
354
+     *
355
+     * @return array An array with the schema configuration.
356
+     *
357
+     * @since 3.1.0
358
+     */
359
+    private function get_thing_schema() {
360
+
361
+        return array(
362
+            'css_class'          => 'wl-thing',
363
+            'uri'                => 'http://schema.org/Thing',
364
+            'same_as'            => array( '*' ),
365
+            // set as default.
366
+            'custom_fields'      => array(
367
+                self::FIELD_SAME_AS                            => array(
368
+                    'predicate'   => 'http://schema.org/sameAs',
369
+                    'type'        => self::DATA_TYPE_URI,
370
+                    'export_type' => 'http://schema.org/Thing',
371
+                    'constraints' => array(
372
+                        'cardinality' => INF
373
+                    ),
374
+                    'input_field' => 'sameas'   // we need a custom metabox
375
+                ),
376
+                // Add the schema:url property.
377
+                Wordlift_Schema_Url_Property_Service::META_KEY => Wordlift_Schema_Url_Property_Service::get_instance()
378
+                                                                                                        ->get_compat_definition()
379
+            ),
380
+            // {{sameAs}} not present in the microdata template,
381
+            // because it is treated separately in *wl_content_embed_item_microdata*
382
+            'microdata_template' => '',
383
+            'templates'          => array(
384
+                'subtitle' => '{{id}}'
385
+            )
386
+        );
387
+
388
+    }
389
+
390
+    /**
391
+     * Get the 'creative work' schema.
392
+     *
393
+     * @return array An array with the schema configuration.
394
+     *
395
+     * @since 3.1.0
396
+     */
397
+    private function get_creative_work_schema() {
398
+
399
+        $schema = array(
400
+            'label'              => 'CreativeWork',
401
+            'description'        => 'A creative work (or a Music Album).',
402
+            'parents'            => array( 'thing' ),
403
+            // give term slug as parent
404
+            'css_class'          => 'wl-creative-work',
405
+            'uri'                => 'http://schema.org/CreativeWork',
406
+            'same_as'            => array(
407
+                'http://schema.org/MusicAlbum',
408
+                'http://schema.org/Product'
409
+            ),
410
+            'custom_fields'      => array(
411
+                self::FIELD_AUTHOR => array(
412
+                    'predicate'   => 'http://schema.org/author',
413
+                    'type'        => self::DATA_TYPE_URI,
414
+                    'export_type' => 'http://schema.org/Person',
415
+                    'constraints' => array(
416
+                        'uri_type'    => array( 'Person', 'Organization' ),
417
+                        'cardinality' => INF
418
+                    )
419
+                ),
420
+            ),
421
+            'microdata_template' => '{{author}}',
422
+            'templates'          => array(
423
+                'subtitle' => '{{id}}'
424
+            )
425
+        );
426
+
427
+        // Merge the custom fields with those provided by the thing schema.
428
+        $thing_schema            = $this->get_thing_schema();
429
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
430
+
431
+        return $schema;
432
+    }
433
+
434
+    /**
435
+     * Get the 'event' schema.
436
+     *
437
+     * @return array An array with the schema configuration.
438
+     *
439
+     * @since 3.1.0
440
+     */
441
+    private function get_event_schema() {
442
+
443
+        $schema = array(
444
+            'label'              => 'Event',
445
+            'description'        => 'An event . ',
446
+            'parents'            => array( 'thing' ),
447
+            'css_class'          => 'wl-event',
448
+            'uri'                => self::SCHEMA_EVENT_TYPE,
449
+            'same_as'            => array( 'http://dbpedia.org/ontology/Event' ),
450
+            'custom_fields'      => array(
451
+                self::FIELD_DATE_START => array(
452
+                    'predicate'   => 'http://schema.org/startDate',
453
+                    'type'        => self::DATA_TYPE_DATE,
454
+                    'export_type' => 'xsd:datetime',
455
+                    'constraints' => ''
456
+                ),
457
+                self::FIELD_DATE_END   => array(
458
+                    'predicate'   => 'http://schema.org/endDate',
459
+                    'type'        => self::DATA_TYPE_DATE,
460
+                    'export_type' => 'xsd:datetime',
461
+                    'constraints' => ''
462
+                ),
463
+                self::FIELD_LOCATION   => array(
464
+                    'predicate'   => 'http://schema.org/location',
465
+                    'type'        => self::DATA_TYPE_URI,
466
+                    'export_type' => 'http://schema.org/PostalAddress',
467
+                    'constraints' => array(
468
+                        'uri_type'    => array( 'Place', 'LocalBusiness' ),
469
+                        'cardinality' => INF
470
+                    )
471
+                )
472
+            ),
473
+            'microdata_template' =>
474
+                '{{startDate}}
475 475
                                 {{endDate}}
476 476
                                 {{location}}',
477
-			'templates'          => array(
478
-				'subtitle' => '{{id}}'
479
-			)
480
-		);
481
-
482
-		// Merge the custom fields with those provided by the thing schema.
483
-		$thing_schema            = $this->get_thing_schema();
484
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
485
-
486
-		return $schema;
487
-	}
488
-
489
-	/**
490
-	 * Get the 'organization' schema.
491
-	 *
492
-	 * @return array An array with the schema configuration.
493
-	 *
494
-	 * @since 3.1.0
495
-	 */
496
-	private function get_organization_schema() {
497
-
498
-		$schema = array(
499
-			'label'              => 'Organization',
500
-			'description'        => 'An organization, including a government or a newspaper.',
501
-			'parents'            => array( 'thing' ),
502
-			'css_class'          => 'wl-organization',
503
-			'uri'                => 'http://schema.org/Organization',
504
-			'same_as'            => array(
505
-				'http://rdf.freebase.com/ns/organization.organization',
506
-				'http://rdf.freebase.com/ns/government.government',
507
-				'http://schema.org/Newspaper'
508
-			),
509
-			'custom_fields'      => array(
510
-				self::FIELD_FOUNDER             => array(
511
-					'predicate'   => 'http://schema.org/founder',
512
-					'type'        => self::DATA_TYPE_URI,
513
-					'export_type' => 'http://schema.org/Person',
514
-					'constraints' => array(
515
-						'uri_type'    => 'Person',
516
-						'cardinality' => INF
517
-					)
518
-				),
519
-				self::FIELD_ADDRESS             => array(
520
-					'predicate'   => 'http://schema.org/streetAddress',
521
-					'type'        => self::DATA_TYPE_STRING,
522
-					'export_type' => 'xsd:string',
523
-					'constraints' => '',
524
-					'input_field' => 'address'   // to build custom metabox
525
-				),
526
-				self::FIELD_ADDRESS_PO_BOX      => array(
527
-					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
528
-					'type'        => self::DATA_TYPE_STRING,
529
-					'export_type' => 'xsd:string',
530
-					'constraints' => '',
531
-					'input_field' => 'address'   // to build custom metabox
532
-				),
533
-				self::FIELD_ADDRESS_POSTAL_CODE => array(
534
-					'predicate'   => 'http://schema.org/postalCode',
535
-					'type'        => self::DATA_TYPE_STRING,
536
-					'export_type' => 'xsd:string',
537
-					'constraints' => '',
538
-					'input_field' => 'address'   // to build custom metabox
539
-				),
540
-				self::FIELD_ADDRESS_LOCALITY    => array(
541
-					'predicate'   => 'http://schema.org/addressLocality',
542
-					'type'        => self::DATA_TYPE_STRING,
543
-					'export_type' => 'xsd:string',
544
-					'constraints' => '',
545
-					'input_field' => 'address'   // to build custom metabox
546
-				),
547
-				self::FIELD_ADDRESS_REGION      => array(
548
-					'predicate'   => 'http://schema.org/addressRegion',
549
-					'type'        => self::DATA_TYPE_STRING,
550
-					'export_type' => 'xsd:string',
551
-					'constraints' => '',
552
-					'input_field' => 'address'   // to build custom metabox
553
-				),
554
-				self::FIELD_ADDRESS_COUNTRY     => array(
555
-					'predicate'   => 'http://schema.org/addressCountry',
556
-					'type'        => self::DATA_TYPE_STRING,
557
-					'export_type' => 'xsd:string',
558
-					'constraints' => '',
559
-					'input_field' => 'address'   // to build custom metabox
560
-				),
561
-				self::FIELD_EMAIL               => array(
562
-					'predicate'   => 'http://schema.org/email',
563
-					'type'        => self::DATA_TYPE_STRING,
564
-					'export_type' => 'xsd:string',
565
-					'constraints' => ''
566
-				),
567
-				'wl_schema_telephone'           => array(
568
-					'predicate'   => 'http://schema.org/telephone',
569
-					'type'        => self::DATA_TYPE_STRING,
570
-					'export_type' => 'xsd:string',
571
-					'constraints' => ''
572
-				),
573
-			),
574
-			'microdata_template' => '{{founder}}'
575
-			                        . '<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{{streetAddress}}{{postOfficeBoxNumber}}{{postalCode}}{{addressLocality}}{{addressRegion}}{{addressCountry}}{{email}}</span>',
576
-			'templates'          => array(
577
-				'subtitle' => '{{id}}'
578
-			)
579
-		);
580
-
581
-		// Merge the custom fields with those provided by the thing schema.
582
-		$thing_schema            = $this->get_thing_schema();
583
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
584
-
585
-		return $schema;
586
-	}
587
-
588
-	/**
589
-	 * Get the 'person' schema.
590
-	 *
591
-	 * @return array An array with the schema configuration.
592
-	 *
593
-	 * @since 3.1.0
594
-	 */
595
-	private function get_person_schema() {
596
-
597
-		$schema = array(
598
-			'label'              => 'Person',
599
-			'description'        => 'A person (or a music artist).',
600
-			'parents'            => array( 'thing' ),
601
-			'css_class'          => 'wl-person',
602
-			'uri'                => 'http://schema.org/Person',
603
-			'same_as'            => array(
604
-				'http://rdf.freebase.com/ns/people.person',
605
-				'http://rdf.freebase.com/ns/music.artist',
606
-				'http://dbpedia.org/class/yago/LivingPeople'
607
-			),
608
-			'custom_fields'      => array(
609
-				self::FIELD_KNOWS       => array(
610
-					'predicate'   => 'http://schema.org/knows',
611
-					'type'        => self::DATA_TYPE_URI,
612
-					'export_type' => 'http://schema.org/Person',
613
-					'constraints' => array(
614
-						'uri_type'    => 'Person',
615
-						'cardinality' => INF
616
-					)
617
-				),
618
-				self::FIELD_BIRTH_DATE  => array(
619
-					'predicate'   => 'http://schema.org/birthDate',
620
-					'type'        => self::DATA_TYPE_DATE,
621
-					'export_type' => 'xsd:date',
622
-					'constraints' => ''
623
-				),
624
-				self::FIELD_BIRTH_PLACE => array(
625
-					'predicate'   => 'http://schema.org/birthPlace',
626
-					'type'        => self::DATA_TYPE_URI,
627
-					'export_type' => 'http://schema.org/Place',
628
-					'constraints' => array(
629
-						'uri_type' => 'Place'
630
-					)
631
-				),
632
-				self::FIELD_AFFILIATION => array(
633
-					'predicate'   => 'http://schema.org/affiliation',
634
-					'type'        => self::DATA_TYPE_URI,
635
-					'export_type' => 'http://schema.org/Organization',
636
-					'constraints' => array(
637
-						'uri_type'    => array(
638
-							'Organization',
639
-							'LocalBusiness'
640
-						),
641
-						'cardinality' => INF
642
-					)
643
-				),
644
-				self::FIELD_EMAIL       => array(
645
-					'predicate'   => 'http://schema.org/email',
646
-					'type'        => self::DATA_TYPE_STRING,
647
-					'export_type' => 'xsd:string',
648
-					'constraints' => array(
649
-						'cardinality' => INF
650
-					)
651
-				)
652
-			),
653
-			'microdata_template' => '{{birthDate}}{{birthPlace}}{{knows}}{{affiliation}}{{email}}',
654
-			'templates'          => array(
655
-				'subtitle' => '{{id}}'
656
-			)
657
-		);
658
-
659
-		// Merge the custom fields with those provided by the thing schema.
660
-		$thing_schema            = $this->get_thing_schema();
661
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
662
-
663
-		return $schema;
664
-
665
-	}
666
-
667
-	/**
668
-	 * Get the 'place' schema.
669
-	 *
670
-	 * @return array An array with the schema configuration.
671
-	 *
672
-	 * @since 3.1.0
673
-	 */
674
-	private function get_place_schema() {
675
-
676
-		$schema = array(
677
-			'label'              => 'Place',
678
-			'description'        => 'A place.',
679
-			'parents'            => array( 'thing' ),
680
-			'css_class'          => 'wl-place',
681
-			'uri'                => 'http://schema.org/Place',
682
-			'same_as'            => array(
683
-				'http://rdf.freebase.com/ns/location.location',
684
-				'http://www.opengis.net/gml/_Feature'
685
-			),
686
-			'custom_fields'      => array(
687
-				self::FIELD_GEO_LATITUDE        => array(
688
-					'predicate'   => 'http://schema.org/latitude',
689
-					'type'        => self::DATA_TYPE_DOUBLE,
690
-					'export_type' => 'xsd:double',
691
-					'constraints' => '',
692
-					'input_field' => 'coordinates'   // to build custom metabox
693
-				),
694
-				self::FIELD_GEO_LONGITUDE       => array(
695
-					'predicate'   => 'http://schema.org/longitude',
696
-					'type'        => self::DATA_TYPE_DOUBLE,
697
-					'export_type' => 'xsd:double',
698
-					'constraints' => '',
699
-					'input_field' => 'coordinates'   // to build custom metabox
700
-				),
701
-				self::FIELD_ADDRESS             => array(
702
-					'predicate'   => 'http://schema.org/streetAddress',
703
-					'type'        => self::DATA_TYPE_STRING,
704
-					'export_type' => 'xsd:string',
705
-					'constraints' => '',
706
-					'input_field' => 'address'   // to build custom metabox
707
-				),
708
-				self::FIELD_ADDRESS_PO_BOX      => array(
709
-					'predicate'   => 'http://schema.org/postOfficeBoxNumber',
710
-					'type'        => self::DATA_TYPE_STRING,
711
-					'export_type' => 'xsd:string',
712
-					'constraints' => '',
713
-					'input_field' => 'address'   // to build custom metabox
714
-				),
715
-				self::FIELD_ADDRESS_POSTAL_CODE => array(
716
-					'predicate'   => 'http://schema.org/postalCode',
717
-					'type'        => self::DATA_TYPE_STRING,
718
-					'export_type' => 'xsd:string',
719
-					'constraints' => '',
720
-					'input_field' => 'address'   // to build custom metabox
721
-				),
722
-				self::FIELD_ADDRESS_LOCALITY    => array(
723
-					'predicate'   => 'http://schema.org/addressLocality',
724
-					'type'        => self::DATA_TYPE_STRING,
725
-					'export_type' => 'xsd:string',
726
-					'constraints' => '',
727
-					'input_field' => 'address'   // to build custom metabox
728
-				),
729
-				self::FIELD_ADDRESS_REGION      => array(
730
-					'predicate'   => 'http://schema.org/addressRegion',
731
-					'type'        => self::DATA_TYPE_STRING,
732
-					'export_type' => 'xsd:string',
733
-					'constraints' => '',
734
-					'input_field' => 'address'   // to build custom metabox
735
-				),
736
-				self::FIELD_ADDRESS_COUNTRY     => array(
737
-					'predicate'   => 'http://schema.org/addressCountry',
738
-					'type'        => self::DATA_TYPE_STRING,
739
-					'export_type' => 'xsd:string',
740
-					'constraints' => '',
741
-					'input_field' => 'address'   // to build custom metabox
742
-				)
743
-			),
744
-			'microdata_template' => '<span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates">{{latitude}}{{longitude}}</span>'
745
-			                        . '<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{{streetAddress}}{{postOfficeBoxNumber}}{{postalCode}}{{addressLocality}}{{addressRegion}}{{addressCountry}}</span>',
746
-			'templates'          => array(
747
-				'subtitle' => '{{id}}'
748
-			)
749
-		);
750
-
751
-		// Merge the custom fields with those provided by the thing schema.
752
-		$thing_schema            = $this->get_thing_schema();
753
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
754
-
755
-		return $schema;
756
-	}
757
-
758
-	/**
759
-	 * Get the 'local business' schema.
760
-	 *
761
-	 * @return array An array with the schema configuration.
762
-	 *
763
-	 * @since 3.1.0
764
-	 */
765
-	private function get_local_business_schema() {
766
-
767
-		$schema = array(
768
-			'label'              => 'LocalBusiness',
769
-			'description'        => 'A local business.',
770
-			'parents'            => array( 'place', 'organization' ),
771
-			'css_class'          => 'wl-local-business',
772
-			'uri'                => 'http://schema.org/LocalBusiness',
773
-			'same_as'            => array(
774
-				'http://rdf.freebase.com/ns/business/business_location',
775
-				'https://schema.org/Store'
776
-			),
777
-			'custom_fields'      => array(),
778
-			'microdata_template' => '<span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates">{{latitude}}{{longitude}}</span>'
779
-			                        . '<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{{streetAddress}}{{postOfficeBoxNumber}}{{postalCode}}{{addressLocality}}{{addressRegion}}{{addressCountry}}</span>'
780
-			                        . '{{founder}}'
781
-			                        . '{{email}}',
782
-			'templates'          => array(
783
-				'subtitle' => '{{id}}'
784
-			)
785
-		);
786
-
787
-		// Merge the custom fields with those provided by the place and organization schema.
788
-		$place_schema            = $this->get_place_schema();
789
-		$organization_schema     = $this->get_organization_schema();
790
-		$schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
791
-
792
-		return $schema;
793
-	}
477
+            'templates'          => array(
478
+                'subtitle' => '{{id}}'
479
+            )
480
+        );
481
+
482
+        // Merge the custom fields with those provided by the thing schema.
483
+        $thing_schema            = $this->get_thing_schema();
484
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
485
+
486
+        return $schema;
487
+    }
488
+
489
+    /**
490
+     * Get the 'organization' schema.
491
+     *
492
+     * @return array An array with the schema configuration.
493
+     *
494
+     * @since 3.1.0
495
+     */
496
+    private function get_organization_schema() {
497
+
498
+        $schema = array(
499
+            'label'              => 'Organization',
500
+            'description'        => 'An organization, including a government or a newspaper.',
501
+            'parents'            => array( 'thing' ),
502
+            'css_class'          => 'wl-organization',
503
+            'uri'                => 'http://schema.org/Organization',
504
+            'same_as'            => array(
505
+                'http://rdf.freebase.com/ns/organization.organization',
506
+                'http://rdf.freebase.com/ns/government.government',
507
+                'http://schema.org/Newspaper'
508
+            ),
509
+            'custom_fields'      => array(
510
+                self::FIELD_FOUNDER             => array(
511
+                    'predicate'   => 'http://schema.org/founder',
512
+                    'type'        => self::DATA_TYPE_URI,
513
+                    'export_type' => 'http://schema.org/Person',
514
+                    'constraints' => array(
515
+                        'uri_type'    => 'Person',
516
+                        'cardinality' => INF
517
+                    )
518
+                ),
519
+                self::FIELD_ADDRESS             => array(
520
+                    'predicate'   => 'http://schema.org/streetAddress',
521
+                    'type'        => self::DATA_TYPE_STRING,
522
+                    'export_type' => 'xsd:string',
523
+                    'constraints' => '',
524
+                    'input_field' => 'address'   // to build custom metabox
525
+                ),
526
+                self::FIELD_ADDRESS_PO_BOX      => array(
527
+                    'predicate'   => 'http://schema.org/postOfficeBoxNumber',
528
+                    'type'        => self::DATA_TYPE_STRING,
529
+                    'export_type' => 'xsd:string',
530
+                    'constraints' => '',
531
+                    'input_field' => 'address'   // to build custom metabox
532
+                ),
533
+                self::FIELD_ADDRESS_POSTAL_CODE => array(
534
+                    'predicate'   => 'http://schema.org/postalCode',
535
+                    'type'        => self::DATA_TYPE_STRING,
536
+                    'export_type' => 'xsd:string',
537
+                    'constraints' => '',
538
+                    'input_field' => 'address'   // to build custom metabox
539
+                ),
540
+                self::FIELD_ADDRESS_LOCALITY    => array(
541
+                    'predicate'   => 'http://schema.org/addressLocality',
542
+                    'type'        => self::DATA_TYPE_STRING,
543
+                    'export_type' => 'xsd:string',
544
+                    'constraints' => '',
545
+                    'input_field' => 'address'   // to build custom metabox
546
+                ),
547
+                self::FIELD_ADDRESS_REGION      => array(
548
+                    'predicate'   => 'http://schema.org/addressRegion',
549
+                    'type'        => self::DATA_TYPE_STRING,
550
+                    'export_type' => 'xsd:string',
551
+                    'constraints' => '',
552
+                    'input_field' => 'address'   // to build custom metabox
553
+                ),
554
+                self::FIELD_ADDRESS_COUNTRY     => array(
555
+                    'predicate'   => 'http://schema.org/addressCountry',
556
+                    'type'        => self::DATA_TYPE_STRING,
557
+                    'export_type' => 'xsd:string',
558
+                    'constraints' => '',
559
+                    'input_field' => 'address'   // to build custom metabox
560
+                ),
561
+                self::FIELD_EMAIL               => array(
562
+                    'predicate'   => 'http://schema.org/email',
563
+                    'type'        => self::DATA_TYPE_STRING,
564
+                    'export_type' => 'xsd:string',
565
+                    'constraints' => ''
566
+                ),
567
+                'wl_schema_telephone'           => array(
568
+                    'predicate'   => 'http://schema.org/telephone',
569
+                    'type'        => self::DATA_TYPE_STRING,
570
+                    'export_type' => 'xsd:string',
571
+                    'constraints' => ''
572
+                ),
573
+            ),
574
+            'microdata_template' => '{{founder}}'
575
+                                    . '<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{{streetAddress}}{{postOfficeBoxNumber}}{{postalCode}}{{addressLocality}}{{addressRegion}}{{addressCountry}}{{email}}</span>',
576
+            'templates'          => array(
577
+                'subtitle' => '{{id}}'
578
+            )
579
+        );
580
+
581
+        // Merge the custom fields with those provided by the thing schema.
582
+        $thing_schema            = $this->get_thing_schema();
583
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
584
+
585
+        return $schema;
586
+    }
587
+
588
+    /**
589
+     * Get the 'person' schema.
590
+     *
591
+     * @return array An array with the schema configuration.
592
+     *
593
+     * @since 3.1.0
594
+     */
595
+    private function get_person_schema() {
596
+
597
+        $schema = array(
598
+            'label'              => 'Person',
599
+            'description'        => 'A person (or a music artist).',
600
+            'parents'            => array( 'thing' ),
601
+            'css_class'          => 'wl-person',
602
+            'uri'                => 'http://schema.org/Person',
603
+            'same_as'            => array(
604
+                'http://rdf.freebase.com/ns/people.person',
605
+                'http://rdf.freebase.com/ns/music.artist',
606
+                'http://dbpedia.org/class/yago/LivingPeople'
607
+            ),
608
+            'custom_fields'      => array(
609
+                self::FIELD_KNOWS       => array(
610
+                    'predicate'   => 'http://schema.org/knows',
611
+                    'type'        => self::DATA_TYPE_URI,
612
+                    'export_type' => 'http://schema.org/Person',
613
+                    'constraints' => array(
614
+                        'uri_type'    => 'Person',
615
+                        'cardinality' => INF
616
+                    )
617
+                ),
618
+                self::FIELD_BIRTH_DATE  => array(
619
+                    'predicate'   => 'http://schema.org/birthDate',
620
+                    'type'        => self::DATA_TYPE_DATE,
621
+                    'export_type' => 'xsd:date',
622
+                    'constraints' => ''
623
+                ),
624
+                self::FIELD_BIRTH_PLACE => array(
625
+                    'predicate'   => 'http://schema.org/birthPlace',
626
+                    'type'        => self::DATA_TYPE_URI,
627
+                    'export_type' => 'http://schema.org/Place',
628
+                    'constraints' => array(
629
+                        'uri_type' => 'Place'
630
+                    )
631
+                ),
632
+                self::FIELD_AFFILIATION => array(
633
+                    'predicate'   => 'http://schema.org/affiliation',
634
+                    'type'        => self::DATA_TYPE_URI,
635
+                    'export_type' => 'http://schema.org/Organization',
636
+                    'constraints' => array(
637
+                        'uri_type'    => array(
638
+                            'Organization',
639
+                            'LocalBusiness'
640
+                        ),
641
+                        'cardinality' => INF
642
+                    )
643
+                ),
644
+                self::FIELD_EMAIL       => array(
645
+                    'predicate'   => 'http://schema.org/email',
646
+                    'type'        => self::DATA_TYPE_STRING,
647
+                    'export_type' => 'xsd:string',
648
+                    'constraints' => array(
649
+                        'cardinality' => INF
650
+                    )
651
+                )
652
+            ),
653
+            'microdata_template' => '{{birthDate}}{{birthPlace}}{{knows}}{{affiliation}}{{email}}',
654
+            'templates'          => array(
655
+                'subtitle' => '{{id}}'
656
+            )
657
+        );
658
+
659
+        // Merge the custom fields with those provided by the thing schema.
660
+        $thing_schema            = $this->get_thing_schema();
661
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
662
+
663
+        return $schema;
664
+
665
+    }
666
+
667
+    /**
668
+     * Get the 'place' schema.
669
+     *
670
+     * @return array An array with the schema configuration.
671
+     *
672
+     * @since 3.1.0
673
+     */
674
+    private function get_place_schema() {
675
+
676
+        $schema = array(
677
+            'label'              => 'Place',
678
+            'description'        => 'A place.',
679
+            'parents'            => array( 'thing' ),
680
+            'css_class'          => 'wl-place',
681
+            'uri'                => 'http://schema.org/Place',
682
+            'same_as'            => array(
683
+                'http://rdf.freebase.com/ns/location.location',
684
+                'http://www.opengis.net/gml/_Feature'
685
+            ),
686
+            'custom_fields'      => array(
687
+                self::FIELD_GEO_LATITUDE        => array(
688
+                    'predicate'   => 'http://schema.org/latitude',
689
+                    'type'        => self::DATA_TYPE_DOUBLE,
690
+                    'export_type' => 'xsd:double',
691
+                    'constraints' => '',
692
+                    'input_field' => 'coordinates'   // to build custom metabox
693
+                ),
694
+                self::FIELD_GEO_LONGITUDE       => array(
695
+                    'predicate'   => 'http://schema.org/longitude',
696
+                    'type'        => self::DATA_TYPE_DOUBLE,
697
+                    'export_type' => 'xsd:double',
698
+                    'constraints' => '',
699
+                    'input_field' => 'coordinates'   // to build custom metabox
700
+                ),
701
+                self::FIELD_ADDRESS             => array(
702
+                    'predicate'   => 'http://schema.org/streetAddress',
703
+                    'type'        => self::DATA_TYPE_STRING,
704
+                    'export_type' => 'xsd:string',
705
+                    'constraints' => '',
706
+                    'input_field' => 'address'   // to build custom metabox
707
+                ),
708
+                self::FIELD_ADDRESS_PO_BOX      => array(
709
+                    'predicate'   => 'http://schema.org/postOfficeBoxNumber',
710
+                    'type'        => self::DATA_TYPE_STRING,
711
+                    'export_type' => 'xsd:string',
712
+                    'constraints' => '',
713
+                    'input_field' => 'address'   // to build custom metabox
714
+                ),
715
+                self::FIELD_ADDRESS_POSTAL_CODE => array(
716
+                    'predicate'   => 'http://schema.org/postalCode',
717
+                    'type'        => self::DATA_TYPE_STRING,
718
+                    'export_type' => 'xsd:string',
719
+                    'constraints' => '',
720
+                    'input_field' => 'address'   // to build custom metabox
721
+                ),
722
+                self::FIELD_ADDRESS_LOCALITY    => array(
723
+                    'predicate'   => 'http://schema.org/addressLocality',
724
+                    'type'        => self::DATA_TYPE_STRING,
725
+                    'export_type' => 'xsd:string',
726
+                    'constraints' => '',
727
+                    'input_field' => 'address'   // to build custom metabox
728
+                ),
729
+                self::FIELD_ADDRESS_REGION      => array(
730
+                    'predicate'   => 'http://schema.org/addressRegion',
731
+                    'type'        => self::DATA_TYPE_STRING,
732
+                    'export_type' => 'xsd:string',
733
+                    'constraints' => '',
734
+                    'input_field' => 'address'   // to build custom metabox
735
+                ),
736
+                self::FIELD_ADDRESS_COUNTRY     => array(
737
+                    'predicate'   => 'http://schema.org/addressCountry',
738
+                    'type'        => self::DATA_TYPE_STRING,
739
+                    'export_type' => 'xsd:string',
740
+                    'constraints' => '',
741
+                    'input_field' => 'address'   // to build custom metabox
742
+                )
743
+            ),
744
+            'microdata_template' => '<span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates">{{latitude}}{{longitude}}</span>'
745
+                                    . '<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{{streetAddress}}{{postOfficeBoxNumber}}{{postalCode}}{{addressLocality}}{{addressRegion}}{{addressCountry}}</span>',
746
+            'templates'          => array(
747
+                'subtitle' => '{{id}}'
748
+            )
749
+        );
750
+
751
+        // Merge the custom fields with those provided by the thing schema.
752
+        $thing_schema            = $this->get_thing_schema();
753
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $thing_schema['custom_fields'] );
754
+
755
+        return $schema;
756
+    }
757
+
758
+    /**
759
+     * Get the 'local business' schema.
760
+     *
761
+     * @return array An array with the schema configuration.
762
+     *
763
+     * @since 3.1.0
764
+     */
765
+    private function get_local_business_schema() {
766
+
767
+        $schema = array(
768
+            'label'              => 'LocalBusiness',
769
+            'description'        => 'A local business.',
770
+            'parents'            => array( 'place', 'organization' ),
771
+            'css_class'          => 'wl-local-business',
772
+            'uri'                => 'http://schema.org/LocalBusiness',
773
+            'same_as'            => array(
774
+                'http://rdf.freebase.com/ns/business/business_location',
775
+                'https://schema.org/Store'
776
+            ),
777
+            'custom_fields'      => array(),
778
+            'microdata_template' => '<span itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates">{{latitude}}{{longitude}}</span>'
779
+                                    . '<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{{streetAddress}}{{postOfficeBoxNumber}}{{postalCode}}{{addressLocality}}{{addressRegion}}{{addressCountry}}</span>'
780
+                                    . '{{founder}}'
781
+                                    . '{{email}}',
782
+            'templates'          => array(
783
+                'subtitle' => '{{id}}'
784
+            )
785
+        );
786
+
787
+        // Merge the custom fields with those provided by the place and organization schema.
788
+        $place_schema            = $this->get_place_schema();
789
+        $organization_schema     = $this->get_organization_schema();
790
+        $schema['custom_fields'] = array_merge( $schema['custom_fields'], $place_schema['custom_fields'], $organization_schema['custom_fields'] );
791
+
792
+        return $schema;
793
+    }
794 794
 
795 795
 }
Please login to merge, or discard this patch.
src/includes/class-wordlift-entity-service.php 2 patches
Indentation   +835 added lines, -835 removed lines patch added patch discarded remove patch
@@ -7,845 +7,845 @@
 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_service The Log service.
16
-	 */
17
-	private $log_service;
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 Schema service.
30
-	 *
31
-	 * @since 3.3.0
32
-	 * @access private
33
-	 * @var \Wordlift_Schema_Service $schema_service The Schema service.
34
-	 */
35
-	private $schema_service;
36
-
37
-	/**
38
-	 * The Notice service.
39
-	 *
40
-	 * @since 3.3.0
41
-	 * @access private
42
-	 * @var \Wordlift_Notice_Service $notice_service The Notice service.
43
-	 */
44
-	private $notice_service;
45
-
46
-	/**
47
-	 * The entity post type name.
48
-	 *
49
-	 * @since 3.1.0
50
-	 */
51
-	const TYPE_NAME = 'entity';
52
-
53
-	/**
54
-	 * Entity rating max.
55
-	 *
56
-	 * @since 3.3.0
57
-	 */
58
-	const RATING_MAX = 7;
59
-
60
-	/**
61
-	 * Entity rating score meta key.
62
-	 *
63
-	 * @since 3.3.0
64
-	 */
65
-	const RATING_RAW_SCORE_META_KEY = '_wl_entity_rating_raw_score';
66
-
67
-	/**
68
-	 * Entity rating warnings meta key.
69
-	 *
70
-	 * @since 3.3.0
71
-	 */
72
-	const RATING_WARNINGS_META_KEY = '_wl_entity_rating_warnings';
73
-
74
-	/**
75
-	 * Entity warning has related post identifier.
76
-	 *
77
-	 * @since 3.3.0
78
-	 */
79
-	const RATING_WARNING_HAS_RELATED_POSTS = 'There are no related posts for the current entity.';
80
-
81
-	/**
82
-	 * Entity warning has content post identifier.
83
-	 *
84
-	 * @since 3.3.0
85
-	 */
86
-	const RATING_WARNING_HAS_CONTENT_POST = 'This entity has not description.';
87
-
88
-	/**
89
-	 * Entity warning has related entities identifier.
90
-	 *
91
-	 * @since 3.3.0
92
-	 */
93
-	const RATING_WARNING_HAS_RELATED_ENTITIES = 'There are no related entities for the current entity.';
94
-
95
-	/**
96
-	 * Entity warning is published identifier.
97
-	 *
98
-	 * @since 3.3.0
99
-	 */
100
-	const RATING_WARNING_IS_PUBLISHED = 'This entity is not published. It will not appear within analysis results.';
101
-
102
-	/**
103
-	 * Entity warning has thumbnail identifier.
104
-	 *
105
-	 * @since 3.3.0
106
-	 */
107
-	const RATING_WARNING_HAS_THUMBNAIL = 'This entity has no featured image yet.';
108
-
109
-	/**
110
-	 * Entity warning has same as identifier.
111
-	 *
112
-	 * @since 3.3.0
113
-	 */
114
-	const RATING_WARNING_HAS_SAME_AS = 'There are no sameAs configured for this entity.';
115
-
116
-	/**
117
-	 * Entity warning has completed metadata identifier.
118
-	 *
119
-	 * @since 3.3.0
120
-	 */
121
-	const RATING_WARNING_HAS_COMPLETED_METADATA = 'Schema.org metadata for this entity are not completed.';
122
-
123
-	/**
124
-	 * The alternative label meta key.
125
-	 *
126
-	 * @since 3.2.0
127
-	 */
128
-	const ALTERNATIVE_LABEL_META_KEY = '_wl_alt_label';
129
-
130
-	/**
131
-	 * The alternative label input template.
132
-	 *
133
-	 * @since 3.2.0
134
-	 */
135
-	// TODO: this should be moved to a class that deals with HTML code.
136
-	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_service The Log service.
16
+     */
17
+    private $log_service;
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 Schema service.
30
+     *
31
+     * @since 3.3.0
32
+     * @access private
33
+     * @var \Wordlift_Schema_Service $schema_service The Schema service.
34
+     */
35
+    private $schema_service;
36
+
37
+    /**
38
+     * The Notice service.
39
+     *
40
+     * @since 3.3.0
41
+     * @access private
42
+     * @var \Wordlift_Notice_Service $notice_service The Notice service.
43
+     */
44
+    private $notice_service;
45
+
46
+    /**
47
+     * The entity post type name.
48
+     *
49
+     * @since 3.1.0
50
+     */
51
+    const TYPE_NAME = 'entity';
52
+
53
+    /**
54
+     * Entity rating max.
55
+     *
56
+     * @since 3.3.0
57
+     */
58
+    const RATING_MAX = 7;
59
+
60
+    /**
61
+     * Entity rating score meta key.
62
+     *
63
+     * @since 3.3.0
64
+     */
65
+    const RATING_RAW_SCORE_META_KEY = '_wl_entity_rating_raw_score';
66
+
67
+    /**
68
+     * Entity rating warnings meta key.
69
+     *
70
+     * @since 3.3.0
71
+     */
72
+    const RATING_WARNINGS_META_KEY = '_wl_entity_rating_warnings';
73
+
74
+    /**
75
+     * Entity warning has related post identifier.
76
+     *
77
+     * @since 3.3.0
78
+     */
79
+    const RATING_WARNING_HAS_RELATED_POSTS = 'There are no related posts for the current entity.';
80
+
81
+    /**
82
+     * Entity warning has content post identifier.
83
+     *
84
+     * @since 3.3.0
85
+     */
86
+    const RATING_WARNING_HAS_CONTENT_POST = 'This entity has not description.';
87
+
88
+    /**
89
+     * Entity warning has related entities identifier.
90
+     *
91
+     * @since 3.3.0
92
+     */
93
+    const RATING_WARNING_HAS_RELATED_ENTITIES = 'There are no related entities for the current entity.';
94
+
95
+    /**
96
+     * Entity warning is published identifier.
97
+     *
98
+     * @since 3.3.0
99
+     */
100
+    const RATING_WARNING_IS_PUBLISHED = 'This entity is not published. It will not appear within analysis results.';
101
+
102
+    /**
103
+     * Entity warning has thumbnail identifier.
104
+     *
105
+     * @since 3.3.0
106
+     */
107
+    const RATING_WARNING_HAS_THUMBNAIL = 'This entity has no featured image yet.';
108
+
109
+    /**
110
+     * Entity warning has same as identifier.
111
+     *
112
+     * @since 3.3.0
113
+     */
114
+    const RATING_WARNING_HAS_SAME_AS = 'There are no sameAs configured for this entity.';
115
+
116
+    /**
117
+     * Entity warning has completed metadata identifier.
118
+     *
119
+     * @since 3.3.0
120
+     */
121
+    const RATING_WARNING_HAS_COMPLETED_METADATA = 'Schema.org metadata for this entity are not completed.';
122
+
123
+    /**
124
+     * The alternative label meta key.
125
+     *
126
+     * @since 3.2.0
127
+     */
128
+    const ALTERNATIVE_LABEL_META_KEY = '_wl_alt_label';
129
+
130
+    /**
131
+     * The alternative label input template.
132
+     *
133
+     * @since 3.2.0
134
+     */
135
+    // TODO: this should be moved to a class that deals with HTML code.
136
+    const ALTERNATIVE_LABEL_INPUT_TEMPLATE = '<div class="wl-alternative-label">
137 137
                 <label class="screen-reader-text" id="wl-alternative-label-prompt-text" for="wl-alternative-label">Enter alternative label here</label>
138 138
                 <input name="wl_alternative_label[]" size="30" value="%s" id="wl-alternative-label" type="text">
139 139
                 <button class="button wl-delete-button">%s</button>
140 140
                 </div>';
141 141
 
142
-	/**
143
-	 * A singleton instance of the Entity service.
144
-	 *
145
-	 * @since 3.2.0
146
-	 * @access private
147
-	 * @var \Wordlift_Entity_Service $instance A singleton instance of the Entity service.
148
-	 */
149
-	private static $instance;
150
-
151
-	/**
152
-	 * Create a Wordlift_Entity_Service instance.
153
-	 *
154
-	 * @since 3.2.0
155
-	 *
156
-	 * @param \Wordlift_UI_Service $ui_service The UI service.
157
-	 */
158
-	public function __construct( $ui_service, $schema_service, $notice_service ) {
159
-
160
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
161
-
162
-		// Set the UI service.
163
-		$this->ui_service = $ui_service;
164
-
165
-		// Set the Schema service.
166
-		$this->schema_service = $schema_service;
167
-
168
-		// Set the Schema service.
169
-		$this->notice_service = $notice_service;
170
-
171
-		// Set the singleton instance.
172
-		self::$instance = $this;
173
-
174
-	}
175
-
176
-	/**
177
-	 * Get the singleton instance of the Entity service.
178
-	 *
179
-	 * @since 3.2.0
180
-	 * @return \Wordlift_Entity_Service The singleton instance of the Entity service.
181
-	 */
182
-	public static function get_instance() {
183
-
184
-		return self::$instance;
185
-	}
186
-
187
-	/**
188
-	 * Get rating max
189
-	 *
190
-	 * @since 3.3.0
191
-	 *
192
-	 * @return int Max rating according to performed checks.
193
-	 */
194
-	public static function get_rating_max() {
195
-		return self::RATING_MAX;
196
-	}
197
-
198
-	/**
199
-	 * Get the entities related to the last 50 posts published on this blog (we're keeping a long function name due to
200
-	 * its specific function).
201
-	 *
202
-	 * @since 3.1.0
203
-	 *
204
-	 * @return array An array of post IDs.
205
-	 */
206
-	public function get_all_related_to_last_50_published_posts() {
207
-
208
-		// Global timeline. Get entities from the latest posts.
209
-		$latest_posts_ids = get_posts( array(
210
-			'numberposts' => 50,
211
-			'fields'      => 'ids', //only get post IDs
212
-			'post_type'   => 'post',
213
-			'post_status' => 'publish'
214
-		) );
215
-
216
-		if ( empty( $latest_posts_ids ) ) {
217
-			// There are no posts.
218
-			return array();
219
-		}
220
-
221
-		// Collect entities related to latest posts
222
-		$entity_ids = array();
223
-		foreach ( $latest_posts_ids as $id ) {
224
-			$entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
225
-				'status' => 'publish'
226
-			) ) );
227
-		}
228
-
229
-		return $entity_ids;
230
-	}
231
-
232
-	/**
233
-	 * Determines whether a post is an entity or not.
234
-	 *
235
-	 * @since 3.1.0
236
-	 *
237
-	 * @param int $post_id A post id.
238
-	 *
239
-	 * @return bool Return true if the post is an entity otherwise false.
240
-	 */
241
-	public function is_entity( $post_id ) {
242
-
243
-		return ( self::TYPE_NAME === get_post_type( $post_id ) );
244
-	}
245
-
246
-	/**
247
-	 * Get the proper classification scope for a given entity post
248
-	 *
249
-	 * @since 3.5.0
250
-	 *
251
-	 * @param integer $post_id An entity post id.
252
-	 *
253
-	 * @return string Returns an uri.
254
-	 */
255
-	public function get_classification_scope_for( $post_id ) {
256
-
257
-		if ( FALSE === $this->is_entity( $post_id ) ) {
258
-			return NULL;
259
-		}
260
-		// Retrieve the entity type
261
-		$entity_type_arr = wl_entity_type_taxonomy_get_type( $post_id );
262
-		$entity_type     = str_replace( 'wl-', '', $entity_type_arr['css_class'] );
263
-		// Retrieve classification boxes configuration
264
-		$classification_boxes = unserialize( WL_CORE_POST_CLASSIFICATION_BOXES );
265
-		foreach ( $classification_boxes as $cb ) {
266
-			if ( in_array( $entity_type, $cb['registeredTypes'] ) ) {
267
-				return $cb['id'];
268
-			}
269
-		}
270
-
271
-		// or null
272
-		return NULL;
273
-
274
-	}
275
-
276
-	/**
277
-	 * Build an entity uri for a given title
278
-	 * The uri is composed using a given post_type and a title
279
-	 * If already exists an entity e2 with a given uri a numeric suffix is added
280
-	 * If a schema type is given entities with same label and same type are overridden
281
-	 *
282
-	 * @since 3.5.0
283
-	 *
284
-	 * @param string $title A post title.
285
-	 * @param string $post_type A post type. Default value is 'entity'
286
-	 * @param string $schema_type A schema org type.
287
-	 * @param integer $increment_digit A digit used to call recursively the same function.
288
-	 *
289
-	 * @return string Returns an uri.
290
-	 */
291
-	public function build_uri( $title, $post_type, $schema_type = NULL, $increment_digit = 0 ) {
292
-
293
-		// Get the entity slug suffix digit
294
-		$suffix_digit = $increment_digit + 1;
295
-		// Get a sanitized uri for a given title
296
-		$entity_slug = ( 0 == $increment_digit ) ?
297
-			wl_sanitize_uri_path( $title ) :
298
-			wl_sanitize_uri_path( $title . '_' . $suffix_digit );
299
-
300
-		// Compose a candidated uri
301
-		$new_entity_uri = sprintf( '%s/%s/%s',
302
-			wl_configuration_get_redlink_dataset_uri(),
303
-			$post_type,
304
-			$entity_slug
305
-		);
306
-
307
-		$this->log_service->trace( "Going to check if uri is used [ new_entity_uri :: $new_entity_uri ] [ increment_digit :: $increment_digit ]" );
308
-
309
-		global $wpdb;
310
-		// Check if the candidated uri already is used
311
-		$stmt = $wpdb->prepare(
312
-			"SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s LIMIT 1",
313
-			WL_ENTITY_URL_META_NAME,
314
-			$new_entity_uri
315
-		);
316
-
317
-		// Perform the query
318
-		$post_id = $wpdb->get_var( $stmt );
319
-
320
-		// If the post does not exist, then the new uri is returned 	
321
-		if ( ! is_numeric( $post_id ) ) {
322
-			$this->log_service->trace( "Going to return uri [ new_entity_uri :: $new_entity_uri ]" );
323
-
324
-			return $new_entity_uri;
325
-		}
326
-		// If schema_type is equal to schema org type of post x, then the new uri is returned 
327
-		$schema_post_type = wl_entity_type_taxonomy_get_type( $post_id );
328
-
329
-		if ( $schema_type === $schema_post_type['css_class'] ) {
330
-			$this->log_service->trace( "An entity with the same title and type already exists! Return uri [ new_entity_uri :: $new_entity_uri ]" );
331
-
332
-			return $new_entity_uri;
333
-		}
334
-
335
-		// Otherwise the same function is called recorsively
336
-		return $this->build_uri( $title, $post_type, $schema_type, ++ $increment_digit );
337
-	}
338
-
339
-	public function is_used( $post_id ) {
340
-
341
-		if ( FALSE === $this->is_entity( $post_id ) ) {
342
-			return NULL;
343
-		}
344
-		// Retrieve the post
345
-		$entity = get_post( $post_id );
346
-
347
-		global $wpdb;
348
-		// Retrieve Wordlift relation instances table name
349
-		$table_name = wl_core_get_relation_instances_table_name();
350
-
351
-		// Check is it's referenced / related to another post / entity
352
-		$stmt = $wpdb->prepare(
353
-			"SELECT COUNT(*) FROM $table_name WHERE  object_id = %d",
354
-			$entity->ID
355
-		);
356
-
357
-		// Perform the query
358
-		$relation_instances = (int) $wpdb->get_var( $stmt );
359
-		// If there is at least one relation instance for the current entity, then it's used
360
-		if ( 0 < $relation_instances ) {
361
-			return TRUE;
362
-		}
363
-
364
-		// Check if the entity uri is used as meta_value
365
-		$stmt = $wpdb->prepare(
366
-			"SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id != %d AND meta_value = %s",
367
-			$entity->ID,
368
-			wl_get_entity_uri( $entity->ID )
369
-		);
370
-		// Perform the query
371
-		$meta_instances = (int) $wpdb->get_var( $stmt );
372
-
373
-		// If there is at least one meta that refers the current entity uri, then current entity is used
374
-		if ( 0 < $meta_instances ) {
375
-			return TRUE;
376
-		}
377
-
378
-		// If we are here, it means the current entity is not used at the moment
379
-		return FALSE;
380
-	}
381
-
382
-	/**
383
-	 * Determines whether a given uri is an internal uri or not.
384
-	 *
385
-	 * @since 3.3.2
386
-	 *
387
-	 * @param int $uri An uri.
388
-	 *
389
-	 * @return true if the uri internal to the current dataset otherwise false.
390
-	 */
391
-	public function is_internal_uri( $uri ) {
392
-
393
-		return ( 0 === strrpos( $uri, wl_configuration_get_redlink_dataset_uri() ) );
394
-	}
395
-
396
-	/**
397
-	 * Find entity posts by the entity URI. Entity as searched by their entity URI or same as.
398
-	 *
399
-	 * @since 3.2.0
400
-	 *
401
-	 * @param string $uri The entity URI.
402
-	 *
403
-	 * @return WP_Post|null A WP_Post instance or null if not found.
404
-	 */
405
-	public function get_entity_post_by_uri( $uri ) {
406
-
407
-		// Check if we've been provided with a value otherwise return null.
408
-		if ( empty( $uri ) ) {
409
-			return NULL;
410
-		}
411
-
412
-		$query_args = array(
413
-			'posts_per_page' => 1,
414
-			'post_status'    => 'any',
415
-			'post_type'      => self::TYPE_NAME,
416
-			'meta_query'     => array(
417
-				array(
418
-					'key'     => WL_ENTITY_URL_META_NAME,
419
-					'value'   => $uri,
420
-					'compare' => '='
421
-				)
422
-			)
423
-		);
424
-
425
-		// Only if the current uri is not an internal uri 
426
-		// entity search is performed also looking at sameAs values
427
-		// This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237
428
-		if ( ! $this->is_internal_uri( $uri ) ) {
429
-
430
-			$query_args['meta_query']['relation'] = 'OR';
431
-			$query_args['meta_query'][]           = array(
432
-				'key'     => Wordlift_Schema_Service::FIELD_SAME_AS,
433
-				'value'   => $uri,
434
-				'compare' => '='
435
-			);
436
-		}
437
-
438
-		$query = new WP_Query( $query_args );
439
-
440
-		// Get the matching entity posts.
441
-		$posts = $query->get_posts();
442
-
443
-		// Return null if no post is found.
444
-		if ( 0 === count( $posts ) ) {
445
-			return NULL;
446
-		}
447
-
448
-		// Return the found post.
449
-		return $posts[0];
450
-	}
451
-
452
-	/**
453
-	 * Fires once a post has been saved. This function uses the $_REQUEST, therefore
454
-	 * we check that the post we're saving is the current post.
455
-	 *
456
-	 * @see https://github.com/insideout10/wordlift-plugin/issues/363
457
-	 *
458
-	 * @since 3.2.0
459
-	 *
460
-	 * @param int $post_id Post ID.
461
-	 * @param WP_Post $post Post object.
462
-	 * @param bool $update Whether this is an existing post being updated or not.
463
-	 */
464
-	public function save_post( $post_id, $post, $update ) {
465
-
466
-		// We're setting the alternative label that have been provided via the UI
467
-		// (in fact we're using $_REQUEST), while save_post may be also called
468
-		// programmatically by some other function: we need to check therefore if
469
-		// the $post_id in the save_post call matches the post id set in the request.
470
-		//
471
-		// If this is not the current post being saved or if it's not an entity, return.
472
-		if ( ! isset( $_REQUEST['post_ID'] ) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity( $post_id ) ) {
473
-			return;
474
-		}
475
-
476
-		// Get the alt labels from the request (or empty array).
477
-		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
478
-
479
-		// Set the alternative labels.
480
-		$this->set_alternative_labels( $post_id, $alt_labels );
481
-
482
-	}
483
-
484
-	/**
485
-	 * Set the alternative labels.
486
-	 *
487
-	 * @since 3.2.0
488
-	 *
489
-	 * @param int $post_id The post id.
490
-	 * @param array $alt_labels An array of labels.
491
-	 */
492
-	public function set_alternative_labels( $post_id, $alt_labels ) {
493
-
494
-		// Force $alt_labels to be an array
495
-		if ( ! is_array( $alt_labels ) ) {
496
-			$alt_labels = array( $alt_labels );
497
-		}
498
-
499
-		$this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
500
-
501
-		// Delete all the existing alternate labels.
502
-		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
503
-
504
-		// Set the alternative labels.
505
-		foreach ( $alt_labels as $alt_label ) {
506
-			if ( ! empty( $alt_label ) ) {
507
-				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
508
-			}
509
-		}
510
-
511
-	}
512
-
513
-	/**
514
-	 * Retrieve the alternate labels.
515
-	 *
516
-	 * @since 3.2.0
517
-	 *
518
-	 * @param int $post_id Post id.
519
-	 *
520
-	 * @return mixed An array  of alternative labels.
521
-	 */
522
-	public function get_alternative_labels( $post_id ) {
523
-
524
-		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
525
-	}
526
-
527
-	/**
528
-	 * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
529
-	 *
530
-	 * @since 3.2.0
531
-	 *
532
-	 * @param WP_Post $post Post object.
533
-	 */
534
-	public function edit_form_before_permalink( $post ) {
535
-
536
-		// If it's not an entity, return.
537
-		if ( ! $this->is_entity( $post->ID ) ) {
538
-			return;
539
-		}
540
-
541
-		// Print the input template.
542
-		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
543
-
544
-		// Print all the currently set alternative labels.
545
-		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
546
-
547
-			echo $this->get_alternative_label_input( $alt_label );
548
-
549
-		};
550
-
551
-		// Print the button.
552
-		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
553
-
554
-	}
555
-
556
-	/**
557
-	 * Add admin notices for the current entity depending on the current rating.
558
-	 *
559
-	 * @since 3.3.0
560
-	 *
561
-	 * @param WP_Post $post Post object.
562
-	 */
563
-	public function in_admin_header() {
564
-
565
-		// Return safely if get_current_screen() is not defined (yet)
566
-		if ( FALSE === function_exists( 'get_current_screen' ) ) {
567
-			return;
568
-		}
569
-
570
-		$screen = get_current_screen();
571
-		// If there is any valid screen nothing to do
572
-		if ( NULL === $screen ) {
573
-			return $clauses;
574
-		}
575
-
576
-		// If you're not in the entity post edit page, return.
577
-		if ( self::TYPE_NAME !== $screen->id ) {
578
-			return;
579
-		}
580
-		// Retrieve the current global post
581
-		global $post;
582
-		// If it's not an entity, return.
583
-		if ( ! $this->is_entity( $post->ID ) ) {
584
-			return;
585
-		}
586
-		// Retrieve an updated rating for the current entity
587
-		$rating = $this->get_rating_for( $post->ID, TRUE );
588
-		// If there is at least 1 warning
589
-		if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
590
-			// TODO - Pass Wordlift_Notice_Service trough the service constructor 
591
-			$this->notice_service->add_suggestion( $rating['warnings'] );
592
-		}
593
-
594
-	}
595
-
596
-	/**
597
-	 * Set rating for a given entity
598
-	 *
599
-	 * @since 3.3.0
600
-	 *
601
-	 * @param int $post_id The entity post id.
602
-	 *
603
-	 * @return int An array representing the rating obj.
604
-	 */
605
-	public function set_rating_for( $post_id ) {
606
-
607
-		// Calculate rating for the given post
608
-		$rating = $this->calculate_rating_for( $post_id );
609
-		// Store the rating on db as post meta
610
-		// Please notice that RATING_RAW_SCORE_META_KEY 
611
-		// is saved on a different meta to allow score sorting
612
-		// Both meta are managed as unique
613
-		// https://codex.wordpress.org/Function_Reference/update_post_meta
614
-		update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
615
-		update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
616
-
617
-		$this->log_service->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
618
-
619
-		// Finally returns the rating 
620
-		return $rating;
621
-	}
622
-
623
-	/**
624
-	 * Get or calculate rating for a given entity
625
-	 *
626
-	 * @since 3.3.0
627
-	 *
628
-	 * @param int $post_id The entity post id.
629
-	 * @param $force_reload $warnings_needed If true, detailed warnings collection is provided with the rating obj.
630
-	 *
631
-	 * @return int An array representing the rating obj.
632
-	 */
633
-	public function get_rating_for( $post_id, $force_reload = FALSE ) {
634
-
635
-		// If forced reload is required or rating is missing ..
636
-		if ( $force_reload ) {
637
-			$this->log_service->trace( "Force rating reload [ post_id :: $post_id ]" );
638
-
639
-			return $this->set_rating_for( $post_id );
640
-		}
641
-
642
-		$current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, TRUE );
643
-
644
-		if ( ! is_numeric( $current_raw_score ) ) {
645
-			$this->log_service->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
646
-
647
-			return $this->set_rating_for( $post_id );
648
-		}
649
-		$current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, TRUE );
650
-
651
-		// Finally return score and warnings
652
-		return array(
653
-			'raw_score'           => $current_raw_score,
654
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
655
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
656
-			'warnings'            => $current_warnings,
657
-		);
658
-
659
-	}
660
-
661
-	/**
662
-	 * Calculate rating for a given entity
663
-	 * Rating depends from following criteria
664
-	 *
665
-	 * 1. Is the current entity related to at least 1 post?
666
-	 * 2. Is the current entity content post not empty?
667
-	 * 3. Is the current entity related to at least 1 entity?
668
-	 * 4. Is the entity published?
669
-	 * 5. There is a a thumbnail associated to the entity?
670
-	 * 6. Has the entity a sameas defined?
671
-	 * 7. Are all schema.org required metadata compiled?
672
-	 *
673
-	 * Each positive check means +1 in terms of rating score
674
-	 *
675
-	 * @since 3.3.0
676
-	 *
677
-	 * @param int $post_id The entity post id.
678
-	 *
679
-	 * @return int An array representing the rating obj.
680
-	 */
681
-	public function calculate_rating_for( $post_id ) {
682
-
683
-		// If it's not an entity, return.
684
-		if ( ! $this->is_entity( $post_id ) ) {
685
-			return;
686
-		}
687
-		// Retrieve the post object
688
-		$post = get_post( $post_id );
689
-		// Rating value
690
-		$score = 0;
691
-		// Store warning messages
692
-		$warnings = array();
693
-
694
-		// Is the current entity related to at least 1 post?
695
-		( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
696
-			$score ++ :
697
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift' ) );
698
-
699
-		// Is the post content not empty?
700
-		( ! empty( $post->post_content ) ) ?
701
-			$score ++ :
702
-			array_push( $warnings, __( self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift' ) );
703
-
704
-		// Is the current entity related to at least 1 entity?
705
-		// Was the current entity already disambiguated?
706
-		( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
707
-			$score ++ :
708
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift' ) );
709
-
710
-		// Is the entity published?
711
-		( 'publish' === get_post_status( $post->ID ) ) ?
712
-			$score ++ :
713
-			array_push( $warnings, __( self::RATING_WARNING_IS_PUBLISHED, 'wordlift' ) );
714
-
715
-		// Has a thumbnail?
716
-		( has_post_thumbnail( $post->ID ) ) ?
717
-			$score ++ :
718
-			array_push( $warnings, __( self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift' ) );
719
-
720
-		// Get all post meta keys for the current post		
721
-		global $wpdb;
722
-		$query = $wpdb->prepare(
723
-			"SELECT DISTINCT(meta_key) FROM $wpdb->postmeta  WHERE post_id = %d", $post->ID
724
-		);
725
-
726
-		// Check intersection between available meta keys 
727
-		// and expected ones arrays to detect missing values
728
-		$available_meta_keys = $wpdb->get_col( $query );
729
-
730
-		// If each expected key is contained in available keys array ...
731
-		( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
732
-			$score ++ :
733
-			array_push( $warnings, __( self::RATING_WARNING_HAS_SAME_AS, 'wordlift' ) );
734
-
735
-		$schema = wl_entity_type_taxonomy_get_type( $post_id );
736
-
737
-		$expected_meta_keys = ( NULL === $schema['custom_fields'] ) ?
738
-			array() :
739
-			array_keys( $schema['custom_fields'] );
740
-
741
-		$intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
742
-		// If each expected key is contained in available keys array ...
743
-		( count( $intersection ) === count( $expected_meta_keys ) ) ?
744
-			$score ++ :
745
-			array_push( $warnings, __( self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift' ) );
746
-
747
-		// Finally return score and warnings
748
-		return array(
749
-			'raw_score'           => $score,
750
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
751
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
752
-			'warnings'            => $warnings,
753
-		);
754
-
755
-	}
756
-
757
-	/**
758
-	 * Get the URI for the entity with the specified post id.
759
-	 *
760
-	 * @since 3.6.0
761
-	 *
762
-	 * @param int $post_id The entity post id.
763
-	 *
764
-	 * @return null|string The entity URI or NULL if not found or the dataset URI is not configured.
765
-	 */
766
-	public function get_uri( $post_id ) {
767
-
768
-		// If a null is given, nothing to do
769
-		if ( NULL == $post_id ) {
770
-			return NULL;
771
-		}
772
-
773
-		$uri = get_post_meta( $post_id, WL_ENTITY_URL_META_NAME, TRUE );
774
-
775
-		// If the dataset uri is not properly configured, null is returned
776
-		if ( '' === wl_configuration_get_redlink_dataset_uri() ) {
777
-			return NULL;
778
-		}
779
-
780
-		// Set the URI if it isn't set yet.
781
-		$post_status = get_post_status( $post_id );
782
-		if ( empty( $uri ) && 'auto-draft' !== $post_status && 'revision' !== $post_status ) {
783
-			$uri = wl_build_entity_uri( $post_id );
784
-			wl_set_entity_uri( $post_id, $uri );
785
-		}
786
-
787
-		return $uri;
788
-	}
789
-
790
-	/**
791
-	 * Get as rating as input and convert in a traffic-light rating
792
-	 *
793
-	 * @since 3.3.0
794
-	 *
795
-	 * @param int $score The rating score for a given entity.
796
-	 *
797
-	 * @return string The input HTML code.
798
-	 */
799
-	private function convert_raw_score_to_traffic_light( $score ) {
800
-		// RATING_MAX : $score = 3 : x 
801
-		// See http://php.net/manual/en/function.round.php
802
-		$rating = round( ( $score * 3 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
803
-
804
-		// If rating is 0, return 1, otherwise return rating
805
-		return ( 0 == $rating ) ? 1 : $rating;
806
-
807
-	}
808
-
809
-	/**
810
-	 * Get as rating as input and convert in a traffic-light rating
811
-	 *
812
-	 * @since 3.3.0
813
-	 *
814
-	 * @param int $score The rating score for a given entity.
815
-	 *
816
-	 * @return string The input HTML code.
817
-	 */
818
-	public function convert_raw_score_to_percentage( $score ) {
819
-		// RATING_MAX : $score = 100 : x 
820
-		return round( ( $score * 100 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
821
-	}
822
-
823
-	/**
824
-	 * Get the alternative label input HTML code.
825
-	 *
826
-	 * @since 3.2.0
827
-	 *
828
-	 * @param string $value The input value.
829
-	 *
830
-	 * @return string The input HTML code.
831
-	 */
832
-	private function get_alternative_label_input( $value = '' ) {
833
-
834
-		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
835
-	}
836
-
837
-	/**
838
-	 * Get the number of entity posts published in this blog.
839
-	 *
840
-	 * @since 3.6.0
841
-	 *
842
-	 * @return int The number of published entity posts.
843
-	 */
844
-	public function count() {
845
-
846
-		$count = wp_count_posts( self::TYPE_NAME );
847
-
848
-		return $count->publish;
849
-	}
142
+    /**
143
+     * A singleton instance of the Entity service.
144
+     *
145
+     * @since 3.2.0
146
+     * @access private
147
+     * @var \Wordlift_Entity_Service $instance A singleton instance of the Entity service.
148
+     */
149
+    private static $instance;
150
+
151
+    /**
152
+     * Create a Wordlift_Entity_Service instance.
153
+     *
154
+     * @since 3.2.0
155
+     *
156
+     * @param \Wordlift_UI_Service $ui_service The UI service.
157
+     */
158
+    public function __construct( $ui_service, $schema_service, $notice_service ) {
159
+
160
+        $this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
161
+
162
+        // Set the UI service.
163
+        $this->ui_service = $ui_service;
164
+
165
+        // Set the Schema service.
166
+        $this->schema_service = $schema_service;
167
+
168
+        // Set the Schema service.
169
+        $this->notice_service = $notice_service;
170
+
171
+        // Set the singleton instance.
172
+        self::$instance = $this;
173
+
174
+    }
175
+
176
+    /**
177
+     * Get the singleton instance of the Entity service.
178
+     *
179
+     * @since 3.2.0
180
+     * @return \Wordlift_Entity_Service The singleton instance of the Entity service.
181
+     */
182
+    public static function get_instance() {
183
+
184
+        return self::$instance;
185
+    }
186
+
187
+    /**
188
+     * Get rating max
189
+     *
190
+     * @since 3.3.0
191
+     *
192
+     * @return int Max rating according to performed checks.
193
+     */
194
+    public static function get_rating_max() {
195
+        return self::RATING_MAX;
196
+    }
197
+
198
+    /**
199
+     * Get the entities related to the last 50 posts published on this blog (we're keeping a long function name due to
200
+     * its specific function).
201
+     *
202
+     * @since 3.1.0
203
+     *
204
+     * @return array An array of post IDs.
205
+     */
206
+    public function get_all_related_to_last_50_published_posts() {
207
+
208
+        // Global timeline. Get entities from the latest posts.
209
+        $latest_posts_ids = get_posts( array(
210
+            'numberposts' => 50,
211
+            'fields'      => 'ids', //only get post IDs
212
+            'post_type'   => 'post',
213
+            'post_status' => 'publish'
214
+        ) );
215
+
216
+        if ( empty( $latest_posts_ids ) ) {
217
+            // There are no posts.
218
+            return array();
219
+        }
220
+
221
+        // Collect entities related to latest posts
222
+        $entity_ids = array();
223
+        foreach ( $latest_posts_ids as $id ) {
224
+            $entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
225
+                'status' => 'publish'
226
+            ) ) );
227
+        }
228
+
229
+        return $entity_ids;
230
+    }
231
+
232
+    /**
233
+     * Determines whether a post is an entity or not.
234
+     *
235
+     * @since 3.1.0
236
+     *
237
+     * @param int $post_id A post id.
238
+     *
239
+     * @return bool Return true if the post is an entity otherwise false.
240
+     */
241
+    public function is_entity( $post_id ) {
242
+
243
+        return ( self::TYPE_NAME === get_post_type( $post_id ) );
244
+    }
245
+
246
+    /**
247
+     * Get the proper classification scope for a given entity post
248
+     *
249
+     * @since 3.5.0
250
+     *
251
+     * @param integer $post_id An entity post id.
252
+     *
253
+     * @return string Returns an uri.
254
+     */
255
+    public function get_classification_scope_for( $post_id ) {
256
+
257
+        if ( FALSE === $this->is_entity( $post_id ) ) {
258
+            return NULL;
259
+        }
260
+        // Retrieve the entity type
261
+        $entity_type_arr = wl_entity_type_taxonomy_get_type( $post_id );
262
+        $entity_type     = str_replace( 'wl-', '', $entity_type_arr['css_class'] );
263
+        // Retrieve classification boxes configuration
264
+        $classification_boxes = unserialize( WL_CORE_POST_CLASSIFICATION_BOXES );
265
+        foreach ( $classification_boxes as $cb ) {
266
+            if ( in_array( $entity_type, $cb['registeredTypes'] ) ) {
267
+                return $cb['id'];
268
+            }
269
+        }
270
+
271
+        // or null
272
+        return NULL;
273
+
274
+    }
275
+
276
+    /**
277
+     * Build an entity uri for a given title
278
+     * The uri is composed using a given post_type and a title
279
+     * If already exists an entity e2 with a given uri a numeric suffix is added
280
+     * If a schema type is given entities with same label and same type are overridden
281
+     *
282
+     * @since 3.5.0
283
+     *
284
+     * @param string $title A post title.
285
+     * @param string $post_type A post type. Default value is 'entity'
286
+     * @param string $schema_type A schema org type.
287
+     * @param integer $increment_digit A digit used to call recursively the same function.
288
+     *
289
+     * @return string Returns an uri.
290
+     */
291
+    public function build_uri( $title, $post_type, $schema_type = NULL, $increment_digit = 0 ) {
292
+
293
+        // Get the entity slug suffix digit
294
+        $suffix_digit = $increment_digit + 1;
295
+        // Get a sanitized uri for a given title
296
+        $entity_slug = ( 0 == $increment_digit ) ?
297
+            wl_sanitize_uri_path( $title ) :
298
+            wl_sanitize_uri_path( $title . '_' . $suffix_digit );
299
+
300
+        // Compose a candidated uri
301
+        $new_entity_uri = sprintf( '%s/%s/%s',
302
+            wl_configuration_get_redlink_dataset_uri(),
303
+            $post_type,
304
+            $entity_slug
305
+        );
306
+
307
+        $this->log_service->trace( "Going to check if uri is used [ new_entity_uri :: $new_entity_uri ] [ increment_digit :: $increment_digit ]" );
308
+
309
+        global $wpdb;
310
+        // Check if the candidated uri already is used
311
+        $stmt = $wpdb->prepare(
312
+            "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s LIMIT 1",
313
+            WL_ENTITY_URL_META_NAME,
314
+            $new_entity_uri
315
+        );
316
+
317
+        // Perform the query
318
+        $post_id = $wpdb->get_var( $stmt );
319
+
320
+        // If the post does not exist, then the new uri is returned 	
321
+        if ( ! is_numeric( $post_id ) ) {
322
+            $this->log_service->trace( "Going to return uri [ new_entity_uri :: $new_entity_uri ]" );
323
+
324
+            return $new_entity_uri;
325
+        }
326
+        // If schema_type is equal to schema org type of post x, then the new uri is returned 
327
+        $schema_post_type = wl_entity_type_taxonomy_get_type( $post_id );
328
+
329
+        if ( $schema_type === $schema_post_type['css_class'] ) {
330
+            $this->log_service->trace( "An entity with the same title and type already exists! Return uri [ new_entity_uri :: $new_entity_uri ]" );
331
+
332
+            return $new_entity_uri;
333
+        }
334
+
335
+        // Otherwise the same function is called recorsively
336
+        return $this->build_uri( $title, $post_type, $schema_type, ++ $increment_digit );
337
+    }
338
+
339
+    public function is_used( $post_id ) {
340
+
341
+        if ( FALSE === $this->is_entity( $post_id ) ) {
342
+            return NULL;
343
+        }
344
+        // Retrieve the post
345
+        $entity = get_post( $post_id );
346
+
347
+        global $wpdb;
348
+        // Retrieve Wordlift relation instances table name
349
+        $table_name = wl_core_get_relation_instances_table_name();
350
+
351
+        // Check is it's referenced / related to another post / entity
352
+        $stmt = $wpdb->prepare(
353
+            "SELECT COUNT(*) FROM $table_name WHERE  object_id = %d",
354
+            $entity->ID
355
+        );
356
+
357
+        // Perform the query
358
+        $relation_instances = (int) $wpdb->get_var( $stmt );
359
+        // If there is at least one relation instance for the current entity, then it's used
360
+        if ( 0 < $relation_instances ) {
361
+            return TRUE;
362
+        }
363
+
364
+        // Check if the entity uri is used as meta_value
365
+        $stmt = $wpdb->prepare(
366
+            "SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id != %d AND meta_value = %s",
367
+            $entity->ID,
368
+            wl_get_entity_uri( $entity->ID )
369
+        );
370
+        // Perform the query
371
+        $meta_instances = (int) $wpdb->get_var( $stmt );
372
+
373
+        // If there is at least one meta that refers the current entity uri, then current entity is used
374
+        if ( 0 < $meta_instances ) {
375
+            return TRUE;
376
+        }
377
+
378
+        // If we are here, it means the current entity is not used at the moment
379
+        return FALSE;
380
+    }
381
+
382
+    /**
383
+     * Determines whether a given uri is an internal uri or not.
384
+     *
385
+     * @since 3.3.2
386
+     *
387
+     * @param int $uri An uri.
388
+     *
389
+     * @return true if the uri internal to the current dataset otherwise false.
390
+     */
391
+    public function is_internal_uri( $uri ) {
392
+
393
+        return ( 0 === strrpos( $uri, wl_configuration_get_redlink_dataset_uri() ) );
394
+    }
395
+
396
+    /**
397
+     * Find entity posts by the entity URI. Entity as searched by their entity URI or same as.
398
+     *
399
+     * @since 3.2.0
400
+     *
401
+     * @param string $uri The entity URI.
402
+     *
403
+     * @return WP_Post|null A WP_Post instance or null if not found.
404
+     */
405
+    public function get_entity_post_by_uri( $uri ) {
406
+
407
+        // Check if we've been provided with a value otherwise return null.
408
+        if ( empty( $uri ) ) {
409
+            return NULL;
410
+        }
411
+
412
+        $query_args = array(
413
+            'posts_per_page' => 1,
414
+            'post_status'    => 'any',
415
+            'post_type'      => self::TYPE_NAME,
416
+            'meta_query'     => array(
417
+                array(
418
+                    'key'     => WL_ENTITY_URL_META_NAME,
419
+                    'value'   => $uri,
420
+                    'compare' => '='
421
+                )
422
+            )
423
+        );
424
+
425
+        // Only if the current uri is not an internal uri 
426
+        // entity search is performed also looking at sameAs values
427
+        // This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237
428
+        if ( ! $this->is_internal_uri( $uri ) ) {
429
+
430
+            $query_args['meta_query']['relation'] = 'OR';
431
+            $query_args['meta_query'][]           = array(
432
+                'key'     => Wordlift_Schema_Service::FIELD_SAME_AS,
433
+                'value'   => $uri,
434
+                'compare' => '='
435
+            );
436
+        }
437
+
438
+        $query = new WP_Query( $query_args );
439
+
440
+        // Get the matching entity posts.
441
+        $posts = $query->get_posts();
442
+
443
+        // Return null if no post is found.
444
+        if ( 0 === count( $posts ) ) {
445
+            return NULL;
446
+        }
447
+
448
+        // Return the found post.
449
+        return $posts[0];
450
+    }
451
+
452
+    /**
453
+     * Fires once a post has been saved. This function uses the $_REQUEST, therefore
454
+     * we check that the post we're saving is the current post.
455
+     *
456
+     * @see https://github.com/insideout10/wordlift-plugin/issues/363
457
+     *
458
+     * @since 3.2.0
459
+     *
460
+     * @param int $post_id Post ID.
461
+     * @param WP_Post $post Post object.
462
+     * @param bool $update Whether this is an existing post being updated or not.
463
+     */
464
+    public function save_post( $post_id, $post, $update ) {
465
+
466
+        // We're setting the alternative label that have been provided via the UI
467
+        // (in fact we're using $_REQUEST), while save_post may be also called
468
+        // programmatically by some other function: we need to check therefore if
469
+        // the $post_id in the save_post call matches the post id set in the request.
470
+        //
471
+        // If this is not the current post being saved or if it's not an entity, return.
472
+        if ( ! isset( $_REQUEST['post_ID'] ) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity( $post_id ) ) {
473
+            return;
474
+        }
475
+
476
+        // Get the alt labels from the request (or empty array).
477
+        $alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
478
+
479
+        // Set the alternative labels.
480
+        $this->set_alternative_labels( $post_id, $alt_labels );
481
+
482
+    }
483
+
484
+    /**
485
+     * Set the alternative labels.
486
+     *
487
+     * @since 3.2.0
488
+     *
489
+     * @param int $post_id The post id.
490
+     * @param array $alt_labels An array of labels.
491
+     */
492
+    public function set_alternative_labels( $post_id, $alt_labels ) {
493
+
494
+        // Force $alt_labels to be an array
495
+        if ( ! is_array( $alt_labels ) ) {
496
+            $alt_labels = array( $alt_labels );
497
+        }
498
+
499
+        $this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
500
+
501
+        // Delete all the existing alternate labels.
502
+        delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
503
+
504
+        // Set the alternative labels.
505
+        foreach ( $alt_labels as $alt_label ) {
506
+            if ( ! empty( $alt_label ) ) {
507
+                add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
508
+            }
509
+        }
510
+
511
+    }
512
+
513
+    /**
514
+     * Retrieve the alternate labels.
515
+     *
516
+     * @since 3.2.0
517
+     *
518
+     * @param int $post_id Post id.
519
+     *
520
+     * @return mixed An array  of alternative labels.
521
+     */
522
+    public function get_alternative_labels( $post_id ) {
523
+
524
+        return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
525
+    }
526
+
527
+    /**
528
+     * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
529
+     *
530
+     * @since 3.2.0
531
+     *
532
+     * @param WP_Post $post Post object.
533
+     */
534
+    public function edit_form_before_permalink( $post ) {
535
+
536
+        // If it's not an entity, return.
537
+        if ( ! $this->is_entity( $post->ID ) ) {
538
+            return;
539
+        }
540
+
541
+        // Print the input template.
542
+        $this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
543
+
544
+        // Print all the currently set alternative labels.
545
+        foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
546
+
547
+            echo $this->get_alternative_label_input( $alt_label );
548
+
549
+        };
550
+
551
+        // Print the button.
552
+        $this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
553
+
554
+    }
555
+
556
+    /**
557
+     * Add admin notices for the current entity depending on the current rating.
558
+     *
559
+     * @since 3.3.0
560
+     *
561
+     * @param WP_Post $post Post object.
562
+     */
563
+    public function in_admin_header() {
564
+
565
+        // Return safely if get_current_screen() is not defined (yet)
566
+        if ( FALSE === function_exists( 'get_current_screen' ) ) {
567
+            return;
568
+        }
569
+
570
+        $screen = get_current_screen();
571
+        // If there is any valid screen nothing to do
572
+        if ( NULL === $screen ) {
573
+            return $clauses;
574
+        }
575
+
576
+        // If you're not in the entity post edit page, return.
577
+        if ( self::TYPE_NAME !== $screen->id ) {
578
+            return;
579
+        }
580
+        // Retrieve the current global post
581
+        global $post;
582
+        // If it's not an entity, return.
583
+        if ( ! $this->is_entity( $post->ID ) ) {
584
+            return;
585
+        }
586
+        // Retrieve an updated rating for the current entity
587
+        $rating = $this->get_rating_for( $post->ID, TRUE );
588
+        // If there is at least 1 warning
589
+        if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
590
+            // TODO - Pass Wordlift_Notice_Service trough the service constructor 
591
+            $this->notice_service->add_suggestion( $rating['warnings'] );
592
+        }
593
+
594
+    }
595
+
596
+    /**
597
+     * Set rating for a given entity
598
+     *
599
+     * @since 3.3.0
600
+     *
601
+     * @param int $post_id The entity post id.
602
+     *
603
+     * @return int An array representing the rating obj.
604
+     */
605
+    public function set_rating_for( $post_id ) {
606
+
607
+        // Calculate rating for the given post
608
+        $rating = $this->calculate_rating_for( $post_id );
609
+        // Store the rating on db as post meta
610
+        // Please notice that RATING_RAW_SCORE_META_KEY 
611
+        // is saved on a different meta to allow score sorting
612
+        // Both meta are managed as unique
613
+        // https://codex.wordpress.org/Function_Reference/update_post_meta
614
+        update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
615
+        update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
616
+
617
+        $this->log_service->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
618
+
619
+        // Finally returns the rating 
620
+        return $rating;
621
+    }
622
+
623
+    /**
624
+     * Get or calculate rating for a given entity
625
+     *
626
+     * @since 3.3.0
627
+     *
628
+     * @param int $post_id The entity post id.
629
+     * @param $force_reload $warnings_needed If true, detailed warnings collection is provided with the rating obj.
630
+     *
631
+     * @return int An array representing the rating obj.
632
+     */
633
+    public function get_rating_for( $post_id, $force_reload = FALSE ) {
634
+
635
+        // If forced reload is required or rating is missing ..
636
+        if ( $force_reload ) {
637
+            $this->log_service->trace( "Force rating reload [ post_id :: $post_id ]" );
638
+
639
+            return $this->set_rating_for( $post_id );
640
+        }
641
+
642
+        $current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, TRUE );
643
+
644
+        if ( ! is_numeric( $current_raw_score ) ) {
645
+            $this->log_service->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
646
+
647
+            return $this->set_rating_for( $post_id );
648
+        }
649
+        $current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, TRUE );
650
+
651
+        // Finally return score and warnings
652
+        return array(
653
+            'raw_score'           => $current_raw_score,
654
+            'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
655
+            'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
656
+            'warnings'            => $current_warnings,
657
+        );
658
+
659
+    }
660
+
661
+    /**
662
+     * Calculate rating for a given entity
663
+     * Rating depends from following criteria
664
+     *
665
+     * 1. Is the current entity related to at least 1 post?
666
+     * 2. Is the current entity content post not empty?
667
+     * 3. Is the current entity related to at least 1 entity?
668
+     * 4. Is the entity published?
669
+     * 5. There is a a thumbnail associated to the entity?
670
+     * 6. Has the entity a sameas defined?
671
+     * 7. Are all schema.org required metadata compiled?
672
+     *
673
+     * Each positive check means +1 in terms of rating score
674
+     *
675
+     * @since 3.3.0
676
+     *
677
+     * @param int $post_id The entity post id.
678
+     *
679
+     * @return int An array representing the rating obj.
680
+     */
681
+    public function calculate_rating_for( $post_id ) {
682
+
683
+        // If it's not an entity, return.
684
+        if ( ! $this->is_entity( $post_id ) ) {
685
+            return;
686
+        }
687
+        // Retrieve the post object
688
+        $post = get_post( $post_id );
689
+        // Rating value
690
+        $score = 0;
691
+        // Store warning messages
692
+        $warnings = array();
693
+
694
+        // Is the current entity related to at least 1 post?
695
+        ( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
696
+            $score ++ :
697
+            array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift' ) );
698
+
699
+        // Is the post content not empty?
700
+        ( ! empty( $post->post_content ) ) ?
701
+            $score ++ :
702
+            array_push( $warnings, __( self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift' ) );
703
+
704
+        // Is the current entity related to at least 1 entity?
705
+        // Was the current entity already disambiguated?
706
+        ( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
707
+            $score ++ :
708
+            array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift' ) );
709
+
710
+        // Is the entity published?
711
+        ( 'publish' === get_post_status( $post->ID ) ) ?
712
+            $score ++ :
713
+            array_push( $warnings, __( self::RATING_WARNING_IS_PUBLISHED, 'wordlift' ) );
714
+
715
+        // Has a thumbnail?
716
+        ( has_post_thumbnail( $post->ID ) ) ?
717
+            $score ++ :
718
+            array_push( $warnings, __( self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift' ) );
719
+
720
+        // Get all post meta keys for the current post		
721
+        global $wpdb;
722
+        $query = $wpdb->prepare(
723
+            "SELECT DISTINCT(meta_key) FROM $wpdb->postmeta  WHERE post_id = %d", $post->ID
724
+        );
725
+
726
+        // Check intersection between available meta keys 
727
+        // and expected ones arrays to detect missing values
728
+        $available_meta_keys = $wpdb->get_col( $query );
729
+
730
+        // If each expected key is contained in available keys array ...
731
+        ( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
732
+            $score ++ :
733
+            array_push( $warnings, __( self::RATING_WARNING_HAS_SAME_AS, 'wordlift' ) );
734
+
735
+        $schema = wl_entity_type_taxonomy_get_type( $post_id );
736
+
737
+        $expected_meta_keys = ( NULL === $schema['custom_fields'] ) ?
738
+            array() :
739
+            array_keys( $schema['custom_fields'] );
740
+
741
+        $intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
742
+        // If each expected key is contained in available keys array ...
743
+        ( count( $intersection ) === count( $expected_meta_keys ) ) ?
744
+            $score ++ :
745
+            array_push( $warnings, __( self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift' ) );
746
+
747
+        // Finally return score and warnings
748
+        return array(
749
+            'raw_score'           => $score,
750
+            'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
751
+            'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
752
+            'warnings'            => $warnings,
753
+        );
754
+
755
+    }
756
+
757
+    /**
758
+     * Get the URI for the entity with the specified post id.
759
+     *
760
+     * @since 3.6.0
761
+     *
762
+     * @param int $post_id The entity post id.
763
+     *
764
+     * @return null|string The entity URI or NULL if not found or the dataset URI is not configured.
765
+     */
766
+    public function get_uri( $post_id ) {
767
+
768
+        // If a null is given, nothing to do
769
+        if ( NULL == $post_id ) {
770
+            return NULL;
771
+        }
772
+
773
+        $uri = get_post_meta( $post_id, WL_ENTITY_URL_META_NAME, TRUE );
774
+
775
+        // If the dataset uri is not properly configured, null is returned
776
+        if ( '' === wl_configuration_get_redlink_dataset_uri() ) {
777
+            return NULL;
778
+        }
779
+
780
+        // Set the URI if it isn't set yet.
781
+        $post_status = get_post_status( $post_id );
782
+        if ( empty( $uri ) && 'auto-draft' !== $post_status && 'revision' !== $post_status ) {
783
+            $uri = wl_build_entity_uri( $post_id );
784
+            wl_set_entity_uri( $post_id, $uri );
785
+        }
786
+
787
+        return $uri;
788
+    }
789
+
790
+    /**
791
+     * Get as rating as input and convert in a traffic-light rating
792
+     *
793
+     * @since 3.3.0
794
+     *
795
+     * @param int $score The rating score for a given entity.
796
+     *
797
+     * @return string The input HTML code.
798
+     */
799
+    private function convert_raw_score_to_traffic_light( $score ) {
800
+        // RATING_MAX : $score = 3 : x 
801
+        // See http://php.net/manual/en/function.round.php
802
+        $rating = round( ( $score * 3 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
803
+
804
+        // If rating is 0, return 1, otherwise return rating
805
+        return ( 0 == $rating ) ? 1 : $rating;
806
+
807
+    }
808
+
809
+    /**
810
+     * Get as rating as input and convert in a traffic-light rating
811
+     *
812
+     * @since 3.3.0
813
+     *
814
+     * @param int $score The rating score for a given entity.
815
+     *
816
+     * @return string The input HTML code.
817
+     */
818
+    public function convert_raw_score_to_percentage( $score ) {
819
+        // RATING_MAX : $score = 100 : x 
820
+        return round( ( $score * 100 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
821
+    }
822
+
823
+    /**
824
+     * Get the alternative label input HTML code.
825
+     *
826
+     * @since 3.2.0
827
+     *
828
+     * @param string $value The input value.
829
+     *
830
+     * @return string The input HTML code.
831
+     */
832
+    private function get_alternative_label_input( $value = '' ) {
833
+
834
+        return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
835
+    }
836
+
837
+    /**
838
+     * Get the number of entity posts published in this blog.
839
+     *
840
+     * @since 3.6.0
841
+     *
842
+     * @return int The number of published entity posts.
843
+     */
844
+    public function count() {
845
+
846
+        $count = wp_count_posts( self::TYPE_NAME );
847
+
848
+        return $count->publish;
849
+    }
850 850
 
851 851
 }
Please login to merge, or discard this patch.
Spacing   +127 added lines, -136 removed lines patch added patch discarded remove patch
@@ -155,9 +155,9 @@  discard block
 block discarded – undo
155 155
 	 *
156 156
 	 * @param \Wordlift_UI_Service $ui_service The UI service.
157 157
 	 */
158
-	public function __construct( $ui_service, $schema_service, $notice_service ) {
158
+	public function __construct($ui_service, $schema_service, $notice_service) {
159 159
 
160
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
160
+		$this->log_service = Wordlift_Log_Service::get_logger('Wordlift_Entity_Service');
161 161
 
162 162
 		// Set the UI service.
163 163
 		$this->ui_service = $ui_service;
@@ -206,24 +206,24 @@  discard block
 block discarded – undo
206 206
 	public function get_all_related_to_last_50_published_posts() {
207 207
 
208 208
 		// Global timeline. Get entities from the latest posts.
209
-		$latest_posts_ids = get_posts( array(
209
+		$latest_posts_ids = get_posts(array(
210 210
 			'numberposts' => 50,
211 211
 			'fields'      => 'ids', //only get post IDs
212 212
 			'post_type'   => 'post',
213 213
 			'post_status' => 'publish'
214
-		) );
214
+		));
215 215
 
216
-		if ( empty( $latest_posts_ids ) ) {
216
+		if (empty($latest_posts_ids)) {
217 217
 			// There are no posts.
218 218
 			return array();
219 219
 		}
220 220
 
221 221
 		// Collect entities related to latest posts
222 222
 		$entity_ids = array();
223
-		foreach ( $latest_posts_ids as $id ) {
224
-			$entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
223
+		foreach ($latest_posts_ids as $id) {
224
+			$entity_ids = array_merge($entity_ids, wl_core_get_related_entity_ids($id, array(
225 225
 				'status' => 'publish'
226
-			) ) );
226
+			)));
227 227
 		}
228 228
 
229 229
 		return $entity_ids;
@@ -238,9 +238,9 @@  discard block
 block discarded – undo
238 238
 	 *
239 239
 	 * @return bool Return true if the post is an entity otherwise false.
240 240
 	 */
241
-	public function is_entity( $post_id ) {
241
+	public function is_entity($post_id) {
242 242
 
243
-		return ( self::TYPE_NAME === get_post_type( $post_id ) );
243
+		return (self::TYPE_NAME === get_post_type($post_id));
244 244
 	}
245 245
 
246 246
 	/**
@@ -252,18 +252,18 @@  discard block
 block discarded – undo
252 252
 	 *
253 253
 	 * @return string Returns an uri.
254 254
 	 */
255
-	public function get_classification_scope_for( $post_id ) {
255
+	public function get_classification_scope_for($post_id) {
256 256
 
257
-		if ( FALSE === $this->is_entity( $post_id ) ) {
257
+		if (FALSE === $this->is_entity($post_id)) {
258 258
 			return NULL;
259 259
 		}
260 260
 		// Retrieve the entity type
261
-		$entity_type_arr = wl_entity_type_taxonomy_get_type( $post_id );
262
-		$entity_type     = str_replace( 'wl-', '', $entity_type_arr['css_class'] );
261
+		$entity_type_arr = wl_entity_type_taxonomy_get_type($post_id);
262
+		$entity_type     = str_replace('wl-', '', $entity_type_arr['css_class']);
263 263
 		// Retrieve classification boxes configuration
264
-		$classification_boxes = unserialize( WL_CORE_POST_CLASSIFICATION_BOXES );
265
-		foreach ( $classification_boxes as $cb ) {
266
-			if ( in_array( $entity_type, $cb['registeredTypes'] ) ) {
264
+		$classification_boxes = unserialize(WL_CORE_POST_CLASSIFICATION_BOXES);
265
+		foreach ($classification_boxes as $cb) {
266
+			if (in_array($entity_type, $cb['registeredTypes'])) {
267 267
 				return $cb['id'];
268 268
 			}
269 269
 		}
@@ -288,23 +288,22 @@  discard block
 block discarded – undo
288 288
 	 *
289 289
 	 * @return string Returns an uri.
290 290
 	 */
291
-	public function build_uri( $title, $post_type, $schema_type = NULL, $increment_digit = 0 ) {
291
+	public function build_uri($title, $post_type, $schema_type = NULL, $increment_digit = 0) {
292 292
 
293 293
 		// Get the entity slug suffix digit
294 294
 		$suffix_digit = $increment_digit + 1;
295 295
 		// Get a sanitized uri for a given title
296
-		$entity_slug = ( 0 == $increment_digit ) ?
297
-			wl_sanitize_uri_path( $title ) :
298
-			wl_sanitize_uri_path( $title . '_' . $suffix_digit );
296
+		$entity_slug = (0 == $increment_digit) ?
297
+			wl_sanitize_uri_path($title) : wl_sanitize_uri_path($title.'_'.$suffix_digit);
299 298
 
300 299
 		// Compose a candidated uri
301
-		$new_entity_uri = sprintf( '%s/%s/%s',
300
+		$new_entity_uri = sprintf('%s/%s/%s',
302 301
 			wl_configuration_get_redlink_dataset_uri(),
303 302
 			$post_type,
304 303
 			$entity_slug
305 304
 		);
306 305
 
307
-		$this->log_service->trace( "Going to check if uri is used [ new_entity_uri :: $new_entity_uri ] [ increment_digit :: $increment_digit ]" );
306
+		$this->log_service->trace("Going to check if uri is used [ new_entity_uri :: $new_entity_uri ] [ increment_digit :: $increment_digit ]");
308 307
 
309 308
 		global $wpdb;
310 309
 		// Check if the candidated uri already is used
@@ -315,34 +314,34 @@  discard block
 block discarded – undo
315 314
 		);
316 315
 
317 316
 		// Perform the query
318
-		$post_id = $wpdb->get_var( $stmt );
317
+		$post_id = $wpdb->get_var($stmt);
319 318
 
320 319
 		// If the post does not exist, then the new uri is returned 	
321
-		if ( ! is_numeric( $post_id ) ) {
322
-			$this->log_service->trace( "Going to return uri [ new_entity_uri :: $new_entity_uri ]" );
320
+		if ( ! is_numeric($post_id)) {
321
+			$this->log_service->trace("Going to return uri [ new_entity_uri :: $new_entity_uri ]");
323 322
 
324 323
 			return $new_entity_uri;
325 324
 		}
326 325
 		// If schema_type is equal to schema org type of post x, then the new uri is returned 
327
-		$schema_post_type = wl_entity_type_taxonomy_get_type( $post_id );
326
+		$schema_post_type = wl_entity_type_taxonomy_get_type($post_id);
328 327
 
329
-		if ( $schema_type === $schema_post_type['css_class'] ) {
330
-			$this->log_service->trace( "An entity with the same title and type already exists! Return uri [ new_entity_uri :: $new_entity_uri ]" );
328
+		if ($schema_type === $schema_post_type['css_class']) {
329
+			$this->log_service->trace("An entity with the same title and type already exists! Return uri [ new_entity_uri :: $new_entity_uri ]");
331 330
 
332 331
 			return $new_entity_uri;
333 332
 		}
334 333
 
335 334
 		// Otherwise the same function is called recorsively
336
-		return $this->build_uri( $title, $post_type, $schema_type, ++ $increment_digit );
335
+		return $this->build_uri($title, $post_type, $schema_type, ++ $increment_digit);
337 336
 	}
338 337
 
339
-	public function is_used( $post_id ) {
338
+	public function is_used($post_id) {
340 339
 
341
-		if ( FALSE === $this->is_entity( $post_id ) ) {
340
+		if (FALSE === $this->is_entity($post_id)) {
342 341
 			return NULL;
343 342
 		}
344 343
 		// Retrieve the post
345
-		$entity = get_post( $post_id );
344
+		$entity = get_post($post_id);
346 345
 
347 346
 		global $wpdb;
348 347
 		// Retrieve Wordlift relation instances table name
@@ -355,9 +354,9 @@  discard block
 block discarded – undo
355 354
 		);
356 355
 
357 356
 		// Perform the query
358
-		$relation_instances = (int) $wpdb->get_var( $stmt );
357
+		$relation_instances = (int) $wpdb->get_var($stmt);
359 358
 		// If there is at least one relation instance for the current entity, then it's used
360
-		if ( 0 < $relation_instances ) {
359
+		if (0 < $relation_instances) {
361 360
 			return TRUE;
362 361
 		}
363 362
 
@@ -365,13 +364,13 @@  discard block
 block discarded – undo
365 364
 		$stmt = $wpdb->prepare(
366 365
 			"SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id != %d AND meta_value = %s",
367 366
 			$entity->ID,
368
-			wl_get_entity_uri( $entity->ID )
367
+			wl_get_entity_uri($entity->ID)
369 368
 		);
370 369
 		// Perform the query
371
-		$meta_instances = (int) $wpdb->get_var( $stmt );
370
+		$meta_instances = (int) $wpdb->get_var($stmt);
372 371
 
373 372
 		// If there is at least one meta that refers the current entity uri, then current entity is used
374
-		if ( 0 < $meta_instances ) {
373
+		if (0 < $meta_instances) {
375 374
 			return TRUE;
376 375
 		}
377 376
 
@@ -388,9 +387,9 @@  discard block
 block discarded – undo
388 387
 	 *
389 388
 	 * @return true if the uri internal to the current dataset otherwise false.
390 389
 	 */
391
-	public function is_internal_uri( $uri ) {
390
+	public function is_internal_uri($uri) {
392 391
 
393
-		return ( 0 === strrpos( $uri, wl_configuration_get_redlink_dataset_uri() ) );
392
+		return (0 === strrpos($uri, wl_configuration_get_redlink_dataset_uri()));
394 393
 	}
395 394
 
396 395
 	/**
@@ -402,10 +401,10 @@  discard block
 block discarded – undo
402 401
 	 *
403 402
 	 * @return WP_Post|null A WP_Post instance or null if not found.
404 403
 	 */
405
-	public function get_entity_post_by_uri( $uri ) {
404
+	public function get_entity_post_by_uri($uri) {
406 405
 
407 406
 		// Check if we've been provided with a value otherwise return null.
408
-		if ( empty( $uri ) ) {
407
+		if (empty($uri)) {
409 408
 			return NULL;
410 409
 		}
411 410
 
@@ -425,7 +424,7 @@  discard block
 block discarded – undo
425 424
 		// Only if the current uri is not an internal uri 
426 425
 		// entity search is performed also looking at sameAs values
427 426
 		// This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237
428
-		if ( ! $this->is_internal_uri( $uri ) ) {
427
+		if ( ! $this->is_internal_uri($uri)) {
429 428
 
430 429
 			$query_args['meta_query']['relation'] = 'OR';
431 430
 			$query_args['meta_query'][]           = array(
@@ -435,13 +434,13 @@  discard block
 block discarded – undo
435 434
 			);
436 435
 		}
437 436
 
438
-		$query = new WP_Query( $query_args );
437
+		$query = new WP_Query($query_args);
439 438
 
440 439
 		// Get the matching entity posts.
441 440
 		$posts = $query->get_posts();
442 441
 
443 442
 		// Return null if no post is found.
444
-		if ( 0 === count( $posts ) ) {
443
+		if (0 === count($posts)) {
445 444
 			return NULL;
446 445
 		}
447 446
 
@@ -461,7 +460,7 @@  discard block
 block discarded – undo
461 460
 	 * @param WP_Post $post Post object.
462 461
 	 * @param bool $update Whether this is an existing post being updated or not.
463 462
 	 */
464
-	public function save_post( $post_id, $post, $update ) {
463
+	public function save_post($post_id, $post, $update) {
465 464
 
466 465
 		// We're setting the alternative label that have been provided via the UI
467 466
 		// (in fact we're using $_REQUEST), while save_post may be also called
@@ -469,15 +468,15 @@  discard block
 block discarded – undo
469 468
 		// the $post_id in the save_post call matches the post id set in the request.
470 469
 		//
471 470
 		// If this is not the current post being saved or if it's not an entity, return.
472
-		if ( ! isset( $_REQUEST['post_ID'] ) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity( $post_id ) ) {
471
+		if ( ! isset($_REQUEST['post_ID']) || $_REQUEST['post_ID'] != $post_id || ! $this->is_entity($post_id)) {
473 472
 			return;
474 473
 		}
475 474
 
476 475
 		// Get the alt labels from the request (or empty array).
477
-		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
476
+		$alt_labels = isset($_REQUEST['wl_alternative_label']) ? $_REQUEST['wl_alternative_label'] : array();
478 477
 
479 478
 		// Set the alternative labels.
480
-		$this->set_alternative_labels( $post_id, $alt_labels );
479
+		$this->set_alternative_labels($post_id, $alt_labels);
481 480
 
482 481
 	}
483 482
 
@@ -489,22 +488,22 @@  discard block
 block discarded – undo
489 488
 	 * @param int $post_id The post id.
490 489
 	 * @param array $alt_labels An array of labels.
491 490
 	 */
492
-	public function set_alternative_labels( $post_id, $alt_labels ) {
491
+	public function set_alternative_labels($post_id, $alt_labels) {
493 492
 
494 493
 		// Force $alt_labels to be an array
495
-		if ( ! is_array( $alt_labels ) ) {
496
-			$alt_labels = array( $alt_labels );
494
+		if ( ! is_array($alt_labels)) {
495
+			$alt_labels = array($alt_labels);
497 496
 		}
498 497
 
499
-		$this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
498
+		$this->log_service->debug("Setting alternative labels [ post id :: $post_id ][ alt labels :: ".implode(',', $alt_labels)." ]");
500 499
 
501 500
 		// Delete all the existing alternate labels.
502
-		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
501
+		delete_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY);
503 502
 
504 503
 		// Set the alternative labels.
505
-		foreach ( $alt_labels as $alt_label ) {
506
-			if ( ! empty( $alt_label ) ) {
507
-				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
504
+		foreach ($alt_labels as $alt_label) {
505
+			if ( ! empty($alt_label)) {
506
+				add_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label);
508 507
 			}
509 508
 		}
510 509
 
@@ -519,9 +518,9 @@  discard block
 block discarded – undo
519 518
 	 *
520 519
 	 * @return mixed An array  of alternative labels.
521 520
 	 */
522
-	public function get_alternative_labels( $post_id ) {
521
+	public function get_alternative_labels($post_id) {
523 522
 
524
-		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
523
+		return get_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY);
525 524
 	}
526 525
 
527 526
 	/**
@@ -531,25 +530,25 @@  discard block
 block discarded – undo
531 530
 	 *
532 531
 	 * @param WP_Post $post Post object.
533 532
 	 */
534
-	public function edit_form_before_permalink( $post ) {
533
+	public function edit_form_before_permalink($post) {
535 534
 
536 535
 		// If it's not an entity, return.
537
-		if ( ! $this->is_entity( $post->ID ) ) {
536
+		if ( ! $this->is_entity($post->ID)) {
538 537
 			return;
539 538
 		}
540 539
 
541 540
 		// Print the input template.
542
-		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
541
+		$this->ui_service->print_template('wl-tmpl-alternative-label-input', $this->get_alternative_label_input());
543 542
 
544 543
 		// Print all the currently set alternative labels.
545
-		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
544
+		foreach ($this->get_alternative_labels($post->ID) as $alt_label) {
546 545
 
547
-			echo $this->get_alternative_label_input( $alt_label );
546
+			echo $this->get_alternative_label_input($alt_label);
548 547
 
549 548
 		};
550 549
 
551 550
 		// Print the button.
552
-		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
551
+		$this->ui_service->print_button('wl-add-alternative-labels-button', __('Add more titles', 'wordlift'));
553 552
 
554 553
 	}
555 554
 
@@ -563,32 +562,32 @@  discard block
 block discarded – undo
563 562
 	public function in_admin_header() {
564 563
 
565 564
 		// Return safely if get_current_screen() is not defined (yet)
566
-		if ( FALSE === function_exists( 'get_current_screen' ) ) {
565
+		if (FALSE === function_exists('get_current_screen')) {
567 566
 			return;
568 567
 		}
569 568
 
570 569
 		$screen = get_current_screen();
571 570
 		// If there is any valid screen nothing to do
572
-		if ( NULL === $screen ) {
571
+		if (NULL === $screen) {
573 572
 			return $clauses;
574 573
 		}
575 574
 
576 575
 		// If you're not in the entity post edit page, return.
577
-		if ( self::TYPE_NAME !== $screen->id ) {
576
+		if (self::TYPE_NAME !== $screen->id) {
578 577
 			return;
579 578
 		}
580 579
 		// Retrieve the current global post
581 580
 		global $post;
582 581
 		// If it's not an entity, return.
583
-		if ( ! $this->is_entity( $post->ID ) ) {
582
+		if ( ! $this->is_entity($post->ID)) {
584 583
 			return;
585 584
 		}
586 585
 		// Retrieve an updated rating for the current entity
587
-		$rating = $this->get_rating_for( $post->ID, TRUE );
586
+		$rating = $this->get_rating_for($post->ID, TRUE);
588 587
 		// If there is at least 1 warning
589
-		if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
588
+		if (isset($rating['warnings']) && 0 < count($rating['warnings'])) {
590 589
 			// TODO - Pass Wordlift_Notice_Service trough the service constructor 
591
-			$this->notice_service->add_suggestion( $rating['warnings'] );
590
+			$this->notice_service->add_suggestion($rating['warnings']);
592 591
 		}
593 592
 
594 593
 	}
@@ -602,19 +601,19 @@  discard block
 block discarded – undo
602 601
 	 *
603 602
 	 * @return int An array representing the rating obj.
604 603
 	 */
605
-	public function set_rating_for( $post_id ) {
604
+	public function set_rating_for($post_id) {
606 605
 
607 606
 		// Calculate rating for the given post
608
-		$rating = $this->calculate_rating_for( $post_id );
607
+		$rating = $this->calculate_rating_for($post_id);
609 608
 		// Store the rating on db as post meta
610 609
 		// Please notice that RATING_RAW_SCORE_META_KEY 
611 610
 		// is saved on a different meta to allow score sorting
612 611
 		// Both meta are managed as unique
613 612
 		// https://codex.wordpress.org/Function_Reference/update_post_meta
614
-		update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
615
-		update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
613
+		update_post_meta($post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score']);
614
+		update_post_meta($post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings']);
616 615
 
617
-		$this->log_service->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
616
+		$this->log_service->trace(sprintf("Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score']));
618 617
 
619 618
 		// Finally returns the rating 
620 619
 		return $rating;
@@ -630,29 +629,29 @@  discard block
 block discarded – undo
630 629
 	 *
631 630
 	 * @return int An array representing the rating obj.
632 631
 	 */
633
-	public function get_rating_for( $post_id, $force_reload = FALSE ) {
632
+	public function get_rating_for($post_id, $force_reload = FALSE) {
634 633
 
635 634
 		// If forced reload is required or rating is missing ..
636
-		if ( $force_reload ) {
637
-			$this->log_service->trace( "Force rating reload [ post_id :: $post_id ]" );
635
+		if ($force_reload) {
636
+			$this->log_service->trace("Force rating reload [ post_id :: $post_id ]");
638 637
 
639
-			return $this->set_rating_for( $post_id );
638
+			return $this->set_rating_for($post_id);
640 639
 		}
641 640
 
642
-		$current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, TRUE );
641
+		$current_raw_score = get_post_meta($post_id, self::RATING_RAW_SCORE_META_KEY, TRUE);
643 642
 
644
-		if ( ! is_numeric( $current_raw_score ) ) {
645
-			$this->log_service->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
643
+		if ( ! is_numeric($current_raw_score)) {
644
+			$this->log_service->trace("Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]");
646 645
 
647
-			return $this->set_rating_for( $post_id );
646
+			return $this->set_rating_for($post_id);
648 647
 		}
649
-		$current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, TRUE );
648
+		$current_warnings = get_post_meta($post_id, self::RATING_WARNINGS_META_KEY, TRUE);
650 649
 
651 650
 		// Finally return score and warnings
652 651
 		return array(
653 652
 			'raw_score'           => $current_raw_score,
654
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
655
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
653
+			'traffic_light_score' => $this->convert_raw_score_to_traffic_light($current_raw_score),
654
+			'percentage_score'    => $this->convert_raw_score_to_percentage($current_raw_score),
656 655
 			'warnings'            => $current_warnings,
657 656
 		);
658 657
 
@@ -678,44 +677,39 @@  discard block
 block discarded – undo
678 677
 	 *
679 678
 	 * @return int An array representing the rating obj.
680 679
 	 */
681
-	public function calculate_rating_for( $post_id ) {
680
+	public function calculate_rating_for($post_id) {
682 681
 
683 682
 		// If it's not an entity, return.
684
-		if ( ! $this->is_entity( $post_id ) ) {
683
+		if ( ! $this->is_entity($post_id)) {
685 684
 			return;
686 685
 		}
687 686
 		// Retrieve the post object
688
-		$post = get_post( $post_id );
687
+		$post = get_post($post_id);
689 688
 		// Rating value
690 689
 		$score = 0;
691 690
 		// Store warning messages
692 691
 		$warnings = array();
693 692
 
694 693
 		// Is the current entity related to at least 1 post?
695
-		( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
696
-			$score ++ :
697
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift' ) );
694
+		(0 < count(wl_core_get_related_post_ids($post->ID))) ?
695
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift'));
698 696
 
699 697
 		// Is the post content not empty?
700
-		( ! empty( $post->post_content ) ) ?
701
-			$score ++ :
702
-			array_push( $warnings, __( self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift' ) );
698
+		( ! empty($post->post_content)) ?
699
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift'));
703 700
 
704 701
 		// Is the current entity related to at least 1 entity?
705 702
 		// Was the current entity already disambiguated?
706
-		( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
707
-			$score ++ :
708
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift' ) );
703
+		(0 < count(wl_core_get_related_entity_ids($post->ID))) ?
704
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift'));
709 705
 
710 706
 		// Is the entity published?
711
-		( 'publish' === get_post_status( $post->ID ) ) ?
712
-			$score ++ :
713
-			array_push( $warnings, __( self::RATING_WARNING_IS_PUBLISHED, 'wordlift' ) );
707
+		('publish' === get_post_status($post->ID)) ?
708
+			$score++ : array_push($warnings, __(self::RATING_WARNING_IS_PUBLISHED, 'wordlift'));
714 709
 
715 710
 		// Has a thumbnail?
716
-		( has_post_thumbnail( $post->ID ) ) ?
717
-			$score ++ :
718
-			array_push( $warnings, __( self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift' ) );
711
+		(has_post_thumbnail($post->ID)) ?
712
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift'));
719 713
 
720 714
 		// Get all post meta keys for the current post		
721 715
 		global $wpdb;
@@ -725,30 +719,27 @@  discard block
 block discarded – undo
725 719
 
726 720
 		// Check intersection between available meta keys 
727 721
 		// and expected ones arrays to detect missing values
728
-		$available_meta_keys = $wpdb->get_col( $query );
722
+		$available_meta_keys = $wpdb->get_col($query);
729 723
 
730 724
 		// If each expected key is contained in available keys array ...
731
-		( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
732
-			$score ++ :
733
-			array_push( $warnings, __( self::RATING_WARNING_HAS_SAME_AS, 'wordlift' ) );
725
+		(in_array(Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys)) ?
726
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_SAME_AS, 'wordlift'));
734 727
 
735
-		$schema = wl_entity_type_taxonomy_get_type( $post_id );
728
+		$schema = wl_entity_type_taxonomy_get_type($post_id);
736 729
 
737
-		$expected_meta_keys = ( NULL === $schema['custom_fields'] ) ?
738
-			array() :
739
-			array_keys( $schema['custom_fields'] );
730
+		$expected_meta_keys = (NULL === $schema['custom_fields']) ?
731
+			array() : array_keys($schema['custom_fields']);
740 732
 
741
-		$intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
733
+		$intersection = array_intersect($expected_meta_keys, $available_meta_keys);
742 734
 		// If each expected key is contained in available keys array ...
743
-		( count( $intersection ) === count( $expected_meta_keys ) ) ?
744
-			$score ++ :
745
-			array_push( $warnings, __( self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift' ) );
735
+		(count($intersection) === count($expected_meta_keys)) ?
736
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift'));
746 737
 
747 738
 		// Finally return score and warnings
748 739
 		return array(
749 740
 			'raw_score'           => $score,
750
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
751
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
741
+			'traffic_light_score' => $this->convert_raw_score_to_traffic_light($score),
742
+			'percentage_score'    => $this->convert_raw_score_to_percentage($score),
752 743
 			'warnings'            => $warnings,
753 744
 		);
754 745
 
@@ -763,25 +754,25 @@  discard block
 block discarded – undo
763 754
 	 *
764 755
 	 * @return null|string The entity URI or NULL if not found or the dataset URI is not configured.
765 756
 	 */
766
-	public function get_uri( $post_id ) {
757
+	public function get_uri($post_id) {
767 758
 
768 759
 		// If a null is given, nothing to do
769
-		if ( NULL == $post_id ) {
760
+		if (NULL == $post_id) {
770 761
 			return NULL;
771 762
 		}
772 763
 
773
-		$uri = get_post_meta( $post_id, WL_ENTITY_URL_META_NAME, TRUE );
764
+		$uri = get_post_meta($post_id, WL_ENTITY_URL_META_NAME, TRUE);
774 765
 
775 766
 		// If the dataset uri is not properly configured, null is returned
776
-		if ( '' === wl_configuration_get_redlink_dataset_uri() ) {
767
+		if ('' === wl_configuration_get_redlink_dataset_uri()) {
777 768
 			return NULL;
778 769
 		}
779 770
 
780 771
 		// Set the URI if it isn't set yet.
781
-		$post_status = get_post_status( $post_id );
782
-		if ( empty( $uri ) && 'auto-draft' !== $post_status && 'revision' !== $post_status ) {
783
-			$uri = wl_build_entity_uri( $post_id );
784
-			wl_set_entity_uri( $post_id, $uri );
772
+		$post_status = get_post_status($post_id);
773
+		if (empty($uri) && 'auto-draft' !== $post_status && 'revision' !== $post_status) {
774
+			$uri = wl_build_entity_uri($post_id);
775
+			wl_set_entity_uri($post_id, $uri);
785 776
 		}
786 777
 
787 778
 		return $uri;
@@ -796,13 +787,13 @@  discard block
 block discarded – undo
796 787
 	 *
797 788
 	 * @return string The input HTML code.
798 789
 	 */
799
-	private function convert_raw_score_to_traffic_light( $score ) {
790
+	private function convert_raw_score_to_traffic_light($score) {
800 791
 		// RATING_MAX : $score = 3 : x 
801 792
 		// See http://php.net/manual/en/function.round.php
802
-		$rating = round( ( $score * 3 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
793
+		$rating = round(($score * 3) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP);
803 794
 
804 795
 		// If rating is 0, return 1, otherwise return rating
805
-		return ( 0 == $rating ) ? 1 : $rating;
796
+		return (0 == $rating) ? 1 : $rating;
806 797
 
807 798
 	}
808 799
 
@@ -815,9 +806,9 @@  discard block
 block discarded – undo
815 806
 	 *
816 807
 	 * @return string The input HTML code.
817 808
 	 */
818
-	public function convert_raw_score_to_percentage( $score ) {
809
+	public function convert_raw_score_to_percentage($score) {
819 810
 		// RATING_MAX : $score = 100 : x 
820
-		return round( ( $score * 100 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
811
+		return round(($score * 100) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP);
821 812
 	}
822 813
 
823 814
 	/**
@@ -829,9 +820,9 @@  discard block
 block discarded – undo
829 820
 	 *
830 821
 	 * @return string The input HTML code.
831 822
 	 */
832
-	private function get_alternative_label_input( $value = '' ) {
823
+	private function get_alternative_label_input($value = '') {
833 824
 
834
-		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
825
+		return sprintf(self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr($value), __('Delete', 'wordlift'));
835 826
 	}
836 827
 
837 828
 	/**
@@ -843,7 +834,7 @@  discard block
 block discarded – undo
843 834
 	 */
844 835
 	public function count() {
845 836
 
846
-		$count = wp_count_posts( self::TYPE_NAME );
837
+		$count = wp_count_posts(self::TYPE_NAME);
847 838
 
848 839
 		return $count->publish;
849 840
 	}
Please login to merge, or discard this patch.
src/wordlift_content_filter.php 1 patch
Indentation   +172 added lines, -172 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@  discard block
 block discarded – undo
10 10
  * @param string $uri Uri of the entity to search in the post content.
11 11
  */
12 12
 function wl_content_embed_build_regex_from_uri( $uri ) {
13
-	return '|<(\\w+)[^<]* itemid=\"' . esc_attr( $uri ) . '\"[^>]*>([^<]*)<\\/\\1>|i';
13
+    return '|<(\\w+)[^<]* itemid=\"' . esc_attr( $uri ) . '\"[^>]*>([^<]*)<\\/\\1>|i';
14 14
 }
15 15
 
16 16
 /**
@@ -22,8 +22,8 @@  discard block
 block discarded – undo
22 22
  */
23 23
 function wl_content_embed_microdata( $content ) {
24 24
 
25
-	// Apply microdata only to single pages.
26
-	/*if ( ! is_single() ) {
25
+    // Apply microdata only to single pages.
26
+    /*if ( ! is_single() ) {
27 27
 		wl_write_log( "wl_content_embed_microdata : is not single" );
28 28
 
29 29
 		return $content;
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
 
32 32
 	global $post;
33 33
         */
34
-	return _wl_content_embed_microdata( get_the_ID(), $content );
34
+    return _wl_content_embed_microdata( get_the_ID(), $content );
35 35
 }
36 36
 
37 37
 /**
@@ -44,31 +44,31 @@  discard block
 block discarded – undo
44 44
  */
45 45
 function _wl_content_embed_microdata( $post_id, $content ) {
46 46
 
47
-	// If it is an entity, add its own microdata to the content.
48
-	if ( get_post_type( $post_id ) == Wordlift_Entity_Service::TYPE_NAME ) {
49
-		$own_uri = wl_get_entity_uri( $post_id );
50
-		$content .= '<span itemid="' . $own_uri . '"></span>';
51
-	}
47
+    // If it is an entity, add its own microdata to the content.
48
+    if ( get_post_type( $post_id ) == Wordlift_Entity_Service::TYPE_NAME ) {
49
+        $own_uri = wl_get_entity_uri( $post_id );
50
+        $content .= '<span itemid="' . $own_uri . '"></span>';
51
+    }
52 52
 
53
-	// Now search in the text entity mentions
54
-	$regex   = '/<(\\w+)[^<]* itemid=\"([^"]+)\"[^>]*>([^<]*)<\\/\\1>/i';
55
-	$matches = array();
53
+    // Now search in the text entity mentions
54
+    $regex   = '/<(\\w+)[^<]* itemid=\"([^"]+)\"[^>]*>([^<]*)<\\/\\1>/i';
55
+    $matches = array();
56 56
 
57
-	// Return the content if not item IDs have been found.
58
-	if ( FALSE === preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) ) {
59
-		return $content;
60
-	}
57
+    // Return the content if not item IDs have been found.
58
+    if ( FALSE === preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) ) {
59
+        return $content;
60
+    }
61 61
 
62
-	// TODO: Retrieve here just one time entities type structure to avoid multiple queries.
63
-	foreach ( $matches as $match ) {
64
-		$item_id = $match[2];
62
+    // TODO: Retrieve here just one time entities type structure to avoid multiple queries.
63
+    foreach ( $matches as $match ) {
64
+        $item_id = $match[2];
65 65
 
66
-		// wl_write_log( "_wl_content_embed_microdata [ item ID :: $item_id ]" );
66
+        // wl_write_log( "_wl_content_embed_microdata [ item ID :: $item_id ]" );
67 67
 
68
-		$content = wl_content_embed_item_microdata( $content, $item_id );
69
-	}
68
+        $content = wl_content_embed_item_microdata( $content, $item_id );
69
+    }
70 70
 
71
-	return $content;
71
+    return $content;
72 72
 }
73 73
 
74 74
 /**
@@ -82,80 +82,80 @@  discard block
 block discarded – undo
82 82
  */
83 83
 function wl_content_embed_item_microdata( $content, $uri, $itemprop = NULL, $recursion_level = 0 ) {
84 84
 
85
-	// The recursion level is set by `wl_content_embed_compile_microdata_template`
86
-	// which is loading referenced entities and calling again this function to print
87
-	// additional properties. By default WordLift doesn't print more than 3 nested
88
-	// entities.
89
-	if ( $recursion_level > wl_config_get_recursion_depth() ) {
90
-		wl_write_log( "recursion depth limit exceeded [ level :: $recursion_level ][ max :: " . wl_config_get_recursion_depth() . " ]" );
85
+    // The recursion level is set by `wl_content_embed_compile_microdata_template`
86
+    // which is loading referenced entities and calling again this function to print
87
+    // additional properties. By default WordLift doesn't print more than 3 nested
88
+    // entities.
89
+    if ( $recursion_level > wl_config_get_recursion_depth() ) {
90
+        wl_write_log( "recursion depth limit exceeded [ level :: $recursion_level ][ max :: " . wl_config_get_recursion_depth() . " ]" );
91 91
 
92
-		return '';
93
-	}
92
+        return '';
93
+    }
94 94
 
95
-	$post = Wordlift_Entity_Service::get_instance()
96
-	                               ->get_entity_post_by_uri( $uri );
95
+    $post = Wordlift_Entity_Service::get_instance()
96
+                                    ->get_entity_post_by_uri( $uri );
97 97
 
98
-	// Entity not found or not published. Delete <span> tags but leave their content on page.
99
-	if ( NULL === $post || $post->post_status !== 'publish' ) {
98
+    // Entity not found or not published. Delete <span> tags but leave their content on page.
99
+    if ( NULL === $post || $post->post_status !== 'publish' ) {
100 100
 
101
-		// wl_write_log( "wl_content_embed_item_microdata : entity not found or not published [ uri :: $uri ]" );
101
+        // wl_write_log( "wl_content_embed_item_microdata : entity not found or not published [ uri :: $uri ]" );
102 102
 
103
-		// Replace the original tagging with the new tagging.
104
-		$regex   = wl_content_embed_build_regex_from_uri( $uri );
105
-		$content = preg_replace( $regex, '$2', $content );
103
+        // Replace the original tagging with the new tagging.
104
+        $regex   = wl_content_embed_build_regex_from_uri( $uri );
105
+        $content = preg_replace( $regex, '$2', $content );
106 106
 
107
-		return $content;
108
-	}
107
+        return $content;
108
+    }
109 109
 
110
-	// Get the entity URI and its escaped version for the regex.
111
-	$entity_uri = wl_get_entity_uri( $post->ID );
112
-	// Get the main type.
113
-	$main_type = wl_entity_type_taxonomy_get_type( $post->ID );
110
+    // Get the entity URI and its escaped version for the regex.
111
+    $entity_uri = wl_get_entity_uri( $post->ID );
112
+    // Get the main type.
113
+    $main_type = wl_entity_type_taxonomy_get_type( $post->ID );
114 114
 
115
-	// Set the item type if available.
116
-	$item_type = ( NULL === $main_type ? '' : ' itemtype="' . esc_attr( $main_type['uri'] ) . '"' );
115
+    // Set the item type if available.
116
+    $item_type = ( NULL === $main_type ? '' : ' itemtype="' . esc_attr( $main_type['uri'] ) . '"' );
117 117
 
118
-	// Define attribute itemprop if this entity is nested.
119
-	if ( ! is_null( $itemprop ) ) {
120
-		$itemprop = ' itemprop="' . $itemprop . '"';
121
-	}
118
+    // Define attribute itemprop if this entity is nested.
119
+    if ( ! is_null( $itemprop ) ) {
120
+        $itemprop = ' itemprop="' . $itemprop . '"';
121
+    }
122 122
 
123
-	// Get additional properties (this may imply a recursion of this method on a sub-entity).
124
-	$additional_properties = wl_content_embed_compile_microdata_template( $post->ID, $main_type, $recursion_level );
123
+    // Get additional properties (this may imply a recursion of this method on a sub-entity).
124
+    $additional_properties = wl_content_embed_compile_microdata_template( $post->ID, $main_type, $recursion_level );
125 125
 
126
-	$same_as = '';
127
-	// Get the array of sameAs uris.
128
-	$same_as_uris = wl_schema_get_value( $post->ID, 'sameAs' );
129
-	// Prepare the sameAs fragment.
130
-	foreach ( $same_as_uris as $same_as_uri ) {
131
-		$same_as .= "<link itemprop=\"sameAs\" href=\"$same_as_uri\">";
132
-	}
126
+    $same_as = '';
127
+    // Get the array of sameAs uris.
128
+    $same_as_uris = wl_schema_get_value( $post->ID, 'sameAs' );
129
+    // Prepare the sameAs fragment.
130
+    foreach ( $same_as_uris as $same_as_uri ) {
131
+        $same_as .= "<link itemprop=\"sameAs\" href=\"$same_as_uri\">";
132
+    }
133 133
 
134
-	// Get the entity URL.
135
-	$permalink = get_permalink( $post->ID );
136
-	$url       = '<link itemprop="url" href="' . $permalink . '" />';
134
+    // Get the entity URL.
135
+    $permalink = get_permalink( $post->ID );
136
+    $url       = '<link itemprop="url" href="' . $permalink . '" />';
137 137
 
138 138
 
139
-	// If entity is nested, we do not show a link, but a hidden meta.
140
-	// See https://github.com/insideout10/wordlift-plugin/issues/348
141
-	$name = ! is_null( $itemprop )
142
-		? "<meta itemprop='name' content='$post->post_title' /></$1>"
143
-		: '<a class="wl-entity-page-link" href="' . $permalink . '" itemprop="name" content="' . $post->post_title . '">' . ( is_null( $itemprop ) ? '$2' : '' ) . '</a></$1>';
139
+    // If entity is nested, we do not show a link, but a hidden meta.
140
+    // See https://github.com/insideout10/wordlift-plugin/issues/348
141
+    $name = ! is_null( $itemprop )
142
+        ? "<meta itemprop='name' content='$post->post_title' /></$1>"
143
+        : '<a class="wl-entity-page-link" href="' . $permalink . '" itemprop="name" content="' . $post->post_title . '">' . ( is_null( $itemprop ) ? '$2' : '' ) . '</a></$1>';
144 144
 
145
-	// Replace the original tagging with the new tagging.
146
-	$regex   = wl_content_embed_build_regex_from_uri( $uri );
147
-	$content = preg_replace( $regex,
148
-		'<$1' . $itemprop . ' itemscope' . $item_type . ' itemid="' . esc_attr( $entity_uri ) . '">'
149
-		. $same_as
150
-		. $additional_properties
151
-		. $url
152
-		. $name,
153
-		$content
154
-	);
145
+    // Replace the original tagging with the new tagging.
146
+    $regex   = wl_content_embed_build_regex_from_uri( $uri );
147
+    $content = preg_replace( $regex,
148
+        '<$1' . $itemprop . ' itemscope' . $item_type . ' itemid="' . esc_attr( $entity_uri ) . '">'
149
+        . $same_as
150
+        . $additional_properties
151
+        . $url
152
+        . $name,
153
+        $content
154
+    );
155 155
 
156
-	// wl_write_log( "wl_content_embed_item_microdata [ uri :: $uri ][ regex :: $regex ]" );
156
+    // wl_write_log( "wl_content_embed_item_microdata [ uri :: $uri ][ regex :: $regex ]" );
157 157
 
158
-	return $content;
158
+    return $content;
159 159
 }
160 160
 
161 161
 add_filter( 'the_content', 'wl_content_embed_microdata' );
@@ -170,96 +170,96 @@  discard block
 block discarded – undo
170 170
  * @return string The content with embedded microdata.
171 171
  */
172 172
 function wl_content_embed_compile_microdata_template( $entity_id, $entity_type, $recursion_level = 0 ) {
173
-	global $wl_logger;
174
-
175
-	if ( WP_DEBUG ) {
176
-		$wl_logger->trace( "Embedding microdata [ entity id :: $entity_id ][ recursion level :: $recursion_level ]" );
177
-	}
178
-
179
-	$regex   = '/{{(.*?)}}/';
180
-	$matches = array();
181
-
182
-	if ( NULL === $entity_type ) {
183
-		return '';
184
-	}
185
-
186
-	$template = $entity_type['microdata_template'];
187
-	// Return empty string if template fields have not been found.
188
-	if ( FALSE === preg_match_all( $regex, $template, $matches, PREG_SET_ORDER ) ) {
189
-		return '';
190
-	}
191
-
192
-	foreach ( $matches as $match ) {
193
-
194
-		$placeholder = $match[0];
195
-		$field_name  = $match[1];
196
-
197
-		// Get property value.
198
-		$meta_collection = wl_schema_get_value( $entity_id, $field_name );
199
-
200
-		// If no value is given, just remove the placeholder from the template
201
-		if ( NULL == $meta_collection ) {
202
-			$template = str_replace( $placeholder, '', $template );
203
-			continue;
204
-		}
205
-
206
-		// What kind of value is it?
207
-		// TODO: Performance issue here: meta type retrieving should be centralized
208
-		$expected_type = wl_get_meta_type( $field_name );
209
-
210
-		if ( WP_DEBUG ) {
211
-			$wl_logger->trace( "Embedding microdata [ placeholder :: $placeholder ][ field name :: $field_name ][ meta collection :: " . ( is_array( $meta_collection ) ? var_export( $meta_collection, TRUE ) : $meta_collection ) . " ][ expected type :: $expected_type ]" );
212
-		}
213
-
214
-		foreach ( $meta_collection as $field_value ) {
215
-
216
-			// Quick and dirty patch for #163:
217
-			//  - only apply to URIs, i.e. to properties pointing to another post ( $field_value should be a post ID ),
218
-			//  - check that $field_value is actually a number,
219
-			//  - check that the referenced post is published.
220
-			//  OR
221
-			//  - if the value is empty then we don't display it.
222
-			//
223
-			// see https://github.com/insideout10/wordlift-plugin/issues/163
224
-			if ( Wordlift_Schema_Service::DATA_TYPE_URI === $expected_type && is_numeric( $field_value ) && 'publish' !== ( $post_status = get_post_status( $field_value ) )
225
-			     || empty( $field_value )
226
-			) {
227
-
228
-				if ( WP_DEBUG ) {
229
-					$wl_logger->trace( "Microdata refers to a non-published post [ field value :: $field_value ][ post status :: $post_status ]" );
230
-				}
231
-
232
-				// Remove the placeholder.
233
-				$template = str_replace( $placeholder, '', $template );
234
-				continue;
235
-			}
236
-
237
-			if ( Wordlift_Schema_Service::DATA_TYPE_URI == $expected_type ) {
238
-				// If is a numeric value we assume it is an ID referencing for an internal entity.
239
-				if ( is_numeric( $field_value ) ) {
240
-					// Found id, get uri.
241
-					$field_value = wl_get_entity_uri( $field_value );
242
-				}
243
-				// Just if the linked entity does exist I can go further with template compiling
244
-				$nested_entity = Wordlift_Entity_Service::get_instance()
245
-				                                        ->get_entity_post_by_uri( $field_value );
246
-				if ( ! is_null( $nested_entity ) ) {
247
-					$content           = '<span itemid="' . esc_attr( $field_value ) . '">' . $nested_entity->post_title . '</span>';
248
-					$compiled_template = wl_content_embed_item_microdata( $content, $field_value, $field_name, ++ $recursion_level );
249
-					$template          = str_replace( $placeholder, $compiled_template, $template );
250
-				} else {
251
-					$template = str_replace( $placeholder, '', $template );
252
-				}
253
-				continue;
254
-			}
255
-
256
-			// Standard condition: field containing a raw value
257
-			// For non visible test, schema.org dictates to use the *meta* tag.
258
-			// see http://schema.org/docs/gs.html#advanced_missing
259
-			$value    = '<meta itemprop="' . esc_attr( $field_name ) . '" content="' . esc_attr( $field_value ) . '" />';
260
-			$template = str_replace( $placeholder, $value, $template );
261
-		}
262
-	}
263
-
264
-	return $template;
173
+    global $wl_logger;
174
+
175
+    if ( WP_DEBUG ) {
176
+        $wl_logger->trace( "Embedding microdata [ entity id :: $entity_id ][ recursion level :: $recursion_level ]" );
177
+    }
178
+
179
+    $regex   = '/{{(.*?)}}/';
180
+    $matches = array();
181
+
182
+    if ( NULL === $entity_type ) {
183
+        return '';
184
+    }
185
+
186
+    $template = $entity_type['microdata_template'];
187
+    // Return empty string if template fields have not been found.
188
+    if ( FALSE === preg_match_all( $regex, $template, $matches, PREG_SET_ORDER ) ) {
189
+        return '';
190
+    }
191
+
192
+    foreach ( $matches as $match ) {
193
+
194
+        $placeholder = $match[0];
195
+        $field_name  = $match[1];
196
+
197
+        // Get property value.
198
+        $meta_collection = wl_schema_get_value( $entity_id, $field_name );
199
+
200
+        // If no value is given, just remove the placeholder from the template
201
+        if ( NULL == $meta_collection ) {
202
+            $template = str_replace( $placeholder, '', $template );
203
+            continue;
204
+        }
205
+
206
+        // What kind of value is it?
207
+        // TODO: Performance issue here: meta type retrieving should be centralized
208
+        $expected_type = wl_get_meta_type( $field_name );
209
+
210
+        if ( WP_DEBUG ) {
211
+            $wl_logger->trace( "Embedding microdata [ placeholder :: $placeholder ][ field name :: $field_name ][ meta collection :: " . ( is_array( $meta_collection ) ? var_export( $meta_collection, TRUE ) : $meta_collection ) . " ][ expected type :: $expected_type ]" );
212
+        }
213
+
214
+        foreach ( $meta_collection as $field_value ) {
215
+
216
+            // Quick and dirty patch for #163:
217
+            //  - only apply to URIs, i.e. to properties pointing to another post ( $field_value should be a post ID ),
218
+            //  - check that $field_value is actually a number,
219
+            //  - check that the referenced post is published.
220
+            //  OR
221
+            //  - if the value is empty then we don't display it.
222
+            //
223
+            // see https://github.com/insideout10/wordlift-plugin/issues/163
224
+            if ( Wordlift_Schema_Service::DATA_TYPE_URI === $expected_type && is_numeric( $field_value ) && 'publish' !== ( $post_status = get_post_status( $field_value ) )
225
+                 || empty( $field_value )
226
+            ) {
227
+
228
+                if ( WP_DEBUG ) {
229
+                    $wl_logger->trace( "Microdata refers to a non-published post [ field value :: $field_value ][ post status :: $post_status ]" );
230
+                }
231
+
232
+                // Remove the placeholder.
233
+                $template = str_replace( $placeholder, '', $template );
234
+                continue;
235
+            }
236
+
237
+            if ( Wordlift_Schema_Service::DATA_TYPE_URI == $expected_type ) {
238
+                // If is a numeric value we assume it is an ID referencing for an internal entity.
239
+                if ( is_numeric( $field_value ) ) {
240
+                    // Found id, get uri.
241
+                    $field_value = wl_get_entity_uri( $field_value );
242
+                }
243
+                // Just if the linked entity does exist I can go further with template compiling
244
+                $nested_entity = Wordlift_Entity_Service::get_instance()
245
+                                                        ->get_entity_post_by_uri( $field_value );
246
+                if ( ! is_null( $nested_entity ) ) {
247
+                    $content           = '<span itemid="' . esc_attr( $field_value ) . '">' . $nested_entity->post_title . '</span>';
248
+                    $compiled_template = wl_content_embed_item_microdata( $content, $field_value, $field_name, ++ $recursion_level );
249
+                    $template          = str_replace( $placeholder, $compiled_template, $template );
250
+                } else {
251
+                    $template = str_replace( $placeholder, '', $template );
252
+                }
253
+                continue;
254
+            }
255
+
256
+            // Standard condition: field containing a raw value
257
+            // For non visible test, schema.org dictates to use the *meta* tag.
258
+            // see http://schema.org/docs/gs.html#advanced_missing
259
+            $value    = '<meta itemprop="' . esc_attr( $field_name ) . '" content="' . esc_attr( $field_value ) . '" />';
260
+            $template = str_replace( $placeholder, $value, $template );
261
+        }
262
+    }
263
+
264
+    return $template;
265 265
 }
266 266
\ No newline at end of file
Please login to merge, or discard this patch.
src/includes/class-wordlift-timeline-service.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -291,7 +291,7 @@
 block discarded – undo
291 291
 	 *
292 292
 	 * @since 3.7.0
293 293
 	 *
294
-	 * @param $value int A date value.
294
+	 * @param integer $value int A date value.
295 295
 	 *
296 296
 	 * @return array An array containing year, month and day values.
297 297
 	 */
Please login to merge, or discard this patch.
Indentation   +297 added lines, -297 removed lines patch added patch discarded remove patch
@@ -7,302 +7,302 @@
 block discarded – undo
7 7
  */
8 8
 class Wordlift_Timeline_Service {
9 9
 
10
-	/**
11
-	 * The Log service.
12
-	 *
13
-	 * @since 3.1.0
14
-	 * @access private
15
-	 * @var \Wordlift_Log_Service $log_service The Log service.
16
-	 */
17
-	private $log_service;
18
-
19
-	/**
20
-	 * The Entity service.
21
-	 *
22
-	 * @since 3.1.0
23
-	 * @access private
24
-	 * @var \Wordlift_Entity_Service $entity_service The Entity service.
25
-	 */
26
-	private $entity_service;
27
-
28
-	/**
29
-	 * The number of words to use for the excerpt, set in the `to_json` function
30
-	 * and used by a filter.
31
-	 *
32
-	 * @since 3.7.0
33
-	 * @access private
34
-	 * @var int $excerpt_length The number of words to use for the excerpt.
35
-	 */
36
-	private $excerpt_length;
37
-
38
-	/**
39
-	 * A singleton instance of the Timeline service (useful for unit tests).
40
-	 *
41
-	 * @since 3.1.0
42
-	 * @access private
43
-	 * @var \Wordlift_Timeline_Service $instance The singleton instance.
44
-	 */
45
-	private static $instance;
46
-
47
-	/**
48
-	 * Create a Wordlift_Timeline_Service instance.
49
-	 *
50
-	 * @since 3.1.0
51
-	 *
52
-	 * @param \Wordlift_Entity_Service $entity_service The Entity service.
53
-	 */
54
-	public function __construct( $entity_service ) {
55
-
56
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Service' );
57
-
58
-		$this->entity_service = $entity_service;
59
-
60
-		self::$instance = $this;
61
-
62
-	}
63
-
64
-	/**
65
-	 * Get the singleton instance of the Wordlift_Timeline_Service
66
-	 *
67
-	 * @since 3.1.0
68
-	 *
69
-	 * @return \Wordlift_Timeline_Service The singleton instance of the Wordlift_Timeline_Service.
70
-	 */
71
-	public static function get_instance() {
72
-
73
-		return self::$instance;
74
-	}
75
-
76
-	/**
77
-	 * Retrieve timeline events and output them in JSON.
78
-	 *
79
-	 * @since 3.1.0
80
-	 */
81
-	public function ajax_timeline() {
82
-
83
-		// Get the ID of the post who requested the timeline.
84
-		$post_id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : NULL );
85
-
86
-		// Get the events and transform them for the JSON response, then send them to the client.
87
-		wp_send_json( $this->to_json( $this->get_events( $post_id ) ) );
88
-
89
-	}
90
-
91
-	/**
92
-	 * Retrieve timeline events.
93
-	 *
94
-	 * @since 3.1.0
95
-	 *
96
-	 * @uses wl_core_get_related_entity_ids() to retrieve the entities referenced by the specified post.
97
-	 *
98
-	 * @param int $post_id The post ID.
99
-	 *
100
-	 * @return array An array of event posts.
101
-	 */
102
-	public function get_events( $post_id = NULL ) {
103
-
104
-		// Get the entity IDs either from the entities related to the specified post or from the last 50 published
105
-		// posts if no post has been specified.
106
-		$ids = ( is_numeric( $post_id )
107
-			? wl_core_get_related_entity_ids( $post_id )
108
-			: $this->entity_service->get_all_related_to_last_50_published_posts() );
109
-
110
-		// Add the post itself if it's an entity.
111
-		if ( is_numeric( $post_id ) && $this->entity_service->is_entity( $post_id ) ) {
112
-			$ids[] = $post_id;
113
-		}
114
-
115
-		// If there's no entities, return an empty array right away.
116
-		if ( 0 === sizeof( $ids ) ) {
117
-			$this->log_service->trace( "No events found [ post id :: $post_id ]" );
118
-
119
-			return array();
120
-		}
121
-
122
-		$this->log_service->trace( "Getting events [ entity ids :: " . join( ', ', $ids ) . " ]" );
123
-
124
-		return get_posts( array(
125
-			'post__in'       => $ids,
126
-			'post_type'      => Wordlift_Entity_Service::TYPE_NAME,
127
-			'post_status'    => 'publish',
128
-			'posts_per_page' => - 1,
129
-			'meta_query'     => array(
130
-				'relation' => 'AND',
131
-				array(
132
-					'key'     => Wordlift_Schema_Service::FIELD_DATE_START,
133
-					'value'   => NULL,
134
-					'compare' => '!='
135
-				),
136
-				array(
137
-					'key'     => Wordlift_Schema_Service::FIELD_DATE_END,
138
-					'value'   => NULL,
139
-					'compare' => '!='
140
-				)
141
-			),
142
-			'tax_query'      => array(
143
-				'taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME,
144
-				'field'    => 'slug',
145
-				'terms'    => 'event'
146
-			)
147
-		) );
148
-	}
149
-
150
-	/**
151
-	 * Convert timeline events to JSON. This function sets the global post in order
152
-	 * to get an automatic excerpt. Since we're being called inside an AJAX request,
153
-	 * we're not taking care of restoring any previous post: there isn't any.
154
-	 *
155
-	 * @since 3.1.0
156
-	 *
157
-	 * @param array $posts An array of posts.
158
-	 *
159
-	 * @return array|string An array of timeline events or an empty string if no posts are provided.
160
-	 */
161
-	public function to_json( $posts ) {
162
-
163
-		// If there are no events, return empty JSON
164
-		if ( empty( $posts ) || is_null( $posts ) ) {
165
-			return '';
166
-		}
167
-
168
-		// {media|thumbnail}: if set to 'media' the image is attached to the slide, if set to 'background' the image is set as background.
169
-		$display_images_as = isset( $_REQUEST['display_images_as'] ) ? $_REQUEST['display_images_as'] : 'media';
170
-
171
-		// The number of words for the excerpt (by default 55, as WordPress).
172
-		$this->excerpt_length = isset( $_REQUEST['excerpt_words'] ) && is_numeric( $_REQUEST['excerpt_words'] ) ? $_REQUEST['excerpt_words'] : 55;
173
-		add_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
174
-
175
-		// Add a filter to remove the [...] after excerpts, since we're adding
176
-		// a link to the post itself.
177
-		add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
178
-
179
-		// Prepare for the starting slide data. The starting slide will be the one where *now* is between *start/end* dates.
180
-		$start_at_slide = 0;
181
-		$event_index    = - 1;
182
-		$now            = time();
183
-
184
-		// Prepare the timeline variable.
185
-		$timeline = array();
186
-
187
-		// Populate the arrays.
188
-		$timeline['events'] = array_map( function ( $item ) use ( &$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as ) {
189
-
190
-			// Get the start and end dates.
191
-			$start_date = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_START, TRUE ) );
192
-			$end_date   = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_END, TRUE ) );
193
-
194
-			// Set the starting slide.
195
-			$event_index ++;
196
-			if ( 0 === $start_at_slide && $now >= $start_date && $now <= $end_date ) {
197
-				$start_at_slide = $event_index;
198
-			}
199
-
200
-			// Load thumbnail
201
-			if ( '' !== ( $thumbnail_id = get_post_thumbnail_id( $item->ID ) )
202
-			     && FALSE !== ( $attachment = wp_get_attachment_image_src( $thumbnail_id ) )
203
-			) {
204
-
205
-				// Set the thumbnail URL.
206
-				if ( 'background' === $display_images_as ) {
207
-					$date['background'] = array( 'url' => $attachment[0], );
208
-					$date['media']      = array( 'thumbnail' => $attachment[0], );
209
-				} else {
210
-					$date['media'] = array(
211
-						'url'       => $attachment[0],
212
-						'thumbnail' => $attachment[0],
213
-					);
214
-				}
215
-
216
-			}
217
-
218
-			// Set the start/end dates by converting them to TimelineJS required format.
219
-			$date['start_date'] = Wordlift_Timeline_Service::date( $start_date );
220
-			$date['end_date']   = Wordlift_Timeline_Service::date( $end_date );
221
-
222
-			setup_postdata( $GLOBALS['post'] = &$item );
223
-
224
-			$more_link_text = sprintf(
225
-				'<span aria-label="%1$s">%2$s</span>',
226
-				sprintf(
227
-				/* translators: %s: Name of current post */
228
-					__( 'Continue reading %s' ),
229
-					the_title_attribute( array( 'echo' => FALSE ) )
230
-				),
231
-				__( '(more&hellip;)' )
232
-			);
233
-
234
-			// Set the event text only with the headline (see https://github.com/insideout10/wordlift-plugin/issues/352).
235
-			$date['text'] = array(
236
-				'headline' => '<a href="' . get_permalink( $item->ID ) . '">' . $item->post_title . '</a>',
237
-			);
238
-
239
-			// If we have an excerpt, set it.
240
-			if ( 0 < $this->excerpt_length ) {
241
-				$date['text']['text'] = sprintf( '%s <a href="%s">%s</a>', get_the_excerpt( $item ), get_permalink(), $more_link_text );
242
-			}
243
-
244
-			return $date;
245
-
246
-		}, $posts );
247
-
248
-		// Finally remove the excerpt filter.
249
-		remove_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
250
-
251
-		// The JSON format is defined here: https://timeline.knightlab.com/docs/json-format.html
252
-		return array(
253
-			'timeline'       => $timeline,
254
-			'start_at_slide' => $start_at_slide,
255
-		);
256
-	}
257
-
258
-	/**
259
-	 * This function filters {@link excerpt_more} by removing it, since we're
260
-	 * adding the 'read more' link. This filter is set by {@see to_json}.
261
-	 *
262
-	 * @since 3.7.0
263
-	 *
264
-	 * @param string $excerpt_more The excerpt more preset.
265
-	 *
266
-	 * @return string An empty string.
267
-	 */
268
-	public function excerpt_more( $excerpt_more ) {
269
-
270
-		return '';
271
-	}
272
-
273
-	/**
274
-	 * A filter for the excerpt length, set by the `to_json` function, to tailor
275
-	 * how many words to return according to the client setting.
276
-	 *
277
-	 * @since 3.7.0
278
-	 *
279
-	 * @param int $length The preset number of words.
280
-	 *
281
-	 * @return int The number of words for the preset.
282
-	 */
283
-	public function excerpt_length( $length ) {
284
-
285
-		return $this->excerpt_length;
286
-	}
287
-
288
-
289
-	/**
290
-	 * Convert the date to a date array.
291
-	 *
292
-	 * @since 3.7.0
293
-	 *
294
-	 * @param $value int A date value.
295
-	 *
296
-	 * @return array An array containing year, month and day values.
297
-	 */
298
-	public static function date( $value ) {
299
-
300
-		return array(
301
-			'year'  => (int) date( 'Y', $value ),
302
-			'month' => (int) date( 'm', $value ),
303
-			'day'   => (int) date( 'd', $value ),
304
-
305
-		);
306
-	}
10
+    /**
11
+     * The Log service.
12
+     *
13
+     * @since 3.1.0
14
+     * @access private
15
+     * @var \Wordlift_Log_Service $log_service The Log service.
16
+     */
17
+    private $log_service;
18
+
19
+    /**
20
+     * The Entity service.
21
+     *
22
+     * @since 3.1.0
23
+     * @access private
24
+     * @var \Wordlift_Entity_Service $entity_service The Entity service.
25
+     */
26
+    private $entity_service;
27
+
28
+    /**
29
+     * The number of words to use for the excerpt, set in the `to_json` function
30
+     * and used by a filter.
31
+     *
32
+     * @since 3.7.0
33
+     * @access private
34
+     * @var int $excerpt_length The number of words to use for the excerpt.
35
+     */
36
+    private $excerpt_length;
37
+
38
+    /**
39
+     * A singleton instance of the Timeline service (useful for unit tests).
40
+     *
41
+     * @since 3.1.0
42
+     * @access private
43
+     * @var \Wordlift_Timeline_Service $instance The singleton instance.
44
+     */
45
+    private static $instance;
46
+
47
+    /**
48
+     * Create a Wordlift_Timeline_Service instance.
49
+     *
50
+     * @since 3.1.0
51
+     *
52
+     * @param \Wordlift_Entity_Service $entity_service The Entity service.
53
+     */
54
+    public function __construct( $entity_service ) {
55
+
56
+        $this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Service' );
57
+
58
+        $this->entity_service = $entity_service;
59
+
60
+        self::$instance = $this;
61
+
62
+    }
63
+
64
+    /**
65
+     * Get the singleton instance of the Wordlift_Timeline_Service
66
+     *
67
+     * @since 3.1.0
68
+     *
69
+     * @return \Wordlift_Timeline_Service The singleton instance of the Wordlift_Timeline_Service.
70
+     */
71
+    public static function get_instance() {
72
+
73
+        return self::$instance;
74
+    }
75
+
76
+    /**
77
+     * Retrieve timeline events and output them in JSON.
78
+     *
79
+     * @since 3.1.0
80
+     */
81
+    public function ajax_timeline() {
82
+
83
+        // Get the ID of the post who requested the timeline.
84
+        $post_id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : NULL );
85
+
86
+        // Get the events and transform them for the JSON response, then send them to the client.
87
+        wp_send_json( $this->to_json( $this->get_events( $post_id ) ) );
88
+
89
+    }
90
+
91
+    /**
92
+     * Retrieve timeline events.
93
+     *
94
+     * @since 3.1.0
95
+     *
96
+     * @uses wl_core_get_related_entity_ids() to retrieve the entities referenced by the specified post.
97
+     *
98
+     * @param int $post_id The post ID.
99
+     *
100
+     * @return array An array of event posts.
101
+     */
102
+    public function get_events( $post_id = NULL ) {
103
+
104
+        // Get the entity IDs either from the entities related to the specified post or from the last 50 published
105
+        // posts if no post has been specified.
106
+        $ids = ( is_numeric( $post_id )
107
+            ? wl_core_get_related_entity_ids( $post_id )
108
+            : $this->entity_service->get_all_related_to_last_50_published_posts() );
109
+
110
+        // Add the post itself if it's an entity.
111
+        if ( is_numeric( $post_id ) && $this->entity_service->is_entity( $post_id ) ) {
112
+            $ids[] = $post_id;
113
+        }
114
+
115
+        // If there's no entities, return an empty array right away.
116
+        if ( 0 === sizeof( $ids ) ) {
117
+            $this->log_service->trace( "No events found [ post id :: $post_id ]" );
118
+
119
+            return array();
120
+        }
121
+
122
+        $this->log_service->trace( "Getting events [ entity ids :: " . join( ', ', $ids ) . " ]" );
123
+
124
+        return get_posts( array(
125
+            'post__in'       => $ids,
126
+            'post_type'      => Wordlift_Entity_Service::TYPE_NAME,
127
+            'post_status'    => 'publish',
128
+            'posts_per_page' => - 1,
129
+            'meta_query'     => array(
130
+                'relation' => 'AND',
131
+                array(
132
+                    'key'     => Wordlift_Schema_Service::FIELD_DATE_START,
133
+                    'value'   => NULL,
134
+                    'compare' => '!='
135
+                ),
136
+                array(
137
+                    'key'     => Wordlift_Schema_Service::FIELD_DATE_END,
138
+                    'value'   => NULL,
139
+                    'compare' => '!='
140
+                )
141
+            ),
142
+            'tax_query'      => array(
143
+                'taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME,
144
+                'field'    => 'slug',
145
+                'terms'    => 'event'
146
+            )
147
+        ) );
148
+    }
149
+
150
+    /**
151
+     * Convert timeline events to JSON. This function sets the global post in order
152
+     * to get an automatic excerpt. Since we're being called inside an AJAX request,
153
+     * we're not taking care of restoring any previous post: there isn't any.
154
+     *
155
+     * @since 3.1.0
156
+     *
157
+     * @param array $posts An array of posts.
158
+     *
159
+     * @return array|string An array of timeline events or an empty string if no posts are provided.
160
+     */
161
+    public function to_json( $posts ) {
162
+
163
+        // If there are no events, return empty JSON
164
+        if ( empty( $posts ) || is_null( $posts ) ) {
165
+            return '';
166
+        }
167
+
168
+        // {media|thumbnail}: if set to 'media' the image is attached to the slide, if set to 'background' the image is set as background.
169
+        $display_images_as = isset( $_REQUEST['display_images_as'] ) ? $_REQUEST['display_images_as'] : 'media';
170
+
171
+        // The number of words for the excerpt (by default 55, as WordPress).
172
+        $this->excerpt_length = isset( $_REQUEST['excerpt_words'] ) && is_numeric( $_REQUEST['excerpt_words'] ) ? $_REQUEST['excerpt_words'] : 55;
173
+        add_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
174
+
175
+        // Add a filter to remove the [...] after excerpts, since we're adding
176
+        // a link to the post itself.
177
+        add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
178
+
179
+        // Prepare for the starting slide data. The starting slide will be the one where *now* is between *start/end* dates.
180
+        $start_at_slide = 0;
181
+        $event_index    = - 1;
182
+        $now            = time();
183
+
184
+        // Prepare the timeline variable.
185
+        $timeline = array();
186
+
187
+        // Populate the arrays.
188
+        $timeline['events'] = array_map( function ( $item ) use ( &$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as ) {
189
+
190
+            // Get the start and end dates.
191
+            $start_date = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_START, TRUE ) );
192
+            $end_date   = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_END, TRUE ) );
193
+
194
+            // Set the starting slide.
195
+            $event_index ++;
196
+            if ( 0 === $start_at_slide && $now >= $start_date && $now <= $end_date ) {
197
+                $start_at_slide = $event_index;
198
+            }
199
+
200
+            // Load thumbnail
201
+            if ( '' !== ( $thumbnail_id = get_post_thumbnail_id( $item->ID ) )
202
+                 && FALSE !== ( $attachment = wp_get_attachment_image_src( $thumbnail_id ) )
203
+            ) {
204
+
205
+                // Set the thumbnail URL.
206
+                if ( 'background' === $display_images_as ) {
207
+                    $date['background'] = array( 'url' => $attachment[0], );
208
+                    $date['media']      = array( 'thumbnail' => $attachment[0], );
209
+                } else {
210
+                    $date['media'] = array(
211
+                        'url'       => $attachment[0],
212
+                        'thumbnail' => $attachment[0],
213
+                    );
214
+                }
215
+
216
+            }
217
+
218
+            // Set the start/end dates by converting them to TimelineJS required format.
219
+            $date['start_date'] = Wordlift_Timeline_Service::date( $start_date );
220
+            $date['end_date']   = Wordlift_Timeline_Service::date( $end_date );
221
+
222
+            setup_postdata( $GLOBALS['post'] = &$item );
223
+
224
+            $more_link_text = sprintf(
225
+                '<span aria-label="%1$s">%2$s</span>',
226
+                sprintf(
227
+                /* translators: %s: Name of current post */
228
+                    __( 'Continue reading %s' ),
229
+                    the_title_attribute( array( 'echo' => FALSE ) )
230
+                ),
231
+                __( '(more&hellip;)' )
232
+            );
233
+
234
+            // Set the event text only with the headline (see https://github.com/insideout10/wordlift-plugin/issues/352).
235
+            $date['text'] = array(
236
+                'headline' => '<a href="' . get_permalink( $item->ID ) . '">' . $item->post_title . '</a>',
237
+            );
238
+
239
+            // If we have an excerpt, set it.
240
+            if ( 0 < $this->excerpt_length ) {
241
+                $date['text']['text'] = sprintf( '%s <a href="%s">%s</a>', get_the_excerpt( $item ), get_permalink(), $more_link_text );
242
+            }
243
+
244
+            return $date;
245
+
246
+        }, $posts );
247
+
248
+        // Finally remove the excerpt filter.
249
+        remove_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
250
+
251
+        // The JSON format is defined here: https://timeline.knightlab.com/docs/json-format.html
252
+        return array(
253
+            'timeline'       => $timeline,
254
+            'start_at_slide' => $start_at_slide,
255
+        );
256
+    }
257
+
258
+    /**
259
+     * This function filters {@link excerpt_more} by removing it, since we're
260
+     * adding the 'read more' link. This filter is set by {@see to_json}.
261
+     *
262
+     * @since 3.7.0
263
+     *
264
+     * @param string $excerpt_more The excerpt more preset.
265
+     *
266
+     * @return string An empty string.
267
+     */
268
+    public function excerpt_more( $excerpt_more ) {
269
+
270
+        return '';
271
+    }
272
+
273
+    /**
274
+     * A filter for the excerpt length, set by the `to_json` function, to tailor
275
+     * how many words to return according to the client setting.
276
+     *
277
+     * @since 3.7.0
278
+     *
279
+     * @param int $length The preset number of words.
280
+     *
281
+     * @return int The number of words for the preset.
282
+     */
283
+    public function excerpt_length( $length ) {
284
+
285
+        return $this->excerpt_length;
286
+    }
287
+
288
+
289
+    /**
290
+     * Convert the date to a date array.
291
+     *
292
+     * @since 3.7.0
293
+     *
294
+     * @param $value int A date value.
295
+     *
296
+     * @return array An array containing year, month and day values.
297
+     */
298
+    public static function date( $value ) {
299
+
300
+        return array(
301
+            'year'  => (int) date( 'Y', $value ),
302
+            'month' => (int) date( 'm', $value ),
303
+            'day'   => (int) date( 'd', $value ),
304
+
305
+        );
306
+    }
307 307
 
308 308
 }
Please login to merge, or discard this patch.
Spacing   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -51,9 +51,9 @@  discard block
 block discarded – undo
51 51
 	 *
52 52
 	 * @param \Wordlift_Entity_Service $entity_service The Entity service.
53 53
 	 */
54
-	public function __construct( $entity_service ) {
54
+	public function __construct($entity_service) {
55 55
 
56
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Service' );
56
+		$this->log_service = Wordlift_Log_Service::get_logger('Wordlift_Timeline_Service');
57 57
 
58 58
 		$this->entity_service = $entity_service;
59 59
 
@@ -81,10 +81,10 @@  discard block
 block discarded – undo
81 81
 	public function ajax_timeline() {
82 82
 
83 83
 		// Get the ID of the post who requested the timeline.
84
-		$post_id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : NULL );
84
+		$post_id = (isset($_REQUEST['post_id']) ? $_REQUEST['post_id'] : NULL);
85 85
 
86 86
 		// Get the events and transform them for the JSON response, then send them to the client.
87
-		wp_send_json( $this->to_json( $this->get_events( $post_id ) ) );
87
+		wp_send_json($this->to_json($this->get_events($post_id)));
88 88
 
89 89
 	}
90 90
 
@@ -99,33 +99,33 @@  discard block
 block discarded – undo
99 99
 	 *
100 100
 	 * @return array An array of event posts.
101 101
 	 */
102
-	public function get_events( $post_id = NULL ) {
102
+	public function get_events($post_id = NULL) {
103 103
 
104 104
 		// Get the entity IDs either from the entities related to the specified post or from the last 50 published
105 105
 		// posts if no post has been specified.
106
-		$ids = ( is_numeric( $post_id )
107
-			? wl_core_get_related_entity_ids( $post_id )
108
-			: $this->entity_service->get_all_related_to_last_50_published_posts() );
106
+		$ids = (is_numeric($post_id)
107
+			? wl_core_get_related_entity_ids($post_id)
108
+			: $this->entity_service->get_all_related_to_last_50_published_posts());
109 109
 
110 110
 		// Add the post itself if it's an entity.
111
-		if ( is_numeric( $post_id ) && $this->entity_service->is_entity( $post_id ) ) {
111
+		if (is_numeric($post_id) && $this->entity_service->is_entity($post_id)) {
112 112
 			$ids[] = $post_id;
113 113
 		}
114 114
 
115 115
 		// If there's no entities, return an empty array right away.
116
-		if ( 0 === sizeof( $ids ) ) {
117
-			$this->log_service->trace( "No events found [ post id :: $post_id ]" );
116
+		if (0 === sizeof($ids)) {
117
+			$this->log_service->trace("No events found [ post id :: $post_id ]");
118 118
 
119 119
 			return array();
120 120
 		}
121 121
 
122
-		$this->log_service->trace( "Getting events [ entity ids :: " . join( ', ', $ids ) . " ]" );
122
+		$this->log_service->trace("Getting events [ entity ids :: ".join(', ', $ids)." ]");
123 123
 
124
-		return get_posts( array(
124
+		return get_posts(array(
125 125
 			'post__in'       => $ids,
126 126
 			'post_type'      => Wordlift_Entity_Service::TYPE_NAME,
127 127
 			'post_status'    => 'publish',
128
-			'posts_per_page' => - 1,
128
+			'posts_per_page' => -1,
129 129
 			'meta_query'     => array(
130 130
 				'relation' => 'AND',
131 131
 				array(
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 				'field'    => 'slug',
145 145
 				'terms'    => 'event'
146 146
 			)
147
-		) );
147
+		));
148 148
 	}
149 149
 
150 150
 	/**
@@ -158,23 +158,23 @@  discard block
 block discarded – undo
158 158
 	 *
159 159
 	 * @return array|string An array of timeline events or an empty string if no posts are provided.
160 160
 	 */
161
-	public function to_json( $posts ) {
161
+	public function to_json($posts) {
162 162
 
163 163
 		// If there are no events, return empty JSON
164
-		if ( empty( $posts ) || is_null( $posts ) ) {
164
+		if (empty($posts) || is_null($posts)) {
165 165
 			return '';
166 166
 		}
167 167
 
168 168
 		// {media|thumbnail}: if set to 'media' the image is attached to the slide, if set to 'background' the image is set as background.
169
-		$display_images_as = isset( $_REQUEST['display_images_as'] ) ? $_REQUEST['display_images_as'] : 'media';
169
+		$display_images_as = isset($_REQUEST['display_images_as']) ? $_REQUEST['display_images_as'] : 'media';
170 170
 
171 171
 		// The number of words for the excerpt (by default 55, as WordPress).
172
-		$this->excerpt_length = isset( $_REQUEST['excerpt_words'] ) && is_numeric( $_REQUEST['excerpt_words'] ) ? $_REQUEST['excerpt_words'] : 55;
173
-		add_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
172
+		$this->excerpt_length = isset($_REQUEST['excerpt_words']) && is_numeric($_REQUEST['excerpt_words']) ? $_REQUEST['excerpt_words'] : 55;
173
+		add_filter('excerpt_length', array($this, 'excerpt_length'));
174 174
 
175 175
 		// Add a filter to remove the [...] after excerpts, since we're adding
176 176
 		// a link to the post itself.
177
-		add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
177
+		add_filter('excerpt_more', array($this, 'excerpt_more'));
178 178
 
179 179
 		// Prepare for the starting slide data. The starting slide will be the one where *now* is between *start/end* dates.
180 180
 		$start_at_slide = 0;
@@ -185,27 +185,27 @@  discard block
 block discarded – undo
185 185
 		$timeline = array();
186 186
 
187 187
 		// Populate the arrays.
188
-		$timeline['events'] = array_map( function ( $item ) use ( &$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as ) {
188
+		$timeline['events'] = array_map(function($item) use (&$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as) {
189 189
 
190 190
 			// Get the start and end dates.
191
-			$start_date = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_START, TRUE ) );
192
-			$end_date   = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_END, TRUE ) );
191
+			$start_date = strtotime(get_post_meta($item->ID, Wordlift_Schema_Service::FIELD_DATE_START, TRUE));
192
+			$end_date   = strtotime(get_post_meta($item->ID, Wordlift_Schema_Service::FIELD_DATE_END, TRUE));
193 193
 
194 194
 			// Set the starting slide.
195
-			$event_index ++;
196
-			if ( 0 === $start_at_slide && $now >= $start_date && $now <= $end_date ) {
195
+			$event_index++;
196
+			if (0 === $start_at_slide && $now >= $start_date && $now <= $end_date) {
197 197
 				$start_at_slide = $event_index;
198 198
 			}
199 199
 
200 200
 			// Load thumbnail
201
-			if ( '' !== ( $thumbnail_id = get_post_thumbnail_id( $item->ID ) )
202
-			     && FALSE !== ( $attachment = wp_get_attachment_image_src( $thumbnail_id ) )
201
+			if ('' !== ($thumbnail_id = get_post_thumbnail_id($item->ID))
202
+			     && FALSE !== ($attachment = wp_get_attachment_image_src($thumbnail_id))
203 203
 			) {
204 204
 
205 205
 				// Set the thumbnail URL.
206
-				if ( 'background' === $display_images_as ) {
207
-					$date['background'] = array( 'url' => $attachment[0], );
208
-					$date['media']      = array( 'thumbnail' => $attachment[0], );
206
+				if ('background' === $display_images_as) {
207
+					$date['background'] = array('url' => $attachment[0],);
208
+					$date['media']      = array('thumbnail' => $attachment[0],);
209 209
 				} else {
210 210
 					$date['media'] = array(
211 211
 						'url'       => $attachment[0],
@@ -216,37 +216,37 @@  discard block
 block discarded – undo
216 216
 			}
217 217
 
218 218
 			// Set the start/end dates by converting them to TimelineJS required format.
219
-			$date['start_date'] = Wordlift_Timeline_Service::date( $start_date );
220
-			$date['end_date']   = Wordlift_Timeline_Service::date( $end_date );
219
+			$date['start_date'] = Wordlift_Timeline_Service::date($start_date);
220
+			$date['end_date']   = Wordlift_Timeline_Service::date($end_date);
221 221
 
222
-			setup_postdata( $GLOBALS['post'] = &$item );
222
+			setup_postdata($GLOBALS['post'] = &$item);
223 223
 
224 224
 			$more_link_text = sprintf(
225 225
 				'<span aria-label="%1$s">%2$s</span>',
226 226
 				sprintf(
227 227
 				/* translators: %s: Name of current post */
228
-					__( 'Continue reading %s' ),
229
-					the_title_attribute( array( 'echo' => FALSE ) )
228
+					__('Continue reading %s'),
229
+					the_title_attribute(array('echo' => FALSE))
230 230
 				),
231
-				__( '(more&hellip;)' )
231
+				__('(more&hellip;)')
232 232
 			);
233 233
 
234 234
 			// Set the event text only with the headline (see https://github.com/insideout10/wordlift-plugin/issues/352).
235 235
 			$date['text'] = array(
236
-				'headline' => '<a href="' . get_permalink( $item->ID ) . '">' . $item->post_title . '</a>',
236
+				'headline' => '<a href="'.get_permalink($item->ID).'">'.$item->post_title.'</a>',
237 237
 			);
238 238
 
239 239
 			// If we have an excerpt, set it.
240
-			if ( 0 < $this->excerpt_length ) {
241
-				$date['text']['text'] = sprintf( '%s <a href="%s">%s</a>', get_the_excerpt( $item ), get_permalink(), $more_link_text );
240
+			if (0 < $this->excerpt_length) {
241
+				$date['text']['text'] = sprintf('%s <a href="%s">%s</a>', get_the_excerpt($item), get_permalink(), $more_link_text);
242 242
 			}
243 243
 
244 244
 			return $date;
245 245
 
246
-		}, $posts );
246
+		}, $posts);
247 247
 
248 248
 		// Finally remove the excerpt filter.
249
-		remove_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
249
+		remove_filter('excerpt_length', array($this, 'excerpt_length'));
250 250
 
251 251
 		// The JSON format is defined here: https://timeline.knightlab.com/docs/json-format.html
252 252
 		return array(
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
 	 *
266 266
 	 * @return string An empty string.
267 267
 	 */
268
-	public function excerpt_more( $excerpt_more ) {
268
+	public function excerpt_more($excerpt_more) {
269 269
 
270 270
 		return '';
271 271
 	}
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
 	 *
281 281
 	 * @return int The number of words for the preset.
282 282
 	 */
283
-	public function excerpt_length( $length ) {
283
+	public function excerpt_length($length) {
284 284
 
285 285
 		return $this->excerpt_length;
286 286
 	}
@@ -295,12 +295,12 @@  discard block
 block discarded – undo
295 295
 	 *
296 296
 	 * @return array An array containing year, month and day values.
297 297
 	 */
298
-	public static function date( $value ) {
298
+	public static function date($value) {
299 299
 
300 300
 		return array(
301
-			'year'  => (int) date( 'Y', $value ),
302
-			'month' => (int) date( 'm', $value ),
303
-			'day'   => (int) date( 'd', $value ),
301
+			'year'  => (int) date('Y', $value),
302
+			'month' => (int) date('m', $value),
303
+			'day'   => (int) date('d', $value),
304 304
 
305 305
 		);
306 306
 	}
Please login to merge, or discard this patch.
src/public/class-wordlift-shortcode.php 2 patches
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -8,50 +8,50 @@
 block discarded – undo
8 8
  */
9 9
 abstract class Wordlift_Shortcode {
10 10
 
11
-	/**
12
-	 * The shortcode, set by extending classes.
13
-	 */
14
-	const SHORTCODE = NULL;
15
-
16
-	/**
17
-	 * Create a shortcode instance by registering the shortcode with the render
18
-	 * function.
19
-	 *
20
-	 * @since 3.5.4
21
-	 */
22
-	public function __construct() {
23
-
24
-		add_shortcode( static::SHORTCODE, array( $this, 'render' ) );
25
-
26
-	}
27
-
28
-	/**
29
-	 * Render the shortcode.
30
-	 *
31
-	 * @since 3.5.4
32
-	 *
33
-	 * @param array $atts An array of shortcode attributes as set by the editor.
34
-	 *
35
-	 * @return string The output html code.
36
-	 */
37
-	public abstract function render( $atts );
38
-
39
-	/**
40
-	 * Enqueue scripts. Called by the shortcode implementations in their render
41
-	 * method.
42
-	 *
43
-	 * @since 3.5.4
44
-	 */
45
-	protected function enqueue_scripts() {
46
-
47
-		wp_enqueue_script( 'angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js' );
48
-		wp_enqueue_script( 'angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js', array( 'angularjs' ) );
49
-		wp_enqueue_script( 'wordlift-ui', dirname( plugin_dir_url( __FILE__ ) ) . '/js/wordlift-ui' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '.min' : '' ) . '.js', array(
50
-			'jquery',
51
-			'angularjs',
52
-			'angularjs-touch'
53
-		) );
54
-
55
-	}
11
+    /**
12
+     * The shortcode, set by extending classes.
13
+     */
14
+    const SHORTCODE = NULL;
15
+
16
+    /**
17
+     * Create a shortcode instance by registering the shortcode with the render
18
+     * function.
19
+     *
20
+     * @since 3.5.4
21
+     */
22
+    public function __construct() {
23
+
24
+        add_shortcode( static::SHORTCODE, array( $this, 'render' ) );
25
+
26
+    }
27
+
28
+    /**
29
+     * Render the shortcode.
30
+     *
31
+     * @since 3.5.4
32
+     *
33
+     * @param array $atts An array of shortcode attributes as set by the editor.
34
+     *
35
+     * @return string The output html code.
36
+     */
37
+    public abstract function render( $atts );
38
+
39
+    /**
40
+     * Enqueue scripts. Called by the shortcode implementations in their render
41
+     * method.
42
+     *
43
+     * @since 3.5.4
44
+     */
45
+    protected function enqueue_scripts() {
46
+
47
+        wp_enqueue_script( 'angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js' );
48
+        wp_enqueue_script( 'angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js', array( 'angularjs' ) );
49
+        wp_enqueue_script( 'wordlift-ui', dirname( plugin_dir_url( __FILE__ ) ) . '/js/wordlift-ui' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '.min' : '' ) . '.js', array(
50
+            'jquery',
51
+            'angularjs',
52
+            'angularjs-touch'
53
+        ) );
54
+
55
+    }
56 56
 
57 57
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
 	 */
22 22
 	public function __construct() {
23 23
 
24
-		add_shortcode( static::SHORTCODE, array( $this, 'render' ) );
24
+		add_shortcode(static::SHORTCODE, array($this, 'render'));
25 25
 
26 26
 	}
27 27
 
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
 	 *
35 35
 	 * @return string The output html code.
36 36
 	 */
37
-	public abstract function render( $atts );
37
+	public abstract function render($atts);
38 38
 
39 39
 	/**
40 40
 	 * Enqueue scripts. Called by the shortcode implementations in their render
@@ -44,13 +44,13 @@  discard block
 block discarded – undo
44 44
 	 */
45 45
 	protected function enqueue_scripts() {
46 46
 
47
-		wp_enqueue_script( 'angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js' );
48
-		wp_enqueue_script( 'angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js', array( 'angularjs' ) );
49
-		wp_enqueue_script( 'wordlift-ui', dirname( plugin_dir_url( __FILE__ ) ) . '/js/wordlift-ui' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '.min' : '' ) . '.js', array(
47
+		wp_enqueue_script('angularjs', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js');
48
+		wp_enqueue_script('angularjs-touch', 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular-touch.min.js', array('angularjs'));
49
+		wp_enqueue_script('wordlift-ui', dirname(plugin_dir_url(__FILE__)).'/js/wordlift-ui'.( ! defined('SCRIPT_DEBUG') || ! SCRIPT_DEBUG ? '.min' : '').'.js', array(
50 50
 			'jquery',
51 51
 			'angularjs',
52 52
 			'angularjs-touch'
53
-		) );
53
+		));
54 54
 
55 55
 	}
56 56
 
Please login to merge, or discard this patch.
src/public/class-wordlift-timeline-shortcode.php 2 patches
Indentation   +193 added lines, -193 removed lines patch added patch discarded remove patch
@@ -7,198 +7,198 @@
 block discarded – undo
7 7
  */
8 8
 class Wordlift_Timeline_Shortcode extends Wordlift_Shortcode {
9 9
 
10
-	const SHORTCODE = 'wl_timeline';
11
-
12
-	/**
13
-	 * The list of locales supported by TimelineJS (correspond to the list of
14
-	 * files in the locale subfolder).
15
-	 *
16
-	 * @since 3.7.0
17
-	 * @var array An array of two-letters language codes.
18
-	 */
19
-	private static $supported_locales = array(
20
-		'ur',
21
-		'uk',
22
-		'tr',
23
-		'tl',
24
-		'th',
25
-		'te',
26
-		'ta',
27
-		'sv',
28
-		'sr',
29
-		'sl',
30
-		'sk',
31
-		'si',
32
-		'ru',
33
-		'ro',
34
-		'rm',
35
-		'pt',
36
-		'pl',
37
-		'no',
38
-		'nl',
39
-		'ne',
40
-		'ms',
41
-		'lv',
42
-		'lt',
43
-		'lb',
44
-		'ko',
45
-		'ka',
46
-		'ja',
47
-		'iw',
48
-		'it',
49
-		'is',
50
-		'id',
51
-		'hy',
52
-		'hu',
53
-		'hr',
54
-		'hi',
55
-		'he',
56
-		'gl',
57
-		'ga',
58
-		'fy',
59
-		'fr',
60
-		'fo',
61
-		'fi',
62
-		'fa',
63
-		'eu',
64
-		'et',
65
-		'es',
66
-		'eo',
67
-		'en',
68
-		'el',
69
-		'de',
70
-		'da',
71
-		'cz',
72
-		'ca',
73
-		'bg',
74
-		'be',
75
-		'ar',
76
-		'af'
77
-	);
78
-
79
-	/**
80
-	 * The Log service.
81
-	 *
82
-	 * @since 3.1.0
83
-	 * @access private
84
-	 * @var \Wordlift_Log_Service $log_service The Log service.
85
-	 */
86
-	private $log_service;
87
-
88
-	/**
89
-	 * Create a Wordlift_Timeline_Shortcode instance.
90
-	 *
91
-	 * @since 3.1.0
92
-	 */
93
-	public function __construct() {
94
-		parent::__construct();
95
-
96
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Shortcode' );
97
-
98
-	}
99
-
100
-	/**
101
-	 * Renders the Timeline.
102
-	 *
103
-	 * @since 3.1.0
104
-	 *
105
-	 * @param array $atts An array of shortcode attributes.
106
-	 *
107
-	 * @return string The rendered HTML.
108
-	 */
109
-	public function render( $atts ) {
110
-
111
-		//extract attributes and set default values
112
-		$settings = shortcode_atts( array(
113
-			'debug'                            => defined( 'WP_DEBUG' ) && WP_DEBUG,
114
-			'height'                           => NULL,
115
-			'width'                            => NULL,
116
-			'is_embed'                         => FALSE,
117
-			'hash_bookmark'                    => FALSE,
118
-			'default_bg_color'                 => 'white',
119
-			'scale_factor'                     => 2,
120
-			'initial_zoom'                     => NULL,
121
-			'zoom_sequence'                    => '[0.5, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]',
122
-			'timenav_position'                 => 'bottom',
123
-			'optimal_tick_width'               => 100,
124
-			'base_class'                       => 'tl-timeline',
125
-			'timenav_height'                   => 150,
126
-			'timenav_height_percentage'        => NULL,
127
-			'timenav_mobile_height_percentage' => 40,
128
-			'timenav_height_min'               => 150,
129
-			'marker_height_min'                => 30,
130
-			'marker_width_min'                 => 100,
131
-			'marker_padding'                   => 5,
132
-			'start_at_slide'                   => 0,
133
-			'start_at_end'                     => FALSE,
134
-			'menubar_height'                   => 0,
135
-			'use_bc'                           => FALSE,
136
-			'duration'                         => 1000,
137
-			'ease'                             => 'TL.Ease.easeInOutQuint',
138
-			'slide_default_fade'               => '0%',
139
-			'language'                         => $this->get_locale(),
140
-			'ga_property_id'                   => NULL,
141
-			'track_events'                     => "['back_to_start','nav_next','nav_previous','zoom_in','zoom_out']",
142
-			'global'                           => FALSE,
143
-			// The following settings are unrelated to TimelineJS script.
144
-			'display_images_as'                => 'media',
145
-			'excerpt_words'                    => 55,
146
-		), $atts );
147
-
148
-		// Load the TimelineJS stylesheets and scripts.
149
-		wp_enqueue_style( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/css/timeline.css' );
150
-		wp_enqueue_script( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/js/timeline' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '-min' : '' ) . '.js' );
151
-
152
-		// Enqueue the scripts for the timeline.
153
-		$this->enqueue_scripts();
154
-
155
-		// Provide the script with options.
156
-		wp_localize_script( 'timelinejs', 'wl_timeline_params', array(
157
-			'ajax_url'          => admin_url( 'admin-ajax.php' ),
158
-			// TODO: this parameter is already provided by WP
159
-			'action'            => 'wl_timeline',
160
-			// These settings apply to our wl_timeline AJAX endpoint.
161
-			'display_images_as' => $settings['display_images_as'],
162
-			'excerpt_words'     => $settings['excerpt_words'],
163
-			// These settings apply to the timeline javascript client.
164
-			'settings'          => array_filter( $settings, function ( $value, $key = NULL ) {
165
-				// Do not set NULL values or settings which are not related to the client TimelineJS script.
166
-				return ( NULL != $key && NULL !== $value && 'display_images_as' !== $key && 'excerpt_words' !== $key );
167
-			} )
168
-		) );
169
-
170
-		// Get the current post id or set null if global is set to true.
171
-		$post_id = ( $settings['global'] ? NULL : get_the_ID() );
172
-
173
-		// Escaping atts.
174
-		$style        = sprintf( 'style="%s%s"', isset( $settings['width'] ) ? "width:{$settings['width']};" : '', isset( $settings['height'] ) ? "height:{$settings['height']};" : '' );
175
-		$data_post_id = ( isset( $post_id ) ? "data-post-id='$post_id'" : '' );
176
-
177
-		// Generate a unique ID for this timeline.
178
-		$element_id = uniqid( 'wl-timeline-' );
179
-
180
-		if ( WP_DEBUG ) {
181
-			$this->log_service->trace( "Creating a timeline widget [ element id :: $element_id ][ post id :: $post_id ]" );
182
-		}
183
-
184
-		// Building template.
185
-		return sprintf( '<div class="wl-timeline-container" %s><div class="wl-timeline" id="%s" %s></div></div>', $style, $element_id, $data_post_id );
186
-	}
187
-
188
-	/**
189
-	 * Return the locale for the TimelineJS according to WP's configured locale and
190
-	 * support TimelineJS locales. If WP's locale is not supported, english is used.
191
-	 *
192
-	 * @since 3.7.0
193
-	 * @return string The locale (2 letters code).
194
-	 */
195
-	private function get_locale() {
196
-
197
-		// Get the first 2 letters.
198
-		$locale = substr( get_locale(), 0, 2 );
199
-
200
-		// Check that the specified locale is supported otherwise use English.
201
-		return in_array( $locale, self::$supported_locales ) ? $locale : 'en';
202
-	}
10
+    const SHORTCODE = 'wl_timeline';
11
+
12
+    /**
13
+     * The list of locales supported by TimelineJS (correspond to the list of
14
+     * files in the locale subfolder).
15
+     *
16
+     * @since 3.7.0
17
+     * @var array An array of two-letters language codes.
18
+     */
19
+    private static $supported_locales = array(
20
+        'ur',
21
+        'uk',
22
+        'tr',
23
+        'tl',
24
+        'th',
25
+        'te',
26
+        'ta',
27
+        'sv',
28
+        'sr',
29
+        'sl',
30
+        'sk',
31
+        'si',
32
+        'ru',
33
+        'ro',
34
+        'rm',
35
+        'pt',
36
+        'pl',
37
+        'no',
38
+        'nl',
39
+        'ne',
40
+        'ms',
41
+        'lv',
42
+        'lt',
43
+        'lb',
44
+        'ko',
45
+        'ka',
46
+        'ja',
47
+        'iw',
48
+        'it',
49
+        'is',
50
+        'id',
51
+        'hy',
52
+        'hu',
53
+        'hr',
54
+        'hi',
55
+        'he',
56
+        'gl',
57
+        'ga',
58
+        'fy',
59
+        'fr',
60
+        'fo',
61
+        'fi',
62
+        'fa',
63
+        'eu',
64
+        'et',
65
+        'es',
66
+        'eo',
67
+        'en',
68
+        'el',
69
+        'de',
70
+        'da',
71
+        'cz',
72
+        'ca',
73
+        'bg',
74
+        'be',
75
+        'ar',
76
+        'af'
77
+    );
78
+
79
+    /**
80
+     * The Log service.
81
+     *
82
+     * @since 3.1.0
83
+     * @access private
84
+     * @var \Wordlift_Log_Service $log_service The Log service.
85
+     */
86
+    private $log_service;
87
+
88
+    /**
89
+     * Create a Wordlift_Timeline_Shortcode instance.
90
+     *
91
+     * @since 3.1.0
92
+     */
93
+    public function __construct() {
94
+        parent::__construct();
95
+
96
+        $this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Shortcode' );
97
+
98
+    }
99
+
100
+    /**
101
+     * Renders the Timeline.
102
+     *
103
+     * @since 3.1.0
104
+     *
105
+     * @param array $atts An array of shortcode attributes.
106
+     *
107
+     * @return string The rendered HTML.
108
+     */
109
+    public function render( $atts ) {
110
+
111
+        //extract attributes and set default values
112
+        $settings = shortcode_atts( array(
113
+            'debug'                            => defined( 'WP_DEBUG' ) && WP_DEBUG,
114
+            'height'                           => NULL,
115
+            'width'                            => NULL,
116
+            'is_embed'                         => FALSE,
117
+            'hash_bookmark'                    => FALSE,
118
+            'default_bg_color'                 => 'white',
119
+            'scale_factor'                     => 2,
120
+            'initial_zoom'                     => NULL,
121
+            'zoom_sequence'                    => '[0.5, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]',
122
+            'timenav_position'                 => 'bottom',
123
+            'optimal_tick_width'               => 100,
124
+            'base_class'                       => 'tl-timeline',
125
+            'timenav_height'                   => 150,
126
+            'timenav_height_percentage'        => NULL,
127
+            'timenav_mobile_height_percentage' => 40,
128
+            'timenav_height_min'               => 150,
129
+            'marker_height_min'                => 30,
130
+            'marker_width_min'                 => 100,
131
+            'marker_padding'                   => 5,
132
+            'start_at_slide'                   => 0,
133
+            'start_at_end'                     => FALSE,
134
+            'menubar_height'                   => 0,
135
+            'use_bc'                           => FALSE,
136
+            'duration'                         => 1000,
137
+            'ease'                             => 'TL.Ease.easeInOutQuint',
138
+            'slide_default_fade'               => '0%',
139
+            'language'                         => $this->get_locale(),
140
+            'ga_property_id'                   => NULL,
141
+            'track_events'                     => "['back_to_start','nav_next','nav_previous','zoom_in','zoom_out']",
142
+            'global'                           => FALSE,
143
+            // The following settings are unrelated to TimelineJS script.
144
+            'display_images_as'                => 'media',
145
+            'excerpt_words'                    => 55,
146
+        ), $atts );
147
+
148
+        // Load the TimelineJS stylesheets and scripts.
149
+        wp_enqueue_style( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/css/timeline.css' );
150
+        wp_enqueue_script( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/js/timeline' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '-min' : '' ) . '.js' );
151
+
152
+        // Enqueue the scripts for the timeline.
153
+        $this->enqueue_scripts();
154
+
155
+        // Provide the script with options.
156
+        wp_localize_script( 'timelinejs', 'wl_timeline_params', array(
157
+            'ajax_url'          => admin_url( 'admin-ajax.php' ),
158
+            // TODO: this parameter is already provided by WP
159
+            'action'            => 'wl_timeline',
160
+            // These settings apply to our wl_timeline AJAX endpoint.
161
+            'display_images_as' => $settings['display_images_as'],
162
+            'excerpt_words'     => $settings['excerpt_words'],
163
+            // These settings apply to the timeline javascript client.
164
+            'settings'          => array_filter( $settings, function ( $value, $key = NULL ) {
165
+                // Do not set NULL values or settings which are not related to the client TimelineJS script.
166
+                return ( NULL != $key && NULL !== $value && 'display_images_as' !== $key && 'excerpt_words' !== $key );
167
+            } )
168
+        ) );
169
+
170
+        // Get the current post id or set null if global is set to true.
171
+        $post_id = ( $settings['global'] ? NULL : get_the_ID() );
172
+
173
+        // Escaping atts.
174
+        $style        = sprintf( 'style="%s%s"', isset( $settings['width'] ) ? "width:{$settings['width']};" : '', isset( $settings['height'] ) ? "height:{$settings['height']};" : '' );
175
+        $data_post_id = ( isset( $post_id ) ? "data-post-id='$post_id'" : '' );
176
+
177
+        // Generate a unique ID for this timeline.
178
+        $element_id = uniqid( 'wl-timeline-' );
179
+
180
+        if ( WP_DEBUG ) {
181
+            $this->log_service->trace( "Creating a timeline widget [ element id :: $element_id ][ post id :: $post_id ]" );
182
+        }
183
+
184
+        // Building template.
185
+        return sprintf( '<div class="wl-timeline-container" %s><div class="wl-timeline" id="%s" %s></div></div>', $style, $element_id, $data_post_id );
186
+    }
187
+
188
+    /**
189
+     * Return the locale for the TimelineJS according to WP's configured locale and
190
+     * support TimelineJS locales. If WP's locale is not supported, english is used.
191
+     *
192
+     * @since 3.7.0
193
+     * @return string The locale (2 letters code).
194
+     */
195
+    private function get_locale() {
196
+
197
+        // Get the first 2 letters.
198
+        $locale = substr( get_locale(), 0, 2 );
199
+
200
+        // Check that the specified locale is supported otherwise use English.
201
+        return in_array( $locale, self::$supported_locales ) ? $locale : 'en';
202
+    }
203 203
 
204 204
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
 	public function __construct() {
94 94
 		parent::__construct();
95 95
 
96
-		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Shortcode' );
96
+		$this->log_service = Wordlift_Log_Service::get_logger('Wordlift_Timeline_Shortcode');
97 97
 
98 98
 	}
99 99
 
@@ -106,11 +106,11 @@  discard block
 block discarded – undo
106 106
 	 *
107 107
 	 * @return string The rendered HTML.
108 108
 	 */
109
-	public function render( $atts ) {
109
+	public function render($atts) {
110 110
 
111 111
 		//extract attributes and set default values
112
-		$settings = shortcode_atts( array(
113
-			'debug'                            => defined( 'WP_DEBUG' ) && WP_DEBUG,
112
+		$settings = shortcode_atts(array(
113
+			'debug'                            => defined('WP_DEBUG') && WP_DEBUG,
114 114
 			'height'                           => NULL,
115 115
 			'width'                            => NULL,
116 116
 			'is_embed'                         => FALSE,
@@ -143,46 +143,46 @@  discard block
 block discarded – undo
143 143
 			// The following settings are unrelated to TimelineJS script.
144 144
 			'display_images_as'                => 'media',
145 145
 			'excerpt_words'                    => 55,
146
-		), $atts );
146
+		), $atts);
147 147
 
148 148
 		// Load the TimelineJS stylesheets and scripts.
149
-		wp_enqueue_style( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/css/timeline.css' );
150
-		wp_enqueue_script( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/js/timeline' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '-min' : '' ) . '.js' );
149
+		wp_enqueue_style('timelinejs', dirname(plugin_dir_url(__FILE__)).'/timelinejs/css/timeline.css');
150
+		wp_enqueue_script('timelinejs', dirname(plugin_dir_url(__FILE__)).'/timelinejs/js/timeline'.( ! defined('SCRIPT_DEBUG') || ! SCRIPT_DEBUG ? '-min' : '').'.js');
151 151
 
152 152
 		// Enqueue the scripts for the timeline.
153 153
 		$this->enqueue_scripts();
154 154
 
155 155
 		// Provide the script with options.
156
-		wp_localize_script( 'timelinejs', 'wl_timeline_params', array(
157
-			'ajax_url'          => admin_url( 'admin-ajax.php' ),
156
+		wp_localize_script('timelinejs', 'wl_timeline_params', array(
157
+			'ajax_url'          => admin_url('admin-ajax.php'),
158 158
 			// TODO: this parameter is already provided by WP
159 159
 			'action'            => 'wl_timeline',
160 160
 			// These settings apply to our wl_timeline AJAX endpoint.
161 161
 			'display_images_as' => $settings['display_images_as'],
162 162
 			'excerpt_words'     => $settings['excerpt_words'],
163 163
 			// These settings apply to the timeline javascript client.
164
-			'settings'          => array_filter( $settings, function ( $value, $key = NULL ) {
164
+			'settings'          => array_filter($settings, function($value, $key = NULL) {
165 165
 				// Do not set NULL values or settings which are not related to the client TimelineJS script.
166
-				return ( NULL != $key && NULL !== $value && 'display_images_as' !== $key && 'excerpt_words' !== $key );
166
+				return (NULL != $key && NULL !== $value && 'display_images_as' !== $key && 'excerpt_words' !== $key);
167 167
 			} )
168
-		) );
168
+		));
169 169
 
170 170
 		// Get the current post id or set null if global is set to true.
171
-		$post_id = ( $settings['global'] ? NULL : get_the_ID() );
171
+		$post_id = ($settings['global'] ? NULL : get_the_ID());
172 172
 
173 173
 		// Escaping atts.
174
-		$style        = sprintf( 'style="%s%s"', isset( $settings['width'] ) ? "width:{$settings['width']};" : '', isset( $settings['height'] ) ? "height:{$settings['height']};" : '' );
175
-		$data_post_id = ( isset( $post_id ) ? "data-post-id='$post_id'" : '' );
174
+		$style        = sprintf('style="%s%s"', isset($settings['width']) ? "width:{$settings['width']};" : '', isset($settings['height']) ? "height:{$settings['height']};" : '');
175
+		$data_post_id = (isset($post_id) ? "data-post-id='$post_id'" : '');
176 176
 
177 177
 		// Generate a unique ID for this timeline.
178
-		$element_id = uniqid( 'wl-timeline-' );
178
+		$element_id = uniqid('wl-timeline-');
179 179
 
180
-		if ( WP_DEBUG ) {
181
-			$this->log_service->trace( "Creating a timeline widget [ element id :: $element_id ][ post id :: $post_id ]" );
180
+		if (WP_DEBUG) {
181
+			$this->log_service->trace("Creating a timeline widget [ element id :: $element_id ][ post id :: $post_id ]");
182 182
 		}
183 183
 
184 184
 		// Building template.
185
-		return sprintf( '<div class="wl-timeline-container" %s><div class="wl-timeline" id="%s" %s></div></div>', $style, $element_id, $data_post_id );
185
+		return sprintf('<div class="wl-timeline-container" %s><div class="wl-timeline" id="%s" %s></div></div>', $style, $element_id, $data_post_id);
186 186
 	}
187 187
 
188 188
 	/**
@@ -195,10 +195,10 @@  discard block
 block discarded – undo
195 195
 	private function get_locale() {
196 196
 
197 197
 		// Get the first 2 letters.
198
-		$locale = substr( get_locale(), 0, 2 );
198
+		$locale = substr(get_locale(), 0, 2);
199 199
 
200 200
 		// Check that the specified locale is supported otherwise use English.
201
-		return in_array( $locale, self::$supported_locales ) ? $locale : 'en';
201
+		return in_array($locale, self::$supported_locales) ? $locale : 'en';
202 202
 	}
203 203
 
204 204
 }
Please login to merge, or discard this patch.