Completed
Pull Request — master (#1144)
by Darren
09:09
created
core/EE_Capabilities.core.php 1 patch
Indentation   +1369 added lines, -1369 removed lines patch added patch discarded remove patch
@@ -14,981 +14,981 @@  discard block
 block discarded – undo
14 14
 final class EE_Capabilities extends EE_Base
15 15
 {
16 16
 
17
-    /**
18
-     * the name of the wp option used to store caps previously initialized
19
-     */
20
-    const option_name = 'ee_caps_initialized';
21
-
22
-    /**
23
-     * instance of EE_Capabilities object
24
-     *
25
-     * @var EE_Capabilities
26
-     */
27
-    private static $_instance;
28
-
29
-
30
-    /**
31
-     * This is a map of caps that correspond to a default WP_Role.
32
-     * Array is indexed by Role and values are ee capabilities.
33
-     *
34
-     * @since 4.5.0
35
-     *
36
-     * @var array
37
-     */
38
-    private $capabilities_map = array();
39
-
40
-    /**
41
-     * This used to hold an array of EE_Meta_Capability_Map objects
42
-     * that define the granular capabilities mapped to for a user depending on context.
43
-     *
44
-     * @var EE_Meta_Capability_Map[]
45
-     */
46
-    private $_meta_caps = array();
47
-
48
-    /**
49
-     * The internal $capabilities_map needs to be initialized before it can be used.
50
-     * This flag tracks whether that has happened or not.
51
-     * But for this to work, we need three states to indicate:
52
-     *      initialization has not occurred at all
53
-     *      initialization has started but is not complete
54
-     *      initialization is complete
55
-     * The reason this is needed is because the addCaps() method
56
-     * normally requires the $capabilities_map to be initialized,
57
-     * but is also used during the initialization process.
58
-     * So:
59
-     *      If initialized === null, init_caps() will be called before any other methods will run.
60
-     *      If initialized === false, then init_caps() is in the process of running it's logic.
61
-     *      If initialized === true, then init_caps() has completed the initialization process.
62
-     *
63
-     * @var boolean|null $initialized
64
-     */
65
-    private $initialized;
66
-
67
-    /**
68
-     * @var boolean $reset
69
-     */
70
-    private $reset = false;
71
-
72
-
73
-    /**
74
-     * singleton method used to instantiate class object
75
-     *
76
-     * @since 4.5.0
77
-     *
78
-     * @return EE_Capabilities
79
-     */
80
-    public static function instance()
81
-    {
82
-        // check if instantiated, and if not do so.
83
-        if (! self::$_instance instanceof EE_Capabilities) {
84
-            self::$_instance = new self();
85
-        }
86
-        return self::$_instance;
87
-    }
88
-
89
-
90
-    /**
91
-     * private constructor
92
-     *
93
-     * @since 4.5.0
94
-     */
95
-    private function __construct()
96
-    {
97
-    }
98
-
99
-
100
-    /**
101
-     * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
102
-     *
103
-     * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't
104
-     *                    actually REMOVE any capabilities from existing roles, it just resaves defaults roles and
105
-     *                    ensures that they are up to date.
106
-     *
107
-     * @since 4.5.0
108
-     * @return bool
109
-     * @throws EE_Error
110
-     */
111
-    public function init_caps($reset = false)
112
-    {
113
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
114
-            return false;
115
-        }
116
-        $this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
117
-        // if reset, then completely delete the cache option and clear the $capabilities_map property.
118
-        if ($this->reset) {
119
-            $this->initialized = null;
120
-            $this->capabilities_map = array();
121
-            delete_option(self::option_name);
122
-        }
123
-        if ($this->initialized === null) {
124
-            $this->initialized = false;
125
-            do_action(
126
-                'AHEE__EE_Capabilities__init_caps__before_initialization',
127
-                $this->reset
128
-            );
129
-            $this->addCaps($this->_init_caps_map());
130
-            $this->_set_meta_caps();
131
-            do_action(
132
-                'AHEE__EE_Capabilities__init_caps__after_initialization',
133
-                $this->capabilities_map
134
-            );
135
-            $this->initialized = true;
136
-        }
137
-        // reset $this->reset so that it's not stuck on true if init_caps() gets called again
138
-        $this->reset = false;
139
-        return true;
140
-    }
141
-
142
-
143
-    /**
144
-     * This sets the meta caps property.
145
-     *
146
-     * @since 4.5.0
147
-     * @return void
148
-     * @throws EE_Error
149
-     */
150
-    private function _set_meta_caps()
151
-    {
152
-        // get default meta caps and filter the returned array
153
-        $this->_meta_caps = apply_filters(
154
-            'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
155
-            $this->_get_default_meta_caps_array()
156
-        );
157
-        // add filter for map_meta_caps but only if models can query.
158
-        if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
159
-            add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
160
-        }
161
-    }
162
-
163
-
164
-    /**
165
-     * This builds and returns the default meta_caps array only once.
166
-     *
167
-     * @since  4.8.28.rc.012
168
-     * @return array
169
-     * @throws EE_Error
170
-     */
171
-    private function _get_default_meta_caps_array()
172
-    {
173
-        static $default_meta_caps = array();
174
-        // make sure we're only ever initializing the default _meta_caps array once if it's empty.
175
-        if (empty($default_meta_caps)) {
176
-            $default_meta_caps = array(
177
-                // edits
178
-                new EE_Meta_Capability_Map_Edit(
179
-                    'ee_edit_event',
180
-                    array('Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events')
181
-                ),
182
-                new EE_Meta_Capability_Map_Edit(
183
-                    'ee_edit_venue',
184
-                    array('Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues')
185
-                ),
186
-                new EE_Meta_Capability_Map_Edit(
187
-                    'ee_edit_registration',
188
-                    array('Registration', '', 'ee_edit_others_registrations', '')
189
-                ),
190
-                new EE_Meta_Capability_Map_Edit(
191
-                    'ee_edit_checkin',
192
-                    array('Registration', '', 'ee_edit_others_checkins', '')
193
-                ),
194
-                new EE_Meta_Capability_Map_Messages_Cap(
195
-                    'ee_edit_message',
196
-                    array('Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages')
197
-                ),
198
-                new EE_Meta_Capability_Map_Edit(
199
-                    'ee_edit_default_ticket',
200
-                    array('Ticket', '', 'ee_edit_others_default_tickets', '')
201
-                ),
202
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
203
-                    'ee_edit_question',
204
-                    array('Question', '', '', 'ee_edit_system_questions')
205
-                ),
206
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
207
-                    'ee_edit_question_group',
208
-                    array('Question_Group', '', '', 'ee_edit_system_question_groups')
209
-                ),
210
-                new EE_Meta_Capability_Map_Edit(
211
-                    'ee_edit_payment_method',
212
-                    array('Payment_Method', '', 'ee_edit_others_payment_methods', '')
213
-                ),
214
-                // reads
215
-                new EE_Meta_Capability_Map_Read(
216
-                    'ee_read_event',
217
-                    array('Event', '', 'ee_read_others_events', 'ee_read_private_events')
218
-                ),
219
-                new EE_Meta_Capability_Map_Read(
220
-                    'ee_read_venue',
221
-                    array('Venue', '', 'ee_read_others_venues', 'ee_read_private_venues')
222
-                ),
223
-                new EE_Meta_Capability_Map_Read(
224
-                    'ee_read_registration',
225
-                    array('Registration', '', 'ee_read_others_registrations', '')
226
-                ),
227
-                new EE_Meta_Capability_Map_Read(
228
-                    'ee_read_checkin',
229
-                    array('Registration', '', 'ee_read_others_checkins', '')
230
-                ),
231
-                new EE_Meta_Capability_Map_Messages_Cap(
232
-                    'ee_read_message',
233
-                    array('Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages')
234
-                ),
235
-                new EE_Meta_Capability_Map_Read(
236
-                    'ee_read_default_ticket',
237
-                    array('Ticket', '', 'ee_read_others_default_tickets', '')
238
-                ),
239
-                new EE_Meta_Capability_Map_Read(
240
-                    'ee_read_payment_method',
241
-                    array('Payment_Method', '', 'ee_read_others_payment_methods', '')
242
-                ),
243
-                // deletes
244
-                new EE_Meta_Capability_Map_Delete(
245
-                    'ee_delete_event',
246
-                    array(
247
-                        'Event',
248
-                        'ee_delete_published_events',
249
-                        'ee_delete_others_events',
250
-                        'ee_delete_private_events',
251
-                    )
252
-                ),
253
-                new EE_Meta_Capability_Map_Delete(
254
-                    'ee_delete_venue',
255
-                    array(
256
-                        'Venue',
257
-                        'ee_delete_published_venues',
258
-                        'ee_delete_others_venues',
259
-                        'ee_delete_private_venues',
260
-                    )
261
-                ),
262
-                new EE_Meta_Capability_Map_Delete(
263
-                    'ee_delete_registration',
264
-                    array('Registration', '', 'ee_delete_others_registrations', '')
265
-                ),
266
-                new EE_Meta_Capability_Map_Delete(
267
-                    'ee_delete_checkin',
268
-                    array('Registration', '', 'ee_delete_others_checkins', '')
269
-                ),
270
-                new EE_Meta_Capability_Map_Messages_Cap(
271
-                    'ee_delete_message',
272
-                    array('Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages')
273
-                ),
274
-                new EE_Meta_Capability_Map_Delete(
275
-                    'ee_delete_default_ticket',
276
-                    array('Ticket', '', 'ee_delete_others_default_tickets', '')
277
-                ),
278
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
279
-                    'ee_delete_question',
280
-                    array('Question', '', '', 'delete_system_questions')
281
-                ),
282
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
283
-                    'ee_delete_question_group',
284
-                    array('Question_Group', '', '', 'delete_system_question_groups')
285
-                ),
286
-                new EE_Meta_Capability_Map_Delete(
287
-                    'ee_delete_payment_method',
288
-                    array('Payment_Method', '', 'ee_delete_others_payment_methods', '')
289
-                ),
290
-            );
291
-        }
292
-        return $default_meta_caps;
293
-    }
294
-
295
-
296
-    /**
297
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
298
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
299
-     *
300
-     * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
301
-     *
302
-     * @since 4.5.0
303
-     * @see   wp-includes/capabilities.php
304
-     *
305
-     * @param array  $caps    actual users capabilities
306
-     * @param string $cap     initial capability name that is being checked (the "map" key)
307
-     * @param int    $user_id The user id
308
-     * @param array  $args    Adds context to the cap. Typically the object ID.
309
-     * @return array actual users capabilities
310
-     * @throws EE_Error
311
-     */
312
-    public function map_meta_caps($caps, $cap, $user_id, $args)
313
-    {
314
-        if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
315
-            // loop through our _meta_caps array
316
-            foreach ($this->_meta_caps as $meta_map) {
317
-                if (! $meta_map instanceof EE_Meta_Capability_Map) {
318
-                    continue;
319
-                }
320
-                // don't load models if there is no object ID in the args
321
-                if (! empty($args[0])) {
322
-                    $meta_map->ensure_is_model();
323
-                }
324
-                $caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
325
-            }
326
-        }
327
-        return $caps;
328
-    }
329
-
330
-
331
-    /**
332
-     * This sets up and returns the initial capabilities map for Event Espresso
333
-     * Note this array is filtered.
334
-     * It is assumed that all available EE capabilities are assigned to the administrator role.
335
-     *
336
-     * @since 4.5.0
337
-     *
338
-     * @return array
339
-     */
340
-    private function _init_caps_map()
341
-    {
342
-        return apply_filters(
343
-            'FHEE__EE_Capabilities__init_caps_map__caps',
344
-            array(
345
-                'administrator'           => array(
346
-                    // basic access
347
-                    'ee_read_ee',
348
-                    // gateways
349
-                    /**
350
-                     * note that with payment method capabilities, although we've implemented
351
-                     * capability mapping which will be used for accessing payment methods owned by
352
-                     * other users.  This is not fully implemented yet in the payment method ui.
353
-                     * Currently only the "plural" caps are in active use.
354
-                     * (Specific payment method caps are in use as well).
355
-                     **/
356
-                    'ee_manage_gateways',
357
-                    'ee_read_payment_methods',
358
-                    'ee_read_others_payment_methods',
359
-                    'ee_edit_payment_methods',
360
-                    'ee_edit_others_payment_methods',
361
-                    'ee_delete_payment_methods',
362
-                    // events
363
-                    'ee_publish_events',
364
-                    'ee_read_private_events',
365
-                    'ee_read_others_events',
366
-                    'ee_read_events',
367
-                    'ee_edit_events',
368
-                    'ee_edit_published_events',
369
-                    'ee_edit_others_events',
370
-                    'ee_edit_private_events',
371
-                    'ee_delete_published_events',
372
-                    'ee_delete_private_events',
373
-                    'ee_delete_events',
374
-                    'ee_delete_others_events',
375
-                    // event categories
376
-                    'ee_manage_event_categories',
377
-                    'ee_edit_event_category',
378
-                    'ee_delete_event_category',
379
-                    'ee_assign_event_category',
380
-                    // venues
381
-                    'ee_publish_venues',
382
-                    'ee_read_venues',
383
-                    'ee_read_others_venues',
384
-                    'ee_read_private_venues',
385
-                    'ee_edit_venues',
386
-                    'ee_edit_others_venues',
387
-                    'ee_edit_published_venues',
388
-                    'ee_edit_private_venues',
389
-                    'ee_delete_venues',
390
-                    'ee_delete_others_venues',
391
-                    'ee_delete_private_venues',
392
-                    'ee_delete_published_venues',
393
-                    // venue categories
394
-                    'ee_manage_venue_categories',
395
-                    'ee_edit_venue_category',
396
-                    'ee_delete_venue_category',
397
-                    'ee_assign_venue_category',
398
-                    // contacts
399
-                    'ee_read_contacts',
400
-                    'ee_edit_contacts',
401
-                    'ee_delete_contacts',
402
-                    // registrations
403
-                    'ee_read_registrations',
404
-                    'ee_read_others_registrations',
405
-                    'ee_edit_registrations',
406
-                    'ee_edit_others_registrations',
407
-                    'ee_delete_registrations',
408
-                    'ee_delete_others_registrations',
409
-                    // checkins
410
-                    'ee_read_others_checkins',
411
-                    'ee_read_checkins',
412
-                    'ee_edit_checkins',
413
-                    'ee_edit_others_checkins',
414
-                    'ee_delete_checkins',
415
-                    'ee_delete_others_checkins',
416
-                    // transactions && payments
417
-                    'ee_read_transaction',
418
-                    'ee_read_transactions',
419
-                    'ee_edit_payments',
420
-                    'ee_delete_payments',
421
-                    // messages
422
-                    'ee_read_messages',
423
-                    'ee_read_others_messages',
424
-                    'ee_read_global_messages',
425
-                    'ee_edit_global_messages',
426
-                    'ee_edit_messages',
427
-                    'ee_edit_others_messages',
428
-                    'ee_delete_messages',
429
-                    'ee_delete_others_messages',
430
-                    'ee_delete_global_messages',
431
-                    'ee_send_message',
432
-                    // tickets
433
-                    'ee_read_default_tickets',
434
-                    'ee_read_others_default_tickets',
435
-                    'ee_edit_default_tickets',
436
-                    'ee_edit_others_default_tickets',
437
-                    'ee_delete_default_tickets',
438
-                    'ee_delete_others_default_tickets',
439
-                    // prices
440
-                    'ee_edit_default_price',
441
-                    'ee_edit_default_prices',
442
-                    'ee_delete_default_price',
443
-                    'ee_delete_default_prices',
444
-                    'ee_edit_default_price_type',
445
-                    'ee_edit_default_price_types',
446
-                    'ee_delete_default_price_type',
447
-                    'ee_delete_default_price_types',
448
-                    'ee_read_default_prices',
449
-                    'ee_read_default_price_types',
450
-                    // registration form
451
-                    'ee_edit_questions',
452
-                    'ee_edit_system_questions',
453
-                    'ee_read_questions',
454
-                    'ee_delete_questions',
455
-                    'ee_edit_question_groups',
456
-                    'ee_read_question_groups',
457
-                    'ee_edit_system_question_groups',
458
-                    'ee_delete_question_groups',
459
-                    // event_type taxonomy
460
-                    'ee_assign_event_type',
461
-                    'ee_manage_event_types',
462
-                    'ee_edit_event_type',
463
-                    'ee_delete_event_type',
464
-                ),
465
-                'ee_events_administrator' => array(
466
-                    // core wp caps
467
-                    'read',
468
-                    'read_private_pages',
469
-                    'read_private_posts',
470
-                    'edit_users',
471
-                    'edit_posts',
472
-                    'edit_pages',
473
-                    'edit_published_posts',
474
-                    'edit_published_pages',
475
-                    'edit_private_pages',
476
-                    'edit_private_posts',
477
-                    'edit_others_posts',
478
-                    'edit_others_pages',
479
-                    'publish_posts',
480
-                    'publish_pages',
481
-                    'delete_posts',
482
-                    'delete_pages',
483
-                    'delete_private_pages',
484
-                    'delete_private_posts',
485
-                    'delete_published_pages',
486
-                    'delete_published_posts',
487
-                    'delete_others_posts',
488
-                    'delete_others_pages',
489
-                    'manage_categories',
490
-                    'manage_links',
491
-                    'moderate_comments',
492
-                    'unfiltered_html',
493
-                    'upload_files',
494
-                    'export',
495
-                    'import',
496
-                    'list_users',
497
-                    'level_1', // required if user with this role shows up in author dropdowns
498
-                    // basic ee access
499
-                    'ee_read_ee',
500
-                    // events
501
-                    'ee_publish_events',
502
-                    'ee_read_private_events',
503
-                    'ee_read_others_events',
504
-                    'ee_read_event',
505
-                    'ee_read_events',
506
-                    'ee_edit_event',
507
-                    'ee_edit_events',
508
-                    'ee_edit_published_events',
509
-                    'ee_edit_others_events',
510
-                    'ee_edit_private_events',
511
-                    'ee_delete_published_events',
512
-                    'ee_delete_private_events',
513
-                    'ee_delete_event',
514
-                    'ee_delete_events',
515
-                    'ee_delete_others_events',
516
-                    // event categories
517
-                    'ee_manage_event_categories',
518
-                    'ee_edit_event_category',
519
-                    'ee_delete_event_category',
520
-                    'ee_assign_event_category',
521
-                    // venues
522
-                    'ee_publish_venues',
523
-                    'ee_read_venue',
524
-                    'ee_read_venues',
525
-                    'ee_read_others_venues',
526
-                    'ee_read_private_venues',
527
-                    'ee_edit_venue',
528
-                    'ee_edit_venues',
529
-                    'ee_edit_others_venues',
530
-                    'ee_edit_published_venues',
531
-                    'ee_edit_private_venues',
532
-                    'ee_delete_venue',
533
-                    'ee_delete_venues',
534
-                    'ee_delete_others_venues',
535
-                    'ee_delete_private_venues',
536
-                    'ee_delete_published_venues',
537
-                    // venue categories
538
-                    'ee_manage_venue_categories',
539
-                    'ee_edit_venue_category',
540
-                    'ee_delete_venue_category',
541
-                    'ee_assign_venue_category',
542
-                    // contacts
543
-                    'ee_read_contacts',
544
-                    'ee_edit_contacts',
545
-                    'ee_delete_contacts',
546
-                    // registrations
547
-                    'ee_read_registrations',
548
-                    'ee_read_others_registrations',
549
-                    'ee_edit_registration',
550
-                    'ee_edit_registrations',
551
-                    'ee_edit_others_registrations',
552
-                    'ee_delete_registration',
553
-                    'ee_delete_registrations',
554
-                    'ee_delete_others_registrations',
555
-                    // checkins
556
-                    'ee_read_others_checkins',
557
-                    'ee_read_checkins',
558
-                    'ee_edit_checkins',
559
-                    'ee_edit_others_checkins',
560
-                    'ee_delete_checkins',
561
-                    'ee_delete_others_checkins',
562
-                    // transactions && payments
563
-                    'ee_read_transaction',
564
-                    'ee_read_transactions',
565
-                    'ee_edit_payments',
566
-                    'ee_delete_payments',
567
-                    // messages
568
-                    'ee_read_messages',
569
-                    'ee_read_others_messages',
570
-                    'ee_read_global_messages',
571
-                    'ee_edit_global_messages',
572
-                    'ee_edit_messages',
573
-                    'ee_edit_others_messages',
574
-                    'ee_delete_messages',
575
-                    'ee_delete_others_messages',
576
-                    'ee_delete_global_messages',
577
-                    'ee_send_message',
578
-                    // tickets
579
-                    'ee_read_default_tickets',
580
-                    'ee_read_others_default_tickets',
581
-                    'ee_edit_default_tickets',
582
-                    'ee_edit_others_default_tickets',
583
-                    'ee_delete_default_tickets',
584
-                    'ee_delete_others_default_tickets',
585
-                    // prices
586
-                    'ee_edit_default_price',
587
-                    'ee_edit_default_prices',
588
-                    'ee_delete_default_price',
589
-                    'ee_delete_default_prices',
590
-                    'ee_edit_default_price_type',
591
-                    'ee_edit_default_price_types',
592
-                    'ee_delete_default_price_type',
593
-                    'ee_delete_default_price_types',
594
-                    'ee_read_default_prices',
595
-                    'ee_read_default_price_types',
596
-                    // registration form
597
-                    'ee_edit_questions',
598
-                    'ee_edit_system_questions',
599
-                    'ee_read_questions',
600
-                    'ee_delete_questions',
601
-                    'ee_edit_question_groups',
602
-                    'ee_read_question_groups',
603
-                    'ee_edit_system_question_groups',
604
-                    'ee_delete_question_groups',
605
-                    // event_type taxonomy
606
-                    'ee_assign_event_type',
607
-                    'ee_manage_event_types',
608
-                    'ee_edit_event_type',
609
-                    'ee_delete_event_type',
610
-                ),
611
-            )
612
-        );
613
-    }
614
-
615
-
616
-    /**
617
-     * @return bool
618
-     * @throws EE_Error
619
-     */
620
-    private function setupCapabilitiesMap()
621
-    {
622
-        // if the initialization process hasn't even started, then we need to call init_caps()
623
-        if ($this->initialized === null) {
624
-            return $this->init_caps();
625
-        }
626
-        // unless resetting, get caps from db if we haven't already
627
-        $this->capabilities_map = $this->reset || ! empty($this->capabilities_map)
628
-            ? $this->capabilities_map
629
-            : get_option(self::option_name, array());
630
-        return true;
631
-    }
632
-
633
-
634
-    /**
635
-     * @param bool $update
636
-     * @return bool
637
-     */
638
-    private function updateCapabilitiesMap($update = true)
639
-    {
640
-        return $update ? update_option(self::option_name, $this->capabilities_map) : false;
641
-    }
642
-
643
-
644
-    /**
645
-     * Adds capabilities to roles.
646
-     *
647
-     * @since 4.9.42
648
-     * @param array $capabilities_to_add array of capabilities to add, indexed by roles.
649
-     *                                   Note that this should ONLY be called on activation hook
650
-     *                                   otherwise the caps will be added on every request.
651
-     * @return bool
652
-     * @throws \EE_Error
653
-     */
654
-    public function addCaps(array $capabilities_to_add)
655
-    {
656
-        // don't do anything if the capabilities map can not be initialized
657
-        if (! $this->setupCapabilitiesMap()) {
658
-            return false;
659
-        }
660
-        // and filter the array so others can get in on the fun during resets
661
-        $capabilities_to_add = apply_filters(
662
-            'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
663
-            $capabilities_to_add,
664
-            $this->reset,
665
-            $this->capabilities_map
666
-        );
667
-        $update_capabilities_map = false;
668
-        // if not reset, see what caps are new for each role. if they're new, add them.
669
-        foreach ($capabilities_to_add as $role => $caps_for_role) {
670
-            if (is_array($caps_for_role)) {
671
-                foreach ($caps_for_role as $cap) {
672
-                    if (! $this->capHasBeenAddedToRole($role, $cap)
673
-                        && $this->add_cap_to_role($role, $cap, true, false)
674
-                    ) {
675
-                        $update_capabilities_map = true;
676
-                    }
677
-                }
678
-            }
679
-        }
680
-        // now let's just save the cap that has been set but only if there's been a change.
681
-        $updated = $this->updateCapabilitiesMap($update_capabilities_map);
682
-        $this->flushWpUser($updated);
683
-        do_action('AHEE__EE_Capabilities__addCaps__complete', $this->capabilities_map, $updated);
684
-        return $updated;
685
-    }
686
-
687
-
688
-    /**
689
-     * Loops through the capabilities map and removes the role caps specified by the incoming array
690
-     *
691
-     * @param array $caps_map map of capabilities to be removed (indexed by roles)
692
-     * @return bool
693
-     * @throws \EE_Error
694
-     */
695
-    public function removeCaps($caps_map)
696
-    {
697
-        // don't do anything if the capabilities map can not be initialized
698
-        if (! $this->setupCapabilitiesMap()) {
699
-            return false;
700
-        }
701
-        $update_capabilities_map = false;
702
-        foreach ($caps_map as $role => $caps_for_role) {
703
-            if (is_array($caps_for_role)) {
704
-                foreach ($caps_for_role as $cap) {
705
-                    if ($this->capHasBeenAddedToRole($role, $cap)
706
-                        && $this->remove_cap_from_role($role, $cap, false)
707
-                    ) {
708
-                        $update_capabilities_map = true;
709
-                    }
710
-                }
711
-            }
712
-        }
713
-        // maybe resave the caps
714
-        $updated = $this->updateCapabilitiesMap($update_capabilities_map);
715
-        $this->flushWpUser($updated);
716
-        return $updated;
717
-    }
718
-
719
-
720
-    /**
721
-     * This ensures that the WP User object cached on the $current_user global in WP has the latest capabilities from
722
-     * the roles on that user.
723
-     *
724
-     * @param bool $flush Default is to flush the WP_User object.  If false, then this method effectively does nothing.
725
-     */
726
-    private function flushWpUser($flush = true)
727
-    {
728
-        if ($flush) {
729
-            $user = wp_get_current_user();
730
-            if ($user instanceof WP_User) {
731
-                $user->get_role_caps();
732
-            }
733
-        }
734
-    }
735
-
736
-
737
-    /**
738
-     * This method sets a capability on a role.  Note this should only be done on activation, or if you have something
739
-     * specific to prevent the cap from being added on every page load (adding caps are persistent to the db). Note.
740
-     * this is a wrapper for $wp_role->add_cap()
741
-     *
742
-     * @see   wp-includes/capabilities.php
743
-     * @since 4.5.0
744
-     * @param string|WP_Role $role  A WordPress role the capability is being added to
745
-     * @param string         $cap   The capability being added to the role
746
-     * @param bool           $grant Whether to grant access to this cap on this role.
747
-     * @param bool           $update_capabilities_map
748
-     * @return bool
749
-     * @throws \EE_Error
750
-     */
751
-    public function add_cap_to_role($role, $cap, $grant = true, $update_capabilities_map = true)
752
-    {
753
-        // capture incoming value for $role because we may need it to create a new WP_Role
754
-        $orig_role = $role;
755
-        $role = $role instanceof WP_Role ? $role : get_role($role);
756
-        // if the role isn't available then we create it.
757
-        if (! $role instanceof WP_Role) {
758
-            // if a plugin wants to create a specific role name then they should create the role before
759
-            // EE_Capabilities does.  Otherwise this function will create the role name from the slug:
760
-            // - removes any `ee_` namespacing from the start of the slug.
761
-            // - replaces `_` with ` ` (empty space).
762
-            // - sentence case on the resulting string.
763
-            $role_label = ucwords(str_replace(array('ee_', '_'), array('', ' '), $orig_role));
764
-            $role = add_role($orig_role, $role_label);
765
-        }
766
-        if ($role instanceof WP_Role) {
767
-            // don't do anything if the capabilities map can not be initialized
768
-            if (! $this->setupCapabilitiesMap()) {
769
-                return false;
770
-            }
771
-            if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
772
-                $role->add_cap($cap, $grant);
773
-                $this->capabilities_map[ $role->name ][] = $cap;
774
-                $this->updateCapabilitiesMap($update_capabilities_map);
775
-                return true;
776
-            }
777
-        }
778
-        return false;
779
-    }
780
-
781
-
782
-    /**
783
-     * Functions similarly to add_cap_to_role except removes cap from given role.
784
-     * Wrapper for $wp_role->remove_cap()
785
-     *
786
-     * @see   wp-includes/capabilities.php
787
-     * @since 4.5.0
788
-     * @param string|WP_Role $role A WordPress role the capability is being removed from.
789
-     * @param string         $cap  The capability being removed
790
-     * @param bool           $update_capabilities_map
791
-     * @return bool
792
-     * @throws \EE_Error
793
-     */
794
-    public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
795
-    {
796
-        // don't do anything if the capabilities map can not be initialized
797
-        if (! $this->setupCapabilitiesMap()) {
798
-            return false;
799
-        }
800
-
801
-        $role = $role instanceof WP_Role ? $role : get_role($role);
802
-        if ($role instanceof WP_Role && $index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
803
-            $role->remove_cap($cap);
804
-            unset($this->capabilities_map[ $role->name ][ $index ]);
805
-            $this->updateCapabilitiesMap($update_capabilities_map);
806
-            return true;
807
-        }
808
-        return false;
809
-    }
810
-
811
-
812
-    /**
813
-     * @param string $role_name
814
-     * @param string $cap
815
-     * @param bool   $get_index
816
-     * @return bool|mixed
817
-     */
818
-    private function capHasBeenAddedToRole($role_name = '', $cap = '', $get_index = false)
819
-    {
820
-        if (isset($this->capabilities_map[ $role_name ])
821
-            && ($index = array_search($cap, $this->capabilities_map[ $role_name ], true)) !== false
822
-        ) {
823
-            return $get_index ? $index : true;
824
-        }
825
-        return false;
826
-    }
827
-
828
-
829
-    /**
830
-     * Wrapper for the native WP current_user_can() method.
831
-     * This is provided as a handy method for a couple things:
832
-     * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
833
-     * write those filters wherever current_user_can is called).
834
-     * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
835
-     *
836
-     * @since 4.5.0
837
-     *
838
-     * @param string $cap     The cap being checked.
839
-     * @param string $context The context where the current_user_can is being called from.
840
-     * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
841
-     *                        filters.
842
-     *
843
-     * @return bool  Whether user can or not.
844
-     */
845
-    public function current_user_can($cap, $context, $id = 0)
846
-    {
847
-        // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
848
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
849
-        $filtered_cap = apply_filters(
850
-            'FHEE__EE_Capabilities__current_user_can__cap',
851
-            $filtered_cap,
852
-            $context,
853
-            $cap,
854
-            $id
855
-        );
856
-        return ! empty($id)
857
-            ? current_user_can($filtered_cap, $id)
858
-            : current_user_can($filtered_cap);
859
-    }
860
-
861
-
862
-    /**
863
-     * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
864
-     *
865
-     * @param int|WP_User $user    Either the user_id or a WP_User object
866
-     * @param string      $cap     The capability string being checked
867
-     * @param string      $context The context where the user_can is being called from (used in filters).
868
-     * @param int         $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap()
869
-     *                             filters)
870
-     *
871
-     * @return bool Whether user can or not.
872
-     */
873
-    public function user_can($user, $cap, $context, $id = 0)
874
-    {
875
-        // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
876
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
877
-        $filtered_cap = apply_filters(
878
-            'FHEE__EE_Capabilities__user_can__cap',
879
-            $filtered_cap,
880
-            $context,
881
-            $cap,
882
-            $user,
883
-            $id
884
-        );
885
-        return ! empty($id)
886
-            ? user_can($user, $filtered_cap, $id)
887
-            : user_can($user, $filtered_cap);
888
-    }
889
-
890
-
891
-    /**
892
-     * Wrapper for the native WP current_user_can_for_blog() method.
893
-     * This is provided as a handy method for a couple things:
894
-     * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
895
-     * write those filters wherever current_user_can is called).
896
-     * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
897
-     *
898
-     * @since 4.5.0
899
-     *
900
-     * @param int    $blog_id The blog id that is being checked for.
901
-     * @param string $cap     The cap being checked.
902
-     * @param string $context The context where the current_user_can is being called from.
903
-     * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
904
-     *                        filters.
905
-     *
906
-     * @return bool  Whether user can or not.
907
-     */
908
-    public function current_user_can_for_blog($blog_id, $cap, $context, $id = 0)
909
-    {
910
-        $user_can = ! empty($id)
911
-            ? current_user_can_for_blog($blog_id, $cap, $id)
912
-            : current_user_can($blog_id, $cap);
913
-        // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
914
-        $user_can = apply_filters(
915
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
916
-            $user_can,
917
-            $blog_id,
918
-            $cap,
919
-            $id
920
-        );
921
-        $user_can = apply_filters(
922
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can',
923
-            $user_can,
924
-            $context,
925
-            $blog_id,
926
-            $cap,
927
-            $id
928
-        );
929
-        return $user_can;
930
-    }
931
-
932
-
933
-    /**
934
-     * This helper method just returns an array of registered EE capabilities.
935
-     *
936
-     * @since 4.5.0
937
-     * @param string $role If empty then the entire role/capability map is returned.
938
-     *                     Otherwise just the capabilities for the given role are returned.
939
-     * @return array
940
-     * @throws EE_Error
941
-     */
942
-    public function get_ee_capabilities($role = 'administrator')
943
-    {
944
-        if (! $this->initialized) {
945
-            $this->init_caps();
946
-        }
947
-        if (empty($role)) {
948
-            return $this->capabilities_map;
949
-        }
950
-        return isset($this->capabilities_map[ $role ])
951
-            ? $this->capabilities_map[ $role ]
952
-            : array();
953
-    }
954
-
955
-
956
-    /**
957
-     * @deprecated 4.9.42
958
-     * @param bool  $reset      If you need to reset Event Espresso's capabilities,
959
-     *                          then please use the init_caps() method with the "$reset" parameter set to "true"
960
-     * @param array $caps_map   Optional.
961
-     *                          Can be used to send a custom map of roles and capabilities for setting them up.
962
-     *                          Note that this should ONLY be called on activation hook or some other one-time
963
-     *                          task otherwise the caps will be added on every request.
964
-     * @return void
965
-     * @throws EE_Error
966
-     */
967
-    public function init_role_caps($reset = false, $caps_map = array())
968
-    {
969
-        // If this method is called directly and reset is set as 'true',
970
-        // then display a doing it wrong notice, because we want resets to go through init_caps()
971
-        // to guarantee that everything is set up correctly.
972
-        // This prevents the capabilities map getting reset incorrectly by direct calls to this method.
973
-        if ($reset) {
974
-            EE_Error::doing_it_wrong(
975
-                __METHOD__,
976
-                sprintf(
977
-                    esc_html__(
978
-                        'The "%1$s" parameter for the "%2$s" method is deprecated. If you need to reset Event Espresso\'s capabilities, then please use the "%3$s" method with the "%1$s" parameter set to "%4$s".',
979
-                        'event_espresso'
980
-                    ),
981
-                    '$reset',
982
-                    __METHOD__ . '()',
983
-                    'EE_Capabilities::init_caps()',
984
-                    'true'
985
-                ),
986
-                '4.9.42',
987
-                '5.0.0'
988
-            );
989
-        }
990
-        $this->addCaps($caps_map);
991
-    }
17
+	/**
18
+	 * the name of the wp option used to store caps previously initialized
19
+	 */
20
+	const option_name = 'ee_caps_initialized';
21
+
22
+	/**
23
+	 * instance of EE_Capabilities object
24
+	 *
25
+	 * @var EE_Capabilities
26
+	 */
27
+	private static $_instance;
28
+
29
+
30
+	/**
31
+	 * This is a map of caps that correspond to a default WP_Role.
32
+	 * Array is indexed by Role and values are ee capabilities.
33
+	 *
34
+	 * @since 4.5.0
35
+	 *
36
+	 * @var array
37
+	 */
38
+	private $capabilities_map = array();
39
+
40
+	/**
41
+	 * This used to hold an array of EE_Meta_Capability_Map objects
42
+	 * that define the granular capabilities mapped to for a user depending on context.
43
+	 *
44
+	 * @var EE_Meta_Capability_Map[]
45
+	 */
46
+	private $_meta_caps = array();
47
+
48
+	/**
49
+	 * The internal $capabilities_map needs to be initialized before it can be used.
50
+	 * This flag tracks whether that has happened or not.
51
+	 * But for this to work, we need three states to indicate:
52
+	 *      initialization has not occurred at all
53
+	 *      initialization has started but is not complete
54
+	 *      initialization is complete
55
+	 * The reason this is needed is because the addCaps() method
56
+	 * normally requires the $capabilities_map to be initialized,
57
+	 * but is also used during the initialization process.
58
+	 * So:
59
+	 *      If initialized === null, init_caps() will be called before any other methods will run.
60
+	 *      If initialized === false, then init_caps() is in the process of running it's logic.
61
+	 *      If initialized === true, then init_caps() has completed the initialization process.
62
+	 *
63
+	 * @var boolean|null $initialized
64
+	 */
65
+	private $initialized;
66
+
67
+	/**
68
+	 * @var boolean $reset
69
+	 */
70
+	private $reset = false;
71
+
72
+
73
+	/**
74
+	 * singleton method used to instantiate class object
75
+	 *
76
+	 * @since 4.5.0
77
+	 *
78
+	 * @return EE_Capabilities
79
+	 */
80
+	public static function instance()
81
+	{
82
+		// check if instantiated, and if not do so.
83
+		if (! self::$_instance instanceof EE_Capabilities) {
84
+			self::$_instance = new self();
85
+		}
86
+		return self::$_instance;
87
+	}
88
+
89
+
90
+	/**
91
+	 * private constructor
92
+	 *
93
+	 * @since 4.5.0
94
+	 */
95
+	private function __construct()
96
+	{
97
+	}
98
+
99
+
100
+	/**
101
+	 * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
102
+	 *
103
+	 * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't
104
+	 *                    actually REMOVE any capabilities from existing roles, it just resaves defaults roles and
105
+	 *                    ensures that they are up to date.
106
+	 *
107
+	 * @since 4.5.0
108
+	 * @return bool
109
+	 * @throws EE_Error
110
+	 */
111
+	public function init_caps($reset = false)
112
+	{
113
+		if (! EE_Maintenance_Mode::instance()->models_can_query()) {
114
+			return false;
115
+		}
116
+		$this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
117
+		// if reset, then completely delete the cache option and clear the $capabilities_map property.
118
+		if ($this->reset) {
119
+			$this->initialized = null;
120
+			$this->capabilities_map = array();
121
+			delete_option(self::option_name);
122
+		}
123
+		if ($this->initialized === null) {
124
+			$this->initialized = false;
125
+			do_action(
126
+				'AHEE__EE_Capabilities__init_caps__before_initialization',
127
+				$this->reset
128
+			);
129
+			$this->addCaps($this->_init_caps_map());
130
+			$this->_set_meta_caps();
131
+			do_action(
132
+				'AHEE__EE_Capabilities__init_caps__after_initialization',
133
+				$this->capabilities_map
134
+			);
135
+			$this->initialized = true;
136
+		}
137
+		// reset $this->reset so that it's not stuck on true if init_caps() gets called again
138
+		$this->reset = false;
139
+		return true;
140
+	}
141
+
142
+
143
+	/**
144
+	 * This sets the meta caps property.
145
+	 *
146
+	 * @since 4.5.0
147
+	 * @return void
148
+	 * @throws EE_Error
149
+	 */
150
+	private function _set_meta_caps()
151
+	{
152
+		// get default meta caps and filter the returned array
153
+		$this->_meta_caps = apply_filters(
154
+			'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
155
+			$this->_get_default_meta_caps_array()
156
+		);
157
+		// add filter for map_meta_caps but only if models can query.
158
+		if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
159
+			add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
160
+		}
161
+	}
162
+
163
+
164
+	/**
165
+	 * This builds and returns the default meta_caps array only once.
166
+	 *
167
+	 * @since  4.8.28.rc.012
168
+	 * @return array
169
+	 * @throws EE_Error
170
+	 */
171
+	private function _get_default_meta_caps_array()
172
+	{
173
+		static $default_meta_caps = array();
174
+		// make sure we're only ever initializing the default _meta_caps array once if it's empty.
175
+		if (empty($default_meta_caps)) {
176
+			$default_meta_caps = array(
177
+				// edits
178
+				new EE_Meta_Capability_Map_Edit(
179
+					'ee_edit_event',
180
+					array('Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events')
181
+				),
182
+				new EE_Meta_Capability_Map_Edit(
183
+					'ee_edit_venue',
184
+					array('Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues')
185
+				),
186
+				new EE_Meta_Capability_Map_Edit(
187
+					'ee_edit_registration',
188
+					array('Registration', '', 'ee_edit_others_registrations', '')
189
+				),
190
+				new EE_Meta_Capability_Map_Edit(
191
+					'ee_edit_checkin',
192
+					array('Registration', '', 'ee_edit_others_checkins', '')
193
+				),
194
+				new EE_Meta_Capability_Map_Messages_Cap(
195
+					'ee_edit_message',
196
+					array('Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages')
197
+				),
198
+				new EE_Meta_Capability_Map_Edit(
199
+					'ee_edit_default_ticket',
200
+					array('Ticket', '', 'ee_edit_others_default_tickets', '')
201
+				),
202
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
203
+					'ee_edit_question',
204
+					array('Question', '', '', 'ee_edit_system_questions')
205
+				),
206
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
207
+					'ee_edit_question_group',
208
+					array('Question_Group', '', '', 'ee_edit_system_question_groups')
209
+				),
210
+				new EE_Meta_Capability_Map_Edit(
211
+					'ee_edit_payment_method',
212
+					array('Payment_Method', '', 'ee_edit_others_payment_methods', '')
213
+				),
214
+				// reads
215
+				new EE_Meta_Capability_Map_Read(
216
+					'ee_read_event',
217
+					array('Event', '', 'ee_read_others_events', 'ee_read_private_events')
218
+				),
219
+				new EE_Meta_Capability_Map_Read(
220
+					'ee_read_venue',
221
+					array('Venue', '', 'ee_read_others_venues', 'ee_read_private_venues')
222
+				),
223
+				new EE_Meta_Capability_Map_Read(
224
+					'ee_read_registration',
225
+					array('Registration', '', 'ee_read_others_registrations', '')
226
+				),
227
+				new EE_Meta_Capability_Map_Read(
228
+					'ee_read_checkin',
229
+					array('Registration', '', 'ee_read_others_checkins', '')
230
+				),
231
+				new EE_Meta_Capability_Map_Messages_Cap(
232
+					'ee_read_message',
233
+					array('Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages')
234
+				),
235
+				new EE_Meta_Capability_Map_Read(
236
+					'ee_read_default_ticket',
237
+					array('Ticket', '', 'ee_read_others_default_tickets', '')
238
+				),
239
+				new EE_Meta_Capability_Map_Read(
240
+					'ee_read_payment_method',
241
+					array('Payment_Method', '', 'ee_read_others_payment_methods', '')
242
+				),
243
+				// deletes
244
+				new EE_Meta_Capability_Map_Delete(
245
+					'ee_delete_event',
246
+					array(
247
+						'Event',
248
+						'ee_delete_published_events',
249
+						'ee_delete_others_events',
250
+						'ee_delete_private_events',
251
+					)
252
+				),
253
+				new EE_Meta_Capability_Map_Delete(
254
+					'ee_delete_venue',
255
+					array(
256
+						'Venue',
257
+						'ee_delete_published_venues',
258
+						'ee_delete_others_venues',
259
+						'ee_delete_private_venues',
260
+					)
261
+				),
262
+				new EE_Meta_Capability_Map_Delete(
263
+					'ee_delete_registration',
264
+					array('Registration', '', 'ee_delete_others_registrations', '')
265
+				),
266
+				new EE_Meta_Capability_Map_Delete(
267
+					'ee_delete_checkin',
268
+					array('Registration', '', 'ee_delete_others_checkins', '')
269
+				),
270
+				new EE_Meta_Capability_Map_Messages_Cap(
271
+					'ee_delete_message',
272
+					array('Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages')
273
+				),
274
+				new EE_Meta_Capability_Map_Delete(
275
+					'ee_delete_default_ticket',
276
+					array('Ticket', '', 'ee_delete_others_default_tickets', '')
277
+				),
278
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
279
+					'ee_delete_question',
280
+					array('Question', '', '', 'delete_system_questions')
281
+				),
282
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
283
+					'ee_delete_question_group',
284
+					array('Question_Group', '', '', 'delete_system_question_groups')
285
+				),
286
+				new EE_Meta_Capability_Map_Delete(
287
+					'ee_delete_payment_method',
288
+					array('Payment_Method', '', 'ee_delete_others_payment_methods', '')
289
+				),
290
+			);
291
+		}
292
+		return $default_meta_caps;
293
+	}
294
+
295
+
296
+	/**
297
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
298
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
299
+	 *
300
+	 * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
301
+	 *
302
+	 * @since 4.5.0
303
+	 * @see   wp-includes/capabilities.php
304
+	 *
305
+	 * @param array  $caps    actual users capabilities
306
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
307
+	 * @param int    $user_id The user id
308
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
309
+	 * @return array actual users capabilities
310
+	 * @throws EE_Error
311
+	 */
312
+	public function map_meta_caps($caps, $cap, $user_id, $args)
313
+	{
314
+		if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
315
+			// loop through our _meta_caps array
316
+			foreach ($this->_meta_caps as $meta_map) {
317
+				if (! $meta_map instanceof EE_Meta_Capability_Map) {
318
+					continue;
319
+				}
320
+				// don't load models if there is no object ID in the args
321
+				if (! empty($args[0])) {
322
+					$meta_map->ensure_is_model();
323
+				}
324
+				$caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
325
+			}
326
+		}
327
+		return $caps;
328
+	}
329
+
330
+
331
+	/**
332
+	 * This sets up and returns the initial capabilities map for Event Espresso
333
+	 * Note this array is filtered.
334
+	 * It is assumed that all available EE capabilities are assigned to the administrator role.
335
+	 *
336
+	 * @since 4.5.0
337
+	 *
338
+	 * @return array
339
+	 */
340
+	private function _init_caps_map()
341
+	{
342
+		return apply_filters(
343
+			'FHEE__EE_Capabilities__init_caps_map__caps',
344
+			array(
345
+				'administrator'           => array(
346
+					// basic access
347
+					'ee_read_ee',
348
+					// gateways
349
+					/**
350
+					 * note that with payment method capabilities, although we've implemented
351
+					 * capability mapping which will be used for accessing payment methods owned by
352
+					 * other users.  This is not fully implemented yet in the payment method ui.
353
+					 * Currently only the "plural" caps are in active use.
354
+					 * (Specific payment method caps are in use as well).
355
+					 **/
356
+					'ee_manage_gateways',
357
+					'ee_read_payment_methods',
358
+					'ee_read_others_payment_methods',
359
+					'ee_edit_payment_methods',
360
+					'ee_edit_others_payment_methods',
361
+					'ee_delete_payment_methods',
362
+					// events
363
+					'ee_publish_events',
364
+					'ee_read_private_events',
365
+					'ee_read_others_events',
366
+					'ee_read_events',
367
+					'ee_edit_events',
368
+					'ee_edit_published_events',
369
+					'ee_edit_others_events',
370
+					'ee_edit_private_events',
371
+					'ee_delete_published_events',
372
+					'ee_delete_private_events',
373
+					'ee_delete_events',
374
+					'ee_delete_others_events',
375
+					// event categories
376
+					'ee_manage_event_categories',
377
+					'ee_edit_event_category',
378
+					'ee_delete_event_category',
379
+					'ee_assign_event_category',
380
+					// venues
381
+					'ee_publish_venues',
382
+					'ee_read_venues',
383
+					'ee_read_others_venues',
384
+					'ee_read_private_venues',
385
+					'ee_edit_venues',
386
+					'ee_edit_others_venues',
387
+					'ee_edit_published_venues',
388
+					'ee_edit_private_venues',
389
+					'ee_delete_venues',
390
+					'ee_delete_others_venues',
391
+					'ee_delete_private_venues',
392
+					'ee_delete_published_venues',
393
+					// venue categories
394
+					'ee_manage_venue_categories',
395
+					'ee_edit_venue_category',
396
+					'ee_delete_venue_category',
397
+					'ee_assign_venue_category',
398
+					// contacts
399
+					'ee_read_contacts',
400
+					'ee_edit_contacts',
401
+					'ee_delete_contacts',
402
+					// registrations
403
+					'ee_read_registrations',
404
+					'ee_read_others_registrations',
405
+					'ee_edit_registrations',
406
+					'ee_edit_others_registrations',
407
+					'ee_delete_registrations',
408
+					'ee_delete_others_registrations',
409
+					// checkins
410
+					'ee_read_others_checkins',
411
+					'ee_read_checkins',
412
+					'ee_edit_checkins',
413
+					'ee_edit_others_checkins',
414
+					'ee_delete_checkins',
415
+					'ee_delete_others_checkins',
416
+					// transactions && payments
417
+					'ee_read_transaction',
418
+					'ee_read_transactions',
419
+					'ee_edit_payments',
420
+					'ee_delete_payments',
421
+					// messages
422
+					'ee_read_messages',
423
+					'ee_read_others_messages',
424
+					'ee_read_global_messages',
425
+					'ee_edit_global_messages',
426
+					'ee_edit_messages',
427
+					'ee_edit_others_messages',
428
+					'ee_delete_messages',
429
+					'ee_delete_others_messages',
430
+					'ee_delete_global_messages',
431
+					'ee_send_message',
432
+					// tickets
433
+					'ee_read_default_tickets',
434
+					'ee_read_others_default_tickets',
435
+					'ee_edit_default_tickets',
436
+					'ee_edit_others_default_tickets',
437
+					'ee_delete_default_tickets',
438
+					'ee_delete_others_default_tickets',
439
+					// prices
440
+					'ee_edit_default_price',
441
+					'ee_edit_default_prices',
442
+					'ee_delete_default_price',
443
+					'ee_delete_default_prices',
444
+					'ee_edit_default_price_type',
445
+					'ee_edit_default_price_types',
446
+					'ee_delete_default_price_type',
447
+					'ee_delete_default_price_types',
448
+					'ee_read_default_prices',
449
+					'ee_read_default_price_types',
450
+					// registration form
451
+					'ee_edit_questions',
452
+					'ee_edit_system_questions',
453
+					'ee_read_questions',
454
+					'ee_delete_questions',
455
+					'ee_edit_question_groups',
456
+					'ee_read_question_groups',
457
+					'ee_edit_system_question_groups',
458
+					'ee_delete_question_groups',
459
+					// event_type taxonomy
460
+					'ee_assign_event_type',
461
+					'ee_manage_event_types',
462
+					'ee_edit_event_type',
463
+					'ee_delete_event_type',
464
+				),
465
+				'ee_events_administrator' => array(
466
+					// core wp caps
467
+					'read',
468
+					'read_private_pages',
469
+					'read_private_posts',
470
+					'edit_users',
471
+					'edit_posts',
472
+					'edit_pages',
473
+					'edit_published_posts',
474
+					'edit_published_pages',
475
+					'edit_private_pages',
476
+					'edit_private_posts',
477
+					'edit_others_posts',
478
+					'edit_others_pages',
479
+					'publish_posts',
480
+					'publish_pages',
481
+					'delete_posts',
482
+					'delete_pages',
483
+					'delete_private_pages',
484
+					'delete_private_posts',
485
+					'delete_published_pages',
486
+					'delete_published_posts',
487
+					'delete_others_posts',
488
+					'delete_others_pages',
489
+					'manage_categories',
490
+					'manage_links',
491
+					'moderate_comments',
492
+					'unfiltered_html',
493
+					'upload_files',
494
+					'export',
495
+					'import',
496
+					'list_users',
497
+					'level_1', // required if user with this role shows up in author dropdowns
498
+					// basic ee access
499
+					'ee_read_ee',
500
+					// events
501
+					'ee_publish_events',
502
+					'ee_read_private_events',
503
+					'ee_read_others_events',
504
+					'ee_read_event',
505
+					'ee_read_events',
506
+					'ee_edit_event',
507
+					'ee_edit_events',
508
+					'ee_edit_published_events',
509
+					'ee_edit_others_events',
510
+					'ee_edit_private_events',
511
+					'ee_delete_published_events',
512
+					'ee_delete_private_events',
513
+					'ee_delete_event',
514
+					'ee_delete_events',
515
+					'ee_delete_others_events',
516
+					// event categories
517
+					'ee_manage_event_categories',
518
+					'ee_edit_event_category',
519
+					'ee_delete_event_category',
520
+					'ee_assign_event_category',
521
+					// venues
522
+					'ee_publish_venues',
523
+					'ee_read_venue',
524
+					'ee_read_venues',
525
+					'ee_read_others_venues',
526
+					'ee_read_private_venues',
527
+					'ee_edit_venue',
528
+					'ee_edit_venues',
529
+					'ee_edit_others_venues',
530
+					'ee_edit_published_venues',
531
+					'ee_edit_private_venues',
532
+					'ee_delete_venue',
533
+					'ee_delete_venues',
534
+					'ee_delete_others_venues',
535
+					'ee_delete_private_venues',
536
+					'ee_delete_published_venues',
537
+					// venue categories
538
+					'ee_manage_venue_categories',
539
+					'ee_edit_venue_category',
540
+					'ee_delete_venue_category',
541
+					'ee_assign_venue_category',
542
+					// contacts
543
+					'ee_read_contacts',
544
+					'ee_edit_contacts',
545
+					'ee_delete_contacts',
546
+					// registrations
547
+					'ee_read_registrations',
548
+					'ee_read_others_registrations',
549
+					'ee_edit_registration',
550
+					'ee_edit_registrations',
551
+					'ee_edit_others_registrations',
552
+					'ee_delete_registration',
553
+					'ee_delete_registrations',
554
+					'ee_delete_others_registrations',
555
+					// checkins
556
+					'ee_read_others_checkins',
557
+					'ee_read_checkins',
558
+					'ee_edit_checkins',
559
+					'ee_edit_others_checkins',
560
+					'ee_delete_checkins',
561
+					'ee_delete_others_checkins',
562
+					// transactions && payments
563
+					'ee_read_transaction',
564
+					'ee_read_transactions',
565
+					'ee_edit_payments',
566
+					'ee_delete_payments',
567
+					// messages
568
+					'ee_read_messages',
569
+					'ee_read_others_messages',
570
+					'ee_read_global_messages',
571
+					'ee_edit_global_messages',
572
+					'ee_edit_messages',
573
+					'ee_edit_others_messages',
574
+					'ee_delete_messages',
575
+					'ee_delete_others_messages',
576
+					'ee_delete_global_messages',
577
+					'ee_send_message',
578
+					// tickets
579
+					'ee_read_default_tickets',
580
+					'ee_read_others_default_tickets',
581
+					'ee_edit_default_tickets',
582
+					'ee_edit_others_default_tickets',
583
+					'ee_delete_default_tickets',
584
+					'ee_delete_others_default_tickets',
585
+					// prices
586
+					'ee_edit_default_price',
587
+					'ee_edit_default_prices',
588
+					'ee_delete_default_price',
589
+					'ee_delete_default_prices',
590
+					'ee_edit_default_price_type',
591
+					'ee_edit_default_price_types',
592
+					'ee_delete_default_price_type',
593
+					'ee_delete_default_price_types',
594
+					'ee_read_default_prices',
595
+					'ee_read_default_price_types',
596
+					// registration form
597
+					'ee_edit_questions',
598
+					'ee_edit_system_questions',
599
+					'ee_read_questions',
600
+					'ee_delete_questions',
601
+					'ee_edit_question_groups',
602
+					'ee_read_question_groups',
603
+					'ee_edit_system_question_groups',
604
+					'ee_delete_question_groups',
605
+					// event_type taxonomy
606
+					'ee_assign_event_type',
607
+					'ee_manage_event_types',
608
+					'ee_edit_event_type',
609
+					'ee_delete_event_type',
610
+				),
611
+			)
612
+		);
613
+	}
614
+
615
+
616
+	/**
617
+	 * @return bool
618
+	 * @throws EE_Error
619
+	 */
620
+	private function setupCapabilitiesMap()
621
+	{
622
+		// if the initialization process hasn't even started, then we need to call init_caps()
623
+		if ($this->initialized === null) {
624
+			return $this->init_caps();
625
+		}
626
+		// unless resetting, get caps from db if we haven't already
627
+		$this->capabilities_map = $this->reset || ! empty($this->capabilities_map)
628
+			? $this->capabilities_map
629
+			: get_option(self::option_name, array());
630
+		return true;
631
+	}
632
+
633
+
634
+	/**
635
+	 * @param bool $update
636
+	 * @return bool
637
+	 */
638
+	private function updateCapabilitiesMap($update = true)
639
+	{
640
+		return $update ? update_option(self::option_name, $this->capabilities_map) : false;
641
+	}
642
+
643
+
644
+	/**
645
+	 * Adds capabilities to roles.
646
+	 *
647
+	 * @since 4.9.42
648
+	 * @param array $capabilities_to_add array of capabilities to add, indexed by roles.
649
+	 *                                   Note that this should ONLY be called on activation hook
650
+	 *                                   otherwise the caps will be added on every request.
651
+	 * @return bool
652
+	 * @throws \EE_Error
653
+	 */
654
+	public function addCaps(array $capabilities_to_add)
655
+	{
656
+		// don't do anything if the capabilities map can not be initialized
657
+		if (! $this->setupCapabilitiesMap()) {
658
+			return false;
659
+		}
660
+		// and filter the array so others can get in on the fun during resets
661
+		$capabilities_to_add = apply_filters(
662
+			'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
663
+			$capabilities_to_add,
664
+			$this->reset,
665
+			$this->capabilities_map
666
+		);
667
+		$update_capabilities_map = false;
668
+		// if not reset, see what caps are new for each role. if they're new, add them.
669
+		foreach ($capabilities_to_add as $role => $caps_for_role) {
670
+			if (is_array($caps_for_role)) {
671
+				foreach ($caps_for_role as $cap) {
672
+					if (! $this->capHasBeenAddedToRole($role, $cap)
673
+						&& $this->add_cap_to_role($role, $cap, true, false)
674
+					) {
675
+						$update_capabilities_map = true;
676
+					}
677
+				}
678
+			}
679
+		}
680
+		// now let's just save the cap that has been set but only if there's been a change.
681
+		$updated = $this->updateCapabilitiesMap($update_capabilities_map);
682
+		$this->flushWpUser($updated);
683
+		do_action('AHEE__EE_Capabilities__addCaps__complete', $this->capabilities_map, $updated);
684
+		return $updated;
685
+	}
686
+
687
+
688
+	/**
689
+	 * Loops through the capabilities map and removes the role caps specified by the incoming array
690
+	 *
691
+	 * @param array $caps_map map of capabilities to be removed (indexed by roles)
692
+	 * @return bool
693
+	 * @throws \EE_Error
694
+	 */
695
+	public function removeCaps($caps_map)
696
+	{
697
+		// don't do anything if the capabilities map can not be initialized
698
+		if (! $this->setupCapabilitiesMap()) {
699
+			return false;
700
+		}
701
+		$update_capabilities_map = false;
702
+		foreach ($caps_map as $role => $caps_for_role) {
703
+			if (is_array($caps_for_role)) {
704
+				foreach ($caps_for_role as $cap) {
705
+					if ($this->capHasBeenAddedToRole($role, $cap)
706
+						&& $this->remove_cap_from_role($role, $cap, false)
707
+					) {
708
+						$update_capabilities_map = true;
709
+					}
710
+				}
711
+			}
712
+		}
713
+		// maybe resave the caps
714
+		$updated = $this->updateCapabilitiesMap($update_capabilities_map);
715
+		$this->flushWpUser($updated);
716
+		return $updated;
717
+	}
718
+
719
+
720
+	/**
721
+	 * This ensures that the WP User object cached on the $current_user global in WP has the latest capabilities from
722
+	 * the roles on that user.
723
+	 *
724
+	 * @param bool $flush Default is to flush the WP_User object.  If false, then this method effectively does nothing.
725
+	 */
726
+	private function flushWpUser($flush = true)
727
+	{
728
+		if ($flush) {
729
+			$user = wp_get_current_user();
730
+			if ($user instanceof WP_User) {
731
+				$user->get_role_caps();
732
+			}
733
+		}
734
+	}
735
+
736
+
737
+	/**
738
+	 * This method sets a capability on a role.  Note this should only be done on activation, or if you have something
739
+	 * specific to prevent the cap from being added on every page load (adding caps are persistent to the db). Note.
740
+	 * this is a wrapper for $wp_role->add_cap()
741
+	 *
742
+	 * @see   wp-includes/capabilities.php
743
+	 * @since 4.5.0
744
+	 * @param string|WP_Role $role  A WordPress role the capability is being added to
745
+	 * @param string         $cap   The capability being added to the role
746
+	 * @param bool           $grant Whether to grant access to this cap on this role.
747
+	 * @param bool           $update_capabilities_map
748
+	 * @return bool
749
+	 * @throws \EE_Error
750
+	 */
751
+	public function add_cap_to_role($role, $cap, $grant = true, $update_capabilities_map = true)
752
+	{
753
+		// capture incoming value for $role because we may need it to create a new WP_Role
754
+		$orig_role = $role;
755
+		$role = $role instanceof WP_Role ? $role : get_role($role);
756
+		// if the role isn't available then we create it.
757
+		if (! $role instanceof WP_Role) {
758
+			// if a plugin wants to create a specific role name then they should create the role before
759
+			// EE_Capabilities does.  Otherwise this function will create the role name from the slug:
760
+			// - removes any `ee_` namespacing from the start of the slug.
761
+			// - replaces `_` with ` ` (empty space).
762
+			// - sentence case on the resulting string.
763
+			$role_label = ucwords(str_replace(array('ee_', '_'), array('', ' '), $orig_role));
764
+			$role = add_role($orig_role, $role_label);
765
+		}
766
+		if ($role instanceof WP_Role) {
767
+			// don't do anything if the capabilities map can not be initialized
768
+			if (! $this->setupCapabilitiesMap()) {
769
+				return false;
770
+			}
771
+			if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
772
+				$role->add_cap($cap, $grant);
773
+				$this->capabilities_map[ $role->name ][] = $cap;
774
+				$this->updateCapabilitiesMap($update_capabilities_map);
775
+				return true;
776
+			}
777
+		}
778
+		return false;
779
+	}
780
+
781
+
782
+	/**
783
+	 * Functions similarly to add_cap_to_role except removes cap from given role.
784
+	 * Wrapper for $wp_role->remove_cap()
785
+	 *
786
+	 * @see   wp-includes/capabilities.php
787
+	 * @since 4.5.0
788
+	 * @param string|WP_Role $role A WordPress role the capability is being removed from.
789
+	 * @param string         $cap  The capability being removed
790
+	 * @param bool           $update_capabilities_map
791
+	 * @return bool
792
+	 * @throws \EE_Error
793
+	 */
794
+	public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
795
+	{
796
+		// don't do anything if the capabilities map can not be initialized
797
+		if (! $this->setupCapabilitiesMap()) {
798
+			return false;
799
+		}
800
+
801
+		$role = $role instanceof WP_Role ? $role : get_role($role);
802
+		if ($role instanceof WP_Role && $index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
803
+			$role->remove_cap($cap);
804
+			unset($this->capabilities_map[ $role->name ][ $index ]);
805
+			$this->updateCapabilitiesMap($update_capabilities_map);
806
+			return true;
807
+		}
808
+		return false;
809
+	}
810
+
811
+
812
+	/**
813
+	 * @param string $role_name
814
+	 * @param string $cap
815
+	 * @param bool   $get_index
816
+	 * @return bool|mixed
817
+	 */
818
+	private function capHasBeenAddedToRole($role_name = '', $cap = '', $get_index = false)
819
+	{
820
+		if (isset($this->capabilities_map[ $role_name ])
821
+			&& ($index = array_search($cap, $this->capabilities_map[ $role_name ], true)) !== false
822
+		) {
823
+			return $get_index ? $index : true;
824
+		}
825
+		return false;
826
+	}
827
+
828
+
829
+	/**
830
+	 * Wrapper for the native WP current_user_can() method.
831
+	 * This is provided as a handy method for a couple things:
832
+	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
833
+	 * write those filters wherever current_user_can is called).
834
+	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
835
+	 *
836
+	 * @since 4.5.0
837
+	 *
838
+	 * @param string $cap     The cap being checked.
839
+	 * @param string $context The context where the current_user_can is being called from.
840
+	 * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
841
+	 *                        filters.
842
+	 *
843
+	 * @return bool  Whether user can or not.
844
+	 */
845
+	public function current_user_can($cap, $context, $id = 0)
846
+	{
847
+		// apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
848
+		$filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
849
+		$filtered_cap = apply_filters(
850
+			'FHEE__EE_Capabilities__current_user_can__cap',
851
+			$filtered_cap,
852
+			$context,
853
+			$cap,
854
+			$id
855
+		);
856
+		return ! empty($id)
857
+			? current_user_can($filtered_cap, $id)
858
+			: current_user_can($filtered_cap);
859
+	}
860
+
861
+
862
+	/**
863
+	 * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
864
+	 *
865
+	 * @param int|WP_User $user    Either the user_id or a WP_User object
866
+	 * @param string      $cap     The capability string being checked
867
+	 * @param string      $context The context where the user_can is being called from (used in filters).
868
+	 * @param int         $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap()
869
+	 *                             filters)
870
+	 *
871
+	 * @return bool Whether user can or not.
872
+	 */
873
+	public function user_can($user, $cap, $context, $id = 0)
874
+	{
875
+		// apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
876
+		$filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
877
+		$filtered_cap = apply_filters(
878
+			'FHEE__EE_Capabilities__user_can__cap',
879
+			$filtered_cap,
880
+			$context,
881
+			$cap,
882
+			$user,
883
+			$id
884
+		);
885
+		return ! empty($id)
886
+			? user_can($user, $filtered_cap, $id)
887
+			: user_can($user, $filtered_cap);
888
+	}
889
+
890
+
891
+	/**
892
+	 * Wrapper for the native WP current_user_can_for_blog() method.
893
+	 * This is provided as a handy method for a couple things:
894
+	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
895
+	 * write those filters wherever current_user_can is called).
896
+	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
897
+	 *
898
+	 * @since 4.5.0
899
+	 *
900
+	 * @param int    $blog_id The blog id that is being checked for.
901
+	 * @param string $cap     The cap being checked.
902
+	 * @param string $context The context where the current_user_can is being called from.
903
+	 * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
904
+	 *                        filters.
905
+	 *
906
+	 * @return bool  Whether user can or not.
907
+	 */
908
+	public function current_user_can_for_blog($blog_id, $cap, $context, $id = 0)
909
+	{
910
+		$user_can = ! empty($id)
911
+			? current_user_can_for_blog($blog_id, $cap, $id)
912
+			: current_user_can($blog_id, $cap);
913
+		// apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
914
+		$user_can = apply_filters(
915
+			'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
916
+			$user_can,
917
+			$blog_id,
918
+			$cap,
919
+			$id
920
+		);
921
+		$user_can = apply_filters(
922
+			'FHEE__EE_Capabilities__current_user_can_for_blog__user_can',
923
+			$user_can,
924
+			$context,
925
+			$blog_id,
926
+			$cap,
927
+			$id
928
+		);
929
+		return $user_can;
930
+	}
931
+
932
+
933
+	/**
934
+	 * This helper method just returns an array of registered EE capabilities.
935
+	 *
936
+	 * @since 4.5.0
937
+	 * @param string $role If empty then the entire role/capability map is returned.
938
+	 *                     Otherwise just the capabilities for the given role are returned.
939
+	 * @return array
940
+	 * @throws EE_Error
941
+	 */
942
+	public function get_ee_capabilities($role = 'administrator')
943
+	{
944
+		if (! $this->initialized) {
945
+			$this->init_caps();
946
+		}
947
+		if (empty($role)) {
948
+			return $this->capabilities_map;
949
+		}
950
+		return isset($this->capabilities_map[ $role ])
951
+			? $this->capabilities_map[ $role ]
952
+			: array();
953
+	}
954
+
955
+
956
+	/**
957
+	 * @deprecated 4.9.42
958
+	 * @param bool  $reset      If you need to reset Event Espresso's capabilities,
959
+	 *                          then please use the init_caps() method with the "$reset" parameter set to "true"
960
+	 * @param array $caps_map   Optional.
961
+	 *                          Can be used to send a custom map of roles and capabilities for setting them up.
962
+	 *                          Note that this should ONLY be called on activation hook or some other one-time
963
+	 *                          task otherwise the caps will be added on every request.
964
+	 * @return void
965
+	 * @throws EE_Error
966
+	 */
967
+	public function init_role_caps($reset = false, $caps_map = array())
968
+	{
969
+		// If this method is called directly and reset is set as 'true',
970
+		// then display a doing it wrong notice, because we want resets to go through init_caps()
971
+		// to guarantee that everything is set up correctly.
972
+		// This prevents the capabilities map getting reset incorrectly by direct calls to this method.
973
+		if ($reset) {
974
+			EE_Error::doing_it_wrong(
975
+				__METHOD__,
976
+				sprintf(
977
+					esc_html__(
978
+						'The "%1$s" parameter for the "%2$s" method is deprecated. If you need to reset Event Espresso\'s capabilities, then please use the "%3$s" method with the "%1$s" parameter set to "%4$s".',
979
+						'event_espresso'
980
+					),
981
+					'$reset',
982
+					__METHOD__ . '()',
983
+					'EE_Capabilities::init_caps()',
984
+					'true'
985
+				),
986
+				'4.9.42',
987
+				'5.0.0'
988
+			);
989
+		}
990
+		$this->addCaps($caps_map);
991
+	}
992 992
 }
