Completed
Branch BUG-9961-paypal-pro-items (52e78c)
by
unknown
49:07 queued 32:43
created

EE_Capabilities   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 694
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 8

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 694
rs 8.8
wmc 36
lcom 2
cbo 8

14 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 7 2
A __construct() 0 2 1
A init_caps() 0 7 2
A _set_meta_caps() 0 11 3
B _get_default_meta_caps_array() 0 37 2
A map_meta_caps() 0 12 3
A remove_cap_from_role() 0 6 2
A current_user_can() 0 6 2
A user_can() 0 6 2
A current_user_can_for_blog() 0 8 2
A get_ee_capabilities() 0 7 3
C init_role_caps() 0 22 8
A add_cap_to_role() 0 18 3
B _init_caps_map() 0 315 1
1
<?php
2
3
/**
4
 * This file contains the code related to the capabilities system in Event Espresso.
5
 *
6
 * @since 4.5.0
7
 * @package Event Espresso
8
 * @subpackage core, capabilities
9
 */
10
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
11
	exit( 'No direct script access allowed' );
12
}
13
14
15
/**
16
 * This class contains all the code related to Event Espresso capabilities.
17
 * Assigned to the EE_Registry::instance()->CAP property.
18
 *
19
 * @link https://github.com/eventespresso/event-espresso-core/tree/master/docs/K--Capability-System
20
 *
21
 * @since 4.5.0
22
 * @package Event Espresso
23
 * @subpackage core, capabilities
24
 * @author Darren Ethier
25
 */
