Completed
Push — develop ( 0c26c3...8268ab )
by David
03:02
created

Wordlift_Linked_Data_Service::push()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 6
nop 1
dl 0
loc 58
rs 8.2941
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Services: Linked Data Service.
4
 *
5
 * A service to handle data to be pushed to the remote Linked Data store.
6
 *
7
 * @since      3.15.0
8
 * @package    Wordlift
9
 * @subpackage Wordlift/includes
10
 */
11
12
/**
13
 * Define the {@link Wordlift_Linked_Data_Service} class.
14
 *
15
 * @since      3.15.0
16
 * @package    Wordlift
17
 * @subpackage Wordlift/includes
18
 */
19
class Wordlift_Linked_Data_Service {
20
21
	//<editor-fold desc="## FIELDS">
22
	/**
23
	 * A {@link Wordlift_Log_Service} instance.
24
	 *
25
	 * @since  3.15.0
26
	 * @access private
27
	 * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
28
	 */
29
	private $log;
30
31
	/**
32
	 * The {@link Wordlift_Entity_Service} instance.
33
	 *
34
	 * @since  3.15.0
35
	 * @access private
36
	 * @var \Wordlift_Entity_Service $entity_service The {@link Wordlift_Entity_Service} instance.
37
	 */
38
	private $entity_service;
39
40
	/**
41
	 * The {@link Wordlift_Entity_Type_Service} instance.
42
	 *
43
	 * @since  3.15.0
44
	 * @access private
45
	 * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
46
	 */
47
	private $entity_type_service;
48
49
	/**
50
	 * The {@link Wordlift_Schema_Service} instance.
51
	 *
52
	 * @since  3.15.0
53
	 * @access private
54
	 * @var \Wordlift_Schema_Service $schema_service The {@link Wordlift_Schema_Service} instance.
55
	 */
56
	private $schema_service;
57
58
	/**
59
	 * The {@link Wordlift_Sparql_Service} instance.
60
	 *
61
	 * @since  3.15.0
62
	 * @access private
63
	 * @var \Wordlift_Sparql_Service $sparql_service The {@link Wordlift_Sparql_Service} instance.
64
	 */
65
	private $sparql_service;
66
67
	/**
68
	 * The {@link Wordlift_Linked_Data_Service} singleton instance.
69
	 *
70
	 * @since  3.15.0
71
	 * @access private
72
	 * @var \Wordlift_Linked_Data_Service $instance The {@link Wordlift_Linked_Data_Service} singleton instance.
73
	 */
74
	private static $instance;
75
	//</editor-fold>
76
77
	/**
78
	 * Create a {@link Wordlift_Linked_Data_Service} instance.
79
	 *
80
	 * @param \Wordlift_Entity_Service $entity_service The {@link Wordlift_Entity_Service} instance.
81
	 * @param \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
82
	 * @param \Wordlift_Schema_Service $schema_service The {@link Wordlift_Schema_Service} instance.
83
	 * @param \Wordlift_Sparql_Service $sparql_service The {@link Wordlift_Sparql_Service} instance.
84
	 *
85
	 * @since 3.15.0
86
	 *
87
	 */
88
	public function __construct( $entity_service, $entity_type_service, $schema_service, $sparql_service ) {
89
90
		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Linked_Data_Service' );
91
92
		$this->entity_service      = $entity_service;
93
		$this->entity_type_service = $entity_type_service;
94
		$this->schema_service      = $schema_service;
95
		$this->sparql_service      = $sparql_service;
96
97
		/*
98
		 * Allow callers to call the `push` and `remove` methods using WordPress' hooks.
99
		 *
100
		 * @since 3.27.6
101
		 */
102
		add_action( 'wl_legacy_linked_data__push', array( $this, 'push' ) );
103
		add_action( 'wl_legacy_linked_data__remove', array( $this, 'remove' ) );
104
105
		self::$instance = $this;
106
107
	}
108
109
	/**
110
	 * Get the singleton instance of {@link Wordlift_Linked_Data_Service}.
111
	 *
112
	 * @return Wordlift_Linked_Data_Service The singleton instance of <a href='psi_element://Wordlift_Linked_Data_Service'>Wordlift_Linked_Data_Service</a>.
113
	 * @since 3.15.0
114
	 *
115
	 */
116
	public static function get_instance() {
117
118
		return self::$instance;
119
	}
120
121
	//<editor-fold desc="## FUNCTIONS">
122
123
	/**
124
	 * Push a {@link WP_Post} to the Linked Data store.
125
	 *
126
	 * If the {@link WP_Post} is an entity and it's not of the `Article` type,
127
	 * then it is pushed to the remote Linked Data store.
128
	 *
129
	 * @param int $post_id The {@link WP_Post}'s id.
130
	 *
131
	 * @since 3.15.0
132
	 *
133
	 */
134
	public function push( $post_id ) {
135
136
		if ( null === Wordlift_Configuration_Service::get_instance()->get_dataset_uri() ) {
137
			$this->log->debug( "Post $post_id won't be published because the dataset URI isn't set." );
138
139
			return;
140
		}
141
142
		$this->log->debug( "Pushing post $post_id..." );
143
144
		// @since 3.18.0 we don't check anymore if the post is an entity, i.e.
145
		// we removed the following:
146
		//		if ( ! $this->entity_service->is_entity( $post_id ) ) {
147
		//			$this->log->debug( "Post $post_id is not an entity." );
148
		//
149
		//			return;
150
		//		}
151
152
		// Get the post and push it to the Linked Data store.
153
154
		$this->log->debug( "Doing post $post_id push..." );
155
156
		// Get the post.
157
		$post = get_post( $post_id );
158
159
		// Bail out if the post isn't found.
160
		if ( null === $post ) {
161
			$this->log->warn( "Post $post_id not found." );
162
163
			return;
164
		}
165
166
		// Bail out if the post isn't published.
167
		if ( 'publish' !== $post->post_status ) {
168
			$this->log->info( "Post $post_id not published." );
169
170
			return;
171
		}
172
173
		// Bail out if the URI isn't valid.
174
		if ( ! $this->has_valid_uri( $post_id ) ) {
175
			$this->log->warn( "Post $post_id URI invalid." );
176
177
			return;
178
		}
179
180
		// First remove the post data.
181
		$this->remove( $post_id );
182
183
		// Then execute the insert query.
184
		$this->insert( $post_id );
185
186
		// Reindex the triple store if buffering is turned off.
187
		if ( false === WL_ENABLE_SPARQL_UPDATE_QUERIES_BUFFERING ) {
188
			wordlift_reindex_triple_store();
189
		}
190
191
	}
192
193
	/**
194
	 * Check if an entity's {@link WP_Post} has a valid URI.
195
	 *
196
	 * @param int $post_id The entity's {@link WP_Post}'s id.
197
	 *
198
	 * @return bool True if the URI is valid otherwise false.
199
	 * @since 3.15.0
200
	 *
201
	 */
202
	private function has_valid_uri( $post_id ) {
203
204
		// Get the entity's URI.
205
		$uri = $this->entity_service->get_uri( $post_id );
206
207
		// If the URI isn't found, return false.
208
		if ( null === $uri ) {
209
			return false;
210
		}
211
212
		// If the URI ends with a trailing slash, return false.
213
		if ( '/' === substr( $uri, - 1 ) ) {
214
			return false;
215
		}
216
217
		// URI is valid.
218
		return true;
219
	}
220
221
	/**
222
	 * Remove the specified {@link WP_Post} from the Linked Data.
223
	 *
224
	 * @param int $post_id The {@link WP_Post}'s id.
225
	 *
226
	 * @since 3.18.0
227
	 *
228
	 */
229
	public function remove( $post_id ) {
230
		$delete_query = '';
231
232
		// Get the delete statements.
233
		$triples = $this->get_delete_triples( $post_id );
234
235
		// Loop through all triples and add the statement to delete query.
236
		foreach ( $triples as $item ) {
237
			$delete_query .= "DELETE { $item } WHERE { $item }; \n";
238
		}
239
240
		$this->log->trace( "Delete Query generated [ $delete_query ]." );
241
242
		$this->sparql_service->execute( $delete_query );
243
	}
244
245
	/**
246
	 * Insert the specific {@link WP_Post} to Linked Data store.
247
	 *
248
	 * @param int $post_id The {@link WP_Post}'s id.
249
	 *
250
	 * @since 3.18.0
251
	 *
252
	 */
253
	private function insert( $post_id ) {
254
		// Get the insert statements.
255
		$insert_triples = $this->get_insert_triples( $post_id );
256
257
		// Convert all statements to single string.
258
		$insert_query_body = implode( "\n", $insert_triples );
259
260
		// Build the insert query.
261
		$insert_query = "INSERT DATA { $insert_query_body };";
262
263
		$this->log->trace( "Insert Query generated [ $insert_query ]." );
264
265
		$this->sparql_service->execute( $insert_query );
266
	}
267
268
	/**
269
	 * Get the delete statements.
270
	 *
271
	 * @param int $post_id The {@link WP_Post}'s id.
272
	 *
273
	 * @return array An array of delete statements.
274
	 * @since 3.18.0
275
	 *
276
	 */
277
	private function get_delete_triples( $post_id ) {
278
		$delete_triples = array();
279
280
		// Loop through all renditions and get the triples.
281
		foreach ( $this->schema_service->get_renditions() as $rendition ) {
282
			// Push the rendition delete triple to $delete_triples.
283
			$delete_triples = array_merge(
284
				$delete_triples,
285
				(array) $rendition->get_delete_triples( $post_id )
286
			);
287
		}
288
289
		/**
290
		 * Filter: 'wl_delete_triples' - Allow third parties to hook and add additional delete triples.
291
		 *
292
		 * @param array $delete_triples Delete triples.
293
		 * @param int $post_id The current post ID.
294
		 *
295
		 * @since 3.18.0
296
		 *
297
		 */
298
		return apply_filters( 'wl_delete_triples', array_unique( $delete_triples ), $post_id );
299
	}
300
301
	/**
302
	 * Get the SPARQL insert triples ( ?s ?p ?o ) for the specified {@link WP_Post}.
303
	 *
304
	 * @param int $post_id The {@link WP_Post}'s id.
305
	 *
306
	 * @return array An array of insert triples.
307
	 * @since 3.15.0
308
	 *
309
	 */
310
	private function get_insert_triples( $post_id ) {
311
312
		// Get the entity type.
313
		$type = $this->entity_type_service->get( $post_id );
314
315
		// Get the `linked_data` parameter.
316
		$properties = $type['linked_data'];
317
318
		// Accumulate the triples.
319
		$triples = array();
320
321
		/** @var Wordlift_Default_Sparql_Tuple_Rendition $property A {@link Wordlift_Sparql_Tuple_Rendition} instance. */
322
		foreach ( $properties as $property ) {
323
			foreach ( $property->get_insert_triples( $post_id ) as $triple ) {
324
				$triples[] = $triple;
325
			}
326
		}
327
328
		$this->log->trace( count( $properties ) . ' properties and ' . count( $triples ) . " triples found for post $post_id." );
329
330
		/**
331
		 * Get the INSERT triples properties.
332
		 *
333
		 * The `wl_insert_triples` filter allows 3rd parties to extend
334
		 * the list of triples for SPARQL INSERT statements.
335
		 *
336
		 * @param array $linked_data A {@link Wordlift_Sparql_Tuple_Rendition} instances.
337
		 * @param \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
338
		 * @param int $post_id The {@link WP_Post}'s id.
339
		 *
340
		 * @since 3.18.0 The hook has been renamed from `wl_insert_tuples_properties` to `wl_insert_triples`.
341
		 *
342
		 * @since 3.17.0
343
		 */
344
		return apply_filters( 'wl_insert_triples', $triples, $this->entity_service, $post_id );
345
	}
346
	//</editor-fold>
347
348
}
349