993 993
 
994 994
 
@@ -1005,142 +1005,142 @@  discard block
 block discarded – undo
1005 1005
 abstract class EE_Meta_Capability_Map
1006 1006
 {
1007 1007
 
1008
-    public $meta_cap;
1009
-
1010
-    /**
1011
-     * @var EEM_Base
1012
-     */
1013
-    protected $_model;
1014
-
1015
-    protected $_model_name;
1016
-
1017
-    public $published_cap = '';
1018
-
1019
-    public $others_cap = '';
1020
-
1021
-    public $private_cap = '';
1022
-
1023
-
1024
-    /**
1025
-     * constructor.
1026
-     * Receives the setup arguments for the map.
1027
-     *
1028
-     * @since                        4.5.0
1029
-     *
1030
-     * @param string $meta_cap   What meta capability is this mapping.
1031
-     * @param array  $map_values array {
1032
-     *                           //array of values that MUST match a count of 4.  It's okay to send an empty string for
1033
-     *                           capabilities that don't get mapped to.
1034
-     *
1035
-     * @type         $map_values [0] string A string representing the model name. Required.  String's
1036
-     *                               should always be used when Menu Maps are registered via the
1037
-     *                               plugin API as models are not allowed to be instantiated when
1038
-     *                               in maintenance mode 2 (migrations).
1039
-     * @type         $map_values [1] string represents the capability used for published. Optional.
1040
-     * @type         $map_values [2] string represents the capability used for "others". Optional.
1041
-     * @type         $map_values [3] string represents the capability used for private. Optional.
1042
-     *                               }
1043
-     * @throws EE_Error
1044
-     */
1045
-    public function __construct($meta_cap, $map_values)
1046
-    {
1047
-        $this->meta_cap = $meta_cap;
1048
-        // verify there are four args in the $map_values array;
1049
-        if (count($map_values) !== 4) {
1050
-            throw new EE_Error(
1051
-                sprintf(
1052
-                    __(
1053
-                        'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1054
-                        'event_espresso'
1055
-                    ),
1056
-                    '<br>' . print_r($map_values, true)
1057
-                )
1058
-            );
1059
-        }
1060
-        // set properties
1061
-        $this->_model = null;
1062
-        $this->_model_name = $map_values[0];
1063
-        $this->published_cap = (string) $map_values[1];
1064
-        $this->others_cap = (string) $map_values[2];
1065
-        $this->private_cap = (string) $map_values[3];
1066
-    }
1067
-
1068
-    /**
1069
-     * Makes it so this object stops filtering caps
1070
-     */
1071
-    public function remove_filters()
1072
-    {
1073
-        remove_filter('map_meta_cap', array($this, 'map_meta_caps'), 10);
1074
-    }
1075
-
1076
-
1077
-    /**
1078
-     * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
1079
-     *
1080
-     * @since 4.5.0
1081
-     * @throws EE_Error
1082
-     *
1083
-     * @return void
1084
-     */
1085
-    public function ensure_is_model()
1086
-    {
1087
-        // is it already instantiated?
1088
-        if ($this->_model instanceof EEM_Base) {
1089
-            return;
1090
-        }
1091
-        // ensure model name is string
1092
-        $this->_model_name = (string) $this->_model_name;
1093
-        // error proof if the name has EEM in it
1094
-        $this->_model_name = str_replace('EEM', '', $this->_model_name);
1095
-        $this->_model = EE_Registry::instance()->load_model($this->_model_name);
1096
-        if (! $this->_model instanceof EEM_Base) {
1097
-            throw new EE_Error(
1098
-                sprintf(
1099
-                    __(
1100
-                        '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',
1101
-                        'event_espresso'
1102
-                    ),
1103
-                    get_class($this),
1104
-                    $this->_model
1105
-                )
1106
-            );
1107
-        }
1108
-    }
1109
-
1110
-
1111
-    /**
1112
-     *
1113
-     * @see   EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
1114
-     * @since 4.6.x
1115
-     *
1116
-     * @param $caps
1117
-     * @param $cap
1118
-     * @param $user_id
1119
-     * @param $args
1120
-     *
1121
-     * @return array
1122
-     */
1123
-    public function map_meta_caps($caps, $cap, $user_id, $args)
1124
-    {
1125
-        return $this->_map_meta_caps($caps, $cap, $user_id, $args);
1126
-    }
1127
-
1128
-
1129
-    /**
1130
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1131
-     * "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
-    abstract protected function _map_meta_caps($caps, $cap, $user_id, $args);
1008
+	public $meta_cap;
1009
+
1010
+	/**
1011
+	 * @var EEM_Base
1012
+	 */
1013
+	protected $_model;
1014
+
1015
+	protected $_model_name;
1016
+
1017
+	public $published_cap = '';
1018
+
1019
+	public $others_cap = '';
1020
+
1021
+	public $private_cap = '';
1022
+
1023
+
1024
+	/**
1025
+	 * constructor.
1026
+	 * Receives the setup arguments for the map.
1027
+	 *
1028
+	 * @since                        4.5.0
1029
+	 *
1030
+	 * @param string $meta_cap   What meta capability is this mapping.
1031
+	 * @param array  $map_values array {
1032
+	 *                           //array of values that MUST match a count of 4.  It's okay to send an empty string for
1033
+	 *                           capabilities that don't get mapped to.
1034
+	 *
1035
+	 * @type         $map_values [0] string A string representing the model name. Required.  String's
1036
+	 *                               should always be used when Menu Maps are registered via the
1037
+	 *                               plugin API as models are not allowed to be instantiated when
1038
+	 *                               in maintenance mode 2 (migrations).
1039
+	 * @type         $map_values [1] string represents the capability used for published. Optional.
1040
+	 * @type         $map_values [2] string represents the capability used for "others". Optional.
1041
+	 * @type         $map_values [3] string represents the capability used for private. Optional.
1042
+	 *                               }
1043
+	 * @throws EE_Error
1044
+	 */
1045
+	public function __construct($meta_cap, $map_values)
1046
+	{
1047
+		$this->meta_cap = $meta_cap;
1048
+		// verify there are four args in the $map_values array;
1049
+		if (count($map_values) !== 4) {
1050
+			throw new EE_Error(
1051
+				sprintf(
1052
+					__(
1053
+						'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1054
+						'event_espresso'
1055
+					),
1056
+					'<br>' . print_r($map_values, true)
1057
+				)
1058
+			);
1059
+		}
1060
+		// set properties
1061
+		$this->_model = null;
1062
+		$this->_model_name = $map_values[0];
1063
+		$this->published_cap = (string) $map_values[1];
1064
+		$this->others_cap = (string) $map_values[2];
1065
+		$this->private_cap = (string) $map_values[3];
1066
+	}
1067
+
1068
+	/**
1069
+	 * Makes it so this object stops filtering caps
1070
+	 */
1071
+	public function remove_filters()
1072
+	{
1073
+		remove_filter('map_meta_cap', array($this, 'map_meta_caps'), 10);
1074
+	}
1075
+
1076
+
1077
+	/**
1078
+	 * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
1079
+	 *
1080
+	 * @since 4.5.0
1081
+	 * @throws EE_Error
1082
+	 *
1083
+	 * @return void
1084
+	 */
1085
+	public function ensure_is_model()
1086
+	{
1087
+		// is it already instantiated?
1088
+		if ($this->_model instanceof EEM_Base) {
1089
+			return;
1090
+		}
1091
+		// ensure model name is string
1092
+		$this->_model_name = (string) $this->_model_name;
1093
+		// error proof if the name has EEM in it
1094
+		$this->_model_name = str_replace('EEM', '', $this->_model_name);
1095
+		$this->_model = EE_Registry::instance()->load_model($this->_model_name);
1096
+		if (! $this->_model instanceof EEM_Base) {
1097
+			throw new EE_Error(
1098
+				sprintf(
1099
+					__(
1100
+						'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',
1101
+						'event_espresso'
1102
+					),
1103
+					get_class($this),
1104
+					$this->_model
1105
+				)
1106
+			);
1107
+		}
1108
+	}
1109
+
1110
+
1111
+	/**
1112
+	 *
1113
+	 * @see   EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
1114
+	 * @since 4.6.x
1115
+	 *
1116
+	 * @param $caps
1117
+	 * @param $cap
1118
+	 * @param $user_id
1119
+	 * @param $args
1120
+	 *
1121
+	 * @return array
1122
+	 */
1123
+	public function map_meta_caps($caps, $cap, $user_id, $args)
1124
+	{
1125
+		return $this->_map_meta_caps($caps, $cap, $user_id, $args);
1126
+	}
1127
+
1128
+
1129
+	/**
1130
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1131
+	 * "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
+	abstract protected function _map_meta_caps($caps, $cap, $user_id, $args);
1144 1144
 }
1145 1145
 
1146 1146
 
@@ -1156,81 +1156,81 @@  discard block
 block discarded – undo
1156 1156
 class EE_Meta_Capability_Map_Edit extends EE_Meta_Capability_Map
1157 1157
 {
1158 1158
 
1159
-    /**
1160
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1161
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1162
-     *
1163
-     * @since 4.5.0
1164
-     * @see   wp-includes/capabilities.php
1165
-     *
1166
-     * @param array  $caps    actual users capabilities
1167
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1168
-     * @param int    $user_id The user id
1169
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1170
-     *
1171
-     * @return array   actual users capabilities
1172
-     */
1173
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1174
-    {
1175
-        // only process if we're checking our mapped_cap
1176
-        if ($cap !== $this->meta_cap) {
1177
-            return $caps;
1178
-        }
1179
-
1180
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1181
-        if (($key = array_search($cap, $caps)) !== false) {
1182
-            unset($caps[ $key ]);
1183
-        }
1184
-
1185
-        // cast $user_id to int for later explicit comparisons
1186
-        $user_id = (int) $user_id;
1187
-
1188
-        /** @var EE_Base_Class $obj */
1189
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1190
-        // if no obj then let's just do cap
1191
-        if (! $obj instanceof EE_Base_Class) {
1192
-            $caps[] = 'do_not_allow';
1193
-            return $caps;
1194
-        }
1195
-        $caps[] = $cap . 's';
1196
-        if ($obj instanceof EE_CPT_Base) {
1197
-            // if the item author is set and the user is the author...
1198
-            if ($obj->wp_user() && $user_id === $obj->wp_user()) {
1199
-                // if obj is published...
1200
-                if ($obj->status() === 'publish') {
1201
-                    $caps[] = $this->published_cap;
1202
-                }
1203
-            } else {
1204
-                // the user is trying to edit someone else's obj
1205
-                if (! empty($this->others_cap)) {
1206
-                    $caps[] = $this->others_cap;
1207
-                }
1208
-                if (! empty($this->published_cap) && $obj->status() === 'publish') {
1209
-                    $caps[] = $this->published_cap;
1210
-                } elseif (! empty($this->private_cap) && $obj->status() === 'private') {
1211
-                    $caps[] = $this->private_cap;
1212
-                }
1213
-            }
1214
-        } else {
1215
-            // not a cpt object so handled differently
1216
-            $has_cap = false;
1217
-            try {
1218
-                $has_cap = method_exists($obj, 'wp_user')
1219
-                           && $obj->wp_user()
1220
-                           && $obj->wp_user() === $user_id;
1221
-            } catch (Exception $e) {
1222
-                if (WP_DEBUG) {
1223
-                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1224
-                }
1225
-            }
1226
-            if (! $has_cap) {
1227
-                if (! empty($this->others_cap)) {
1228
-                    $caps[] = $this->others_cap;
1229
-                }
1230
-            }
1231
-        }
1232
-        return $caps;
1233
-    }
1159
+	/**
1160
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1161
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1162
+	 *
1163
+	 * @since 4.5.0
1164
+	 * @see   wp-includes/capabilities.php
1165
+	 *
1166
+	 * @param array  $caps    actual users capabilities
1167
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1168
+	 * @param int    $user_id The user id
1169
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1170
+	 *
1171
+	 * @return array   actual users capabilities
1172
+	 */
1173
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1174
+	{
1175
+		// only process if we're checking our mapped_cap
1176
+		if ($cap !== $this->meta_cap) {
1177
+			return $caps;
1178
+		}
1179
+
1180
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1181
+		if (($key = array_search($cap, $caps)) !== false) {
1182
+			unset($caps[ $key ]);
1183
+		}
1184
+
1185
+		// cast $user_id to int for later explicit comparisons
1186
+		$user_id = (int) $user_id;
1187
+
1188
+		/** @var EE_Base_Class $obj */
1189
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1190
+		// if no obj then let's just do cap
1191
+		if (! $obj instanceof EE_Base_Class) {
1192
+			$caps[] = 'do_not_allow';
1193
+			return $caps;
1194
+		}
1195
+		$caps[] = $cap . 's';
1196
+		if ($obj instanceof EE_CPT_Base) {
1197
+			// if the item author is set and the user is the author...
1198
+			if ($obj->wp_user() && $user_id === $obj->wp_user()) {
1199
+				// if obj is published...
1200
+				if ($obj->status() === 'publish') {
1201
+					$caps[] = $this->published_cap;
1202
+				}
1203
+			} else {
1204
+				// the user is trying to edit someone else's obj
1205
+				if (! empty($this->others_cap)) {
1206
+					$caps[] = $this->others_cap;
1207
+				}
1208
+				if (! empty($this->published_cap) && $obj->status() === 'publish') {
1209
+					$caps[] = $this->published_cap;
1210
+				} elseif (! empty($this->private_cap) && $obj->status() === 'private') {
1211
+					$caps[] = $this->private_cap;
1212
+				}
1213
+			}
1214
+		} else {
1215
+			// not a cpt object so handled differently
1216
+			$has_cap = false;
1217
+			try {
1218
+				$has_cap = method_exists($obj, 'wp_user')
1219
+						   && $obj->wp_user()
1220
+						   && $obj->wp_user() === $user_id;
1221
+			} catch (Exception $e) {
1222
+				if (WP_DEBUG) {
1223
+					EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1224
+				}
1225
+			}
1226
+			if (! $has_cap) {
1227
+				if (! empty($this->others_cap)) {
1228
+					$caps[] = $this->others_cap;
1229
+				}
1230
+			}
1231
+		}
1232
+		return $caps;
1233
+	}
1234 1234
 }
