Completed
Push — master ( 5fda97...957be0 )
by David
03:33
created
src/includes/class-wordlift-entity-service.php 2 patches
Indentation   +780 added lines, -780 removed lines patch added patch discarded remove patch
@@ -7,789 +7,789 @@
 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.
454
-	 *
455
-	 * @since 3.2.0
456
-	 *
457
-	 * @param int $post_id Post ID.
458
-	 * @param WP_Post $post Post object.
459
-	 * @param bool $update Whether this is an existing post being updated or not.
460
-	 */
461
-	public function save_post( $post_id, $post, $update ) {
462
-
463
-		// If it's not an entity, return.
464
-		if ( ! $this->is_entity( $post_id ) ) {
465
-			return;
466
-		}
467
-
468
-		// Get the alt labels from the request (or empty array).
469
-		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
470
-
471
-		// Set the alternative labels.
472
-		$this->set_alternative_labels( $post_id, $alt_labels );
473
-
474
-	}
475
-
476
-	/**
477
-	 * Set the alternative labels.
478
-	 *
479
-	 * @since 3.2.0
480
-	 *
481
-	 * @param int $post_id The post id.
482
-	 * @param array $alt_labels An array of labels.
483
-	 */
484
-	public function set_alternative_labels( $post_id, $alt_labels ) {
485
-
486
-		// Force $alt_labels to be an array
487
-		if ( ! is_array( $alt_labels ) ) {
488
-			$alt_labels = array( $alt_labels );
489
-		}
490
-
491
-		$this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
492
-
493
-		// Delete all the existing alternate labels.
494
-		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
495
-
496
-		// Set the alternative labels.
497
-		foreach ( $alt_labels as $alt_label ) {
498
-			if ( ! empty( $alt_label ) ) {
499
-				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
500
-			}
501
-		}
502
-
503
-	}
504
-
505
-	/**
506
-	 * Retrieve the alternate labels.
507
-	 *
508
-	 * @since 3.2.0
509
-	 *
510
-	 * @param int $post_id Post id.
511
-	 *
512
-	 * @return mixed An array  of alternative labels.
513
-	 */
514
-	public function get_alternative_labels( $post_id ) {
515
-
516
-		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
517
-	}
518
-
519
-	/**
520
-	 * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
521
-	 *
522
-	 * @since 3.2.0
523
-	 *
524
-	 * @param WP_Post $post Post object.
525
-	 */
526
-	public function edit_form_before_permalink( $post ) {
527
-
528
-		// If it's not an entity, return.
529
-		if ( ! $this->is_entity( $post->ID ) ) {
530
-			return;
531
-		}
532
-
533
-		// Print the input template.
534
-		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
535
-
536
-		// Print all the currently set alternative labels.
537
-		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
538
-
539
-			echo $this->get_alternative_label_input( $alt_label );
540
-
541
-		};
542
-
543
-		// Print the button.
544
-		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
545
-
546
-	}
547
-
548
-	/**
549
-	 * Add admin notices for the current entity depending on the current rating.
550
-	 *
551
-	 * @since 3.3.0
552
-	 *
553
-	 * @param WP_Post $post Post object.
554
-	 */
555
-	public function in_admin_header() {
556
-
557
-		// Return safely if get_current_screen() is not defined (yet)
558
-		if ( FALSE === function_exists( 'get_current_screen' ) ) {
559
-			return;
560
-		}
561
-
562
-		$screen = get_current_screen();
563
-		// If there is any valid screen nothing to do
564
-		if ( NULL === $screen ) {
565
-			return $clauses;
566
-		}
567
-
568
-		// If you're not in the entity post edit page, return.
569
-		if ( self::TYPE_NAME !== $screen->id ) {
570
-			return;
571
-		}
572
-		// Retrieve the current global post
573
-		global $post;
574
-		// If it's not an entity, return.
575
-		if ( ! $this->is_entity( $post->ID ) ) {
576
-			return;
577
-		}
578
-		// Retrieve an updated rating for the current entity
579
-		$rating = $this->get_rating_for( $post->ID, TRUE );
580
-		// If there is at least 1 warning
581
-		if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
582
-			// TODO - Pass Wordlift_Notice_Service trough the service constructor 
583
-			$this->notice_service->add_suggestion( $rating['warnings'] );
584
-		}
585
-
586
-	}
587
-
588
-	/**
589
-	 * Set rating for a given entity
590
-	 *
591
-	 * @since 3.3.0
592
-	 *
593
-	 * @param int $post_id The entity post id.
594
-	 *
595
-	 * @return int An array representing the rating obj.
596
-	 */
597
-	public function set_rating_for( $post_id ) {
598
-
599
-		// Calculate rating for the given post
600
-		$rating = $this->calculate_rating_for( $post_id );
601
-		// Store the rating on db as post meta
602
-		// Please notice that RATING_RAW_SCORE_META_KEY 
603
-		// is saved on a different meta to allow score sorting
604
-		// Both meta are managed as unique
605
-		// https://codex.wordpress.org/Function_Reference/update_post_meta
606
-		update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
607
-		update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
608
-
609
-		$this->log_service->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
610
-
611
-		// Finally returns the rating 
612
-		return $rating;
613
-	}
614
-
615
-	/**
616
-	 * Get or calculate rating for a given entity
617
-	 *
618
-	 * @since 3.3.0
619
-	 *
620
-	 * @param int $post_id The entity post id.
621
-	 * @param $force_reload $warnings_needed If true, detailed warnings collection is provided with the rating obj.
622
-	 *
623
-	 * @return int An array representing the rating obj.
624
-	 */
625
-	public function get_rating_for( $post_id, $force_reload = FALSE ) {
626
-
627
-		// If forced reload is required or rating is missing ..
628
-		if ( $force_reload ) {
629
-			$this->log_service->trace( "Force rating reload [ post_id :: $post_id ]" );
630
-
631
-			return $this->set_rating_for( $post_id );
632
-		}
633
-
634
-		$current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, TRUE );
635
-
636
-		if ( ! is_numeric( $current_raw_score ) ) {
637
-			$this->log_service->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
638
-
639
-			return $this->set_rating_for( $post_id );
640
-		}
641
-		$current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, TRUE );
642
-
643
-		// Finally return score and warnings
644
-		return array(
645
-			'raw_score'           => $current_raw_score,
646
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
647
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
648
-			'warnings'            => $current_warnings,
649
-		);
650
-
651
-	}
652
-
653
-	/**
654
-	 * Calculate rating for a given entity
655
-	 * Rating depends from following criteria
656
-	 *
657
-	 * 1. Is the current entity related to at least 1 post?
658
-	 * 2. Is the current entity content post not empty?
659
-	 * 3. Is the current entity related to at least 1 entity?
660
-	 * 4. Is the entity published?
661
-	 * 5. There is a a thumbnail associated to the entity?
662
-	 * 6. Has the entity a sameas defined?
663
-	 * 7. Are all schema.org required metadata compiled?
664
-	 *
665
-	 * Each positive check means +1 in terms of rating score
666
-	 *
667
-	 * @since 3.3.0
668
-	 *
669
-	 * @param int $post_id The entity post id.
670
-	 *
671
-	 * @return int An array representing the rating obj.
672
-	 */
673
-	public function calculate_rating_for( $post_id ) {
674
-
675
-		// If it's not an entity, return.
676
-		if ( ! $this->is_entity( $post_id ) ) {
677
-			return;
678
-		}
679
-		// Retrieve the post object
680
-		$post = get_post( $post_id );
681
-		// Rating value
682
-		$score = 0;
683
-		// Store warning messages
684
-		$warnings = array();
685
-
686
-		// Is the current entity related to at least 1 post?
687
-		( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
688
-			$score ++ :
689
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift' ) );
690
-
691
-		// Is the post content not empty?
692
-		( ! empty( $post->post_content ) ) ?
693
-			$score ++ :
694
-			array_push( $warnings, __( self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift' ) );
695
-
696
-		// Is the current entity related to at least 1 entity?
697
-		// Was the current entity already disambiguated?
698
-		( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
699
-			$score ++ :
700
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift' ) );
701
-
702
-		// Is the entity published?
703
-		( 'publish' === get_post_status( $post->ID ) ) ?
704
-			$score ++ :
705
-			array_push( $warnings, __( self::RATING_WARNING_IS_PUBLISHED, 'wordlift' ) );
706
-
707
-		// Has a thumbnail?
708
-		( has_post_thumbnail( $post->ID ) ) ?
709
-			$score ++ :
710
-			array_push( $warnings, __( self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift' ) );
711
-
712
-		// Get all post meta keys for the current post		
713
-		global $wpdb;
714
-		$query = $wpdb->prepare(
715
-			"SELECT DISTINCT(meta_key) FROM $wpdb->postmeta  WHERE post_id = %d", $post->ID
716
-		);
717
-
718
-		// Check intersection between available meta keys 
719
-		// and expected ones arrays to detect missing values
720
-		$available_meta_keys = $wpdb->get_col( $query );
721
-
722
-		// If each expected key is contained in available keys array ...
723
-		( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
724
-			$score ++ :
725
-			array_push( $warnings, __( self::RATING_WARNING_HAS_SAME_AS, 'wordlift' ) );
726
-
727
-		$schema = wl_entity_type_taxonomy_get_type( $post_id );
728
-
729
-		$expected_meta_keys = ( NULL === $schema['custom_fields'] ) ?
730
-			array() :
731
-			array_keys( $schema['custom_fields'] );
732
-
733
-		$intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
734
-		// If each expected key is contained in available keys array ...
735
-		( count( $intersection ) === count( $expected_meta_keys ) ) ?
736
-			$score ++ :
737
-			array_push( $warnings, __( self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift' ) );
738
-
739
-		// Finally return score and warnings
740
-		return array(
741
-			'raw_score'           => $score,
742
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
743
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
744
-			'warnings'            => $warnings,
745
-		);
746
-
747
-	}
748
-
749
-	/**
750
-	 * Get as rating as input and convert in a traffic-light rating
751
-	 *
752
-	 * @since 3.3.0
753
-	 *
754
-	 * @param int $score The rating score for a given entity.
755
-	 *
756
-	 * @return string The input HTML code.
757
-	 */
758
-	private function convert_raw_score_to_traffic_light( $score ) {
759
-		// RATING_MAX : $score = 3 : x 
760
-		// See http://php.net/manual/en/function.round.php
761
-		$rating = round( ( $score * 3 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
762
-
763
-		// If rating is 0, return 1, otherwise return rating
764
-		return ( 0 == $rating ) ? 1 : $rating;
765
-
766
-	}
767
-
768
-	/**
769
-	 * Get as rating as input and convert in a traffic-light rating
770
-	 *
771
-	 * @since 3.3.0
772
-	 *
773
-	 * @param int $score The rating score for a given entity.
774
-	 *
775
-	 * @return string The input HTML code.
776
-	 */
777
-	public function convert_raw_score_to_percentage( $score ) {
778
-		// RATING_MAX : $score = 100 : x 
779
-		return round( ( $score * 100 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
780
-	}
781
-
782
-	/**
783
-	 * Get the alternative label input HTML code.
784
-	 *
785
-	 * @since 3.2.0
786
-	 *
787
-	 * @param string $value The input value.
788
-	 *
789
-	 * @return string The input HTML code.
790
-	 */
791
-	private function get_alternative_label_input( $value = '' ) {
792
-
793
-		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
794
-	}
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.
454
+     *
455
+     * @since 3.2.0
456
+     *
457
+     * @param int $post_id Post ID.
458
+     * @param WP_Post $post Post object.
459
+     * @param bool $update Whether this is an existing post being updated or not.
460
+     */
461
+    public function save_post( $post_id, $post, $update ) {
462
+
463
+        // If it's not an entity, return.
464
+        if ( ! $this->is_entity( $post_id ) ) {
465
+            return;
466
+        }
467
+
468
+        // Get the alt labels from the request (or empty array).
469
+        $alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
470
+
471
+        // Set the alternative labels.
472
+        $this->set_alternative_labels( $post_id, $alt_labels );
473
+
474
+    }
475
+
476
+    /**
477
+     * Set the alternative labels.
478
+     *
479
+     * @since 3.2.0
480
+     *
481
+     * @param int $post_id The post id.
482
+     * @param array $alt_labels An array of labels.
483
+     */
484
+    public function set_alternative_labels( $post_id, $alt_labels ) {
485
+
486
+        // Force $alt_labels to be an array
487
+        if ( ! is_array( $alt_labels ) ) {
488
+            $alt_labels = array( $alt_labels );
489
+        }
490
+
491
+        $this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
492
+
493
+        // Delete all the existing alternate labels.
494
+        delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
495
+
496
+        // Set the alternative labels.
497
+        foreach ( $alt_labels as $alt_label ) {
498
+            if ( ! empty( $alt_label ) ) {
499
+                add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
500
+            }
501
+        }
502
+
503
+    }
504
+
505
+    /**
506
+     * Retrieve the alternate labels.
507
+     *
508
+     * @since 3.2.0
509
+     *
510
+     * @param int $post_id Post id.
511
+     *
512
+     * @return mixed An array  of alternative labels.
513
+     */
514
+    public function get_alternative_labels( $post_id ) {
515
+
516
+        return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
517
+    }
518
+
519
+    /**
520
+     * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
521
+     *
522
+     * @since 3.2.0
523
+     *
524
+     * @param WP_Post $post Post object.
525
+     */
526
+    public function edit_form_before_permalink( $post ) {
527
+
528
+        // If it's not an entity, return.
529
+        if ( ! $this->is_entity( $post->ID ) ) {
530
+            return;
531
+        }
532
+
533
+        // Print the input template.
534
+        $this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
535
+
536
+        // Print all the currently set alternative labels.
537
+        foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
538
+
539
+            echo $this->get_alternative_label_input( $alt_label );
540
+
541
+        };
542
+
543
+        // Print the button.
544
+        $this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
545
+
546
+    }
547
+
548
+    /**
549
+     * Add admin notices for the current entity depending on the current rating.
550
+     *
551
+     * @since 3.3.0
552
+     *
553
+     * @param WP_Post $post Post object.
554
+     */
555
+    public function in_admin_header() {
556
+
557
+        // Return safely if get_current_screen() is not defined (yet)
558
+        if ( FALSE === function_exists( 'get_current_screen' ) ) {
559
+            return;
560
+        }
561
+
562
+        $screen = get_current_screen();
563
+        // If there is any valid screen nothing to do
564
+        if ( NULL === $screen ) {
565
+            return $clauses;
566
+        }
567
+
568
+        // If you're not in the entity post edit page, return.
569
+        if ( self::TYPE_NAME !== $screen->id ) {
570
+            return;
571
+        }
572
+        // Retrieve the current global post
573
+        global $post;
574
+        // If it's not an entity, return.
575
+        if ( ! $this->is_entity( $post->ID ) ) {
576
+            return;
577
+        }
578
+        // Retrieve an updated rating for the current entity
579
+        $rating = $this->get_rating_for( $post->ID, TRUE );
580
+        // If there is at least 1 warning
581
+        if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
582
+            // TODO - Pass Wordlift_Notice_Service trough the service constructor 
583
+            $this->notice_service->add_suggestion( $rating['warnings'] );
584
+        }
585
+
586
+    }
587
+
588
+    /**
589
+     * Set rating for a given entity
590
+     *
591
+     * @since 3.3.0
592
+     *
593
+     * @param int $post_id The entity post id.
594
+     *
595
+     * @return int An array representing the rating obj.
596
+     */
597
+    public function set_rating_for( $post_id ) {
598
+
599
+        // Calculate rating for the given post
600
+        $rating = $this->calculate_rating_for( $post_id );
601
+        // Store the rating on db as post meta
602
+        // Please notice that RATING_RAW_SCORE_META_KEY 
603
+        // is saved on a different meta to allow score sorting
604
+        // Both meta are managed as unique
605
+        // https://codex.wordpress.org/Function_Reference/update_post_meta
606
+        update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
607
+        update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
608
+
609
+        $this->log_service->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
610
+
611
+        // Finally returns the rating 
612
+        return $rating;
613
+    }
614
+
615
+    /**
616
+     * Get or calculate rating for a given entity
617
+     *
618
+     * @since 3.3.0
619
+     *
620
+     * @param int $post_id The entity post id.
621
+     * @param $force_reload $warnings_needed If true, detailed warnings collection is provided with the rating obj.
622
+     *
623
+     * @return int An array representing the rating obj.
624
+     */
625
+    public function get_rating_for( $post_id, $force_reload = FALSE ) {
626
+
627
+        // If forced reload is required or rating is missing ..
628
+        if ( $force_reload ) {
629
+            $this->log_service->trace( "Force rating reload [ post_id :: $post_id ]" );
630
+
631
+            return $this->set_rating_for( $post_id );
632
+        }
633
+
634
+        $current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, TRUE );
635
+
636
+        if ( ! is_numeric( $current_raw_score ) ) {
637
+            $this->log_service->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
638
+
639
+            return $this->set_rating_for( $post_id );
640
+        }
641
+        $current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, TRUE );
642
+
643
+        // Finally return score and warnings
644
+        return array(
645
+            'raw_score'           => $current_raw_score,
646
+            'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
647
+            'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
648
+            'warnings'            => $current_warnings,
649
+        );
650
+
651
+    }
652
+
653
+    /**
654
+     * Calculate rating for a given entity
655
+     * Rating depends from following criteria
656
+     *
657
+     * 1. Is the current entity related to at least 1 post?
658
+     * 2. Is the current entity content post not empty?
659
+     * 3. Is the current entity related to at least 1 entity?
660
+     * 4. Is the entity published?
661
+     * 5. There is a a thumbnail associated to the entity?
662
+     * 6. Has the entity a sameas defined?
663
+     * 7. Are all schema.org required metadata compiled?
664
+     *
665
+     * Each positive check means +1 in terms of rating score
666
+     *
667
+     * @since 3.3.0
668
+     *
669
+     * @param int $post_id The entity post id.
670
+     *
671
+     * @return int An array representing the rating obj.
672
+     */
673
+    public function calculate_rating_for( $post_id ) {
674
+
675
+        // If it's not an entity, return.
676
+        if ( ! $this->is_entity( $post_id ) ) {
677
+            return;
678
+        }
679
+        // Retrieve the post object
680
+        $post = get_post( $post_id );
681
+        // Rating value
682
+        $score = 0;
683
+        // Store warning messages
684
+        $warnings = array();
685
+
686
+        // Is the current entity related to at least 1 post?
687
+        ( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
688
+            $score ++ :
689
+            array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift' ) );
690
+
691
+        // Is the post content not empty?
692
+        ( ! empty( $post->post_content ) ) ?
693
+            $score ++ :
694
+            array_push( $warnings, __( self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift' ) );
695
+
696
+        // Is the current entity related to at least 1 entity?
697
+        // Was the current entity already disambiguated?
698
+        ( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
699
+            $score ++ :
700
+            array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift' ) );
701
+
702
+        // Is the entity published?
703
+        ( 'publish' === get_post_status( $post->ID ) ) ?
704
+            $score ++ :
705
+            array_push( $warnings, __( self::RATING_WARNING_IS_PUBLISHED, 'wordlift' ) );
706
+
707
+        // Has a thumbnail?
708
+        ( has_post_thumbnail( $post->ID ) ) ?
709
+            $score ++ :
710
+            array_push( $warnings, __( self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift' ) );
711
+
712
+        // Get all post meta keys for the current post		
713
+        global $wpdb;
714
+        $query = $wpdb->prepare(
715
+            "SELECT DISTINCT(meta_key) FROM $wpdb->postmeta  WHERE post_id = %d", $post->ID
716
+        );
717
+
718
+        // Check intersection between available meta keys 
719
+        // and expected ones arrays to detect missing values
720
+        $available_meta_keys = $wpdb->get_col( $query );
721
+
722
+        // If each expected key is contained in available keys array ...
723
+        ( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
724
+            $score ++ :
725
+            array_push( $warnings, __( self::RATING_WARNING_HAS_SAME_AS, 'wordlift' ) );
726
+
727
+        $schema = wl_entity_type_taxonomy_get_type( $post_id );
728
+
729
+        $expected_meta_keys = ( NULL === $schema['custom_fields'] ) ?
730
+            array() :
731
+            array_keys( $schema['custom_fields'] );
732
+
733
+        $intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
734
+        // If each expected key is contained in available keys array ...
735
+        ( count( $intersection ) === count( $expected_meta_keys ) ) ?
736
+            $score ++ :
737
+            array_push( $warnings, __( self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift' ) );
738
+
739
+        // Finally return score and warnings
740
+        return array(
741
+            'raw_score'           => $score,
742
+            'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
743
+            'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
744
+            'warnings'            => $warnings,
745
+        );
746
+
747
+    }
748
+
749
+    /**
750
+     * Get as rating as input and convert in a traffic-light rating
751
+     *
752
+     * @since 3.3.0
753
+     *
754
+     * @param int $score The rating score for a given entity.
755
+     *
756
+     * @return string The input HTML code.
757
+     */
758
+    private function convert_raw_score_to_traffic_light( $score ) {
759
+        // RATING_MAX : $score = 3 : x 
760
+        // See http://php.net/manual/en/function.round.php
761
+        $rating = round( ( $score * 3 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
762
+
763
+        // If rating is 0, return 1, otherwise return rating
764
+        return ( 0 == $rating ) ? 1 : $rating;
765
+
766
+    }
767
+
768
+    /**
769
+     * Get as rating as input and convert in a traffic-light rating
770
+     *
771
+     * @since 3.3.0
772
+     *
773
+     * @param int $score The rating score for a given entity.
774
+     *
775
+     * @return string The input HTML code.
776
+     */
777
+    public function convert_raw_score_to_percentage( $score ) {
778
+        // RATING_MAX : $score = 100 : x 
779
+        return round( ( $score * 100 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
780
+    }
781
+
782
+    /**
783
+     * Get the alternative label input HTML code.
784
+     *
785
+     * @since 3.2.0
786
+     *
787
+     * @param string $value The input value.
788
+     *
789
+     * @return string The input HTML code.
790
+     */
791
+    private function get_alternative_label_input( $value = '' ) {
792
+
793
+        return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
794
+    }
795 795
 }
Please login to merge, or discard this patch.
Spacing   +118 added lines, -127 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
 
@@ -458,18 +457,18 @@  discard block
 block discarded – undo
458 457
 	 * @param WP_Post $post Post object.
459 458
 	 * @param bool $update Whether this is an existing post being updated or not.
460 459
 	 */
461
-	public function save_post( $post_id, $post, $update ) {
460
+	public function save_post($post_id, $post, $update) {
462 461
 
463 462
 		// If it's not an entity, return.
464
-		if ( ! $this->is_entity( $post_id ) ) {
463
+		if ( ! $this->is_entity($post_id)) {
465 464
 			return;
466 465
 		}
467 466
 
468 467
 		// Get the alt labels from the request (or empty array).
469
-		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
468
+		$alt_labels = isset($_REQUEST['wl_alternative_label']) ? $_REQUEST['wl_alternative_label'] : array();
470 469
 
471 470
 		// Set the alternative labels.
472
-		$this->set_alternative_labels( $post_id, $alt_labels );
471
+		$this->set_alternative_labels($post_id, $alt_labels);
473 472
 
474 473
 	}
475 474
 
@@ -481,22 +480,22 @@  discard block
 block discarded – undo
481 480
 	 * @param int $post_id The post id.
482 481
 	 * @param array $alt_labels An array of labels.
483 482
 	 */
484
-	public function set_alternative_labels( $post_id, $alt_labels ) {
483
+	public function set_alternative_labels($post_id, $alt_labels) {
485 484
 
486 485
 		// Force $alt_labels to be an array
487
-		if ( ! is_array( $alt_labels ) ) {
488
-			$alt_labels = array( $alt_labels );
486
+		if ( ! is_array($alt_labels)) {
487
+			$alt_labels = array($alt_labels);
489 488
 		}
490 489
 
491
-		$this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
490
+		$this->log_service->debug("Setting alternative labels [ post id :: $post_id ][ alt labels :: ".implode(',', $alt_labels)." ]");
492 491
 
493 492
 		// Delete all the existing alternate labels.
494
-		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
493
+		delete_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY);
495 494
 
496 495
 		// Set the alternative labels.
497
-		foreach ( $alt_labels as $alt_label ) {
498
-			if ( ! empty( $alt_label ) ) {
499
-				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
496
+		foreach ($alt_labels as $alt_label) {
497
+			if ( ! empty($alt_label)) {
498
+				add_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label);
500 499
 			}
501 500
 		}
502 501
 
@@ -511,9 +510,9 @@  discard block
 block discarded – undo
511 510
 	 *
512 511
 	 * @return mixed An array  of alternative labels.
513 512
 	 */
514
-	public function get_alternative_labels( $post_id ) {
513
+	public function get_alternative_labels($post_id) {
515 514
 
516
-		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
515
+		return get_post_meta($post_id, self::ALTERNATIVE_LABEL_META_KEY);
517 516
 	}
518 517
 
519 518
 	/**
@@ -523,25 +522,25 @@  discard block
 block discarded – undo
523 522
 	 *
524 523
 	 * @param WP_Post $post Post object.
525 524
 	 */
526
-	public function edit_form_before_permalink( $post ) {
525
+	public function edit_form_before_permalink($post) {
527 526
 
528 527
 		// If it's not an entity, return.
529
-		if ( ! $this->is_entity( $post->ID ) ) {
528
+		if ( ! $this->is_entity($post->ID)) {
530 529
 			return;
531 530
 		}
532 531
 
533 532
 		// Print the input template.
534
-		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
533
+		$this->ui_service->print_template('wl-tmpl-alternative-label-input', $this->get_alternative_label_input());
535 534
 
536 535
 		// Print all the currently set alternative labels.
537
-		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
536
+		foreach ($this->get_alternative_labels($post->ID) as $alt_label) {
538 537
 
539
-			echo $this->get_alternative_label_input( $alt_label );
538
+			echo $this->get_alternative_label_input($alt_label);
540 539
 
541 540
 		};
542 541
 
543 542
 		// Print the button.
544
-		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
543
+		$this->ui_service->print_button('wl-add-alternative-labels-button', __('Add more titles', 'wordlift'));
545 544
 
546 545
 	}
547 546
 
@@ -555,32 +554,32 @@  discard block
 block discarded – undo
555 554
 	public function in_admin_header() {
556 555
 
557 556
 		// Return safely if get_current_screen() is not defined (yet)
558
-		if ( FALSE === function_exists( 'get_current_screen' ) ) {
557
+		if (FALSE === function_exists('get_current_screen')) {
559 558
 			return;
560 559
 		}
561 560
 
562 561
 		$screen = get_current_screen();
563 562
 		// If there is any valid screen nothing to do
564
-		if ( NULL === $screen ) {
563
+		if (NULL === $screen) {
565 564
 			return $clauses;
566 565
 		}
567 566
 
568 567
 		// If you're not in the entity post edit page, return.
569
-		if ( self::TYPE_NAME !== $screen->id ) {
568
+		if (self::TYPE_NAME !== $screen->id) {
570 569
 			return;
571 570
 		}
572 571
 		// Retrieve the current global post
573 572
 		global $post;
574 573
 		// If it's not an entity, return.
575
-		if ( ! $this->is_entity( $post->ID ) ) {
574
+		if ( ! $this->is_entity($post->ID)) {
576 575
 			return;
577 576
 		}
578 577
 		// Retrieve an updated rating for the current entity
579
-		$rating = $this->get_rating_for( $post->ID, TRUE );
578
+		$rating = $this->get_rating_for($post->ID, TRUE);
580 579
 		// If there is at least 1 warning
581
-		if ( isset( $rating['warnings'] ) && 0 < count( $rating['warnings'] ) ) {
580
+		if (isset($rating['warnings']) && 0 < count($rating['warnings'])) {
582 581
 			// TODO - Pass Wordlift_Notice_Service trough the service constructor 
583
-			$this->notice_service->add_suggestion( $rating['warnings'] );
582
+			$this->notice_service->add_suggestion($rating['warnings']);
584 583
 		}
585 584
 
586 585
 	}
@@ -594,19 +593,19 @@  discard block
 block discarded – undo
594 593
 	 *
595 594
 	 * @return int An array representing the rating obj.
596 595
 	 */
597
-	public function set_rating_for( $post_id ) {
596
+	public function set_rating_for($post_id) {
598 597
 
599 598
 		// Calculate rating for the given post
600
-		$rating = $this->calculate_rating_for( $post_id );
599
+		$rating = $this->calculate_rating_for($post_id);
601 600
 		// Store the rating on db as post meta
602 601
 		// Please notice that RATING_RAW_SCORE_META_KEY 
603 602
 		// is saved on a different meta to allow score sorting
604 603
 		// Both meta are managed as unique
605 604
 		// https://codex.wordpress.org/Function_Reference/update_post_meta
606
-		update_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score'] );
607
-		update_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings'] );
605
+		update_post_meta($post_id, self::RATING_RAW_SCORE_META_KEY, $rating['raw_score']);
606
+		update_post_meta($post_id, self::RATING_WARNINGS_META_KEY, $rating['warnings']);
608 607
 
609
-		$this->log_service->trace( sprintf( "Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score'] ) );
608
+		$this->log_service->trace(sprintf("Rating set for [ post_id :: $post_id ] [ rating :: %s ]", $rating['raw_score']));
610 609
 
611 610
 		// Finally returns the rating 
612 611
 		return $rating;
@@ -622,29 +621,29 @@  discard block
 block discarded – undo
622 621
 	 *
623 622
 	 * @return int An array representing the rating obj.
624 623
 	 */
625
-	public function get_rating_for( $post_id, $force_reload = FALSE ) {
624
+	public function get_rating_for($post_id, $force_reload = FALSE) {
626 625
 
627 626
 		// If forced reload is required or rating is missing ..
628
-		if ( $force_reload ) {
629
-			$this->log_service->trace( "Force rating reload [ post_id :: $post_id ]" );
627
+		if ($force_reload) {
628
+			$this->log_service->trace("Force rating reload [ post_id :: $post_id ]");
630 629
 
631
-			return $this->set_rating_for( $post_id );
630
+			return $this->set_rating_for($post_id);
632 631
 		}
633 632
 
634
-		$current_raw_score = get_post_meta( $post_id, self::RATING_RAW_SCORE_META_KEY, TRUE );
633
+		$current_raw_score = get_post_meta($post_id, self::RATING_RAW_SCORE_META_KEY, TRUE);
635 634
 
636
-		if ( ! is_numeric( $current_raw_score ) ) {
637
-			$this->log_service->trace( "Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]" );
635
+		if ( ! is_numeric($current_raw_score)) {
636
+			$this->log_service->trace("Rating missing for [ post_id :: $post_id ] [ current_raw_score :: $current_raw_score ]");
638 637
 
639
-			return $this->set_rating_for( $post_id );
638
+			return $this->set_rating_for($post_id);
640 639
 		}
641
-		$current_warnings = get_post_meta( $post_id, self::RATING_WARNINGS_META_KEY, TRUE );
640
+		$current_warnings = get_post_meta($post_id, self::RATING_WARNINGS_META_KEY, TRUE);
642 641
 
643 642
 		// Finally return score and warnings
644 643
 		return array(
645 644
 			'raw_score'           => $current_raw_score,
646
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $current_raw_score ),
647
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $current_raw_score ),
645
+			'traffic_light_score' => $this->convert_raw_score_to_traffic_light($current_raw_score),
646
+			'percentage_score'    => $this->convert_raw_score_to_percentage($current_raw_score),
648 647
 			'warnings'            => $current_warnings,
649 648
 		);
650 649
 
@@ -670,44 +669,39 @@  discard block
 block discarded – undo
670 669
 	 *
671 670
 	 * @return int An array representing the rating obj.
672 671
 	 */
673
-	public function calculate_rating_for( $post_id ) {
672
+	public function calculate_rating_for($post_id) {
674 673
 
675 674
 		// If it's not an entity, return.
676
-		if ( ! $this->is_entity( $post_id ) ) {
675
+		if ( ! $this->is_entity($post_id)) {
677 676
 			return;
678 677
 		}
679 678
 		// Retrieve the post object
680
-		$post = get_post( $post_id );
679
+		$post = get_post($post_id);
681 680
 		// Rating value
682 681
 		$score = 0;
683 682
 		// Store warning messages
684 683
 		$warnings = array();
685 684
 
686 685
 		// Is the current entity related to at least 1 post?
687
-		( 0 < count( wl_core_get_related_post_ids( $post->ID ) ) ) ?
688
-			$score ++ :
689
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift' ) );
686
+		(0 < count(wl_core_get_related_post_ids($post->ID))) ?
687
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_RELATED_POSTS, 'wordlift'));
690 688
 
691 689
 		// Is the post content not empty?
692
-		( ! empty( $post->post_content ) ) ?
693
-			$score ++ :
694
-			array_push( $warnings, __( self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift' ) );
690
+		( ! empty($post->post_content)) ?
691
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_CONTENT_POST, 'wordlift'));
695 692
 
696 693
 		// Is the current entity related to at least 1 entity?
697 694
 		// Was the current entity already disambiguated?
698
-		( 0 < count( wl_core_get_related_entity_ids( $post->ID ) ) ) ?
699
-			$score ++ :
700
-			array_push( $warnings, __( self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift' ) );
695
+		(0 < count(wl_core_get_related_entity_ids($post->ID))) ?
696
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_RELATED_ENTITIES, 'wordlift'));
701 697
 
702 698
 		// Is the entity published?
703
-		( 'publish' === get_post_status( $post->ID ) ) ?
704
-			$score ++ :
705
-			array_push( $warnings, __( self::RATING_WARNING_IS_PUBLISHED, 'wordlift' ) );
699
+		('publish' === get_post_status($post->ID)) ?
700
+			$score++ : array_push($warnings, __(self::RATING_WARNING_IS_PUBLISHED, 'wordlift'));
706 701
 
707 702
 		// Has a thumbnail?
708
-		( has_post_thumbnail( $post->ID ) ) ?
709
-			$score ++ :
710
-			array_push( $warnings, __( self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift' ) );
703
+		(has_post_thumbnail($post->ID)) ?
704
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_THUMBNAIL, 'wordlift'));
711 705
 
712 706
 		// Get all post meta keys for the current post		
713 707
 		global $wpdb;
@@ -717,30 +711,27 @@  discard block
 block discarded – undo
717 711
 
718 712
 		// Check intersection between available meta keys 
719 713
 		// and expected ones arrays to detect missing values
720
-		$available_meta_keys = $wpdb->get_col( $query );
714
+		$available_meta_keys = $wpdb->get_col($query);
721 715
 
722 716
 		// If each expected key is contained in available keys array ...
723
-		( in_array( Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys ) ) ?
724
-			$score ++ :
725
-			array_push( $warnings, __( self::RATING_WARNING_HAS_SAME_AS, 'wordlift' ) );
717
+		(in_array(Wordlift_Schema_Service::FIELD_SAME_AS, $available_meta_keys)) ?
718
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_SAME_AS, 'wordlift'));
726 719
 
727
-		$schema = wl_entity_type_taxonomy_get_type( $post_id );
720
+		$schema = wl_entity_type_taxonomy_get_type($post_id);
728 721
 
729
-		$expected_meta_keys = ( NULL === $schema['custom_fields'] ) ?
730
-			array() :
731
-			array_keys( $schema['custom_fields'] );
722
+		$expected_meta_keys = (NULL === $schema['custom_fields']) ?
723
+			array() : array_keys($schema['custom_fields']);
732 724
 
733
-		$intersection = array_intersect( $expected_meta_keys, $available_meta_keys );
725
+		$intersection = array_intersect($expected_meta_keys, $available_meta_keys);
734 726
 		// If each expected key is contained in available keys array ...
735
-		( count( $intersection ) === count( $expected_meta_keys ) ) ?
736
-			$score ++ :
737
-			array_push( $warnings, __( self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift' ) );
727
+		(count($intersection) === count($expected_meta_keys)) ?
728
+			$score++ : array_push($warnings, __(self::RATING_WARNING_HAS_COMPLETED_METADATA, 'wordlift'));
738 729
 
739 730
 		// Finally return score and warnings
740 731
 		return array(
741 732
 			'raw_score'           => $score,
742
-			'traffic_light_score' => $this->convert_raw_score_to_traffic_light( $score ),
743
-			'percentage_score'    => $this->convert_raw_score_to_percentage( $score ),
733
+			'traffic_light_score' => $this->convert_raw_score_to_traffic_light($score),
734
+			'percentage_score'    => $this->convert_raw_score_to_percentage($score),
744 735
 			'warnings'            => $warnings,
745 736
 		);
746 737
 
@@ -755,13 +746,13 @@  discard block
 block discarded – undo
755 746
 	 *
756 747
 	 * @return string The input HTML code.
757 748
 	 */
758
-	private function convert_raw_score_to_traffic_light( $score ) {
749
+	private function convert_raw_score_to_traffic_light($score) {
759 750
 		// RATING_MAX : $score = 3 : x 
760 751
 		// See http://php.net/manual/en/function.round.php
761
-		$rating = round( ( $score * 3 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
752
+		$rating = round(($score * 3) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP);
762 753
 
763 754
 		// If rating is 0, return 1, otherwise return rating
764
-		return ( 0 == $rating ) ? 1 : $rating;
755
+		return (0 == $rating) ? 1 : $rating;
765 756
 
766 757
 	}
767 758
 
@@ -774,9 +765,9 @@  discard block
 block discarded – undo
774 765
 	 *
775 766
 	 * @return string The input HTML code.
776 767
 	 */
777
-	public function convert_raw_score_to_percentage( $score ) {
768
+	public function convert_raw_score_to_percentage($score) {
778 769
 		// RATING_MAX : $score = 100 : x 
779
-		return round( ( $score * 100 ) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP );
770
+		return round(($score * 100) / self::get_rating_max(), 0, PHP_ROUND_HALF_UP);
780 771
 	}
781 772
 
782 773
 	/**
@@ -788,8 +779,8 @@  discard block
 block discarded – undo
788 779
 	 *
789 780
 	 * @return string The input HTML code.
790 781
 	 */
791
-	private function get_alternative_label_input( $value = '' ) {
782
+	private function get_alternative_label_input($value = '') {
792 783
 
793
-		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
784
+		return sprintf(self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr($value), __('Delete', 'wordlift'));
794 785
 	}
795 786
 }
Please login to merge, or discard this patch.
src/includes/class-wordlift.php 1 patch
Indentation   +487 added lines, -487 removed lines patch added patch discarded remove patch
@@ -29,522 +29,522 @@
 block discarded – undo
29 29
  */
30 30
 class Wordlift {
31 31
 
32
-	/**
33
-	 * The loader that's responsible for maintaining and registering all hooks that power
34
-	 * the plugin.
35
-	 *
36
-	 * @since    1.0.0
37
-	 * @access   protected
38
-	 * @var      Wordlift_Loader $loader Maintains and registers all hooks for the plugin.
39
-	 */
40
-	protected $loader;
41
-
42
-	/**
43
-	 * The unique identifier of this plugin.
44
-	 *
45
-	 * @since    1.0.0
46
-	 * @access   protected
47
-	 * @var      string $plugin_name The string used to uniquely identify this plugin.
48
-	 */
49
-	protected $plugin_name;
50
-
51
-	/**
52
-	 * The current version of the plugin.
53
-	 *
54
-	 * @since    1.0.0
55
-	 * @access   protected
56
-	 * @var      string $version The current version of the plugin.
57
-	 */
58
-	protected $version;
59
-
60
-	/**
61
-	 * The Thumbnail service.
62
-	 *
63
-	 * @since 3.1.5
64
-	 * @access private
65
-	 * @var \Wordlift_Thumbnail_Service $thumbnail_service The Thumbnail service.
66
-	 */
67
-	private $thumbnail_service;
68
-
69
-	/**
70
-	 * The UI service.
71
-	 *
72
-	 * @since 3.2.0
73
-	 * @access private
74
-	 * @var \Wordlift_UI_Service $ui_service The UI service.
75
-	 */
76
-	private $ui_service;
77
-
78
-	/**
79
-	 * The Schema service.
80
-	 *
81
-	 * @since 3.3.0
82
-	 * @access private
83
-	 * @var \Wordlift_Schema_Service $schema_service The Schema service.
84
-	 */
85
-	private $schema_service;
86
-
87
-	/**
88
-	 * The Entity service.
89
-	 *
90
-	 * @since 3.1.0
91
-	 * @access private
92
-	 * @var \Wordlift_Entity_Service $entity_service The Entity service.
93
-	 */
94
-	private $entity_service;
95
-
96
-	/**
97
-	 * The Topic Taxonomy service.
98
-	 *
99
-	 * @since 3.5.0
100
-	 * @access private
101
-	 * @var \Wordlift_Topic_Taxonomy_Service The Topic Taxonomy service.
102
-	 */
103
-	private $topic_taxonomy_service;
104
-
105
-	/**
106
-	 * The User service.
107
-	 *
108
-	 * @since 3.1.7
109
-	 * @access private
110
-	 * @var \Wordlift_User_Service $user_service The User service.
111
-	 */
112
-	private $user_service;
113
-
114
-	/**
115
-	 * The Timeline service.
116
-	 *
117
-	 * @since 3.1.0
118
-	 * @access private
119
-	 * @var \Wordlift_Timeline_Service $timeline_service The Timeline service.
120
-	 */
121
-	private $timeline_service;
122
-
123
-	/**
124
-	 * The Redirect service.
125
-	 *
126
-	 * @since 3.2.0
127
-	 * @access private
128
-	 * @var \Wordlift_Redirect_Service $redirect_service The Redirect service.
129
-	 */
130
-	private $redirect_service;
131
-
132
-	/**
133
-	 * The Notice service.
134
-	 *
135
-	 * @since 3.3.0
136
-	 * @access private
137
-	 * @var \Wordlift_Notice_Service $notice_service The Notice service.
138
-	 */
139
-	private $notice_service;
140
-
141
-	/**
142
-	 * The Entity list customization.
143
-	 *
144
-	 * @since 3.3.0
145
-	 * @access private
146
-	 * @var \Wordlift_List_Service $entity_list_service The Entity list service.
147
-	 */
148
-	private $entity_list_service;
149
-
150
-	/**
151
-	 * The Entity Types Taxonomy Walker.
152
-	 *
153
-	 * @since 3.1.0
154
-	 * @access private
155
-	 * @var \Wordlift_Entity_Types_Taxonomy_Walker $entity_types_taxonomy_walker The Entity Types Taxonomy Walker
156
-	 */
157
-	private $entity_types_taxonomy_walker;
158
-
159
-	/**
160
-	 * The ShareThis service.
161
-	 *
162
-	 * @since 3.2.0
163
-	 * @access private
164
-	 * @var \Wordlift_ShareThis_Service $sharethis_service The ShareThis service.
165
-	 */
166
-	private $sharethis_service;
167
-
168
-	/**
169
-	 * The PrimaShop adapter.
170
-	 *
171
-	 * @since 3.2.3
172
-	 * @access private
173
-	 * @var \Wordlift_PrimaShop_Adapter $primashop_adapter The PrimaShop adapter.
174
-	 */
175
-	private $primashop_adapter;
176
-
177
-	/**
178
-	 * The WordLift Dashboard adapter.
179
-	 *
180
-	 * @since 3.4.0
181
-	 * @access private
182
-	 * @var \Wordlift_Dashboard_Service $dashboard_service The WordLift Dashboard service;
183
-	 */
184
-	private $dashboard_service;
185
-
186
-	/**
187
-	 * @var
188
-	 */
189
-	private $page_service;
190
-
191
-	/**
192
-	 * Define the core functionality of the plugin.
193
-	 *
194
-	 * Set the plugin name and the plugin version that can be used throughout the plugin.
195
-	 * Load the dependencies, define the locale, and set the hooks for the admin area and
196
-	 * the public-facing side of the site.
197
-	 *
198
-	 * @since    1.0.0
199
-	 */
200
-	public function __construct() {
201
-
202
-		$this->plugin_name = 'wordlift';
203
-		$this->version     = '3.5.4';
204
-		$this->load_dependencies();
205
-		$this->set_locale();
206
-		$this->define_admin_hooks();
207
-		$this->define_public_hooks();
208
-
209
-	}
210
-
211
-	/**
212
-	 * Load the required dependencies for this plugin.
213
-	 *
214
-	 * Include the following files that make up the plugin:
215
-	 *
216
-	 * - Wordlift_Loader. Orchestrates the hooks of the plugin.
217
-	 * - Wordlift_i18n. Defines internationalization functionality.
218
-	 * - Wordlift_Admin. Defines all hooks for the admin area.
219
-	 * - Wordlift_Public. Defines all hooks for the public side of the site.
220
-	 *
221
-	 * Create an instance of the loader which will be used to register the hooks
222
-	 * with WordPress.
223
-	 *
224
-	 * @since    1.0.0
225
-	 * @access   private
226
-	 */
227
-	private function load_dependencies() {
228
-
229
-		/**
230
-		 * The class responsible for orchestrating the actions and filters of the
231
-		 * core plugin.
232
-		 */
233
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-loader.php';
234
-
235
-		/**
236
-		 * The class responsible for defining internationalization functionality
237
-		 * of the plugin.
238
-		 */
239
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-i18n.php';
240
-
241
-		/**
242
-		 * Provide support functions to sanitize data.
243
-		 */
244
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-sanitizer.php';
245
-
246
-		/**
247
-		 * The Redirect service.
248
-		 */
249
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-redirect-service.php';
250
-
251
-		/**
252
-		 * The Log service.
253
-		 */
254
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-log-service.php';
255
-
256
-		/**
257
-		 * The Query builder.
258
-		 */
259
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-query-builder.php';
260
-
261
-		/**
262
-		 * The Schema service.
263
-		 */
264
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-schema-service.php';
265
-
266
-		/**
267
-		 * The UI service.
268
-		 */
269
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-ui-service.php';
270
-
271
-		/**
272
-		 * The Thumbnail service.
273
-		 */
274
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-thumbnail-service.php';
275
-
276
-		/**
277
-		 * The Entity Types Taxonomy service.
278
-		 */
279
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-entity-types-taxonomy-service.php';
280
-
281
-		/**
282
-		 * The Entity service.
283
-		 */
284
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-entity-service.php';
285
-
286
-		/**
287
-		 * The User service.
288
-		 */
289
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-user-service.php';
290
-
291
-		/**
292
-		 * The Timeline service.
293
-		 */
294
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-timeline-service.php';
295
-
296
-		/**
297
-		 * The Topic Taxonomy service.
298
-		 */
299
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-topic-taxonomy-service.php';
300
-
301
-
302
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-page-service.php';
303
-
304
-		/**
305
-		 * The class responsible for defining all actions that occur in the admin area.
306
-		 */
307
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-admin.php';
308
-
309
-		/**
310
-		 * The class to customize the entity list admin page.
311
-		 */
312
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-admin-entity-list.php';
313
-
314
-		/**
315
-		 * The Entity Types Taxonomy Walker (transforms checkboxes into radios).
316
-		 */
317
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-entity-types-taxonomy-walker.php';
318
-
319
-		/**
320
-		 * The Notice service.
321
-		 */
322
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-notice-service.php';
323
-
324
-		/**
325
-		 * The PrimaShop adapter.
326
-		 */
327
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-primashop-adapter.php';
328
-
329
-		/**
330
-		 * The WordLift Dashboard service.
331
-		 */
332
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-admin-dashboard.php';
32
+    /**
33
+     * The loader that's responsible for maintaining and registering all hooks that power
34
+     * the plugin.
35
+     *
36
+     * @since    1.0.0
37
+     * @access   protected
38
+     * @var      Wordlift_Loader $loader Maintains and registers all hooks for the plugin.
39
+     */
40
+    protected $loader;
41
+
42
+    /**
43
+     * The unique identifier of this plugin.
44
+     *
45
+     * @since    1.0.0
46
+     * @access   protected
47
+     * @var      string $plugin_name The string used to uniquely identify this plugin.
48
+     */
49
+    protected $plugin_name;
50
+
51
+    /**
52
+     * The current version of the plugin.
53
+     *
54
+     * @since    1.0.0
55
+     * @access   protected
56
+     * @var      string $version The current version of the plugin.
57
+     */
58
+    protected $version;
59
+
60
+    /**
61
+     * The Thumbnail service.
62
+     *
63
+     * @since 3.1.5
64
+     * @access private
65
+     * @var \Wordlift_Thumbnail_Service $thumbnail_service The Thumbnail service.
66
+     */
67
+    private $thumbnail_service;
68
+
69
+    /**
70
+     * The UI service.
71
+     *
72
+     * @since 3.2.0
73
+     * @access private
74
+     * @var \Wordlift_UI_Service $ui_service The UI service.
75
+     */
76
+    private $ui_service;
77
+
78
+    /**
79
+     * The Schema service.
80
+     *
81
+     * @since 3.3.0
82
+     * @access private
83
+     * @var \Wordlift_Schema_Service $schema_service The Schema service.
84
+     */
85
+    private $schema_service;
86
+
87
+    /**
88
+     * The Entity service.
89
+     *
90
+     * @since 3.1.0
91
+     * @access private
92
+     * @var \Wordlift_Entity_Service $entity_service The Entity service.
93
+     */
94
+    private $entity_service;
95
+
96
+    /**
97
+     * The Topic Taxonomy service.
98
+     *
99
+     * @since 3.5.0
100
+     * @access private
101
+     * @var \Wordlift_Topic_Taxonomy_Service The Topic Taxonomy service.
102
+     */
103
+    private $topic_taxonomy_service;
104
+
105
+    /**
106
+     * The User service.
107
+     *
108
+     * @since 3.1.7
109
+     * @access private
110
+     * @var \Wordlift_User_Service $user_service The User service.
111
+     */
112
+    private $user_service;
113
+
114
+    /**
115
+     * The Timeline service.
116
+     *
117
+     * @since 3.1.0
118
+     * @access private
119
+     * @var \Wordlift_Timeline_Service $timeline_service The Timeline service.
120
+     */
121
+    private $timeline_service;
122
+
123
+    /**
124
+     * The Redirect service.
125
+     *
126
+     * @since 3.2.0
127
+     * @access private
128
+     * @var \Wordlift_Redirect_Service $redirect_service The Redirect service.
129
+     */
130
+    private $redirect_service;
131
+
132
+    /**
133
+     * The Notice service.
134
+     *
135
+     * @since 3.3.0
136
+     * @access private
137
+     * @var \Wordlift_Notice_Service $notice_service The Notice service.
138
+     */
139
+    private $notice_service;
140
+
141
+    /**
142
+     * The Entity list customization.
143
+     *
144
+     * @since 3.3.0
145
+     * @access private
146
+     * @var \Wordlift_List_Service $entity_list_service The Entity list service.
147
+     */
148
+    private $entity_list_service;
149
+
150
+    /**
151
+     * The Entity Types Taxonomy Walker.
152
+     *
153
+     * @since 3.1.0
154
+     * @access private
155
+     * @var \Wordlift_Entity_Types_Taxonomy_Walker $entity_types_taxonomy_walker The Entity Types Taxonomy Walker
156
+     */
157
+    private $entity_types_taxonomy_walker;
158
+
159
+    /**
160
+     * The ShareThis service.
161
+     *
162
+     * @since 3.2.0
163
+     * @access private
164
+     * @var \Wordlift_ShareThis_Service $sharethis_service The ShareThis service.
165
+     */
166
+    private $sharethis_service;
167
+
168
+    /**
169
+     * The PrimaShop adapter.
170
+     *
171
+     * @since 3.2.3
172
+     * @access private
173
+     * @var \Wordlift_PrimaShop_Adapter $primashop_adapter The PrimaShop adapter.
174
+     */
175
+    private $primashop_adapter;
176
+
177
+    /**
178
+     * The WordLift Dashboard adapter.
179
+     *
180
+     * @since 3.4.0
181
+     * @access private
182
+     * @var \Wordlift_Dashboard_Service $dashboard_service The WordLift Dashboard service;
183
+     */
184
+    private $dashboard_service;
185
+
186
+    /**
187
+     * @var
188
+     */
189
+    private $page_service;
190
+
191
+    /**
192
+     * Define the core functionality of the plugin.
193
+     *
194
+     * Set the plugin name and the plugin version that can be used throughout the plugin.
195
+     * Load the dependencies, define the locale, and set the hooks for the admin area and
196
+     * the public-facing side of the site.
197
+     *
198
+     * @since    1.0.0
199
+     */
200
+    public function __construct() {
201
+
202
+        $this->plugin_name = 'wordlift';
203
+        $this->version     = '3.5.4';
204
+        $this->load_dependencies();
205
+        $this->set_locale();
206
+        $this->define_admin_hooks();
207
+        $this->define_public_hooks();
208
+
209
+    }
210
+
211
+    /**
212
+     * Load the required dependencies for this plugin.
213
+     *
214
+     * Include the following files that make up the plugin:
215
+     *
216
+     * - Wordlift_Loader. Orchestrates the hooks of the plugin.
217
+     * - Wordlift_i18n. Defines internationalization functionality.
218
+     * - Wordlift_Admin. Defines all hooks for the admin area.
219
+     * - Wordlift_Public. Defines all hooks for the public side of the site.
220
+     *
221
+     * Create an instance of the loader which will be used to register the hooks
222
+     * with WordPress.
223
+     *
224
+     * @since    1.0.0
225
+     * @access   private
226
+     */
227
+    private function load_dependencies() {
228
+
229
+        /**
230
+         * The class responsible for orchestrating the actions and filters of the
231
+         * core plugin.
232
+         */
233
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-loader.php';
234
+
235
+        /**
236
+         * The class responsible for defining internationalization functionality
237
+         * of the plugin.
238
+         */
239
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-i18n.php';
240
+
241
+        /**
242
+         * Provide support functions to sanitize data.
243
+         */
244
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-sanitizer.php';
245
+
246
+        /**
247
+         * The Redirect service.
248
+         */
249
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-redirect-service.php';
250
+
251
+        /**
252
+         * The Log service.
253
+         */
254
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-log-service.php';
255
+
256
+        /**
257
+         * The Query builder.
258
+         */
259
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-query-builder.php';
260
+
261
+        /**
262
+         * The Schema service.
263
+         */
264
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-schema-service.php';
265
+
266
+        /**
267
+         * The UI service.
268
+         */
269
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-ui-service.php';
270
+
271
+        /**
272
+         * The Thumbnail service.
273
+         */
274
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-thumbnail-service.php';
275
+
276
+        /**
277
+         * The Entity Types Taxonomy service.
278
+         */
279
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-entity-types-taxonomy-service.php';
280
+
281
+        /**
282
+         * The Entity service.
283
+         */
284
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-entity-service.php';
285
+
286
+        /**
287
+         * The User service.
288
+         */
289
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-user-service.php';
290
+
291
+        /**
292
+         * The Timeline service.
293
+         */
294
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-timeline-service.php';
295
+
296
+        /**
297
+         * The Topic Taxonomy service.
298
+         */
299
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-topic-taxonomy-service.php';
300
+
301
+
302
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wordlift-page-service.php';
303
+
304
+        /**
305
+         * The class responsible for defining all actions that occur in the admin area.
306
+         */
307
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-admin.php';
308
+
309
+        /**
310
+         * The class to customize the entity list admin page.
311
+         */
312
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-admin-entity-list.php';
313
+
314
+        /**
315
+         * The Entity Types Taxonomy Walker (transforms checkboxes into radios).
316
+         */
317
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-entity-types-taxonomy-walker.php';
318
+
319
+        /**
320
+         * The Notice service.
321
+         */
322
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-notice-service.php';
323
+
324
+        /**
325
+         * The PrimaShop adapter.
326
+         */
327
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-primashop-adapter.php';
328
+
329
+        /**
330
+         * The WordLift Dashboard service.
331
+         */
332
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wordlift-admin-dashboard.php';
333 333
 
334
-		/**
335
-		 * The class responsible for defining all actions that occur in the public-facing
336
-		 * side of the site.
337
-		 */
338
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wordlift-public.php';
334
+        /**
335
+         * The class responsible for defining all actions that occur in the public-facing
336
+         * side of the site.
337
+         */
338
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wordlift-public.php';
339 339
 
340
-		/**
341
-		 * The Timeline shortcode.
342
-		 */
343
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wordlift-timeline-shortcode.php';
340
+        /**
341
+         * The Timeline shortcode.
342
+         */
343
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wordlift-timeline-shortcode.php';
344 344
 
345
-		/**
346
-		 * The ShareThis service.
347
-		 */
348
-		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wordlift-sharethis-service.php';
345
+        /**
346
+         * The ShareThis service.
347
+         */
348
+        require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wordlift-sharethis-service.php';
349 349
 
350
-		$this->loader = new Wordlift_Loader();
350
+        $this->loader = new Wordlift_Loader();
351 351
 
352
-		// Instantiate a global logger.
353
-		global $wl_logger;
354
-		$wl_logger = Wordlift_Log_Service::get_logger( 'WordLift' );
352
+        // Instantiate a global logger.
353
+        global $wl_logger;
354
+        $wl_logger = Wordlift_Log_Service::get_logger( 'WordLift' );
355 355
 
356
-		// Create an instance of the UI service.
357
-		$this->ui_service = new Wordlift_UI_Service();
356
+        // Create an instance of the UI service.
357
+        $this->ui_service = new Wordlift_UI_Service();
358 358
 
359
-		// Create an instance of the Thumbnail service. Later it'll be hooked to post meta events.
360
-		$this->thumbnail_service = new Wordlift_Thumbnail_Service();
359
+        // Create an instance of the Thumbnail service. Later it'll be hooked to post meta events.
360
+        $this->thumbnail_service = new Wordlift_Thumbnail_Service();
361 361
 
362
-		// Create an instance of the Schema service.
363
-		$this->schema_service = new Wordlift_Schema_Service();
362
+        // Create an instance of the Schema service.
363
+        $this->schema_service = new Wordlift_Schema_Service();
364 364
 
365
-		// Create an instance of the Notice service.
366
-		$this->notice_service = new Wordlift_Notice_Service();
365
+        // Create an instance of the Notice service.
366
+        $this->notice_service = new Wordlift_Notice_Service();
367 367
 
368
-		// Create an instance of the Entity service, passing the UI service to draw parts of the Entity admin page.
369
-		$this->entity_service = new Wordlift_Entity_Service( $this->ui_service, $this->schema_service, $this->notice_service );
368
+        // Create an instance of the Entity service, passing the UI service to draw parts of the Entity admin page.
369
+        $this->entity_service = new Wordlift_Entity_Service( $this->ui_service, $this->schema_service, $this->notice_service );
370 370
 
371
-		// Create an instance of the User service.
372
-		$this->user_service = new Wordlift_User_Service();
371
+        // Create an instance of the User service.
372
+        $this->user_service = new Wordlift_User_Service();
373 373
 
374
-		// Create a new instance of the Timeline service and Timeline shortcode.
375
-		$this->timeline_service = new Wordlift_Timeline_Service( $this->entity_service );
374
+        // Create a new instance of the Timeline service and Timeline shortcode.
375
+        $this->timeline_service = new Wordlift_Timeline_Service( $this->entity_service );
376 376
 
377
-		// Create a new instance of the Redirect service.
378
-		$this->redirect_service = new Wordlift_Redirect_Service( $this->entity_service );
377
+        // Create a new instance of the Redirect service.
378
+        $this->redirect_service = new Wordlift_Redirect_Service( $this->entity_service );
379 379
 
380
-		// Create a new instance of the Redirect service.
381
-		$this->dashboard_service = new Wordlift_Dashboard_Service( $this->entity_service );
380
+        // Create a new instance of the Redirect service.
381
+        $this->dashboard_service = new Wordlift_Dashboard_Service( $this->entity_service );
382 382
 
383
-		// Create an instance of the Timeline shortcode.
384
-		new Wordlift_Timeline_Shortcode();
383
+        // Create an instance of the Timeline shortcode.
384
+        new Wordlift_Timeline_Shortcode();
385 385
 
386
-		// Create entity list customization (wp-admin/edit.php)
387
-		$this->entity_list_service = new Wordlift_Entity_List_Service( $this->entity_service );
386
+        // Create entity list customization (wp-admin/edit.php)
387
+        $this->entity_list_service = new Wordlift_Entity_List_Service( $this->entity_service );
388 388
 
389
-		$this->entity_types_taxonomy_walker = new Wordlift_Entity_Types_Taxonomy_Walker();
389
+        $this->entity_types_taxonomy_walker = new Wordlift_Entity_Types_Taxonomy_Walker();
390 390
 
391
-		$this->topic_taxonomy_service = new Wordlift_Topic_Taxonomy_Service();
391
+        $this->topic_taxonomy_service = new Wordlift_Topic_Taxonomy_Service();
392 392
 
393
-		// Create an instance of the ShareThis service, later we hook it to the_content and the_excerpt filters.
394
-		$this->sharethis_service = new Wordlift_ShareThis_Service();
393
+        // Create an instance of the ShareThis service, later we hook it to the_content and the_excerpt filters.
394
+        $this->sharethis_service = new Wordlift_ShareThis_Service();
395 395
 
396
-		// Create an instance of the PrimaShop adapter.
397
-		$this->primashop_adapter = new Wordlift_PrimaShop_Adapter();
396
+        // Create an instance of the PrimaShop adapter.
397
+        $this->primashop_adapter = new Wordlift_PrimaShop_Adapter();
398 398
 
399
-		$this->page_service = new Wordlift_Page_Service();
400
-	}
399
+        $this->page_service = new Wordlift_Page_Service();
400
+    }
401 401
 
402
-	/**
403
-	 * Define the locale for this plugin for internationalization.
404
-	 *
405
-	 * Uses the Wordlift_i18n class in order to set the domain and to register the hook
406
-	 * with WordPress.
407
-	 *
408
-	 * @since    1.0.0
409
-	 * @access   private
410
-	 */
411
-	private function set_locale() {
402
+    /**
403
+     * Define the locale for this plugin for internationalization.
404
+     *
405
+     * Uses the Wordlift_i18n class in order to set the domain and to register the hook
406
+     * with WordPress.
407
+     *
408
+     * @since    1.0.0
409
+     * @access   private
410
+     */
411
+    private function set_locale() {
412 412
 
413
-		$plugin_i18n = new Wordlift_i18n();
414
-		$plugin_i18n->set_domain( $this->get_plugin_name() );
413
+        $plugin_i18n = new Wordlift_i18n();
414
+        $plugin_i18n->set_domain( $this->get_plugin_name() );
415 415
 
416
-		$this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
416
+        $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
417 417
 
418
-	}
418
+    }
419 419
 
420
-	/**
421
-	 * Register all of the hooks related to the admin area functionality
422
-	 * of the plugin.
423
-	 *
424
-	 * @since    1.0.0
425
-	 * @access   private
426
-	 */
427
-	private function define_admin_hooks() {
420
+    /**
421
+     * Register all of the hooks related to the admin area functionality
422
+     * of the plugin.
423
+     *
424
+     * @since    1.0.0
425
+     * @access   private
426
+     */
427
+    private function define_admin_hooks() {
428 428
 
429
-		$plugin_admin = new Wordlift_Admin( $this->get_plugin_name(), $this->get_version() );
429
+        $plugin_admin = new Wordlift_Admin( $this->get_plugin_name(), $this->get_version() );
430 430
 
431
-		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
432
-		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
431
+        $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
432
+        $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
433 433
 
434
-		// Hook the init action to the Topic Taxonomy service.
435
-		$this->loader->add_action( 'init', $this->topic_taxonomy_service, 'init', 0 );
436
-
437
-		// Hook the deleted_post_meta action to the Thumbnail service.
438
-		$this->loader->add_action( 'deleted_post_meta', $this->thumbnail_service, 'deleted_post_meta', 10, 4 );
434
+        // Hook the init action to the Topic Taxonomy service.
435
+        $this->loader->add_action( 'init', $this->topic_taxonomy_service, 'init', 0 );
436
+
437
+        // Hook the deleted_post_meta action to the Thumbnail service.
438
+        $this->loader->add_action( 'deleted_post_meta', $this->thumbnail_service, 'deleted_post_meta', 10, 4 );
439 439
 
440
-		// Hook the added_post_meta action to the Thumbnail service.
441
-		$this->loader->add_action( 'added_post_meta', $this->thumbnail_service, 'added_or_updated_post_meta', 10, 4 );
442
-
443
-		// Hook the updated_post_meta action to the Thumbnail service.
444
-		$this->loader->add_action( 'updated_post_meta', $this->thumbnail_service, 'added_or_updated_post_meta', 10, 4 );
445
-
446
-		// Hook posts inserts (or updates) to the user service.
447
-		$this->loader->add_action( 'wp_insert_post', $this->user_service, 'wp_insert_post', 10, 3 );
448
-
449
-		// Hook the AJAX wl_timeline action to the Timeline service.
450
-		$this->loader->add_action( 'wp_ajax_wl_timeline', $this->timeline_service, 'ajax_timeline' );
451
-
452
-		// Register custom allowed redirect hosts.
453
-		$this->loader->add_filter( 'allowed_redirect_hosts', $this->redirect_service, 'allowed_redirect_hosts' );
454
-		// Hook the AJAX wordlift_redirect action to the Redirect service.
455
-		$this->loader->add_action( 'wp_ajax_wordlift_redirect', $this->redirect_service, 'ajax_redirect' );
456
-		// Hook the AJAX wordlift_redirect action to the Redirect service.
457
-		$this->loader->add_action( 'wp_ajax_wordlift_get_stats', $this->dashboard_service, 'ajax_get_stats' );
458
-		// Hook the AJAX wordlift_redirect action to the Redirect service.
459
-		$this->loader->add_action( 'wp_dashboard_setup', $this->dashboard_service, 'add_dashboard_widgets' );
460
-
461
-		// Hook save_post to the entity service to update custom fields (such as alternate labels).
462
-		// We have a priority of 9 because we want to be executed before data is sent to Redlink.
463
-		$this->loader->add_action( 'save_post', $this->entity_service, 'save_post', 9, 3 );
464
-		$this->loader->add_action( 'save_post_entity', $this->entity_service, 'set_rating_for', 10, 1 );
465
-
466
-		$this->loader->add_action( 'edit_form_before_permalink', $this->entity_service, 'edit_form_before_permalink', 10, 1 );
467
-		$this->loader->add_action( 'in_admin_header', $this->entity_service, 'in_admin_header' );
468
-
469
-		// Entity listing customization (wp-admin/edit.php)
470
-		// Add custom columns
471
-		$this->loader->add_filter( 'manage_entity_posts_columns', $this->entity_list_service, 'register_custom_columns' );
472
-		$this->loader->add_filter( 'manage_entity_posts_custom_column', $this->entity_list_service, 'render_custom_columns', 10, 2 );
473
-		// Add 4W selection
474
-		$this->loader->add_action( 'restrict_manage_posts', $this->entity_list_service, 'restrict_manage_posts_classification_scope' );
475
-		$this->loader->add_filter( 'posts_clauses', $this->entity_list_service, 'posts_clauses_classification_scope' );
476
-
477
-		$this->loader->add_filter( 'wp_terms_checklist_args', $this->entity_types_taxonomy_walker, 'terms_checklist_args' );
478
-
479
-		// Hook the PrimaShop adapter to <em>prima_metabox_entity_header_args</em> in order to add header support for
480
-		// entities.
481
-		$this->loader->add_filter( 'prima_metabox_entity_header_args', $this->primashop_adapter, 'prima_metabox_entity_header_args', 10, 2 );
482
-	}
483
-
484
-	/**
485
-	 * Register all of the hooks related to the public-facing functionality
486
-	 * of the plugin.
487
-	 *
488
-	 * @since    1.0.0
489
-	 * @access   private
490
-	 */
491
-	private function define_public_hooks() {
492
-
493
-		$plugin_public = new Wordlift_Public( $this->get_plugin_name(), $this->get_version() );
494
-
495
-		$this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
496
-		$this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
497
-
498
-		// Hook the AJAX wl_timeline action to the Timeline service.
499
-		$this->loader->add_action( 'wp_ajax_nopriv_wl_timeline', $this->timeline_service, 'ajax_timeline' );
500
-
501
-		// Hook the ShareThis service.
502
-		$this->loader->add_filter( 'the_content', $this->sharethis_service, 'the_content', 99 );
503
-		$this->loader->add_filter( 'the_excerpt', $this->sharethis_service, 'the_excerpt', 99 );
504
-
505
-		$this->loader->add_action( 'wp_head', $this->page_service, 'wp_head', PHP_INT_MAX );
506
-		$this->loader->add_action( 'wp_footer', $this->page_service, 'wp_head', -PHP_INT_MAX );
507
-
508
-	}
509
-
510
-	/**
511
-	 * Run the loader to execute all of the hooks with WordPress.
512
-	 *
513
-	 * @since    1.0.0
514
-	 */
515
-	public function run() {
516
-		$this->loader->run();
517
-	}
518
-
519
-	/**
520
-	 * The name of the plugin used to uniquely identify it within the context of
521
-	 * WordPress and to define internationalization functionality.
522
-	 *
523
-	 * @since     1.0.0
524
-	 * @return    string    The name of the plugin.
525
-	 */
526
-	public function get_plugin_name() {
527
-		return $this->plugin_name;
528
-	}
529
-
530
-	/**
531
-	 * The reference to the class that orchestrates the hooks with the plugin.
532
-	 *
533
-	 * @since     1.0.0
534
-	 * @return    Wordlift_Loader    Orchestrates the hooks of the plugin.
535
-	 */
536
-	public function get_loader() {
537
-		return $this->loader;
538
-	}
539
-
540
-	/**
541
-	 * Retrieve the version number of the plugin.
542
-	 *
543
-	 * @since     1.0.0
544
-	 * @return    string    The version number of the plugin.
545
-	 */
546
-	public function get_version() {
547
-		return $this->version;
548
-	}
440
+        // Hook the added_post_meta action to the Thumbnail service.
441
+        $this->loader->add_action( 'added_post_meta', $this->thumbnail_service, 'added_or_updated_post_meta', 10, 4 );
442
+
443
+        // Hook the updated_post_meta action to the Thumbnail service.
444
+        $this->loader->add_action( 'updated_post_meta', $this->thumbnail_service, 'added_or_updated_post_meta', 10, 4 );
445
+
446
+        // Hook posts inserts (or updates) to the user service.
447
+        $this->loader->add_action( 'wp_insert_post', $this->user_service, 'wp_insert_post', 10, 3 );
448
+
449
+        // Hook the AJAX wl_timeline action to the Timeline service.
450
+        $this->loader->add_action( 'wp_ajax_wl_timeline', $this->timeline_service, 'ajax_timeline' );
451
+
452
+        // Register custom allowed redirect hosts.
453
+        $this->loader->add_filter( 'allowed_redirect_hosts', $this->redirect_service, 'allowed_redirect_hosts' );
454
+        // Hook the AJAX wordlift_redirect action to the Redirect service.
455
+        $this->loader->add_action( 'wp_ajax_wordlift_redirect', $this->redirect_service, 'ajax_redirect' );
456
+        // Hook the AJAX wordlift_redirect action to the Redirect service.
457
+        $this->loader->add_action( 'wp_ajax_wordlift_get_stats', $this->dashboard_service, 'ajax_get_stats' );
458
+        // Hook the AJAX wordlift_redirect action to the Redirect service.
459
+        $this->loader->add_action( 'wp_dashboard_setup', $this->dashboard_service, 'add_dashboard_widgets' );
460
+
461
+        // Hook save_post to the entity service to update custom fields (such as alternate labels).
462
+        // We have a priority of 9 because we want to be executed before data is sent to Redlink.
463
+        $this->loader->add_action( 'save_post', $this->entity_service, 'save_post', 9, 3 );
464
+        $this->loader->add_action( 'save_post_entity', $this->entity_service, 'set_rating_for', 10, 1 );
465
+
466
+        $this->loader->add_action( 'edit_form_before_permalink', $this->entity_service, 'edit_form_before_permalink', 10, 1 );
467
+        $this->loader->add_action( 'in_admin_header', $this->entity_service, 'in_admin_header' );
468
+
469
+        // Entity listing customization (wp-admin/edit.php)
470
+        // Add custom columns
471
+        $this->loader->add_filter( 'manage_entity_posts_columns', $this->entity_list_service, 'register_custom_columns' );
472
+        $this->loader->add_filter( 'manage_entity_posts_custom_column', $this->entity_list_service, 'render_custom_columns', 10, 2 );
473
+        // Add 4W selection
474
+        $this->loader->add_action( 'restrict_manage_posts', $this->entity_list_service, 'restrict_manage_posts_classification_scope' );
475
+        $this->loader->add_filter( 'posts_clauses', $this->entity_list_service, 'posts_clauses_classification_scope' );
476
+
477
+        $this->loader->add_filter( 'wp_terms_checklist_args', $this->entity_types_taxonomy_walker, 'terms_checklist_args' );
478
+
479
+        // Hook the PrimaShop adapter to <em>prima_metabox_entity_header_args</em> in order to add header support for
480
+        // entities.
481
+        $this->loader->add_filter( 'prima_metabox_entity_header_args', $this->primashop_adapter, 'prima_metabox_entity_header_args', 10, 2 );
482
+    }
483
+
484
+    /**
485
+     * Register all of the hooks related to the public-facing functionality
486
+     * of the plugin.
487
+     *
488
+     * @since    1.0.0
489
+     * @access   private
490
+     */
491
+    private function define_public_hooks() {
492
+
493
+        $plugin_public = new Wordlift_Public( $this->get_plugin_name(), $this->get_version() );
494
+
495
+        $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
496
+        $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
497
+
498
+        // Hook the AJAX wl_timeline action to the Timeline service.
499
+        $this->loader->add_action( 'wp_ajax_nopriv_wl_timeline', $this->timeline_service, 'ajax_timeline' );
500
+
501
+        // Hook the ShareThis service.
502
+        $this->loader->add_filter( 'the_content', $this->sharethis_service, 'the_content', 99 );
503
+        $this->loader->add_filter( 'the_excerpt', $this->sharethis_service, 'the_excerpt', 99 );
504
+
505
+        $this->loader->add_action( 'wp_head', $this->page_service, 'wp_head', PHP_INT_MAX );
506
+        $this->loader->add_action( 'wp_footer', $this->page_service, 'wp_head', -PHP_INT_MAX );
507
+
508
+    }
509
+
510
+    /**
511
+     * Run the loader to execute all of the hooks with WordPress.
512
+     *
513
+     * @since    1.0.0
514
+     */
515
+    public function run() {
516
+        $this->loader->run();
517
+    }
518
+
519
+    /**
520
+     * The name of the plugin used to uniquely identify it within the context of
521
+     * WordPress and to define internationalization functionality.
522
+     *
523
+     * @since     1.0.0
524
+     * @return    string    The name of the plugin.
525
+     */
526
+    public function get_plugin_name() {
527
+        return $this->plugin_name;
528
+    }
529
+
530
+    /**
531
+     * The reference to the class that orchestrates the hooks with the plugin.
532
+     *
533
+     * @since     1.0.0
534
+     * @return    Wordlift_Loader    Orchestrates the hooks of the plugin.
535
+     */
536
+    public function get_loader() {
537
+        return $this->loader;
538
+    }
539
+
540
+    /**
541
+     * Retrieve the version number of the plugin.
542
+     *
543
+     * @since     1.0.0
544
+     * @return    string    The version number of the plugin.
545
+     */
546
+    public function get_version() {
547
+        return $this->version;
548
+    }
549 549
 
550 550
 }
Please login to merge, or discard this patch.
src/admin/WL_Metabox/WL_Metabox_Field_uri.php 2 patches
Indentation   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -3,105 +3,105 @@  discard block
 block discarded – undo
3 3
 
4 4
 class WL_Metabox_Field_uri extends WL_Metabox_Field {
5 5
 
6
-	/**
7
-	 * Only accept URIs or local entity IDs.
8
-	 * Build new entity if the user inputted a name that is not present in DB.
9
-	 */
10
-	public function sanitize_data_filter( $value ) {
11
-
12
-		if ( empty( $value ) ) {
13
-			return NULL;
14
-		}
15
-
16
-		// Check that the inserted URI, ID or name does not point to a saved entity.
17
-		if ( is_numeric( $value ) ) {
18
-			$absent_from_db = is_null( get_post( $value ) );                           // search by ID
19
-		} else {
20
-			$absent_from_db =
21
-				is_null( Wordlift_Entity_Service::get_instance()
22
-				                                ->get_entity_post_by_uri( $value ) ) &&                      // search by uri
23
-				is_null( get_page_by_title( $value, OBJECT, Wordlift_Entity_Service::TYPE_NAME ) );   // search by name
24
-		}
25
-
26
-		// Is it an URI?
27
-		$name_is_uri = strpos( $value, 'http' ) === 0;
28
-
29
-		// We create a new entity only if the entity is not present in the DB.
30
-		// In the case of an external uri, we just save the uri.
31
-		if ( $absent_from_db && ! $name_is_uri ) {
32
-
33
-			// ...we create a new entity!
34
-			$new_entity_id = wp_insert_post( array(
35
-				'post_status' => 'publish',
36
-				'post_type'   => Wordlift_Entity_Service::TYPE_NAME,
37
-				'post_title'  => $value
38
-			) );
39
-			$new_entity    = get_post( $new_entity_id );
40
-
41
-			$type = 'http://schema.org/' . ( isset( $this->expected_uri_type ) ? $this->expected_uri_type[0] : 'Thing' );
42
-
43
-			wl_set_entity_main_type( $new_entity_id, $type );
44
-
45
-			// Build uri for this entity
46
-			$new_uri = wl_build_entity_uri( $new_entity_id );
47
-			wl_set_entity_uri( $new_entity_id, $new_uri );
48
-
49
-			wl_push_entity_post_to_redlink( $new_entity );
50
-
51
-			// Update the value that will be saved as meta
52
-			$value = $new_entity_id;
53
-		}
54
-
55
-		return $value;
56
-	}
57
-
58
-	public function html_wrapper_open() {
59
-
60
-		// The containing <div> contains info on cardinality and expected types
61
-		$html = "<div class='wl-field' data-cardinality='$this->cardinality'";
62
-
63
-		if ( isset( $this->expected_uri_type ) && ! is_null( $this->expected_uri_type ) ) {
64
-
65
-			if ( is_array( $this->expected_uri_type ) ) {
66
-				$html .= " data-expected-types='" . implode( ',', $this->expected_uri_type ) . "'";
67
-			} else {
68
-				$html .= " data-expected-types='$this->expected_uri_type'";
69
-			}
70
-		}
71
-
72
-		$html .= '>';
73
-
74
-		return $html;
75
-	}
76
-
77
-	public function html_input( $default_entity_identifier ) {
78
-
79
-		if ( empty( $default_entity_identifier ) ) {
80
-			$entity = NULL;
81
-		} elseif ( is_numeric( $default_entity_identifier ) ) {
82
-			$entity = get_post( $default_entity_identifier );
83
-		} else {
84
-			// @todo: we cannot be so sure this is a URI.
85
-			// It is an URI
86
-			$entity = Wordlift_Entity_Service::get_instance()
87
-			                                 ->get_entity_post_by_uri( $default_entity_identifier );
88
-		}
89
-
90
-		if ( ! is_null( $entity ) ) {
91
-			$label = $entity->post_title;
92
-			$value = $entity->ID;
93
-		} else {
94
-			// No ID and no internal uri. Just leave as is.
95
-			$label = $default_entity_identifier;
96
-			$value = $default_entity_identifier;
97
-		}
98
-
99
-		// Write saved value in page
100
-		// The <input> tags host the meta value.
101
-		// The visible <input> has the human readable value (i.e. entity name or uri)
102
-		// and is accompained by an hidden <input> tag, passed to the server,
103
-		// that contains the raw value (i.e. the uri or entity id).
104
-		$html = <<<EOF
6
+    /**
7
+     * Only accept URIs or local entity IDs.
8
+     * Build new entity if the user inputted a name that is not present in DB.
9
+     */
10
+    public function sanitize_data_filter( $value ) {
11
+
12
+        if ( empty( $value ) ) {
13
+            return NULL;
14
+        }
15
+
16
+        // Check that the inserted URI, ID or name does not point to a saved entity.
17
+        if ( is_numeric( $value ) ) {
18
+            $absent_from_db = is_null( get_post( $value ) );                           // search by ID
19
+        } else {
20
+            $absent_from_db =
21
+                is_null( Wordlift_Entity_Service::get_instance()
22
+                                                ->get_entity_post_by_uri( $value ) ) &&                      // search by uri
23
+                is_null( get_page_by_title( $value, OBJECT, Wordlift_Entity_Service::TYPE_NAME ) );   // search by name
24
+        }
25
+
26
+        // Is it an URI?
27
+        $name_is_uri = strpos( $value, 'http' ) === 0;
28
+
29
+        // We create a new entity only if the entity is not present in the DB.
30
+        // In the case of an external uri, we just save the uri.
31
+        if ( $absent_from_db && ! $name_is_uri ) {
32
+
33
+            // ...we create a new entity!
34
+            $new_entity_id = wp_insert_post( array(
35
+                'post_status' => 'publish',
36
+                'post_type'   => Wordlift_Entity_Service::TYPE_NAME,
37
+                'post_title'  => $value
38
+            ) );
39
+            $new_entity    = get_post( $new_entity_id );
40
+
41
+            $type = 'http://schema.org/' . ( isset( $this->expected_uri_type ) ? $this->expected_uri_type[0] : 'Thing' );
42
+
43
+            wl_set_entity_main_type( $new_entity_id, $type );
44
+
45
+            // Build uri for this entity
46
+            $new_uri = wl_build_entity_uri( $new_entity_id );
47
+            wl_set_entity_uri( $new_entity_id, $new_uri );
48
+
49
+            wl_push_entity_post_to_redlink( $new_entity );
50
+
51
+            // Update the value that will be saved as meta
52
+            $value = $new_entity_id;
53
+        }
54
+
55
+        return $value;
56
+    }
57
+
58
+    public function html_wrapper_open() {
59
+
60
+        // The containing <div> contains info on cardinality and expected types
61
+        $html = "<div class='wl-field' data-cardinality='$this->cardinality'";
62
+
63
+        if ( isset( $this->expected_uri_type ) && ! is_null( $this->expected_uri_type ) ) {
64
+
65
+            if ( is_array( $this->expected_uri_type ) ) {
66
+                $html .= " data-expected-types='" . implode( ',', $this->expected_uri_type ) . "'";
67
+            } else {
68
+                $html .= " data-expected-types='$this->expected_uri_type'";
69
+            }
70
+        }
71
+
72
+        $html .= '>';
73
+
74
+        return $html;
75
+    }
76
+
77
+    public function html_input( $default_entity_identifier ) {
78
+
79
+        if ( empty( $default_entity_identifier ) ) {
80
+            $entity = NULL;
81
+        } elseif ( is_numeric( $default_entity_identifier ) ) {
82
+            $entity = get_post( $default_entity_identifier );
83
+        } else {
84
+            // @todo: we cannot be so sure this is a URI.
85
+            // It is an URI
86
+            $entity = Wordlift_Entity_Service::get_instance()
87
+                                                ->get_entity_post_by_uri( $default_entity_identifier );
88
+        }
89
+
90
+        if ( ! is_null( $entity ) ) {
91
+            $label = $entity->post_title;
92
+            $value = $entity->ID;
93
+        } else {
94
+            // No ID and no internal uri. Just leave as is.
95
+            $label = $default_entity_identifier;
96
+            $value = $default_entity_identifier;
97
+        }
98
+
99
+        // Write saved value in page
100
+        // The <input> tags host the meta value.
101
+        // The visible <input> has the human readable value (i.e. entity name or uri)
102
+        // and is accompained by an hidden <input> tag, passed to the server,
103
+        // that contains the raw value (i.e. the uri or entity id).
104
+        $html = <<<EOF
105 105
 			<div class="wl-input-wrapper wl-autocomplete-wrapper">
106 106
 				<input type="text" class="$this->meta_name wl-autocomplete" value="$label" style="width:88%" />
107 107
 				<input type="hidden" class="$this->meta_name" name="wl_metaboxes[$this->meta_name][]" value="$value" />
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
 			</div>		
111 111
 EOF;
112 112
 
113
-		return $html;
114
-	}
113
+        return $html;
114
+    }
115 115
 }
116 116
 
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -7,46 +7,46 @@  discard block
 block discarded – undo
7 7
 	 * Only accept URIs or local entity IDs.
8 8
 	 * Build new entity if the user inputted a name that is not present in DB.
9 9
 	 */
10
-	public function sanitize_data_filter( $value ) {
10
+	public function sanitize_data_filter($value) {
11 11
 
12
-		if ( empty( $value ) ) {
12
+		if (empty($value)) {
13 13
 			return NULL;
14 14
 		}
15 15
 
16 16
 		// Check that the inserted URI, ID or name does not point to a saved entity.
17
-		if ( is_numeric( $value ) ) {
18
-			$absent_from_db = is_null( get_post( $value ) );                           // search by ID
17
+		if (is_numeric($value)) {
18
+			$absent_from_db = is_null(get_post($value)); // search by ID
19 19
 		} else {
20 20
 			$absent_from_db =
21
-				is_null( Wordlift_Entity_Service::get_instance()
22
-				                                ->get_entity_post_by_uri( $value ) ) &&                      // search by uri
23
-				is_null( get_page_by_title( $value, OBJECT, Wordlift_Entity_Service::TYPE_NAME ) );   // search by name
21
+				is_null(Wordlift_Entity_Service::get_instance()
22
+				                                ->get_entity_post_by_uri($value)) && // search by uri
23
+				is_null(get_page_by_title($value, OBJECT, Wordlift_Entity_Service::TYPE_NAME)); // search by name
24 24
 		}
25 25
 
26 26
 		// Is it an URI?
27
-		$name_is_uri = strpos( $value, 'http' ) === 0;
27
+		$name_is_uri = strpos($value, 'http') === 0;
28 28
 
29 29
 		// We create a new entity only if the entity is not present in the DB.
30 30
 		// In the case of an external uri, we just save the uri.
31
-		if ( $absent_from_db && ! $name_is_uri ) {
31
+		if ($absent_from_db && ! $name_is_uri) {
32 32
 
33 33
 			// ...we create a new entity!
34
-			$new_entity_id = wp_insert_post( array(
34
+			$new_entity_id = wp_insert_post(array(
35 35
 				'post_status' => 'publish',
36 36
 				'post_type'   => Wordlift_Entity_Service::TYPE_NAME,
37 37
 				'post_title'  => $value
38
-			) );
39
-			$new_entity    = get_post( $new_entity_id );
38
+			));
39
+			$new_entity = get_post($new_entity_id);
40 40
 
41
-			$type = 'http://schema.org/' . ( isset( $this->expected_uri_type ) ? $this->expected_uri_type[0] : 'Thing' );
41
+			$type = 'http://schema.org/'.(isset($this->expected_uri_type) ? $this->expected_uri_type[0] : 'Thing');
42 42
 
43
-			wl_set_entity_main_type( $new_entity_id, $type );
43
+			wl_set_entity_main_type($new_entity_id, $type);
44 44
 
45 45
 			// Build uri for this entity
46
-			$new_uri = wl_build_entity_uri( $new_entity_id );
47
-			wl_set_entity_uri( $new_entity_id, $new_uri );
46
+			$new_uri = wl_build_entity_uri($new_entity_id);
47
+			wl_set_entity_uri($new_entity_id, $new_uri);
48 48
 
49
-			wl_push_entity_post_to_redlink( $new_entity );
49
+			wl_push_entity_post_to_redlink($new_entity);
50 50
 
51 51
 			// Update the value that will be saved as meta
52 52
 			$value = $new_entity_id;
@@ -60,10 +60,10 @@  discard block
 block discarded – undo
60 60
 		// The containing <div> contains info on cardinality and expected types
61 61
 		$html = "<div class='wl-field' data-cardinality='$this->cardinality'";
62 62
 
63
-		if ( isset( $this->expected_uri_type ) && ! is_null( $this->expected_uri_type ) ) {
63
+		if (isset($this->expected_uri_type) && ! is_null($this->expected_uri_type)) {
64 64
 
65
-			if ( is_array( $this->expected_uri_type ) ) {
66
-				$html .= " data-expected-types='" . implode( ',', $this->expected_uri_type ) . "'";
65
+			if (is_array($this->expected_uri_type)) {
66
+				$html .= " data-expected-types='".implode(',', $this->expected_uri_type)."'";
67 67
 			} else {
68 68
 				$html .= " data-expected-types='$this->expected_uri_type'";
69 69
 			}
@@ -74,20 +74,20 @@  discard block
 block discarded – undo
74 74
 		return $html;
75 75
 	}
76 76
 
77
-	public function html_input( $default_entity_identifier ) {
77
+	public function html_input($default_entity_identifier) {
78 78
 
79
-		if ( empty( $default_entity_identifier ) ) {
79
+		if (empty($default_entity_identifier)) {
80 80
 			$entity = NULL;
81
-		} elseif ( is_numeric( $default_entity_identifier ) ) {
82
-			$entity = get_post( $default_entity_identifier );
81
+		} elseif (is_numeric($default_entity_identifier)) {
82
+			$entity = get_post($default_entity_identifier);
83 83
 		} else {
84 84
 			// @todo: we cannot be so sure this is a URI.
85 85
 			// It is an URI
86 86
 			$entity = Wordlift_Entity_Service::get_instance()
87
-			                                 ->get_entity_post_by_uri( $default_entity_identifier );
87
+			                                 ->get_entity_post_by_uri($default_entity_identifier);
88 88
 		}
89 89
 
90
-		if ( ! is_null( $entity ) ) {
90
+		if ( ! is_null($entity)) {
91 91
 			$label = $entity->post_title;
92 92
 			$value = $entity->ID;
93 93
 		} else {
Please login to merge, or discard this patch.