Completed
Push — master ( 37bdb3...5c343e )
by David
03:17 queued 10s
created

Wordlift_User_Service::has_cap()   C

Complexity

Conditions 13
Paths 4

Size

Total Lines 35
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 18
nc 4
nop 3
dl 0
loc 35
rs 5.1234
c 0
b 0
f 0

How to fix   Complexity   

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
/**
4
 * Manage user-related functions. This class receives notifications when a post is created/updated and pushes the author's
5
 * data to the triple store. It does NOT receive notification when a user is create/updated because we don't want to send
6
 * to the triple stores users that eventually do not write posts (therefore if user data change, the triple store is updated
7
 * only when the user creates/updates a new post).
8
 *
9
 * @since 3.1.7
10
 */
11
class Wordlift_User_Service {
12
13
	/**
14
	 * The meta key where the user's URI is stored.
15
	 *
16
	 * @since 3.1.7
17
	 */
18
	const URI_META_KEY = '_wl_uri';
19
20
	/**
21
	 * The user meta key where the deny entity edit flag is stored.
22
	 *
23
	 * @since 3.14.0
24
	 */
25
	const DENY_ENTITY_CREATE_META_KEY = '_wl_deny_entity_create';
26
27
	/**
28
	 * The meta key holding the entity id representing a {@link WP_User}.
29
	 *
30
	 * @since 3.14.0
31
	 */
32
	const ENTITY_META_KEY = '_wl_entity';
33
34
	/**
35
	 * The Log service.
36
	 *
37
	 * @since  3.1.7
38
	 * @access private
39
	 * @var \Wordlift_Log_Service $log_service The Log service.
40
	 */
41
	private $log_service;
42
43
	/**
44
	 * The singleton instance of the User service.
45
	 *
46
	 * @since  3.1.7
47
	 * @access private
48
	 * @var \Wordlift_User_Service $user_service The singleton instance of the User service.
49
	 */
50
	private static $instance;
51
52
	/**
53
	 * Create an instance of the User service.
54
	 *
55
	 * @since 3.1.7
56
	 */
57
	public function __construct() {
58
59
		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_User_Service' );
60
61
		self::$instance = $this;
62
63
		add_filter( 'user_has_cap', array( $this, 'has_cap' ), 10, 3 );
64
	}
65
66
	/**
67
	 * Get the singleton instance of the User service.
68
	 *
69
	 * @since 3.1.7
70
	 * @return \Wordlift_User_Service The singleton instance of the User service.
71
	 */
72
	public static function get_instance() {
73
74
		return self::$instance;
75
	}
76
77
	/**
78
	 * Get the URI for a user.
79
	 *
80
	 * @since 3.1.7
81
	 *
82
	 * @param int $user_id The user id
83
	 *
84
	 * @return false|string The user's URI or false in case of failure.
85
	 */
86
	public function get_uri( $user_id ) {
87
88
		// Try to get the URI stored in the user's meta and return it if available.
89
		if ( false !== ( $user_uri = $this->_get_uri( $user_id ) ) ) {
90
			return $user_uri;
91
		}
92
93
		// Try to build an URI, return false in case of failure.
94
		if ( false === ( $user_uri = $this->_build_uri( $user_id ) ) ) {
95
			return false;
96
		}
97
98
		// Store the URI for future requests (we need a "permanent" URI).
99
		$this->_set_uri( $user_id, $user_uri );
100
101
		return $user_uri;
102
	}
103
104
	/**
105
	 * Receives wp_insert_post events.
106
	 *
107
	 * @since 3.1.7
108
	 *
109
	 * @param int     $post_id Post ID.
110
	 * @param WP_Post $post    Post object.
111
	 * @param bool    $update  Whether this is an existing post being updated or not.
112
	 */
113
	public function wp_insert_post( $post_id, $post, $update ) {
0 ignored issues
show
Unused Code introduced by
The parameter $update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
114
115
		// If the post is not published, return.
116
		if ( 'publish' !== get_post_status( $post_id ) ) {
117
			return;
118
		}
119
120
		// We expect a numeric author id.
121
		if ( ! is_numeric( $post->post_author ) ) {
122
			return;
123
		}
124
125
		// Get the delete query,or return in case of failure.
126
		if ( false === ( $delete = $this->get_delete_query( $post->post_author ) ) ) {
127
			return;
128
		}
129
130
		// Get the insert query,or return in case of failure.
131
		if ( false === ( $insert = $this->get_insert_query( $post->post_author ) ) ) {
132
			return;
133
		}
134
135
		// Send the query to the triple store.
136
		rl_execute_sparql_update_query( $delete . $insert );
137
138
	}
139
140
	/**
141
	 * Set the `id` of the entity representing a {@link WP_User}.
142
	 *
143
	 * If the `id` is set to 0 (or less) then the meta is deleted.
144
	 *
145
	 * @since 3.14.0
146
	 *
147
	 * @param int $user_id The {@link WP_User}.
148
	 * @param int $value   The entity {@link WP_Post} `id`.
149
	 *
150
	 * @return bool|int  Meta ID if the key didn't exist, true on successful update, false on failure.
151
	 */
152
	public function set_entity( $user_id, $value ) {
153
154
		return 0 < $value
155
			? update_user_meta( $user_id, self::ENTITY_META_KEY, $value )
156
			: delete_user_meta( $user_id, self::ENTITY_META_KEY );
157
	}
158
159
	/**
160
	 * Get the {@link WP_Post} `id` of the entity representing a {@link WP_User}.
161
	 *
162
	 * @since 3.14.0
163
	 *
164
	 * @param int $user_id The {@link WP_User}'s `id`.
165
	 *
166
	 * @return string The entity {@link WP_Post} `id` or an empty string if not set.
167
	 */
168
	public function get_entity( $user_id ) {
169
170
		return get_user_meta( $user_id, self::ENTITY_META_KEY, true );
171
	}
172
173
	/**
174
	 * Get the user's URI stored in the user's meta.
175
	 *
176
	 * @since 3.1.7
177
	 *
178
	 * @param int $user_id The user id.
179
	 *
180
	 * @return false|string The user's URI or false if not found.
181
	 */
182
	private function _get_uri( $user_id ) {
183
184
		$user_uri = get_user_meta( $user_id, self::URI_META_KEY, true );
185
186
		if ( empty( $user_uri ) ) {
187
			return false;
188
		}
189
190
		return $user_uri;
191
	}
192
193
	/**
194
	 * Build an URI for a user.
195
	 *
196
	 * @since 3.1.7
197
	 *
198
	 * @param int $user_id The user's id.
199
	 *
200
	 * @return false|string The user's URI or false in case of failure.
201
	 */
202
	private function _build_uri( $user_id ) {
203
204
		// Get the user, return false in case of failure.
205
		if ( false === ( $user = get_userdata( $user_id ) ) ) {
206
			return false;
207
		};
208
209
		// If the nicename is not set, return a failure.
210
		if ( empty( $user->user_nicename ) ) {
211
			return false;
212
		}
213
214
		return wl_configuration_get_redlink_dataset_uri() . "/user/$user->user_nicename";
0 ignored issues
show
Deprecated Code introduced by
The function wl_configuration_get_redlink_dataset_uri() has been deprecated with message: use Wordlift_Configuration_Service::get_instance()->get_dataset_uri();

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
215
	}
216
217
	/**
218
	 * Store the URI in user's meta.
219
	 *
220
	 * @since 3.1.7
221
	 *
222
	 * @param int    $user_id  The user's id.
223
	 * @param string $user_uri The user's uri.
224
	 *
225
	 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
226
	 */
227
	private function _set_uri( $user_id, $user_uri ) {
228
229
		return update_user_meta( $user_id, self::URI_META_KEY, $user_uri );
230
	}
231
232
	/**
233
	 * Get the delete query.
234
	 *
235
	 * @since 3.1.7
236
	 *
237
	 * @param int $user_id The user id.
238
	 *
239
	 * @return false|string The delete query or false in case of failure.
240
	 */
241
	private function get_delete_query( $user_id ) {
242
243
		// Get the URI, return if there's none.
244
		if ( false === ( $user_uri = $this->get_uri( $user_id ) ) ) {
245
			return false;
246
		}
247
248
		// Build the delete query.
249
		$query = Wordlift_Query_Builder::new_instance()->delete()
250
		                               ->statement( $user_uri, Wordlift_Query_Builder::RDFS_TYPE_URI, '?o' )
251
		                               ->build()
252
		         . Wordlift_Query_Builder::new_instance()->delete()
253
		                                 ->statement( $user_uri, Wordlift_Query_Builder::RDFS_LABEL_URI, '?o' )
254
		                                 ->build()
255
		         . Wordlift_Query_Builder::new_instance()->delete()
256
		                                 ->statement( $user_uri, Wordlift_Query_Builder::SCHEMA_GIVEN_NAME_URI, '?o' )
257
		                                 ->build()
258
		         . Wordlift_Query_Builder::new_instance()->delete()
259
		                                 ->statement( $user_uri, Wordlift_Query_Builder::SCHEMA_FAMILY_NAME_URI, '?o' )
260
		                                 ->build()
261
		         . Wordlift_Query_Builder::new_instance()->delete()
262
		                                 ->statement( $user_uri, Wordlift_Query_Builder::SCHEMA_URL_URI, '?o' )
263
		                                 ->build();
264
265
		return $query;
266
	}
267
268
	/**
269
	 * Get the insert query.
270
	 *
271
	 * @since 3.1.7
272
	 *
273
	 * @param int $user_id The user id.
274
	 *
275
	 * @return false|string The insert query or false in case of failure.
276
	 */
277
	private function get_insert_query( $user_id ) {
278
279
		// Get the URI, return if there's none.
280
		if ( false === ( $user_uri = $this->get_uri( $user_id ) ) ) {
281
			return false;
282
		}
283
284
		// Try to get the user data, in case of failure return false.
285
		if ( false === ( $user = get_userdata( $user_id ) ) ) {
286
			return false;
287
		};
288
289
		// Build the insert query.
290
		$query = Wordlift_Query_Builder::new_instance()
291
		                               ->insert()
292
		                               ->statement( $user_uri, Wordlift_Query_Builder::RDFS_TYPE_URI, Wordlift_Query_Builder::SCHEMA_PERSON_URI )
293
		                               ->statement( $user_uri, Wordlift_Query_Builder::RDFS_LABEL_URI, $user->display_name )
294
		                               ->statement( $user_uri, Wordlift_Query_Builder::SCHEMA_GIVEN_NAME_URI, $user->user_firstname )
295
		                               ->statement( $user_uri, Wordlift_Query_Builder::SCHEMA_FAMILY_NAME_URI, $user->user_lastname )
296
		                               ->statement( $user_uri, Wordlift_Query_Builder::SCHEMA_URL_URI, ( ! empty( $user->user_url ) ? $user->user_url : get_author_posts_url( $user_id ) ) )
297
		                               ->build();
298
299
		return $query;
300
	}
301
302
	/**
303
	 * Mark an editor user as denied from editing entities.
304
	 * Does nothing if the user is not an editor
305
	 *
306
	 * @since 3.14.0
307
	 *
308
	 * @param integer $user_id The ID of the user
309
	 */
310
	public function deny_editor_entity_create( $user_id ) {
311
312
		// Bail out if the user is not an editor.
313
		if ( ! $this->is_editor( $user_id ) ) {
314
			return;
315
		}
316
317
		// The user explicitly do not have the capability.
318
		update_user_option( $user_id, self::DENY_ENTITY_CREATE_META_KEY, 'yes' );
319
320
	}
321
322
	/**
323
	 * Remove the "deny entity editing" mark from an editor user.
324
	 * Does nothing if the user is not an editor
325
	 *
326
	 * @since 3.14.0
327
	 *
328
	 * @param integer $user_id The ID of the user
329
	 */
330
	public function allow_editor_entity_create( $user_id ) {
331
332
		// Bail out if the user is not an editor.
333
		if ( ! $this->is_editor( $user_id ) ) {
334
			return;
335
		}
336
337
		// The user explicitly do not have the capability.
338
		delete_user_option( $user_id, self::DENY_ENTITY_CREATE_META_KEY );
339
340
	}
341
342
	/**
343
	 * Get whether the 'deny editor entity editing' flag is set.
344
	 *
345
	 * @since 3.14.0
346
	 *
347
	 * @param int $user_id The {@link WP_User} `id`.
348
	 *
349
	 * @return int bool True if editing is denied otherwise false.
350
	 */
351
	public function is_deny_editor_entity_create( $user_id ) {
352
353
		return 'yes' === get_user_option( self::DENY_ENTITY_CREATE_META_KEY, $user_id );
354
	}
355
356
	/**
357
	 * Check whether the {@link WP_User} with the specified `id` is an editor,
358
	 * i.e. has the `editor` role.
359
	 *
360
	 * @since 3.14.0
361
	 *
362
	 * @param int $user_id The {@link WP_User} `id`.
363
	 *
364
	 * @return bool True if the {@link WP_User} is an editor otherwise false.
365
	 */
366
	public function is_editor( $user_id ) {
367
368
		// Get the user.
369
		$user = get_user_by( 'id', $user_id );
370
371
		// Return true, if the user is found and has the `editor` role.
372
		return is_a( $user, 'WP_User' ) && in_array( 'editor', (array) $user->roles );
373
	}
374
375
	/**
376
	 * Check if an editor can create entities.
377
	 *
378
	 * @since 3.14.0
379
	 *
380
	 * @param int $user_id The user id of the user being checked.
381
	 *
382
	 * @return bool    false if it is an editor that is denied from edit entities, true otherwise.
383
	 */
384
	public function editor_can_create_entities( $user_id ) {
385
386
		// Return true if not an editor.
387
		if ( ! $this->is_editor( $user_id ) ) {
388
			return true;
389
		}
390
391
		// Check if the user explicitly denied.
392
		return ! $this->is_deny_editor_entity_create( $user_id );
393
	}
394
395
	/**
396
	 * Filter capabilities of user.
397
	 *
398
	 * Deny the capability of managing and editing entities for some users.
399
	 *
400
	 * @since 3.14.0
401
	 *
402
	 * @param array $allcaps All the capabilities of the user
403
	 * @param array $cap     [0] Required capability
404
	 * @param array $args    [0] Requested capability
405
	 *                       [1] User ID
406
	 *                       [2] Associated object ID
407
	 *
408
	 * @return array The capabilities array.
409
	 */
410
	public function has_cap( $allcaps, $cap, $args ) {
411
		/*
412
		 * For entity management/editing related capabilities
413
		 * check that an editor was not explicitly denied (in user profile)
414
		 * the capability.
415
		 */
416
417
		/*
418
		 * Need protection against the case of edit_user and likes which do not
419
		 * require a capability, just request one.
420
		 */
421
		if ( empty( $cap ) ) {
422
			return $allcaps;
423
		}
424
		if (
425
			( 'edit_wordlift_entity' == $cap[0] ) ||
426
			( 'edit_wordlift_entities' == $cap[0] ) ||
427
			( 'edit_others_wordlift_entities' == $cap[0] ) ||
428
			( 'publish_wordlift_entities' == $cap[0] ) ||
429
			( 'read_private_wordlift_entities' == $cap[0] ) ||
430
			( 'delete_wordlift_entity' == $cap[0] ) ||
431
			( 'delete_wordlift_entities' == $cap[0] ) ||
432
			( 'delete_others_wordlift_entities' == $cap[0] ) ||
433
			( 'delete_published_wordlift_entities' == $cap[0] ) ||
434
			( 'delete_private_wordlift_entities' == $cap[0] )
435
		) {
436
			$user_id = $args[1];
437
438
			if ( ! $this->editor_can_create_entities( $user_id ) ) {
439
				$allcaps[ $cap[0] ] = false;
440
			}
441
		}
442
443
		return $allcaps;
444
	}
445
}
446