1235 1235
 
1236 1236
 
@@ -1247,24 +1247,24 @@  discard block
 block discarded – undo
1247 1247
 class EE_Meta_Capability_Map_Delete extends EE_Meta_Capability_Map_Edit
1248 1248
 {
1249 1249
 
1250
-    /**
1251
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1252
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1253
-     *
1254
-     * @since 4.5.0
1255
-     * @see   wp-includes/capabilities.php
1256
-     *
1257
-     * @param array  $caps    actual users capabilities
1258
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1259
-     * @param int    $user_id The user id
1260
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1261
-     *
1262
-     * @return array   actual users capabilities
1263
-     */
1264
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1265
-    {
1266
-        return parent::_map_meta_caps($caps, $cap, $user_id, $args);
1267
-    }
1250
+	/**
1251
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1252
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1253
+	 *
1254
+	 * @since 4.5.0
1255
+	 * @see   wp-includes/capabilities.php
1256
+	 *
1257
+	 * @param array  $caps    actual users capabilities
1258
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1259
+	 * @param int    $user_id The user id
1260
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1261
+	 *
1262
+	 * @return array   actual users capabilities
1263
+	 */
1264
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1265
+	{
1266
+		return parent::_map_meta_caps($caps, $cap, $user_id, $args);
1267
+	}
1268 1268
 }