26
final class EE_Capabilities extends EE_Base {
27
28
29
	/**
30
	 * instance of EE_Capabilities object
31
	 *
32
	 * @var EE_Capabilities
33
	 */
34
	private static $_instance = null;
35
36
37
	/**
38
	 * This is a map of caps that correspond to a default WP_Role.
39
	 * Array is indexed by Role and values are ee capabilities.
40
	 *
41
	 * @since 4.5.0
42
	 *
43
	 * @var array
44
	 */
45
	private $_caps_map = array();
46
47
48
49
	/**
50
	 * This used to hold an array of EE_Meta_Capability_Map objects that define the granular capabilities mapped to for a user depending on context.
51
	 *
52
	 * @var EE_Meta_Capability_Map[]
53
	 */
54
	private $_meta_caps = array();
55
56
	/**
57
	 * the name of the wp option used to store caps previously initialized
58
	 */
59
	const option_name = 'ee_caps_initialized';
60
61
62
63
64
65
	/**
66
	 * singleton method used to instantiate class object
67
	 *
68
	 * @since 4.5.0
69
	 *
70
	 * @return EE_Capabilities
71
	 */
72
	public static function instance() {
73
		//check if instantiated, and if not do so.
74
		if ( ! self::$_instance instanceof EE_Capabilities ) {
75
			self::$_instance = new self();
76
		}
77
		return self::$_instance;
78
	}
79
80
81
82
	/**
83
	 * private constructor
84
	 *
85
	 * @since 4.5.0
86
	 *
87
	 * @return \EE_Capabilities
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
88
	 */
89
	private function __construct() {
90
	}
91
92
93
94
	/**
95
	 * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
96
	 *
97
	 * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't actually REMOVE any capabilities from existing roles, it just resaves defaults roles and ensures that they are up to date.
98
	 *
99
	 *
100
	 * @since 4.5.0
101
	 * @return void
102
	 */
103
	public function init_caps( $reset = false ) {
104
		if ( EE_Maintenance_Mode::instance()->models_can_query() ){
105
			$this->_caps_map = $this->_init_caps_map();
106
			$this->init_role_caps( $reset );
107
			$this->_set_meta_caps();
108
		}
109
	}
110
111
112
113
114
	/**
115
	 * This sets the meta caps property.
116
117
	 * @since 4.5.0
118
	 *
119
	 * @return void
120
	 */
121
	private function _set_meta_caps() {
122
		//make sure we're only ever initializing the default _meta_caps array once if it's empty.
123
		$this->_meta_caps = $this->_get_default_meta_caps_array();
124
125
		$this->_meta_caps = apply_filters( 'FHEE__EE_Capabilities___set_meta_caps__meta_caps', $this->_meta_caps );
126
127
		//add filter for map_meta_caps but only if models can query.
128
		if ( EE_Maintenance_Mode::instance()->models_can_query() && ! has_filter( 'map_meta_cap', array( $this, 'map_meta_caps' ) ) ) {
129
			add_filter( 'map_meta_cap', array( $this, 'map_meta_caps' ), 10, 4 );
130
		}
131
	}
132
133
134
	/**
135
	 * This builds and returns the default meta_caps array only once.
136
	 *
137
	 * @since  4.8.28.rc.012
138
	 * @return array
139
	 */
140
	private function _get_default_meta_caps_array() {
141
		static $default_meta_caps = array();
142
		if ( empty( $default_meta_caps ) ) {
143
			$default_meta_caps = array(
144
				//edits
145
				new EE_Meta_Capability_Map_Edit( 'ee_edit_event', array( 'Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events' ) ),
146
				new EE_Meta_Capability_Map_Edit( 'ee_edit_venue', array( 'Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues' ) ),
147
				new EE_Meta_Capability_Map_Edit( 'ee_edit_registration', array( 'Registration', '', 'ee_edit_others_registrations', '' ) ),
148
				new EE_Meta_Capability_Map_Edit( 'ee_edit_checkin', array( 'Registration', '', 'ee_edit_others_checkins', '' ) ),
149
				new EE_Meta_Capability_Map_Messages_Cap( 'ee_edit_message', array( 'Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages' ) ),
150
				new EE_Meta_Capability_Map_Edit( 'ee_edit_default_ticket', array( 'Ticket', '', 'ee_edit_others_default_tickets', '' ) ),
151
				new EE_Meta_Capability_Map_Registration_Form_Cap( 'ee_edit_question', array( 'Question', '', '', 'ee_edit_system_questions' ) ),
152
				new EE_Meta_Capability_Map_Registration_Form_Cap( 'ee_edit_question_group', array( 'Question_Group', '', '', 'ee_edit_system_question_groups' ) ),
153
				new EE_Meta_Capability_Map_Edit( 'ee_edit_payment_method', array( 'Payment_Method', '', 'ee_edit_others_payment_methods', '' ) ),
154
				//reads
155
				new EE_Meta_Capability_Map_Read( 'ee_read_event', array( 'Event', '', 'ee_read_others_events', 'ee_read_private_events' ) ),
156
				new EE_Meta_Capability_Map_Read( 'ee_read_venue', array( 'Venue', '', 'ee_read_others_venues', 'ee_read_private_venues' ) ),
157
				new EE_Meta_Capability_Map_Read( 'ee_read_registration', array( 'Registration', '', '', 'ee_edit_others_registrations' ) ),
158
				new EE_Meta_Capability_Map_Read( 'ee_read_checkin', array( 'Registration', '', '', 'ee_read_others_checkins' ) ),
159
				new EE_Meta_Capability_Map_Messages_Cap( 'ee_read_message', array( 'Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages' ) ),
160
				new EE_Meta_Capability_Map_Read( 'ee_read_default_ticket', array( 'Ticket', '', '', 'ee_read_others_default_tickets' ) ),
161
				new EE_Meta_Capability_Map_Read( 'ee_read_payment_method', array( 'Payment_Method', '', '', 'ee_read_others_payment_methods' ) ),
162
163
				//deletes
164
				new EE_Meta_Capability_Map_Delete( 'ee_delete_event', array( 'Event', 'ee_delete_published_events', 'ee_delete_others_events', 'ee_delete_private_events' ) ),
165
				new EE_Meta_Capability_Map_Delete( 'ee_delete_venue', array( 'Venue', 'ee_delete_published_venues', 'ee_delete_others_venues', 'ee_delete_private_venues' ) ),
166
				new EE_Meta_Capability_Map_Delete( 'ee_delete_registration', array( 'Registration', '', 'ee_delete_others_registrations', '' ) ),
167
				new EE_Meta_Capability_Map_Delete( 'ee_delete_checkin', array( 'Registration', '', 'ee_delete_others_checkins', '' ) ),
168
				new EE_Meta_Capability_Map_Messages_Cap( 'ee_delete_message', array( 'Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages' ) ),
169
				new EE_Meta_Capability_Map_Delete( 'ee_delete_default_ticket', array( 'Ticket', '', 'ee_delete_others_default_tickets', '' ) ),
170
				new EE_Meta_Capability_Map_Registration_Form_Cap( 'ee_delete_question', array( 'Question', '', '', 'delete_system_questions' ) ),
171
				new EE_Meta_Capability_Map_Registration_Form_Cap( 'ee_delete_question_group', array( 'Question_Group', '', '', 'delete_system_question_groups' ) ),
172
				new EE_Meta_Capability_Map_Delete( 'ee_delete_payment_method', array( 'Payment_Method', '', 'ee_delete_others_payment_methods', '' ) ),
173
			);
174
		}
175
		return $default_meta_caps;
176
	}
177
178
179
180
	/**
181
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
182
	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
183
	 *
184
	 * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
185
	 *
186
	 * @since 4.5.0
187
	 * @see  wp-includes/capabilities.php
188
	 *
189
	 * @param array  $caps    actual users capabilities
190
	 * @param string $cap     initial capability name that is being checked (the "map" key)
191
	 * @param int    $user_id The user id
192
	 * @param array  $args    Adds context to the cap. Typically the object ID.
193
	 *
194
	 * @return array   actual users capabilities
195
	 */
196
	public function map_meta_caps( $caps, $cap, $user_id, $args ) {
197
		//loop through our _meta_caps array
198
		foreach ( $this->_meta_caps as $meta_map ) {
199
			if ( ! $meta_map instanceof EE_Meta_Capability_Map ) {
200
				continue;
201
			}
202
			$meta_map->ensure_is_model();
203
204
			$caps = $meta_map->map_meta_caps( $caps, $cap, $user_id, $args );
205
		}
206
		return $caps;
207
	}
208
209
210
211
212
	/**
213
	 * This sets up and returns the initial capabilities map for Event Espresso
214
	 *
215
	 * @since 4.5.0
216
	 *
217
	 * @return array
218
	 */
219
	private function _init_caps_map() {
220
		$caps = array(
221
			'administrator' => array(
222
			//basic access
223
				'ee_read_ee',
224
			//gateways
225
			/**
226
			 * note that with payment method capabilities, although we've implemented
227
			 * capability mapping which will be used for accessing payment methods owned by
228
			 * other users.  This is not fully implemented yet in the payment method ui.
229
			 * Currently only the "plural" caps are in active use. (Specific payment method caps are in use as well).
230
			**/
231
				'ee_manage_gateways',
232
				'ee_read_payment_method',
233
				'ee_read_payment_methods',
234
				'ee_read_others_payment_methods',
235
				'ee_edit_payment_method',
236
				'ee_edit_payment_methods',
237
				'ee_edit_others_payment_methods',
238
				'ee_delete_payment_method',
239
				'ee_delete_payment_methods',
240
			//events
241
				'ee_publish_events',
242
				'ee_read_private_events',
243
				'ee_read_others_events',
244
				'ee_read_event',
245
				'ee_read_events',
246
				'ee_edit_event',
247
				'ee_edit_events',
248
				'ee_edit_published_events',
249
				'ee_edit_others_events',
250
				'ee_edit_private_events',
251
				'ee_delete_published_events',
252
				'ee_delete_private_events',
253
				'ee_delete_event',
254
				'ee_delete_events',
255
				'ee_delete_others_events',
256
			//event categories
257
				'ee_manage_event_categories',
258
				'ee_edit_event_category',
259
				'ee_delete_event_category',
260
				'ee_assign_event_category',
261
			//venues
262
				'ee_publish_venues',
263
				'ee_read_venue',
264
				'ee_read_venues',
265
				'ee_read_others_venues',
266
				'ee_read_private_venues',
267
				'ee_edit_venue',
268
				'ee_edit_venues',
269
				'ee_edit_others_venues',
270
				'ee_edit_published_venues',
271
				'ee_edit_private_venues',
272
				'ee_delete_venue',
273
				'ee_delete_venues',
274
				'ee_delete_others_venues',
275
				'ee_delete_private_venues',
276
				'ee_delete_published_venues',
277
			//venue categories
278
				'ee_manage_venue_categories',
279
				'ee_edit_venue_category',
280
				'ee_delete_venue_category',
281
				'ee_assign_venue_category',
282
			//contacts
283
				'ee_read_contact',
284
				'ee_read_contacts',
285
				'ee_edit_contact',
286
				'ee_edit_contacts',
287
				'ee_delete_contact',
288
				'ee_delete_contacts',
289
			//registrations
290
				'ee_read_registration',
291
				'ee_read_registrations',
292
				'ee_read_others_registrations',
293
				'ee_edit_registration',
294
				'ee_edit_registrations',
295
				'ee_edit_others_registrations',
296
				'ee_delete_registration',
297
				'ee_delete_registrations',
298
			//checkins
299
				'ee_read_checkin',
300
				'ee_read_others_checkins',
301
				'ee_read_checkins',
302
				'ee_edit_checkin',
303
				'ee_edit_checkins',
304
				'ee_edit_others_checkins',
305
				'ee_delete_checkin',
306
				'ee_delete_checkins',
307
				'ee_delete_others_checkins',
308
			//transactions && payments
309
				'ee_read_transaction',
310
				'ee_read_transactions',
311
				'ee_edit_payments',
312
				'ee_delete_payments',
313
			//messages
314
				'ee_read_message',
315
				'ee_read_messages',
316
				'ee_read_others_messages',
317
				'ee_read_global_messages',
318
				'ee_edit_global_messages',
319
				'ee_edit_message',
320
				'ee_edit_messages',
321
				'ee_edit_others_messages',
322
				'ee_delete_message',
323
				'ee_delete_messages',
324
				'ee_delete_others_messages',
325
				'ee_delete_global_messages',
326
				'ee_send_message',
327
			//tickets
328
				'ee_read_default_ticket',
329
				'ee_read_default_tickets',
330
				'ee_read_others_default_tickets',
331
				'ee_edit_default_ticket',
332
				'ee_edit_default_tickets',
333
				'ee_edit_others_default_tickets',
334
				'ee_delete_default_ticket',
335
				'ee_delete_default_tickets',
336
				'ee_delete_others_default_tickets',
337
			//prices
338
				'ee_edit_default_price',
339
				'ee_edit_default_prices',
340
				'ee_delete_default_price',
341
				'ee_delete_default_prices',
342
				'ee_edit_default_price_type',
343
				'ee_edit_default_price_types',
344
				'ee_delete_default_price_type',
345
				'ee_delete_default_price_types',
346
				'ee_read_default_prices',
347
				'ee_read_default_price_types',
348
			//registration form
349
				'ee_edit_question',
350
				'ee_edit_questions',
351
				'ee_edit_system_questions',
352
				'ee_read_questions',
353
				'ee_delete_question',
354
				'ee_delete_questions',
355
				'ee_edit_question_group',
356
				'ee_edit_question_groups',
357
				'ee_read_question_groups',
358
				'ee_edit_system_question_groups',
359
				'ee_delete_question_group',
360
				'ee_delete_question_groups',
361
			//event_type taxonomy
362
				'ee_assign_event_type',
363
				'ee_manage_event_types',
364
				'ee_edit_event_type',
365
				'ee_delete_event_type',
366
				),
367
			'ee_events_administrator' => array(
368
			//core wp caps
369
				'read',
370
				'read_private_pages',
371
				'read_private_posts',
372
				'edit_users',
373
				'edit_posts',
374
				'edit_pages',
375
				'edit_published_posts',
376
				'edit_published_pages',
377
				'edit_private_pages',
378
				'edit_private_posts',
379
				'edit_others_posts',
380
				'edit_others_pages',
381
				'publish_posts',
382
				'publish_pages',
383
				'delete_posts',
384
				'delete_pages',
385
				'delete_private_pages',
386
				'delete_private_posts',
387
				'delete_published_pages',
388
				'delete_published_posts',
389
				'delete_others_posts',
390
				'delete_others_pages',
391
				'manage_categories',
392
				'manage_links',
393
				'moderate_comments',
394
				'unfiltered_html',
395
				'upload_files',
396
				'export',
397
				'import',
398
				'list_users',
399
				'level_1', //required if user with this role shows up in author dropdowns
400
			//basic ee access
401
				'ee_read_ee',
402
				//events
403
				'ee_publish_events',
404
				'ee_read_private_events',
405
				'ee_read_others_events',
406
				'ee_read_event',
407
				'ee_read_events',
408
				'ee_edit_event',
409
				'ee_edit_events',
410
				'ee_edit_published_events',
411
				'ee_edit_others_events',
412
				'ee_edit_private_events',
413
				'ee_delete_published_events',
414
				'ee_delete_private_events',
415
				'ee_delete_event',
416
				'ee_delete_events',
417
				'ee_delete_others_events',
418
				//event categories
419
				'ee_manage_event_categories',
420
				'ee_edit_event_category',
421
				'ee_delete_event_category',
422
				'ee_assign_event_category',
423
				//venues
424
				'ee_publish_venues',
425
				'ee_read_venue',
426
				'ee_read_venues',
427
				'ee_read_others_venues',
428
				'ee_read_private_venues',
429
				'ee_edit_venue',
430
				'ee_edit_venues',
431
				'ee_edit_others_venues',
432
				'ee_edit_published_venues',
433
				'ee_edit_private_venues',
434
				'ee_delete_venue',
435
				'ee_delete_venues',
436
				'ee_delete_others_venues',
437
				'ee_delete_private_venues',
438
				'ee_delete_published_venues',
439
				//venue categories
440
				'ee_manage_venue_categories',
441
				'ee_edit_venue_category',
442
				'ee_delete_venue_category',
443
				'ee_assign_venue_category',
444
				//contacts
445
				'ee_read_contact',
446
				'ee_read_contacts',
447
				'ee_edit_contact',
448
				'ee_edit_contacts',
449
				'ee_delete_contact',
450
				'ee_delete_contacts',
451
				//registrations
452
				'ee_read_registration',
453
				'ee_read_registrations',
454
				'ee_read_others_registrations',
455
				'ee_edit_registration',
456
				'ee_edit_registrations',
457
				'ee_edit_others_registrations',
458
				'ee_delete_registration',
459
				'ee_delete_registrations',
460
				//checkins
461
				'ee_read_checkin',
462
				'ee_read_others_checkins',
463
				'ee_read_checkins',
464
				'ee_edit_checkin',
465
				'ee_edit_checkins',
466
				'ee_edit_others_checkins',
467
				'ee_delete_checkin',
468
				'ee_delete_checkins',
469
				'ee_delete_others_checkins',
470
				//transactions && payments
471
				'ee_read_transaction',
472
				'ee_read_transactions',
473
				'ee_edit_payments',
474
				'ee_delete_payments',
475
				//messages
476
				'ee_read_message',
477
				'ee_read_messages',
478
				'ee_read_others_messages',
479
				'ee_read_global_messages',
480
				'ee_edit_global_messages',
481
				'ee_edit_message',
482
				'ee_edit_messages',
483
				'ee_edit_others_messages',
484
				'ee_delete_message',
485
				'ee_delete_messages',
486
				'ee_delete_others_messages',
487
				'ee_delete_global_messages',
488
				'ee_send_message',
489
				//tickets
490
				'ee_read_default_ticket',
491
				'ee_read_default_tickets',
492
				'ee_read_others_default_tickets',
493
				'ee_edit_default_ticket',
494
				'ee_edit_default_tickets',
495
				'ee_edit_others_default_tickets',
496
				'ee_delete_default_ticket',
497
				'ee_delete_default_tickets',
498
				'ee_delete_others_default_tickets',
499
				//prices
500
				'ee_edit_default_price',
501
				'ee_edit_default_prices',
502
				'ee_delete_default_price',
503
				'ee_delete_default_prices',
504
				'ee_edit_default_price_type',
505
				'ee_edit_default_price_types',
506
				'ee_delete_default_price_type',
507
				'ee_delete_default_price_types',
508
				'ee_read_default_prices',
509
				'ee_read_default_price_types',
510
				//registration form
511
				'ee_edit_question',
512
				'ee_edit_questions',
513
				'ee_edit_system_questions',
514
				'ee_read_questions',
515
				'ee_delete_question',
516
				'ee_delete_questions',
517
				'ee_edit_question_group',
518
				'ee_edit_question_groups',
519
				'ee_read_question_groups',
520
				'ee_edit_system_question_groups',
521
				'ee_delete_question_group',
522
				'ee_delete_question_groups',
523
				//event_type taxonomy
524
				'ee_assign_event_type',
525
				'ee_manage_event_types',
526
				'ee_edit_event_type',
527
				'ee_delete_event_type',
528
			)
529
		);
530
531
		$caps = apply_filters( 'FHEE__EE_Capabilities__init_caps_map__caps', $caps );
532
		return $caps;
533
	}
534
535
536
537
538
	/**
539
	 * This adds all the default caps to roles as registered in the _caps_map property.
540
	 *
541
	 * @since 4.5.0
542
	 *
543
	 * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't actually REMOVE any capabilities from existing roles, it just resaves defaults roles and ensures that they are up to date.
544
	 * @param array $custom_map Optional.  Can be used to send a custom map of roles and capabilities for setting them up.  Note that this should ONLY be called on activation hook or some other one-time task otherwise the caps will be added on every request.
545
	 *
546
	 * @return void
547
	 */
548
	public function init_role_caps( $reset = false, $custom_map = array() ) {
549
550
		$caps_map = empty( $custom_map ) ? $this->_caps_map : $custom_map;
551
552
		//first let's determine if these caps have already been set.
553
		$caps_set_before = get_option( self::option_name, array() );
554
		//if not reset, see what caps are new for each role. if they're new, add them.
555
		foreach ( $caps_map as $role => $caps_for_role ) {
556
			foreach ( $caps_for_role as $cap ) {
557
				//first check we haven't already added this cap before, or it's a reset
558
				if ( $reset || ! isset( $caps_set_before[ $role ] ) || ! in_array( $cap, $caps_set_before[ $role ] ) ) {
559
					if ( $this->add_cap_to_role( $role, $cap ) ) {
560
						$caps_set_before[ $role ][] = $cap;
561
					}
562
				}
563
			}
564
		}
565
566
		//now let's just save the cap that has been set.
567
		update_option( self::option_name, $caps_set_before );
568
		do_action( 'AHEE__EE_Capabilities__init_role_caps__complete', $caps_set_before );
569
	}
570
571
572
573
574
	/**
575
	 * This method sets a capability on a role.  Note this should only be done on activation, or if you have something specific to prevent the cap from being added on every page load (adding caps are persistent to the db).
576
	 * Note. this is a wrapper for $wp_role->add_cap()
577
	 *
578
	 * @see wp-includes/capabilities.php
579
	 *
580
	 * @since 4.5.0
581
	 *
582
	 * @param string $role  A WordPress role the capability is being added to
583
	 * @param string $cap   The capability being added to the role
584
	 * @param bool $grant  Whether to grant access to this cap on this role.
585
	 * @return bool
586
	 */
587
	public function add_cap_to_role( $role, $cap, $grant = true ) {
588
		$role_object = get_role( $role );
589
		//if the role isn't available then we create it.
590
		if ( ! $role_object instanceof WP_Role ) {
0 ignored issues
show
Bug introduced by
The class WP_Role does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
591
			//if a plugin wants to create a specific role name then they should create the role before
592
			//EE_Capabilities does.  Otherwise this function will create the role name from the slug:
593
			// - removes any `ee_` namespacing from the start of the slug.
594
			// - replaces `_` with ` ` (empty space).
595
			// - sentence case on the resulting string.
596
			$role_label = ucwords( str_replace( '_', ' ', str_replace( 'ee_', '', $role ) ) );
597
			$role_object = add_role( $role, $role_label );
598
		}
599
		if ( $role_object instanceof WP_Role ) {
0 ignored issues
show
Bug introduced by
The class WP_Role does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
600
			$role_object->add_cap( $cap, $grant );
601
			return true;
602
		}
603
		return false;
604
	}
605
606
607
608
609
610
	/**
611
	 * Functions similarly to add_cap_to_role except removes cap from given role.
612
	 * Wrapper for $wp_role->remove_cap()
613
	 *
614
	 * @see wp-includes/capabilities.php
615
	 * @since 4.5.0
616
	 *
617
	 * @param string $role A WordPress role the capability is being removed from.
618
	 * @param string $cap  The capability being removed
619
	 *
620
	 * @return void
621
	 */
622
	public function remove_cap_from_role( $role, $cap ) {
623
		$role = get_role( $role );
624
		if ( $role instanceof WP_Role ) {
0 ignored issues
show
Bug introduced by
The class WP_Role does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
625
			$role->remove_cap( $cap );
626
		}
627
	}
628
629
630
631
632
	/**
633
	 * Wrapper for the native WP current_user_can() method.
634
	 * This is provided as a handy method for a couple things:
635
	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to write those filters wherever current_user_can is called).
636
	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
637
	 *
638
	 * @since 4.5.0
639
	 *
640
	 * @param string $cap     The cap being checked.
641
	 * @param string $context The context where the current_user_can is being called from.
642
	 * @param int    $id          Optional. Id for item where current_user_can is being called from (used in map_meta_cap() filters.
643
	 *
644
	 * @return bool  Whether user can or not.
645
	 */
646
	public function current_user_can( $cap, $context, $id = 0 ) {
647
		//apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
648
		$filtered_cap = apply_filters( 'FHEE__EE_Capabilities__current_user_can__cap__' . $context,  $cap, $id );
649
		$filtered_cap = apply_filters( 'FHEE__EE_Capabilities__current_user_can__cap', $filtered_cap, $context, $cap, $id );
650
		return ! empty( $id ) ? current_user_can( $filtered_cap, $id ) : current_user_can( $filtered_cap );
651
	}
652
653
654
655
656
657
	/**
658
	 * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
659
	 *
660
	 * @param int|WP_User $user    Either the user_id or a WP_User object
661
	 * @param string $cap     The capability string being checked
662
	 * @param string $context The context where the user_can is being called from (used in filters).
663
	 * @param int    $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap() filters)
664
	 *
665
	 * @return bool Whether user can or not.
666
	 */
667
	public function user_can( $user, $cap, $context, $id = 0 ) {
668
		//apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
669
		$filtered_cap = apply_filters( 'FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id );
670
		$filtered_cap = apply_filters( 'FHEE__EE_Capabilities__user_can__cap', $filtered_cap, $context, $cap, $user,  $id );
671
		return ! empty( $id ) ? user_can( $user, $filtered_cap, $id ) : user_can( $user, $filtered_cap );
672
	}
673
674
675
676
	/**
677
	 * Wrapper for the native WP current_user_can_for_blog() method.
678
	 * This is provided as a handy method for a couple things:
679
	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to write those filters wherever current_user_can is called).
680
	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
681
	 *
682
	 * @since 4.5.0
683
	 *
684
	 * @param int      $blog_id The blog id that is being checked for.
685
	 * @param string $cap     The cap being checked.
686
	 * @param string $context The context where the current_user_can is being called from.
687
	 * @param int    $id          Optional. Id for item where current_user_can is being called from (used in map_meta_cap() filters.
688
	 *
689
	 * @return bool  Whether user can or not.
690
	 */
691
	public function current_user_can_for_blog( $blog_id, $cap, $context, $id = 0 ) {
692
		$user_can = ! empty( $id ) ? current_user_can_for_blog( $blog_id, $cap, $id ) : current_user_can( $blog_id, $cap );
693
694
		//apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
695
		$user_can = apply_filters( 'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context, $user_can, $blog_id, $cap, $id );
696
		$user_can = apply_filters( 'FHEE__EE_Capabilities__current_user_can_for_blog__user_can', $user_can, $context, $blog_id, $cap, $id );
697
		return $user_can;
698
	}
699
700
701
702
	/**
703
	 * This helper method just returns an array of registered EE capabilities.
704
	 * Note this array is filtered.  It is assumed that all available EE capabilities are assigned to the administrator role.
705
	 *
706
	 * @since 4.5.0
707
	 *
708
	 * @param string $role  If empty then the entire role/capability map is returned.  Otherwise just the capabilities for the given role are returned.
709
	 *
710
	 * @return array
711
	 */
712
	public function get_ee_capabilities( $role = 'administrator' ) {
713
		$capabilities = $this->_init_caps_map();
714
		if ( empty( $role ) ) {
715
			return $capabilities;
716
		}
717
		return isset( $capabilities[ $role ] ) ? $capabilities[ $role ] : array();
718
	}
719
}
720
721
722
723
724
/**
725
 * Meta Capability Map class.
726
 * This children of this class are used to define capability mappings for capabilities that have further filtering depending on context.
727
 *
728
 * @since 4.5.0
729
 * @package Event Espresso
730
 * @subpackage core, capabilities
731
 * @author  Darren Ethier
732
 */
733
abstract class EE_Meta_Capability_Map {
734
	public $meta_cap;
735
	/**
736
	 * @var EEM_Base
737
	 */
738
	protected $_model;
739
	protected $_model_name;
740
	public $published_cap = '';
741
	public $others_cap = '';
742
	public $private_cap = '';
743
744
745
746
	/**
747
	 * constructor.
748
	 * Receives the setup arguments for the map.
749
	 *
750
	 * @since    4.5.0
751
	 *
752
	 * @param string $meta_cap     What meta capability is this mapping.
753
	 * @param array  $map_values   array {
754
	 * 		//array of values that MUST match a count of 4.  It's okay to send an empty string for capabilities that don't get mapped to.
755
	 * 		@type $map_values[0] string A string representing the model name. Required.  String's
756
	 * 		      	    	       should always be used when Menu Maps are registered via the
757
	 * 		      	    	       plugin API as models are not allowed to be instantiated when
758
	 * 		      	    	       in maintenance mode 2 (migrations).
759
	 * 		@type $map_values[1] string represents the capability used for published. Optional.
760
	 * 		@type $map_values[2] string represents the capability used for "others". Optional.
761
	 * 		@type $map_values[3] string represents the capability used for private. Optional.
762
	 * 	}
763
	 * @throws EE_Error
764
	 */
765
	public function __construct( $meta_cap, $map_values ) {
766
		$this->meta_cap = $meta_cap;
767
		//verify there are four args in the $map_values array;
768
		if ( count( $map_values ) !== 4 ) {
769
			throw new EE_Error( sprintf( __( 'Incoming $map_values array should have a count of four values in it.  This is what was given: %s', 'event_espresso' ), '<br>' . print_r( $map_values, true ) ) );
770
		}
771
772
		//set properties
773
		$this->_model = null;
774
		$this->_model_name = $map_values[0];
775
		$this->published_cap = (string) $map_values[1];
776
		$this->others_cap = (string) $map_values[2];
777
		$this->private_cap = (string) $map_values[3];
778
	}
779
780
	/**
781
	 * Makes it so this object stops filtering caps
782
	 */
783
	public function remove_filters(){
784
		remove_filter( 'map_meta_cap', array( $this, 'map_meta_caps' ), 10 );
785
	}
786
787
788
789
	/**
790
	 * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
791
	 *
792
	 * @since 4.5.0
793
	 * @throws EE_Error
794
	 *
795
	 * @return void
796
	 */
797
	public function ensure_is_model() {
798
		//is it already instantiated?
799
		if ( $this->_model instanceof EEM_Base ) {
800
			return;
801
		}
802
803
		//ensure model name is string
804
		$this->_model_name = (string) $this->_model_name;
805
		//error proof if the name has EEM in it
806
		$this->_model_name = str_replace( 'EEM', '', $this->_model_name );
807
808
		$this->_model = EE_Registry::instance()->load_model( $this->_model_name );
809
810 View Code Duplication
		if ( ! $this->_model instanceof EEM_Base ) {
811
			throw new EE_Error( sprintf( __( 'This string passed in to %s to represent a EEM_Base model class was not able to be used to instantiate the class.   Please ensure that the string is a match for the EEM_Base model name (not including the EEM_ part). This was given: %s', 'event_espresso' ), get_class( $this ), $this->_model ) );
812
		}
813
	}
814
815
816
	/**
817
	 *
818
	 * @see EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
819
	 * @since 4.6.x
820
	 * @param $caps
821
	 * @param $cap
822
	 * @param $user_id
823
	 * @param $args
824
	 *
825
	 * @return array
826
	 */
827
	public function map_meta_caps( $caps, $cap, $user_id, $args ) {
828
		return $this->_map_meta_caps( $caps, $cap, $user_id, $args );
829
	}
830
831
832
833
	/**
834
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
835
	 *
836
	 * @since 4.5.0
837
	 * @see  wp-includes/capabilities.php
838
	 *
839
	 * @param array  $caps    actual users capabilities
840
	 * @param string $cap     initial capability name that is being checked (the "map" key)
841
	 * @param int     $user_id The user id
842
	 * @param array  $args    Adds context to the cap. Typically the object ID.
843
	 *
844
	 * @return array   actual users capabilities
845
	 */
846
	abstract protected function _map_meta_caps( $caps, $cap, $user_id, $args );
847
}
848
849
850
851
852
853
854
/**
855
 * Meta Capability Map class for Edit type capabilities.
856
 * Any capability that is an edit type of capability utilizes this map.
857
 *
858
 * @since 4.5.0
859
 * @package Event Espresso
860
 * @subpackage core, capabilities
861
 * @author  Darren Ethier
862
 */
863
class EE_Meta_Capability_Map_Edit extends EE_Meta_Capability_Map {
864
865
	/**
866
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
867
	 *
868
	 * @since 4.5.0
869
	 * @see  wp-includes/capabilities.php
870
	 *
871
	 * @param array  $caps    actual users capabilities
872
	 * @param string $cap     initial capability name that is being checked (the "map" key)
873
	 * @param int     $user_id The user id
874
	 * @param array  $args    Adds context to the cap. Typically the object ID.
875
	 *
876
	 * @return array   actual users capabilities
877
	 */
878
	protected function _map_meta_caps( $caps, $cap, $user_id, $args ) {
879
		//only process if we're checking our mapped_cap
880
		if ( $cap !== $this->meta_cap ) {
881
			return $caps;
882
		}
883
884
		$obj = ! empty( $args[0] ) ? $this->_model->get_one_by_ID( $args[0] ) : null;
885
886
		//if no obj then let's just do cap
887
		if ( ! $obj instanceof EE_Base_Class ) {
888
			$caps[] = $cap;
889
			return $caps;
890
		}
891
892
		if ( $obj instanceof EE_CPT_Base ) {
893
			//if the item author is set and the user is the author...
894
			if ( $obj->wp_user() && $user_id == $obj->wp_user() ) {
895
				if ( empty( $this->published_cap ) ) {
896
					$caps[] = $cap;
897
				} else {
898
					//if obj is published...
899
					if ( $obj->status() == 'publish' ) {
900
						$caps[] = $this->published_cap;
901
					} else {
902
						$caps[] = $cap;
903
					}
904
				}
905
			} else {
906
				//the user is trying to edit someone else's obj
907
				if ( ! empty( $this->others_cap ) ) {
908
					$caps[] = $this->others_cap;
909
				}
910
				if ( ! empty( $this->published_cap ) && $obj->status() == 'publish' ) {
911
					$caps[] = $this->published_cap;
912
				} elseif ( ! empty( $this->private_cap ) && $obj->status() == 'private' ) {
913
					$caps[] = $this->private_cap;
914
				}
915
			}
916
		} else {
917
            //not a cpt object so handled differently
918
            $has_cap = false;
919
            try {
920
                $has_cap = method_exists($obj, 'wp_user') && $obj->wp_user() && $user_id == $obj->wp_user();
0 ignored issues
show
Documentation Bug introduced by
The method wp_user does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
921
            } catch (Exception $e) {
922
                if (WP_DEBUG) {
923
                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
924
                }
925
            }
926
			if ($has_cap) {
927
				$caps[] = $cap;
928
			} else {
929
				if ( ! empty( $this->others_cap ) ) {
930
					$caps[] = $this->others_cap;
931
				}
932
			}
933
		}
934
		return $caps;
935
	}
936
}
937
938
939
940
941
942
/**
943
 * Meta Capability Map class for delete type capabilities
944
 * Merely extends the Edit map.  Intention is for type hinting so it's clear a capability is a "delete" type of capability (in case mapping needs to change in the future)
945
 *
946
 * @since 4.5.0
947
 * @package Event Espresso
948
 * @subpackage core, capabilities
949
 * @author  Darren Ethier
950
 */
951
class EE_Meta_Capability_Map_Delete extends EE_Meta_Capability_Map_Edit {
952
953
	/**
954
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
955
	 *
956
	 * @since 4.5.0
957
	 * @see  wp-includes/capabilities.php
958
	 *
959
	 * @param array  $caps    actual users capabilities
960
	 * @param string $cap     initial capability name that is being checked (the "map" key)
961
	 * @param int     $user_id The user id
962
	 * @param array  $args    Adds context to the cap. Typically the object ID.
963
	 *
964
	 * @return array   actual users capabilities
965
	 */
966
	protected function _map_meta_caps( $caps, $cap, $user_id, $args ) {
967
		return parent::_map_meta_caps( $caps, $cap, $user_id, $args );
968
	}
969
}
970
971
972
973
974
975
/**
976
 * Meta Capability Map class for reads.
977
 * Maps any read meta capabilities to equivalents for context.
978
 *
979
 * @since 4.5.0
980
 * @package Event Espresso
981
 * @subpackage core, capabilities
982
 * @author  Darren Ethier
983
 */
984
class EE_Meta_Capability_Map_Read extends EE_Meta_Capability_Map {
985
986
	/**
987
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
988
	 *
989
	 * @since 4.5.0
990
	 * @see  wp-includes/capabilities.php
991
	 *
992
	 * @param array  $caps    actual users capabilities
993
	 * @param string $cap     initial capability name that is being checked (the "map" key)
994
	 * @param int     $user_id The user id
995
	 * @param array  $args    Adds context to the cap. Typically the object ID.
996
	 *
997
	 * @return array   actual users capabilities
998
	 */
999
	protected function _map_meta_caps( $caps, $cap, $user_id, $args ) {
1000
		//only process if we're checking our mapped cap;
1001
		if ( $cap !== $this->meta_cap ) {
1002
			return $caps;
1003
		}
1004
1005
		$obj = ! empty( $args[0] ) ? $this->_model->get_one_by_ID( $args[0] ) : null;
1006
1007
		//if no obj then let's just do cap
1008
		if ( ! $obj instanceof EE_Base_Class ) {
1009
			$caps[] = $cap;
1010
			return $caps;
1011
		}
1012
1013
		if ( $obj instanceof EE_CPT_Base ) {
1014
			$status_obj = get_post_status_object( $obj->status() );
1015
			if ( $status_obj->public ) {
1016
				$caps[] = $cap;
1017
				return $caps;
1018
			}
1019
1020
			//if the item author is set and the user is the author...
1021
			if ( $obj->wp_user() && $user_id == $obj->wp_user() ) {
1022
				$caps[] = $cap;
1023
			} elseif ( $status_obj->private && ! empty( $this->private_cap ) ) {
1024
				//the user is trying to view someone else's obj
1025
				$caps[] = $this->private_cap;
1026
			} elseif ( ! empty( $this->others_cap ) ) {
1027
				$caps[] = $this->others_cap;
1028
			} else {
1029
				$caps[] = $cap;
1030
			}
1031
		} else {
1032
            //not a cpt object so handled differently
1033
            $has_cap = false;
1034
            try {
1035
                $has_cap = method_exists($obj, 'wp_user') && $obj->wp_user() && $user_id == $obj->wp_user();
0 ignored issues
show
Documentation Bug introduced by
The method wp_user does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1036
            } catch (Exception $e) {
1037
                if (WP_DEBUG) {
1038
                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1039
                }
1040
            }
1041
			if ($has_cap) {
1042
				$caps[] = $cap;
1043
			} elseif ( ! empty( $this->private_cap ) ) {
1044
				$caps[] = $this->private_cap;
1045
			} elseif ( ! empty( $this->others_cap ) ) {
1046
				$caps[] = $this->others_cap;
1047
			} else {
1048
				$caps[] = $cap;
1049
			}
1050
		}
1051
		return $caps;
1052
	}
1053
}
1054
1055
1056
1057
1058
/**
1059
 * Meta Capability Map class for the messages component
1060
 * This is a special map due to messages having global and custom messages.  Only users with the edit_global_message capability should be able to do things with the global messages.
1061
 *
1062
 * @since 4.5.0
1063
 * @package Event Espresso
1064
 * @subpackage core, capabilities
1065
 * @author  Darren Ethier
1066
 */
1067
class EE_Meta_Capability_Map_Messages_Cap extends EE_Meta_Capability_Map {
1068
1069
	/**
1070
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1071
	 *
1072
	 * @since 4.5.0
1073
	 * @see  wp-includes/capabilities.php
1074
	 *
1075
	 * @param array  $caps    actual users capabilities
1076
	 * @param string $cap     initial capability name that is being checked (the "map" key)
1077
	 * @param int     $user_id The user id
1078
	 * @param array  $args    Adds context to the cap. Typically the object ID.
1079
	 *
1080
	 * @return array   actual users capabilities
1081
	 */
1082
	protected function _map_meta_caps( $caps, $cap, $user_id, $args ) {
1083
		//only process if we're checking our mapped_cap
1084
		if ( $cap !== $this->meta_cap ) {
1085
			return $caps;
1086
		}
1087
1088
		$obj = ! empty( $args[0] ) ? $this->_model->get_one_by_ID( $args[0] ) : null;
1089
1090
		//if no obj then let's just do cap
1091
		if ( ! $obj instanceof EE_Message_Template_Group ) {
1092
			$caps[] = $cap;
1093
			return $caps;
1094
		}
1095
1096
		$is_global = $obj->is_global();
1097
1098
		if ( $obj->wp_user() && $user_id == $obj->wp_user() ) {
1099
			if ( $is_global ) {
1100
				$caps[]  = $this->private_cap;
1101
			} else {
1102
				$caps[] = $cap;
1103
			}
1104
		} else {
1105
			if ( $is_global ) {
1106
				$caps[] = $this->private_cap;
1107
			} else {
1108
				$caps[] = $this->others_cap;
1109
			}
1110
		}
1111
1112
		return $caps;
1113
	}
1114
}
1115
1116
1117
1118
1119
/**
1120
 * Meta Capability Map class for the registration form (questions and question groups) component
1121
 * This is a special map due to questions and question groups having special "system" data.  Only users with the edit_system_question or edit_system_question_group capability should be able to do things with the system data.
1122
 *
1123
 * @since 4.5.0
1124
 * @package Event Espresso
1125
 * @subpackage core, capabilities
1126
 * @author  Darren Ethier
1127
 */
1128
class EE_Meta_Capability_Map_Registration_Form_Cap extends EE_Meta_Capability_Map {
1129
1130
	/**
1131
	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1132
	 *
1133
	 * @since 4.5.0
1134
	 * @see  wp-includes/capabilities.php
1135
	 *
1136
	 * @param array  $caps    actual users capabilities
1137
	 * @param string $cap     initial capability name that is being checked (the "map" key)
1138
	 * @param int     $user_id The user id
1139
	 * @param array  $args    Adds context to the cap. Typically the object ID.
1140
	 *
1141
	 * @return array   actual users capabilities
1142
	 */
1143
	protected function _map_meta_caps( $caps, $cap, $user_id, $args ) {
1144
		//only process if we're checking our mapped_cap
1145
		if ( $cap !== $this->meta_cap ) {
1146
			return $caps;
1147
		}
1148
1149
		$obj = ! empty( $args[0] ) ? $this->_model->get_one_by_ID( $args[0] ) : null;
1150
1151
		//if no obj then let's just do cap
1152
		if ( ! $obj instanceof EE_Base_Class ) {
1153
			$caps[] = $cap;
1154
			return $caps;
1155
		}
1156
1157
		$is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1158
		$is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1159
1160
		if ( $is_system ) {
1161
			$caps[] = $this->private_cap;
1162
		} else {
1163
			$caps[] = $cap;
1164
		}
1165
1166
		return $caps;
1167
	}
1168
}
1169