1269 1269
 
1270 1270
 
@@ -1280,85 +1280,85 @@  discard block
 block discarded – undo
1280 1280
 class EE_Meta_Capability_Map_Read extends EE_Meta_Capability_Map
1281 1281
 {
1282 1282
 
1283
-    /**
1284
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1285
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1286
-     *
1287
-     * @since 4.5.0
1288
-     * @see   wp-includes/capabilities.php
1289
-     *
1290
-     * @param array  $caps    actual users capabilities
1291
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1292
-     * @param int    $user_id The user id
1293
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1294
-     *
1295
-     * @return array   actual users capabilities
1296
-     */
1297
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1298
-    {
1299
-        // only process if we're checking our mapped cap;
1300
-        if ($cap !== $this->meta_cap) {
1301
-            return $caps;
1302
-        }
1303
-
1304
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1305
-        if (($key = array_search($cap, $caps)) !== false) {
1306
-            unset($caps[ $key ]);
1307
-        }
1308
-
1309
-        // cast $user_id to int for later explicit comparisons
1310
-        $user_id = (int) $user_id;
1311
-
1312
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1313
-        // if no obj then let's just do cap
1314
-        if (! $obj instanceof EE_Base_Class) {
1315
-            $caps[] = 'do_not_allow';
1316
-            return $caps;
1317
-        }
1318
-
1319
-        $caps[] = $cap . 's';
1320
-        if ($obj instanceof EE_CPT_Base) {
1321
-            $status_obj = get_post_status_object($obj->status());
1322
-            if ($status_obj->public) {
1323
-                return $caps;
1324
-            }
1325
-            // if the item author is set and the user is not the author...
1326
-            if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1327
-                if (! empty($this->others_cap)) {
1328
-                    $caps[] = $this->others_cap;
1329
-                }
1330
-            }
1331
-            // yes this means that if users created the private post, they are able to see it regardless of private cap.
1332
-            if ($status_obj->private
1333
-                && ! empty($this->private_cap)
1334
-                && $obj->wp_user() !== $user_id
1335
-            ) {
1336
-                // the user is trying to view a private object for an object they don't own.
1337
-                $caps[] = $this->private_cap;
1338
-            }
1339
-        } else {
1340
-            // not a cpt object so handled differently
1341
-            $has_cap = false;
1342
-            try {
1343
-                $has_cap = method_exists($obj, 'wp_user')
1344
-                           && $obj->wp_user()
1345
-                           && $obj->wp_user() === $user_id;
1346
-            } catch (Exception $e) {
1347
-                if (WP_DEBUG) {
1348
-                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1349
-                }
1350
-            }
1351
-            if (! $has_cap) {
1352
-                if (! empty($this->private_cap)) {
1353
-                    $caps[] = $this->private_cap;
1354
-                }
1355
-                if (! empty($this->others_cap)) {
1356
-                    $caps[] = $this->others_cap;
1357
-                }
1358
-            }
1359
-        }
1360
-        return $caps;
1361
-    }
1283
+	/**
1284
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1285
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1286
+	 *
1287
+	 * @since 4.5.0
1288
+	 * @see   wp-includes/capabilities.php
1289
+	 *
1290
+	 * @param array  $caps    actual users capabilities
1291
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1292
+	 * @param int    $user_id The user id
1293
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1294
+	 *
1295
+	 * @return array   actual users capabilities
1296
+	 */
1297
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1298
+	{
1299
+		// only process if we're checking our mapped cap;
1300
+		if ($cap !== $this->meta_cap) {
1301
+			return $caps;
1302
+		}
1303
+
1304
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1305
+		if (($key = array_search($cap, $caps)) !== false) {
1306
+			unset($caps[ $key ]);
1307
+		}
1308
+
1309
+		// cast $user_id to int for later explicit comparisons
1310
+		$user_id = (int) $user_id;
1311
+
1312
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1313
+		// if no obj then let's just do cap
1314
+		if (! $obj instanceof EE_Base_Class) {
1315
+			$caps[] = 'do_not_allow';
1316
+			return $caps;
1317
+		}
1318
+
1319
+		$caps[] = $cap . 's';
1320
+		if ($obj instanceof EE_CPT_Base) {
1321
+			$status_obj = get_post_status_object($obj->status());
1322
+			if ($status_obj->public) {
1323
+				return $caps;
1324
+			}
1325
+			// if the item author is set and the user is not the author...
1326
+			if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1327
+				if (! empty($this->others_cap)) {
1328
+					$caps[] = $this->others_cap;
1329
+				}
1330
+			}
1331
+			// yes this means that if users created the private post, they are able to see it regardless of private cap.
1332
+			if ($status_obj->private
1333
+				&& ! empty($this->private_cap)
1334
+				&& $obj->wp_user() !== $user_id
1335
+			) {
1336
+				// the user is trying to view a private object for an object they don't own.
1337
+				$caps[] = $this->private_cap;
1338
+			}
1339
+		} else {
1340
+			// not a cpt object so handled differently
1341
+			$has_cap = false;
1342
+			try {
1343
+				$has_cap = method_exists($obj, 'wp_user')
1344
+						   && $obj->wp_user()
1345
+						   && $obj->wp_user() === $user_id;
1346
+			} catch (Exception $e) {
1347
+				if (WP_DEBUG) {
1348
+					EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1349
+				}
1350
+			}
1351
+			if (! $has_cap) {
1352
+				if (! empty($this->private_cap)) {
1353
+					$caps[] = $this->private_cap;
1354
+				}
1355
+				if (! empty($this->others_cap)) {
1356
+					$caps[] = $this->others_cap;
1357
+				}
1358
+			}
1359
+		}
1360
+		return $caps;
1361
+	}
1362 1362
 }
1363 1363
 
1364 1364
 
@@ -1375,56 +1375,56 @@  discard block
 block discarded – undo
1375 1375
 class EE_Meta_Capability_Map_Messages_Cap extends EE_Meta_Capability_Map
1376 1376
 {
1377 1377
 
1378
-    /**
1379
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1380
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1381
-     *
1382
-     * @since 4.5.0
1383
-     * @see   wp-includes/capabilities.php
1384
-     *
1385
-     * @param array  $caps    actual users capabilities
1386
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1387
-     * @param int    $user_id The user id
1388
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1389
-     *
1390
-     * @return array   actual users capabilities
1391
-     */
1392
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1393
-    {
1394
-        // only process if we're checking our mapped_cap
1395
-        if ($cap !== $this->meta_cap) {
1396
-            return $caps;
1397
-        }
1398
-
1399
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1400
-        if (($key = array_search($cap, $caps)) !== false) {
1401
-            unset($caps[ $key ]);
1402
-        }
1403
-
1404
-        // cast $user_id to int for later explicit comparisons
1405
-        $user_id = (int) $user_id;
1406
-
1407
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1408
-        // if no obj then let's just do cap
1409
-        if (! $obj instanceof EE_Message_Template_Group) {
1410
-            $caps[] = 'do_not_allow';
1411
-            return $caps;
1412
-        }
1413
-        $caps[] = $cap . 's';
1414
-        $is_global = $obj->is_global();
1415
-        if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1416
-            if ($is_global) {
1417
-                $caps[] = $this->private_cap;
1418
-            }
1419
-        } else {
1420
-            if ($is_global) {
1421
-                $caps[] = $this->private_cap;
1422
-            } else {
1423
-                $caps[] = $this->others_cap;
1424
-            }
1425
-        }
1426
-        return $caps;
1427
-    }
1378
+	/**
1379
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1380
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1381
+	 *
1382
+	 * @since 4.5.0
1383
+	 * @see   wp-includes/capabilities.php
1384
+	 *
1385
+	 * @param array  $caps    actual users capabilities
1386
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1387
+	 * @param int    $user_id The user id
1388
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1389
+	 *
1390
+	 * @return array   actual users capabilities
1391
+	 */
1392
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1393
+	{
1394
+		// only process if we're checking our mapped_cap
1395
+		if ($cap !== $this->meta_cap) {
1396
+			return $caps;
1397
+		}
1398
+
1399
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1400
+		if (($key = array_search($cap, $caps)) !== false) {
1401
+			unset($caps[ $key ]);
1402
+		}
1403
+
1404
+		// cast $user_id to int for later explicit comparisons
1405
+		$user_id = (int) $user_id;
1406
+
1407
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1408
+		// if no obj then let's just do cap
1409
+		if (! $obj instanceof EE_Message_Template_Group) {
1410
+			$caps[] = 'do_not_allow';
1411
+			return $caps;
1412
+		}
1413
+		$caps[] = $cap . 's';
1414
+		$is_global = $obj->is_global();
1415
+		if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1416
+			if ($is_global) {
1417
+				$caps[] = $this->private_cap;
1418
+			}
1419
+		} else {
1420
+			if ($is_global) {
1421
+				$caps[] = $this->private_cap;
1422
+			} else {
1423
+				$caps[] = $this->others_cap;
1424
+			}
1425
+		}
1426
+		return $caps;
1427
+	}
1428 1428
 }
1429 1429
 
1430 1430
 
@@ -1441,40 +1441,40 @@  discard block
 block discarded – undo
1441 1441
 class EE_Meta_Capability_Map_Registration_Form_Cap extends EE_Meta_Capability_Map
1442 1442
 {
1443 1443
 
1444
-    /**
1445
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1446
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1447
-     *
1448
-     * @since 4.5.0
1449
-     * @see   wp-includes/capabilities.php
1450
-     * @param array  $caps    actual users capabilities
1451
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1452
-     * @param int    $user_id The user id
1453
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1454
-     * @return array   actual users capabilities
1455
-     */
1456
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1457
-    {
1458
-        // only process if we're checking our mapped_cap
1459
-        if ($cap !== $this->meta_cap) {
1460
-            return $caps;
1461
-        }
1462
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1463
-        if (($key = array_search($cap, $caps)) !== false) {
1464
-            unset($caps[ $key ]);
1465
-        }
1466
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1467
-        // if no obj then let's just do cap
1468
-        if (! $obj instanceof EE_Base_Class) {
1469
-            $caps[] = 'do_not_allow';
1470
-            return $caps;
1471
-        }
1472
-        $caps[] = $cap . 's';
1473
-        $is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1474
-        $is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1475
-        if ($is_system) {
1476
-            $caps[] = $this->private_cap;
1477
-        }
1478
-        return $caps;
1479
-    }
1444
+	/**
1445
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1446
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1447
+	 *
1448
+	 * @since 4.5.0
1449
+	 * @see   wp-includes/capabilities.php
1450
+	 * @param array  $caps    actual users capabilities
1451
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1452
+	 * @param int    $user_id The user id
1453
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1454
+	 * @return array   actual users capabilities
1455
+	 */
1456
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1457
+	{
1458
+		// only process if we're checking our mapped_cap
1459
+		if ($cap !== $this->meta_cap) {
1460
+			return $caps;
1461
+		}
1462
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1463
+		if (($key = array_search($cap, $caps)) !== false) {
1464
+			unset($caps[ $key ]);
1465
+		}
1466
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1467
+		// if no obj then let's just do cap
1468
+		if (! $obj instanceof EE_Base_Class) {
1469
+			$caps[] = 'do_not_allow';
1470
+			return $caps;
1471
+		}
1472
+		$caps[] = $cap . 's';
1473
+		$is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1474
+		$is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1475
+		if ($is_system) {
1476
+			$caps[] = $this->private_cap;
1477
+		}
1478
+		return $caps;
1479
+	}
1480 1480
 }
Please login to merge, or discard this patch.