Completed
Branch fix-dummy-related-question-qst... (e5efcf)
by
unknown
07:49 queued 03:45
created
core/exceptions/InvalidStatusException.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -7,26 +7,26 @@
 block discarded – undo
7 7
 
8 8
 class InvalidStatusException extends InvalidArgumentException
9 9
 {
10
-    /**
11
-     * InvalidStatusException constructor.
12
-     * @param string $status the invalid status id that was supplied
13
-     * @param string $domain the name of the domain, model, or class that the status belongs to
14
-     * @param string $message custom message
15
-     * @param int $code
16
-     * @param Exception|null $previous
17
-     */
18
-    public function __construct($status, $domain, $message = '', $code = 0, Exception $previous = null)
19
-    {
20
-        if (empty($message)) {
21
-            $message = sprintf(
22
-                esc_html__(
23
-                    '"%1$s" is not a valid %2$s status',
24
-                    'event_espresso'
25
-                ),
26
-                $status,
27
-                $domain
28
-            );
29
-        }
30
-        parent::__construct($message, $code, $previous);
31
-    }
10
+	/**
11
+	 * InvalidStatusException constructor.
12
+	 * @param string $status the invalid status id that was supplied
13
+	 * @param string $domain the name of the domain, model, or class that the status belongs to
14
+	 * @param string $message custom message
15
+	 * @param int $code
16
+	 * @param Exception|null $previous
17
+	 */
18
+	public function __construct($status, $domain, $message = '', $code = 0, Exception $previous = null)
19
+	{
20
+		if (empty($message)) {
21
+			$message = sprintf(
22
+				esc_html__(
23
+					'"%1$s" is not a valid %2$s status',
24
+					'event_espresso'
25
+				),
26
+				$status,
27
+				$domain
28
+			);
29
+		}
30
+		parent::__construct($message, $code, $previous);
31
+	}
32 32
 }
Please login to merge, or discard this patch.
core/exceptions/InvalidDataTypeException.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
     {
32 32
         if (empty($message)) {
33 33
             $expected = strpos(' was expected.', $expected) === false
34
-                ? $this->addIndefiniteArticle($expected) . ' was expected.'
34
+                ? $this->addIndefiniteArticle($expected).' was expected.'
35 35
                 : $expected;
36 36
             $message = sprintf(
37 37
                 esc_html__(
@@ -56,6 +56,6 @@  discard block
 block discarded – undo
56 56
         if (strtolower($string) === 'null') {
57 57
             return $string;
58 58
         }
59
-        return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ') . $string;
59
+        return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ').$string;
60 60
     }
61 61
 }
Please login to merge, or discard this patch.
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -15,46 +15,46 @@
 block discarded – undo
15 15
  */
16 16
 class InvalidDataTypeException extends InvalidArgumentException
17 17
 {
18
-    /**
19
-     * InvalidDataTypeException constructor
20
-     *
21
-     * @param string    $var_name  name of the variable that was of the wrong type ie: "$my_var"
22
-     * @param mixed     $variable  the actual variable that was of the wrong data type, ie: $my_var
23
-     * @param string    $expected  data type we wanted ie: "integer", "string", "array", etc.
24
-     *                             or an entire rewrite of: "{something something} was expected."
25
-     * @param string    $message
26
-     * @param int       $code
27
-     * @param Exception $previous
28
-     */
29
-    public function __construct($var_name, $variable, $expected, $message = '', $code = 0, Exception $previous = null)
30
-    {
31
-        if (empty($message)) {
32
-            $expected = strpos(' was expected.', $expected) === false
33
-                ? $this->addIndefiniteArticle($expected) . ' was expected.'
34
-                : $expected;
35
-            $message = sprintf(
36
-                esc_html__(
37
-                    'The supplied data for "%1$s" was %2$s, but %3$s',
38
-                    'event_espresso'
39
-                ),
40
-                $var_name,
41
-                $this->addIndefiniteArticle(gettype($variable)),
42
-                $expected
43
-            );
44
-        }
45
-        parent::__construct($message, $code, $previous);
46
-    }
18
+	/**
19
+	 * InvalidDataTypeException constructor
20
+	 *
21
+	 * @param string    $var_name  name of the variable that was of the wrong type ie: "$my_var"
22
+	 * @param mixed     $variable  the actual variable that was of the wrong data type, ie: $my_var
23
+	 * @param string    $expected  data type we wanted ie: "integer", "string", "array", etc.
24
+	 *                             or an entire rewrite of: "{something something} was expected."
25
+	 * @param string    $message
26
+	 * @param int       $code
27
+	 * @param Exception $previous
28
+	 */
29
+	public function __construct($var_name, $variable, $expected, $message = '', $code = 0, Exception $previous = null)
30
+	{
31
+		if (empty($message)) {
32
+			$expected = strpos(' was expected.', $expected) === false
33
+				? $this->addIndefiniteArticle($expected) . ' was expected.'
34
+				: $expected;
35
+			$message = sprintf(
36
+				esc_html__(
37
+					'The supplied data for "%1$s" was %2$s, but %3$s',
38
+					'event_espresso'
39
+				),
40
+				$var_name,
41
+				$this->addIndefiniteArticle(gettype($variable)),
42
+				$expected
43
+			);
44
+		}
45
+		parent::__construct($message, $code, $previous);
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * @param $string
51
-     * @return string
52
-     */
53
-    protected function addIndefiniteArticle($string)
54
-    {
55
-        if (strtolower($string) === 'null') {
56
-            return $string;
57
-        }
58
-        return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ') . $string;
59
-    }
49
+	/**
50
+	 * @param $string
51
+	 * @return string
52
+	 */
53
+	protected function addIndefiniteArticle($string)
54
+	{
55
+		if (strtolower($string) === 'null') {
56
+			return $string;
57
+		}
58
+		return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ') . $string;
59
+	}
60 60
 }
Please login to merge, or discard this patch.
core/EE_Capabilities.core.php 2 patches
Spacing   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
     public static function instance()
81 81
     {
82 82
         // check if instantiated, and if not do so.
83
-        if (! self::$_instance instanceof EE_Capabilities) {
83
+        if ( ! self::$_instance instanceof EE_Capabilities) {
84 84
             self::$_instance = new self();
85 85
         }
86 86
         return self::$_instance;
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
      */
111 111
     public function init_caps($reset = false)
112 112
     {
113
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
113
+        if ( ! EE_Maintenance_Mode::instance()->models_can_query()) {
114 114
             return false;
115 115
         }
116 116
         $this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
             $this->_get_default_meta_caps_array()
156 156
         );
157 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'))) {
158
+        if ( ! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
159 159
             add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
160 160
         }
161 161
     }
@@ -314,11 +314,11 @@  discard block
 block discarded – undo
314 314
         if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
315 315
             // loop through our _meta_caps array
316 316
             foreach ($this->_meta_caps as $meta_map) {
317
-                if (! $meta_map instanceof EE_Meta_Capability_Map) {
317
+                if ( ! $meta_map instanceof EE_Meta_Capability_Map) {
318 318
                     continue;
319 319
                 }
320 320
                 // don't load models if there is no object ID in the args
321
-                if (! empty($args[0])) {
321
+                if ( ! empty($args[0])) {
322 322
                     $meta_map->ensure_is_model();
323 323
                 }
324 324
                 $caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
@@ -654,7 +654,7 @@  discard block
 block discarded – undo
654 654
     public function addCaps(array $capabilities_to_add)
655 655
     {
656 656
         // don't do anything if the capabilities map can not be initialized
657
-        if (! $this->setupCapabilitiesMap()) {
657
+        if ( ! $this->setupCapabilitiesMap()) {
658 658
             return false;
659 659
         }
660 660
         // and filter the array so others can get in on the fun during resets
@@ -696,7 +696,7 @@  discard block
 block discarded – undo
696 696
     public function removeCaps($caps_map)
697 697
     {
698 698
         // don't do anything if the capabilities map can not be initialized
699
-        if (! $this->setupCapabilitiesMap()) {
699
+        if ( ! $this->setupCapabilitiesMap()) {
700 700
             return false;
701 701
         }
702 702
         $update_capabilities_map = false;
@@ -756,7 +756,7 @@  discard block
 block discarded – undo
756 756
         $orig_role = $role;
757 757
         $role = $role instanceof WP_Role ? $role : get_role($role);
758 758
         // if the role isn't available then we create it.
759
-        if (! $role instanceof WP_Role) {
759
+        if ( ! $role instanceof WP_Role) {
760 760
             // if a plugin wants to create a specific role name then they should create the role before
761 761
             // EE_Capabilities does.  Otherwise this function will create the role name from the slug:
762 762
             // - removes any `ee_` namespacing from the start of the slug.
@@ -767,12 +767,12 @@  discard block
 block discarded – undo
767 767
         }
768 768
         if ($role instanceof WP_Role) {
769 769
             // don't do anything if the capabilities map can not be initialized
770
-            if (! $this->setupCapabilitiesMap()) {
770
+            if ( ! $this->setupCapabilitiesMap()) {
771 771
                 return false;
772 772
             }
773
-            if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
773
+            if ( ! $this->capHasBeenAddedToRole($role->name, $cap)) {
774 774
                 $role->add_cap($cap, $grant);
775
-                $this->capabilities_map[ $role->name ][] = $cap;
775
+                $this->capabilities_map[$role->name][] = $cap;
776 776
                 $this->updateCapabilitiesMap($update_capabilities_map);
777 777
                 return true;
778 778
             }
@@ -796,14 +796,14 @@  discard block
 block discarded – undo
796 796
     public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
797 797
     {
798 798
         // don't do anything if the capabilities map can not be initialized
799
-        if (! $this->setupCapabilitiesMap()) {
799
+        if ( ! $this->setupCapabilitiesMap()) {
800 800
             return false;
801 801
         }
802 802
 
803 803
         $role = $role instanceof WP_Role ? $role : get_role($role);
804 804
         if ($role instanceof WP_Role && $index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
805 805
             $role->remove_cap($cap);
806
-            unset($this->capabilities_map[ $role->name ][ $index ]);
806
+            unset($this->capabilities_map[$role->name][$index]);
807 807
             $this->updateCapabilitiesMap($update_capabilities_map);
808 808
             return true;
809 809
         }
@@ -820,8 +820,8 @@  discard block
 block discarded – undo
820 820
     private function capHasBeenAddedToRole($role_name = '', $cap = '', $get_index = false)
821 821
     {
822 822
         if (
823
-            isset($this->capabilities_map[ $role_name ])
824
-            && ($index = array_search($cap, $this->capabilities_map[ $role_name ], true)) !== false
823
+            isset($this->capabilities_map[$role_name])
824
+            && ($index = array_search($cap, $this->capabilities_map[$role_name], true)) !== false
825 825
         ) {
826 826
             return $get_index ? $index : true;
827 827
         }
@@ -848,7 +848,7 @@  discard block
 block discarded – undo
848 848
     public function current_user_can($cap, $context, $id = 0)
849 849
     {
850 850
         // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
851
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
851
+        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__'.$context, $cap, $id);
852 852
         $filtered_cap = apply_filters(
853 853
             'FHEE__EE_Capabilities__current_user_can__cap',
854 854
             $filtered_cap,
@@ -876,7 +876,7 @@  discard block
 block discarded – undo
876 876
     public function user_can($user, $cap, $context, $id = 0)
877 877
     {
878 878
         // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
879
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
879
+        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__'.$context, $cap, $user, $id);
880 880
         $filtered_cap = apply_filters(
881 881
             'FHEE__EE_Capabilities__user_can__cap',
882 882
             $filtered_cap,
@@ -915,7 +915,7 @@  discard block
 block discarded – undo
915 915
             : current_user_can($blog_id, $cap);
916 916
         // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
917 917
         $user_can = apply_filters(
918
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
918
+            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__'.$context,
919 919
             $user_can,
920 920
             $blog_id,
921 921
             $cap,
@@ -944,14 +944,14 @@  discard block
 block discarded – undo
944 944
      */
945 945
     public function get_ee_capabilities($role = 'administrator')
946 946
     {
947
-        if (! $this->initialized) {
947
+        if ( ! $this->initialized) {
948 948
             $this->init_caps();
949 949
         }
950 950
         if (empty($role)) {
951 951
             return $this->capabilities_map;
952 952
         }
953
-        return isset($this->capabilities_map[ $role ])
954
-            ? $this->capabilities_map[ $role ]
953
+        return isset($this->capabilities_map[$role])
954
+            ? $this->capabilities_map[$role]
955 955
             : array();
956 956
     }
957 957
 
@@ -982,7 +982,7 @@  discard block
 block discarded – undo
982 982
                         'event_espresso'
983 983
                     ),
984 984
                     '$reset',
985
-                    __METHOD__ . '()',
985
+                    __METHOD__.'()',
986 986
                     'EE_Capabilities::init_caps()',
987 987
                     'true'
988 988
                 ),
@@ -1056,7 +1056,7 @@  discard block
 block discarded – undo
1056 1056
                         'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1057 1057
                         'event_espresso'
1058 1058
                     ),
1059
-                    '<br>' . print_r($map_values, true)
1059
+                    '<br>'.print_r($map_values, true)
1060 1060
                 )
1061 1061
             );
1062 1062
         }
@@ -1096,7 +1096,7 @@  discard block
 block discarded – undo
1096 1096
         // error proof if the name has EEM in it
1097 1097
         $this->_model_name = str_replace('EEM', '', $this->_model_name);
1098 1098
         $this->_model = EE_Registry::instance()->load_model($this->_model_name);
1099
-        if (! $this->_model instanceof EEM_Base) {
1099
+        if ( ! $this->_model instanceof EEM_Base) {
1100 1100
             throw new EE_Error(
1101 1101
                 sprintf(
1102 1102
                     esc_html__(
@@ -1182,7 +1182,7 @@  discard block
 block discarded – undo
1182 1182
 
1183 1183
         // okay it is a meta cap so let's first remove that cap from the $caps array.
1184 1184
         if (($key = array_search($cap, $caps)) !== false) {
1185
-            unset($caps[ $key ]);
1185
+            unset($caps[$key]);
1186 1186
         }
1187 1187
 
1188 1188
         // cast $user_id to int for later explicit comparisons
@@ -1191,11 +1191,11 @@  discard block
 block discarded – undo
1191 1191
         /** @var EE_Base_Class $obj */
1192 1192
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1193 1193
         // if no obj then let's just do cap
1194
-        if (! $obj instanceof EE_Base_Class) {
1194
+        if ( ! $obj instanceof EE_Base_Class) {
1195 1195
             $caps[] = 'do_not_allow';
1196 1196
             return $caps;
1197 1197
         }
1198
-        $caps[] = $cap . 's';
1198
+        $caps[] = $cap.'s';
1199 1199
         if ($obj instanceof EE_CPT_Base) {
1200 1200
             // if the item author is set and the user is the author...
1201 1201
             if ($obj->wp_user() && $user_id === $obj->wp_user()) {
@@ -1205,12 +1205,12 @@  discard block
 block discarded – undo
1205 1205
                 }
1206 1206
             } else {
1207 1207
                 // the user is trying to edit someone else's obj
1208
-                if (! empty($this->others_cap)) {
1208
+                if ( ! empty($this->others_cap)) {
1209 1209
                     $caps[] = $this->others_cap;
1210 1210
                 }
1211
-                if (! empty($this->published_cap) && $obj->status() === 'publish') {
1211
+                if ( ! empty($this->published_cap) && $obj->status() === 'publish') {
1212 1212
                     $caps[] = $this->published_cap;
1213
-                } elseif (! empty($this->private_cap) && $obj->status() === 'private') {
1213
+                } elseif ( ! empty($this->private_cap) && $obj->status() === 'private') {
1214 1214
                     $caps[] = $this->private_cap;
1215 1215
                 }
1216 1216
             }
@@ -1226,8 +1226,8 @@  discard block
 block discarded – undo
1226 1226
                     EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1227 1227
                 }
1228 1228
             }
1229
-            if (! $has_cap) {
1230
-                if (! empty($this->others_cap)) {
1229
+            if ( ! $has_cap) {
1230
+                if ( ! empty($this->others_cap)) {
1231 1231
                     $caps[] = $this->others_cap;
1232 1232
                 }
1233 1233
             }
@@ -1306,7 +1306,7 @@  discard block
 block discarded – undo
1306 1306
 
1307 1307
         // okay it is a meta cap so let's first remove that cap from the $caps array.
1308 1308
         if (($key = array_search($cap, $caps)) !== false) {
1309
-            unset($caps[ $key ]);
1309
+            unset($caps[$key]);
1310 1310
         }
1311 1311
 
1312 1312
         // cast $user_id to int for later explicit comparisons
@@ -1314,12 +1314,12 @@  discard block
 block discarded – undo
1314 1314
 
1315 1315
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1316 1316
         // if no obj then let's just do cap
1317
-        if (! $obj instanceof EE_Base_Class) {
1317
+        if ( ! $obj instanceof EE_Base_Class) {
1318 1318
             $caps[] = 'do_not_allow';
1319 1319
             return $caps;
1320 1320
         }
1321 1321
 
1322
-        $caps[] = $cap . 's';
1322
+        $caps[] = $cap.'s';
1323 1323
         if ($obj instanceof EE_CPT_Base) {
1324 1324
             $status_obj = get_post_status_object($obj->status());
1325 1325
             if ($status_obj->public) {
@@ -1327,7 +1327,7 @@  discard block
 block discarded – undo
1327 1327
             }
1328 1328
             // if the item author is set and the user is not the author...
1329 1329
             if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1330
-                if (! empty($this->others_cap)) {
1330
+                if ( ! empty($this->others_cap)) {
1331 1331
                     $caps[] = $this->others_cap;
1332 1332
                 }
1333 1333
             }
@@ -1352,11 +1352,11 @@  discard block
 block discarded – undo
1352 1352
                     EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1353 1353
                 }
1354 1354
             }
1355
-            if (! $has_cap) {
1356
-                if (! empty($this->private_cap)) {
1355
+            if ( ! $has_cap) {
1356
+                if ( ! empty($this->private_cap)) {
1357 1357
                     $caps[] = $this->private_cap;
1358 1358
                 }
1359
-                if (! empty($this->others_cap)) {
1359
+                if ( ! empty($this->others_cap)) {
1360 1360
                     $caps[] = $this->others_cap;
1361 1361
                 }
1362 1362
             }
@@ -1402,7 +1402,7 @@  discard block
 block discarded – undo
1402 1402
 
1403 1403
         // okay it is a meta cap so let's first remove that cap from the $caps array.
1404 1404
         if (($key = array_search($cap, $caps)) !== false) {
1405
-            unset($caps[ $key ]);
1405
+            unset($caps[$key]);
1406 1406
         }
1407 1407
 
1408 1408
         // cast $user_id to int for later explicit comparisons
@@ -1410,11 +1410,11 @@  discard block
 block discarded – undo
1410 1410
 
1411 1411
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1412 1412
         // if no obj then let's just do cap
1413
-        if (! $obj instanceof EE_Message_Template_Group) {
1413
+        if ( ! $obj instanceof EE_Message_Template_Group) {
1414 1414
             $caps[] = 'do_not_allow';
1415 1415
             return $caps;
1416 1416
         }
1417
-        $caps[] = $cap . 's';
1417
+        $caps[] = $cap.'s';
1418 1418
         $is_global = $obj->is_global();
1419 1419
         if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1420 1420
             if ($is_global) {
@@ -1465,15 +1465,15 @@  discard block
 block discarded – undo
1465 1465
         }
1466 1466
         // okay it is a meta cap so let's first remove that cap from the $caps array.
1467 1467
         if (($key = array_search($cap, $caps)) !== false) {
1468
-            unset($caps[ $key ]);
1468
+            unset($caps[$key]);
1469 1469
         }
1470 1470
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1471 1471
         // if no obj then let's just do cap
1472
-        if (! $obj instanceof EE_Base_Class) {
1472
+        if ( ! $obj instanceof EE_Base_Class) {
1473 1473
             $caps[] = 'do_not_allow';
1474 1474
             return $caps;
1475 1475
         }
1476
-        $caps[] = $cap . 's';
1476
+        $caps[] = $cap.'s';
1477 1477
         $is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1478 1478
         $is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1479 1479
         if ($is_system) {
Please login to merge, or discard this patch.
Indentation   +1373 added lines, -1373 removed lines patch added patch discarded remove patch
@@ -13,984 +13,984 @@  discard block
 block discarded – undo
13 13
  */
14 14
 final class EE_Capabilities extends EE_Base
15 15
 {
16
-    /**
17
-     * the name of the wp option used to store caps previously initialized
18
-     */
19
-    const option_name = 'ee_caps_initialized';
20
-
21
-    /**
22
-     * instance of EE_Capabilities object
23
-     *
24
-     * @var EE_Capabilities
25
-     */
26
-    private static $_instance;
27
-
28
-
29
-    /**
30
-     * This is a map of caps that correspond to a default WP_Role.
31
-     * Array is indexed by Role and values are ee capabilities.
32
-     *
33
-     * @since 4.5.0
34
-     *
35
-     * @var array
36
-     */
37
-    private $capabilities_map = array();
38
-
39
-    /**
40
-     * This used to hold an array of EE_Meta_Capability_Map objects
41
-     * that define the granular capabilities mapped to for a user depending on context.
42
-     *
43
-     * @var EE_Meta_Capability_Map[]
44
-     */
45
-    private $_meta_caps = array();
46
-
47
-    /**
48
-     * The internal $capabilities_map needs to be initialized before it can be used.
49
-     * This flag tracks whether that has happened or not.
50
-     * But for this to work, we need three states to indicate:
51
-     *      initialization has not occurred at all
52
-     *      initialization has started but is not complete
53
-     *      initialization is complete
54
-     * The reason this is needed is because the addCaps() method
55
-     * normally requires the $capabilities_map to be initialized,
56
-     * but is also used during the initialization process.
57
-     * So:
58
-     *      If initialized === null, init_caps() will be called before any other methods will run.
59
-     *      If initialized === false, then init_caps() is in the process of running it's logic.
60
-     *      If initialized === true, then init_caps() has completed the initialization process.
61
-     *
62
-     * @var boolean|null $initialized
63
-     */
64
-    private $initialized;
65
-
66
-    /**
67
-     * @var boolean $reset
68
-     */
69
-    private $reset = false;
70
-
71
-
72
-    /**
73
-     * singleton method used to instantiate class object
74
-     *
75
-     * @since 4.5.0
76
-     *
77
-     * @return EE_Capabilities
78
-     */
79
-    public static function instance()
80
-    {
81
-        // check if instantiated, and if not do so.
82
-        if (! self::$_instance instanceof EE_Capabilities) {
83
-            self::$_instance = new self();
84
-        }
85
-        return self::$_instance;
86
-    }
87
-
88
-
89
-    /**
90
-     * private constructor
91
-     *
92
-     * @since 4.5.0
93
-     */
94
-    private function __construct()
95
-    {
96
-    }
97
-
98
-
99
-    /**
100
-     * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
101
-     *
102
-     * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't
103
-     *                    actually REMOVE any capabilities from existing roles, it just resaves defaults roles and
104
-     *                    ensures that they are up to date.
105
-     *
106
-     * @since 4.5.0
107
-     * @return bool
108
-     * @throws EE_Error
109
-     */
110
-    public function init_caps($reset = false)
111
-    {
112
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
113
-            return false;
114
-        }
115
-        $this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
116
-        // if reset, then completely delete the cache option and clear the $capabilities_map property.
117
-        if ($this->reset) {
118
-            $this->initialized = null;
119
-            $this->capabilities_map = array();
120
-            delete_option(self::option_name);
121
-        }
122
-        if ($this->initialized === null) {
123
-            $this->initialized = false;
124
-            do_action(
125
-                'AHEE__EE_Capabilities__init_caps__before_initialization',
126
-                $this->reset
127
-            );
128
-            $this->addCaps($this->_init_caps_map());
129
-            $this->_set_meta_caps();
130
-            do_action(
131
-                'AHEE__EE_Capabilities__init_caps__after_initialization',
132
-                $this->capabilities_map
133
-            );
134
-            $this->initialized = true;
135
-        }
136
-        // reset $this->reset so that it's not stuck on true if init_caps() gets called again
137
-        $this->reset = false;
138
-        return true;
139
-    }
140
-
141
-
142
-    /**
143
-     * This sets the meta caps property.
144
-     *
145
-     * @since 4.5.0
146
-     * @return void
147
-     * @throws EE_Error
148
-     */
149
-    private function _set_meta_caps()
150
-    {
151
-        // get default meta caps and filter the returned array
152
-        $this->_meta_caps = apply_filters(
153
-            'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
154
-            $this->_get_default_meta_caps_array()
155
-        );
156
-        // add filter for map_meta_caps but only if models can query.
157
-        if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
158
-            add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
159
-        }
160
-    }
161
-
162
-
163
-    /**
164
-     * This builds and returns the default meta_caps array only once.
165
-     *
166
-     * @since  4.8.28.rc.012
167
-     * @return array
168
-     * @throws EE_Error
169
-     */
170
-    private function _get_default_meta_caps_array()
171
-    {
172
-        static $default_meta_caps = array();
173
-        // make sure we're only ever initializing the default _meta_caps array once if it's empty.
174
-        if (empty($default_meta_caps)) {
175
-            $default_meta_caps = array(
176
-                // edits
177
-                new EE_Meta_Capability_Map_Edit(
178
-                    'ee_edit_event',
179
-                    array('Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events')
180
-                ),
181
-                new EE_Meta_Capability_Map_Edit(
182
-                    'ee_edit_venue',
183
-                    array('Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues')
184
-                ),
185
-                new EE_Meta_Capability_Map_Edit(
186
-                    'ee_edit_registration',
187
-                    array('Registration', '', 'ee_edit_others_registrations', '')
188
-                ),
189
-                new EE_Meta_Capability_Map_Edit(
190
-                    'ee_edit_checkin',
191
-                    array('Registration', '', 'ee_edit_others_checkins', '')
192
-                ),
193
-                new EE_Meta_Capability_Map_Messages_Cap(
194
-                    'ee_edit_message',
195
-                    array('Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages')
196
-                ),
197
-                new EE_Meta_Capability_Map_Edit(
198
-                    'ee_edit_default_ticket',
199
-                    array('Ticket', '', 'ee_edit_others_default_tickets', '')
200
-                ),
201
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
202
-                    'ee_edit_question',
203
-                    array('Question', '', '', 'ee_edit_system_questions')
204
-                ),
205
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
206
-                    'ee_edit_question_group',
207
-                    array('Question_Group', '', '', 'ee_edit_system_question_groups')
208
-                ),
209
-                new EE_Meta_Capability_Map_Edit(
210
-                    'ee_edit_payment_method',
211
-                    array('Payment_Method', '', 'ee_edit_others_payment_methods', '')
212
-                ),
213
-                // reads
214
-                new EE_Meta_Capability_Map_Read(
215
-                    'ee_read_event',
216
-                    array('Event', '', 'ee_read_others_events', 'ee_read_private_events')
217
-                ),
218
-                new EE_Meta_Capability_Map_Read(
219
-                    'ee_read_venue',
220
-                    array('Venue', '', 'ee_read_others_venues', 'ee_read_private_venues')
221
-                ),
222
-                new EE_Meta_Capability_Map_Read(
223
-                    'ee_read_registration',
224
-                    array('Registration', '', 'ee_read_others_registrations', '')
225
-                ),
226
-                new EE_Meta_Capability_Map_Read(
227
-                    'ee_read_checkin',
228
-                    array('Registration', '', 'ee_read_others_checkins', '')
229
-                ),
230
-                new EE_Meta_Capability_Map_Messages_Cap(
231
-                    'ee_read_message',
232
-                    array('Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages')
233
-                ),
234
-                new EE_Meta_Capability_Map_Read(
235
-                    'ee_read_default_ticket',
236
-                    array('Ticket', '', 'ee_read_others_default_tickets', '')
237
-                ),
238
-                new EE_Meta_Capability_Map_Read(
239
-                    'ee_read_payment_method',
240
-                    array('Payment_Method', '', 'ee_read_others_payment_methods', '')
241
-                ),
242
-                // deletes
243
-                new EE_Meta_Capability_Map_Delete(
244
-                    'ee_delete_event',
245
-                    array(
246
-                        'Event',
247
-                        'ee_delete_published_events',
248
-                        'ee_delete_others_events',
249
-                        'ee_delete_private_events',
250
-                    )
251
-                ),
252
-                new EE_Meta_Capability_Map_Delete(
253
-                    'ee_delete_venue',
254
-                    array(
255
-                        'Venue',
256
-                        'ee_delete_published_venues',
257
-                        'ee_delete_others_venues',
258
-                        'ee_delete_private_venues',
259
-                    )
260
-                ),
261
-                new EE_Meta_Capability_Map_Delete(
262
-                    'ee_delete_registration',
263
-                    array('Registration', '', 'ee_delete_others_registrations', '')
264
-                ),
265
-                new EE_Meta_Capability_Map_Delete(
266
-                    'ee_delete_checkin',
267
-                    array('Registration', '', 'ee_delete_others_checkins', '')
268
-                ),
269
-                new EE_Meta_Capability_Map_Messages_Cap(
270
-                    'ee_delete_message',
271
-                    array('Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages')
272
-                ),
273
-                new EE_Meta_Capability_Map_Delete(
274
-                    'ee_delete_default_ticket',
275
-                    array('Ticket', '', 'ee_delete_others_default_tickets', '')
276
-                ),
277
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
278
-                    'ee_delete_question',
279
-                    array('Question', '', '', 'delete_system_questions')
280
-                ),
281
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
282
-                    'ee_delete_question_group',
283
-                    array('Question_Group', '', '', 'delete_system_question_groups')
284
-                ),
285
-                new EE_Meta_Capability_Map_Delete(
286
-                    'ee_delete_payment_method',
287
-                    array('Payment_Method', '', 'ee_delete_others_payment_methods', '')
288
-                ),
289
-            );
290
-        }
291
-        return $default_meta_caps;
292
-    }
293
-
294
-
295
-    /**
296
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
297
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
298
-     *
299
-     * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
300
-     *
301
-     * @since 4.5.0
302
-     * @see   wp-includes/capabilities.php
303
-     *
304
-     * @param array  $caps    actual users capabilities
305
-     * @param string $cap     initial capability name that is being checked (the "map" key)
306
-     * @param int    $user_id The user id
307
-     * @param array  $args    Adds context to the cap. Typically the object ID.
308
-     * @return array actual users capabilities
309
-     * @throws EE_Error
310
-     */
311
-    public function map_meta_caps($caps, $cap, $user_id, $args)
312
-    {
313
-        if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
314
-            // loop through our _meta_caps array
315
-            foreach ($this->_meta_caps as $meta_map) {
316
-                if (! $meta_map instanceof EE_Meta_Capability_Map) {
317
-                    continue;
318
-                }
319
-                // don't load models if there is no object ID in the args
320
-                if (! empty($args[0])) {
321
-                    $meta_map->ensure_is_model();
322
-                }
323
-                $caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
324
-            }
325
-        }
326
-        return $caps;
327
-    }
328
-
329
-
330
-    /**
331
-     * This sets up and returns the initial capabilities map for Event Espresso
332
-     * Note this array is filtered.
333
-     * It is assumed that all available EE capabilities are assigned to the administrator role.
334
-     *
335
-     * @since 4.5.0
336
-     *
337
-     * @return array
338
-     */
339
-    private function _init_caps_map()
340
-    {
341
-        return apply_filters(
342
-            'FHEE__EE_Capabilities__init_caps_map__caps',
343
-            array(
344
-                'administrator'           => array(
345
-                    // basic access
346
-                    'ee_read_ee',
347
-                    // gateways
348
-                    /**
349
-                     * note that with payment method capabilities, although we've implemented
350
-                     * capability mapping which will be used for accessing payment methods owned by
351
-                     * other users.  This is not fully implemented yet in the payment method ui.
352
-                     * Currently only the "plural" caps are in active use.
353
-                     * (Specific payment method caps are in use as well).
354
-                     **/
355
-                    'ee_manage_gateways',
356
-                    'ee_read_payment_methods',
357
-                    'ee_read_others_payment_methods',
358
-                    'ee_edit_payment_methods',
359
-                    'ee_edit_others_payment_methods',
360
-                    'ee_delete_payment_methods',
361
-                    // events
362
-                    'ee_publish_events',
363
-                    'ee_read_private_events',
364
-                    'ee_read_others_events',
365
-                    'ee_read_events',
366
-                    'ee_edit_events',
367
-                    'ee_edit_published_events',
368
-                    'ee_edit_others_events',
369
-                    'ee_edit_private_events',
370
-                    'ee_delete_published_events',
371
-                    'ee_delete_private_events',
372
-                    'ee_delete_events',
373
-                    'ee_delete_others_events',
374
-                    // event categories
375
-                    'ee_manage_event_categories',
376
-                    'ee_edit_event_category',
377
-                    'ee_delete_event_category',
378
-                    'ee_assign_event_category',
379
-                    // venues
380
-                    'ee_publish_venues',
381
-                    'ee_read_venues',
382
-                    'ee_read_others_venues',
383
-                    'ee_read_private_venues',
384
-                    'ee_edit_venues',
385
-                    'ee_edit_others_venues',
386
-                    'ee_edit_published_venues',
387
-                    'ee_edit_private_venues',
388
-                    'ee_delete_venues',
389
-                    'ee_delete_others_venues',
390
-                    'ee_delete_private_venues',
391
-                    'ee_delete_published_venues',
392
-                    // venue categories
393
-                    'ee_manage_venue_categories',
394
-                    'ee_edit_venue_category',
395
-                    'ee_delete_venue_category',
396
-                    'ee_assign_venue_category',
397
-                    // contacts
398
-                    'ee_read_contacts',
399
-                    'ee_edit_contacts',
400
-                    'ee_delete_contacts',
401
-                    // registrations
402
-                    'ee_read_registrations',
403
-                    'ee_read_others_registrations',
404
-                    'ee_edit_registrations',
405
-                    'ee_edit_others_registrations',
406
-                    'ee_delete_registrations',
407
-                    'ee_delete_others_registrations',
408
-                    // checkins
409
-                    'ee_read_others_checkins',
410
-                    'ee_read_checkins',
411
-                    'ee_edit_checkins',
412
-                    'ee_edit_others_checkins',
413
-                    'ee_delete_checkins',
414
-                    'ee_delete_others_checkins',
415
-                    // transactions && payments
416
-                    'ee_read_transaction',
417
-                    'ee_read_transactions',
418
-                    'ee_edit_payments',
419
-                    'ee_delete_payments',
420
-                    // messages
421
-                    'ee_read_messages',
422
-                    'ee_read_others_messages',
423
-                    'ee_read_global_messages',
424
-                    'ee_edit_global_messages',
425
-                    'ee_edit_messages',
426
-                    'ee_edit_others_messages',
427
-                    'ee_delete_messages',
428
-                    'ee_delete_others_messages',
429
-                    'ee_delete_global_messages',
430
-                    'ee_send_message',
431
-                    // tickets
432
-                    'ee_read_default_tickets',
433
-                    'ee_read_others_default_tickets',
434
-                    'ee_edit_default_tickets',
435
-                    'ee_edit_others_default_tickets',
436
-                    'ee_delete_default_tickets',
437
-                    'ee_delete_others_default_tickets',
438
-                    // prices
439
-                    'ee_edit_default_price',
440
-                    'ee_edit_default_prices',
441
-                    'ee_delete_default_price',
442
-                    'ee_delete_default_prices',
443
-                    'ee_edit_default_price_type',
444
-                    'ee_edit_default_price_types',
445
-                    'ee_delete_default_price_type',
446
-                    'ee_delete_default_price_types',
447
-                    'ee_read_default_prices',
448
-                    'ee_read_default_price_types',
449
-                    // registration form
450
-                    'ee_edit_questions',
451
-                    'ee_edit_system_questions',
452
-                    'ee_read_questions',
453
-                    'ee_delete_questions',
454
-                    'ee_edit_question_groups',
455
-                    'ee_read_question_groups',
456
-                    'ee_edit_system_question_groups',
457
-                    'ee_delete_question_groups',
458
-                    // event_type taxonomy
459
-                    'ee_assign_event_type',
460
-                    'ee_manage_event_types',
461
-                    'ee_edit_event_type',
462
-                    'ee_delete_event_type',
463
-                ),
464
-                'ee_events_administrator' => array(
465
-                    // core wp caps
466
-                    'read',
467
-                    'read_private_pages',
468
-                    'read_private_posts',
469
-                    'edit_users',
470
-                    'edit_posts',
471
-                    'edit_pages',
472
-                    'edit_published_posts',
473
-                    'edit_published_pages',
474
-                    'edit_private_pages',
475
-                    'edit_private_posts',
476
-                    'edit_others_posts',
477
-                    'edit_others_pages',
478
-                    'publish_posts',
479
-                    'publish_pages',
480
-                    'delete_posts',
481
-                    'delete_pages',
482
-                    'delete_private_pages',
483
-                    'delete_private_posts',
484
-                    'delete_published_pages',
485
-                    'delete_published_posts',
486
-                    'delete_others_posts',
487
-                    'delete_others_pages',
488
-                    'manage_categories',
489
-                    'manage_links',
490
-                    'moderate_comments',
491
-                    'unfiltered_html',
492
-                    'upload_files',
493
-                    'export',
494
-                    'import',
495
-                    'list_users',
496
-                    'level_1', // required if user with this role shows up in author dropdowns
497
-                    // basic ee access
498
-                    'ee_read_ee',
499
-                    // events
500
-                    'ee_publish_events',
501
-                    'ee_read_private_events',
502
-                    'ee_read_others_events',
503
-                    'ee_read_event',
504
-                    'ee_read_events',
505
-                    'ee_edit_event',
506
-                    'ee_edit_events',
507
-                    'ee_edit_published_events',
508
-                    'ee_edit_others_events',
509
-                    'ee_edit_private_events',
510
-                    'ee_delete_published_events',
511
-                    'ee_delete_private_events',
512
-                    'ee_delete_event',
513
-                    'ee_delete_events',
514
-                    'ee_delete_others_events',
515
-                    // event categories
516
-                    'ee_manage_event_categories',
517
-                    'ee_edit_event_category',
518
-                    'ee_delete_event_category',
519
-                    'ee_assign_event_category',
520
-                    // venues
521
-                    'ee_publish_venues',
522
-                    'ee_read_venue',
523
-                    'ee_read_venues',
524
-                    'ee_read_others_venues',
525
-                    'ee_read_private_venues',
526
-                    'ee_edit_venue',
527
-                    'ee_edit_venues',
528
-                    'ee_edit_others_venues',
529
-                    'ee_edit_published_venues',
530
-                    'ee_edit_private_venues',
531
-                    'ee_delete_venue',
532
-                    'ee_delete_venues',
533
-                    'ee_delete_others_venues',
534
-                    'ee_delete_private_venues',
535
-                    'ee_delete_published_venues',
536
-                    // venue categories
537
-                    'ee_manage_venue_categories',
538
-                    'ee_edit_venue_category',
539
-                    'ee_delete_venue_category',
540
-                    'ee_assign_venue_category',
541
-                    // contacts
542
-                    'ee_read_contacts',
543
-                    'ee_edit_contacts',
544
-                    'ee_delete_contacts',
545
-                    // registrations
546
-                    'ee_read_registrations',
547
-                    'ee_read_others_registrations',
548
-                    'ee_edit_registration',
549
-                    'ee_edit_registrations',
550
-                    'ee_edit_others_registrations',
551
-                    'ee_delete_registration',
552
-                    'ee_delete_registrations',
553
-                    'ee_delete_others_registrations',
554
-                    // checkins
555
-                    'ee_read_others_checkins',
556
-                    'ee_read_checkins',
557
-                    'ee_edit_checkins',
558
-                    'ee_edit_others_checkins',
559
-                    'ee_delete_checkins',
560
-                    'ee_delete_others_checkins',
561
-                    // transactions && payments
562
-                    'ee_read_transaction',
563
-                    'ee_read_transactions',
564
-                    'ee_edit_payments',
565
-                    'ee_delete_payments',
566
-                    // messages
567
-                    'ee_read_messages',
568
-                    'ee_read_others_messages',
569
-                    'ee_read_global_messages',
570
-                    'ee_edit_global_messages',
571
-                    'ee_edit_messages',
572
-                    'ee_edit_others_messages',
573
-                    'ee_delete_messages',
574
-                    'ee_delete_others_messages',
575
-                    'ee_delete_global_messages',
576
-                    'ee_send_message',
577
-                    // tickets
578
-                    'ee_read_default_tickets',
579
-                    'ee_read_others_default_tickets',
580
-                    'ee_edit_default_tickets',
581
-                    'ee_edit_others_default_tickets',
582
-                    'ee_delete_default_tickets',
583
-                    'ee_delete_others_default_tickets',
584
-                    // prices
585
-                    'ee_edit_default_price',
586
-                    'ee_edit_default_prices',
587
-                    'ee_delete_default_price',
588
-                    'ee_delete_default_prices',
589
-                    'ee_edit_default_price_type',
590
-                    'ee_edit_default_price_types',
591
-                    'ee_delete_default_price_type',
592
-                    'ee_delete_default_price_types',
593
-                    'ee_read_default_prices',
594
-                    'ee_read_default_price_types',
595
-                    // registration form
596
-                    'ee_edit_questions',
597
-                    'ee_edit_system_questions',
598
-                    'ee_read_questions',
599
-                    'ee_delete_questions',
600
-                    'ee_edit_question_groups',
601
-                    'ee_read_question_groups',
602
-                    'ee_edit_system_question_groups',
603
-                    'ee_delete_question_groups',
604
-                    // event_type taxonomy
605
-                    'ee_assign_event_type',
606
-                    'ee_manage_event_types',
607
-                    'ee_edit_event_type',
608
-                    'ee_delete_event_type',
609
-                ),
610
-            )
611
-        );
612
-    }
613
-
614
-
615
-    /**
616
-     * @return bool
617
-     * @throws EE_Error
618
-     */
619
-    private function setupCapabilitiesMap()
620
-    {
621
-        // if the initialization process hasn't even started, then we need to call init_caps()
622
-        if ($this->initialized === null) {
623
-            return $this->init_caps();
624
-        }
625
-        // unless resetting, get caps from db if we haven't already
626
-        $this->capabilities_map = $this->reset || ! empty($this->capabilities_map)
627
-            ? $this->capabilities_map
628
-            : get_option(self::option_name, array());
629
-        return true;
630
-    }
631
-
632
-
633
-    /**
634
-     * @param bool $update
635
-     * @return bool
636
-     */
637
-    private function updateCapabilitiesMap($update = true)
638
-    {
639
-        return $update ? update_option(self::option_name, $this->capabilities_map) : false;
640
-    }
641
-
642
-
643
-    /**
644
-     * Adds capabilities to roles.
645
-     *
646
-     * @since 4.9.42
647
-     * @param array $capabilities_to_add array of capabilities to add, indexed by roles.
648
-     *                                   Note that this should ONLY be called on activation hook
649
-     *                                   otherwise the caps will be added on every request.
650
-     * @return bool
651
-     * @throws \EE_Error
652
-     */
653
-    public function addCaps(array $capabilities_to_add)
654
-    {
655
-        // don't do anything if the capabilities map can not be initialized
656
-        if (! $this->setupCapabilitiesMap()) {
657
-            return false;
658
-        }
659
-        // and filter the array so others can get in on the fun during resets
660
-        $capabilities_to_add = apply_filters(
661
-            'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
662
-            $capabilities_to_add,
663
-            $this->reset,
664
-            $this->capabilities_map
665
-        );
666
-        $update_capabilities_map = false;
667
-        // if not reset, see what caps are new for each role. if they're new, add them.
668
-        foreach ($capabilities_to_add as $role => $caps_for_role) {
669
-            if (is_array($caps_for_role)) {
670
-                foreach ($caps_for_role as $cap) {
671
-                    if (
672
-                        ! $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 (
706
-                        $this->capHasBeenAddedToRole($role, $cap)
707
-                        && $this->remove_cap_from_role($role, $cap, false)
708
-                    ) {
709
-                        $update_capabilities_map = true;
710
-                    }
711
-                }
712
-            }
713
-        }
714
-        // maybe resave the caps
715
-        $updated = $this->updateCapabilitiesMap($update_capabilities_map);
716
-        $this->flushWpUser($updated);
717
-        return $updated;
718
-    }
719
-
720
-
721
-    /**
722
-     * This ensures that the WP User object cached on the $current_user global in WP has the latest capabilities from
723
-     * the roles on that user.
724
-     *
725
-     * @param bool $flush Default is to flush the WP_User object.  If false, then this method effectively does nothing.
726
-     */
727
-    private function flushWpUser($flush = true)
728
-    {
729
-        if ($flush) {
730
-            $user = wp_get_current_user();
731
-            if ($user instanceof WP_User) {
732
-                $user->get_role_caps();
733
-            }
734
-        }
735
-    }
736
-
737
-
738
-    /**
739
-     * This method sets a capability on a role.  Note this should only be done on activation, or if you have something
740
-     * specific to prevent the cap from being added on every page load (adding caps are persistent to the db). Note.
741
-     * this is a wrapper for $wp_role->add_cap()
742
-     *
743
-     * @see   wp-includes/capabilities.php
744
-     * @since 4.5.0
745
-     * @param string|WP_Role $role  A WordPress role the capability is being added to
746
-     * @param string         $cap   The capability being added to the role
747
-     * @param bool           $grant Whether to grant access to this cap on this role.
748
-     * @param bool           $update_capabilities_map
749
-     * @return bool
750
-     * @throws \EE_Error
751
-     */
752
-    public function add_cap_to_role($role, $cap, $grant = true, $update_capabilities_map = true)
753
-    {
754
-        // capture incoming value for $role because we may need it to create a new WP_Role
755
-        $orig_role = $role;
756
-        $role = $role instanceof WP_Role ? $role : get_role($role);
757
-        // if the role isn't available then we create it.
758
-        if (! $role instanceof WP_Role) {
759
-            // if a plugin wants to create a specific role name then they should create the role before
760
-            // EE_Capabilities does.  Otherwise this function will create the role name from the slug:
761
-            // - removes any `ee_` namespacing from the start of the slug.
762
-            // - replaces `_` with ` ` (empty space).
763
-            // - sentence case on the resulting string.
764
-            $role_label = ucwords(str_replace(array('ee_', '_'), array('', ' '), $orig_role));
765
-            $role = add_role($orig_role, $role_label);
766
-        }
767
-        if ($role instanceof WP_Role) {
768
-            // don't do anything if the capabilities map can not be initialized
769
-            if (! $this->setupCapabilitiesMap()) {
770
-                return false;
771
-            }
772
-            if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
773
-                $role->add_cap($cap, $grant);
774
-                $this->capabilities_map[ $role->name ][] = $cap;
775
-                $this->updateCapabilitiesMap($update_capabilities_map);
776
-                return true;
777
-            }
778
-        }
779
-        return false;
780
-    }
781
-
782
-
783
-    /**
784
-     * Functions similarly to add_cap_to_role except removes cap from given role.
785
-     * Wrapper for $wp_role->remove_cap()
786
-     *
787
-     * @see   wp-includes/capabilities.php
788
-     * @since 4.5.0
789
-     * @param string|WP_Role $role A WordPress role the capability is being removed from.
790
-     * @param string         $cap  The capability being removed
791
-     * @param bool           $update_capabilities_map
792
-     * @return bool
793
-     * @throws \EE_Error
794
-     */
795
-    public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
796
-    {
797
-        // don't do anything if the capabilities map can not be initialized
798
-        if (! $this->setupCapabilitiesMap()) {
799
-            return false;
800
-        }
801
-
802
-        $role = $role instanceof WP_Role ? $role : get_role($role);
803
-        if ($role instanceof WP_Role && $index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
804
-            $role->remove_cap($cap);
805
-            unset($this->capabilities_map[ $role->name ][ $index ]);
806
-            $this->updateCapabilitiesMap($update_capabilities_map);
807
-            return true;
808
-        }
809
-        return false;
810
-    }
811
-
812
-
813
-    /**
814
-     * @param string $role_name
815
-     * @param string $cap
816
-     * @param bool   $get_index
817
-     * @return bool|mixed
818
-     */
819
-    private function capHasBeenAddedToRole($role_name = '', $cap = '', $get_index = false)
820
-    {
821
-        if (
822
-            isset($this->capabilities_map[ $role_name ])
823
-            && ($index = array_search($cap, $this->capabilities_map[ $role_name ], true)) !== false
824
-        ) {
825
-            return $get_index ? $index : true;
826
-        }
827
-        return false;
828
-    }
829
-
830
-
831
-    /**
832
-     * Wrapper for the native WP current_user_can() method.
833
-     * This is provided as a handy method for a couple things:
834
-     * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
835
-     * write those filters wherever current_user_can is called).
836
-     * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
837
-     *
838
-     * @since 4.5.0
839
-     *
840
-     * @param string $cap     The cap being checked.
841
-     * @param string $context The context where the current_user_can is being called from.
842
-     * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
843
-     *                        filters.
844
-     *
845
-     * @return bool  Whether user can or not.
846
-     */
847
-    public function current_user_can($cap, $context, $id = 0)
848
-    {
849
-        // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
850
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
851
-        $filtered_cap = apply_filters(
852
-            'FHEE__EE_Capabilities__current_user_can__cap',
853
-            $filtered_cap,
854
-            $context,
855
-            $cap,
856
-            $id
857
-        );
858
-        return ! empty($id)
859
-            ? current_user_can($filtered_cap, $id)
860
-            : current_user_can($filtered_cap);
861
-    }
862
-
863
-
864
-    /**
865
-     * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
866
-     *
867
-     * @param int|WP_User $user    Either the user_id or a WP_User object
868
-     * @param string      $cap     The capability string being checked
869
-     * @param string      $context The context where the user_can is being called from (used in filters).
870
-     * @param int         $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap()
871
-     *                             filters)
872
-     *
873
-     * @return bool Whether user can or not.
874
-     */
875
-    public function user_can($user, $cap, $context, $id = 0)
876
-    {
877
-        // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
878
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
879
-        $filtered_cap = apply_filters(
880
-            'FHEE__EE_Capabilities__user_can__cap',
881
-            $filtered_cap,
882
-            $context,
883
-            $cap,
884
-            $user,
885
-            $id
886
-        );
887
-        return ! empty($id)
888
-            ? user_can($user, $filtered_cap, $id)
889
-            : user_can($user, $filtered_cap);
890
-    }
891
-
892
-
893
-    /**
894
-     * Wrapper for the native WP current_user_can_for_blog() method.
895
-     * This is provided as a handy method for a couple things:
896
-     * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
897
-     * write those filters wherever current_user_can is called).
898
-     * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
899
-     *
900
-     * @since 4.5.0
901
-     *
902
-     * @param int    $blog_id The blog id that is being checked for.
903
-     * @param string $cap     The cap being checked.
904
-     * @param string $context The context where the current_user_can is being called from.
905
-     * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
906
-     *                        filters.
907
-     *
908
-     * @return bool  Whether user can or not.
909
-     */
910
-    public function current_user_can_for_blog($blog_id, $cap, $context, $id = 0)
911
-    {
912
-        $user_can = ! empty($id)
913
-            ? current_user_can_for_blog($blog_id, $cap, $id)
914
-            : current_user_can($blog_id, $cap);
915
-        // apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
916
-        $user_can = apply_filters(
917
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
918
-            $user_can,
919
-            $blog_id,
920
-            $cap,
921
-            $id
922
-        );
923
-        $user_can = apply_filters(
924
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can',
925
-            $user_can,
926
-            $context,
927
-            $blog_id,
928
-            $cap,
929
-            $id
930
-        );
931
-        return $user_can;
932
-    }
933
-
934
-
935
-    /**
936
-     * This helper method just returns an array of registered EE capabilities.
937
-     *
938
-     * @since 4.5.0
939
-     * @param string $role If empty then the entire role/capability map is returned.
940
-     *                     Otherwise just the capabilities for the given role are returned.
941
-     * @return array
942
-     * @throws EE_Error
943
-     */
944
-    public function get_ee_capabilities($role = 'administrator')
945
-    {
946
-        if (! $this->initialized) {
947
-            $this->init_caps();
948
-        }
949
-        if (empty($role)) {
950
-            return $this->capabilities_map;
951
-        }
952
-        return isset($this->capabilities_map[ $role ])
953
-            ? $this->capabilities_map[ $role ]
954
-            : array();
955
-    }
956
-
957
-
958
-    /**
959
-     * @deprecated 4.9.42
960
-     * @param bool  $reset      If you need to reset Event Espresso's capabilities,
961
-     *                          then please use the init_caps() method with the "$reset" parameter set to "true"
962
-     * @param array $caps_map   Optional.
963
-     *                          Can be used to send a custom map of roles and capabilities for setting them up.
964
-     *                          Note that this should ONLY be called on activation hook or some other one-time
965
-     *                          task otherwise the caps will be added on every request.
966
-     * @return void
967
-     * @throws EE_Error
968
-     */
969
-    public function init_role_caps($reset = false, $caps_map = array())
970
-    {
971
-        // If this method is called directly and reset is set as 'true',
972
-        // then display a doing it wrong notice, because we want resets to go through init_caps()
973
-        // to guarantee that everything is set up correctly.
974
-        // This prevents the capabilities map getting reset incorrectly by direct calls to this method.
975
-        if ($reset) {
976
-            EE_Error::doing_it_wrong(
977
-                __METHOD__,
978
-                sprintf(
979
-                    esc_html__(
980
-                        '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".',
981
-                        'event_espresso'
982
-                    ),
983
-                    '$reset',
984
-                    __METHOD__ . '()',
985
-                    'EE_Capabilities::init_caps()',
986
-                    'true'
987
-                ),
988
-                '4.9.42',
989
-                '5.0.0'
990
-            );
991
-        }
992
-        $this->addCaps($caps_map);
993
-    }
16
+	/**
17
+	 * the name of the wp option used to store caps previously initialized
18
+	 */
19
+	const option_name = 'ee_caps_initialized';
20
+
21
+	/**
22
+	 * instance of EE_Capabilities object
23
+	 *
24
+	 * @var EE_Capabilities
25
+	 */
26
+	private static $_instance;
27
+
28
+
29
+	/**
30
+	 * This is a map of caps that correspond to a default WP_Role.
31
+	 * Array is indexed by Role and values are ee capabilities.
32
+	 *
33
+	 * @since 4.5.0
34
+	 *
35
+	 * @var array
36
+	 */
37
+	private $capabilities_map = array();
38
+
39
+	/**
40
+	 * This used to hold an array of EE_Meta_Capability_Map objects
41
+	 * that define the granular capabilities mapped to for a user depending on context.
42
+	 *
43
+	 * @var EE_Meta_Capability_Map[]
44
+	 */
45
+	private $_meta_caps = array();
46
+
47
+	/**
48
+	 * The internal $capabilities_map needs to be initialized before it can be used.
49
+	 * This flag tracks whether that has happened or not.
50
+	 * But for this to work, we need three states to indicate:
51
+	 *      initialization has not occurred at all
52
+	 *      initialization has started but is not complete
53
+	 *      initialization is complete
54
+	 * The reason this is needed is because the addCaps() method
55
+	 * normally requires the $capabilities_map to be initialized,
56
+	 * but is also used during the initialization process.
57
+	 * So:
58
+	 *      If initialized === null, init_caps() will be called before any other methods will run.
59
+	 *      If initialized === false, then init_caps() is in the process of running it's logic.
60
+	 *      If initialized === true, then init_caps() has completed the initialization process.
61
+	 *
62
+	 * @var boolean|null $initialized
63
+	 */
64
+	private $initialized;
65
+
66
+	/**
67
+	 * @var boolean $reset
68
+	 */
69
+	private $reset = false;
70
+
71
+
72
+	/**
73
+	 * singleton method used to instantiate class object
74
+	 *
75
+	 * @since 4.5.0
76
+	 *
77
+	 * @return EE_Capabilities
78
+	 */
79
+	public static function instance()
80
+	{
81
+		// check if instantiated, and if not do so.
82
+		if (! self::$_instance instanceof EE_Capabilities) {
83
+			self::$_instance = new self();
84
+		}
85
+		return self::$_instance;
86
+	}
87
+
88
+
89
+	/**
90
+	 * private constructor
91
+	 *
92
+	 * @since 4.5.0
93
+	 */
94
+	private function __construct()
95
+	{
96
+	}
97
+
98
+
99
+	/**
100
+	 * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
101
+	 *
102
+	 * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't
103
+	 *                    actually REMOVE any capabilities from existing roles, it just resaves defaults roles and
104
+	 *                    ensures that they are up to date.
105
+	 *
106
+	 * @since 4.5.0
107
+	 * @return bool
108
+	 * @throws EE_Error
109
+	 */
110
+	public function init_caps($reset = false)
111
+	{
112
+		if (! EE_Maintenance_Mode::instance()->models_can_query()) {
113
+			return false;
114
+		}
115
+		$this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
116
+		// if reset, then completely delete the cache option and clear the $capabilities_map property.
117
+		if ($this->reset) {
118
+			$this->initialized = null;
119
+			$this->capabilities_map = array();
120
+			delete_option(self::option_name);
121
+		}
122
+		if ($this->initialized === null) {
123
+			$this->initialized = false;
124
+			do_action(
125
+				'AHEE__EE_Capabilities__init_caps__before_initialization',
126
+				$this->reset
127
+			);
128
+			$this->addCaps($this->_init_caps_map());
129
+			$this->_set_meta_caps();
130
+			do_action(
131
+				'AHEE__EE_Capabilities__init_caps__after_initialization',
132
+				$this->capabilities_map
133
+			);
134
+			$this->initialized = true;
135
+		}
136
+		// reset $this->reset so that it's not stuck on true if init_caps() gets called again
137
+		$this->reset = false;
138
+		return true;
139
+	}
140
+
141
+
142
+	/**
143
+	 * This sets the meta caps property.
144
+	 *
145
+	 * @since 4.5.0
146
+	 * @return void
147
+	 * @throws EE_Error
148
+	 */
149
+	private function _set_meta_caps()
150
+	{
151
+		// get default meta caps and filter the returned array
152
+		$this->_meta_caps = apply_filters(
153
+			'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
154
+			$this->_get_default_meta_caps_array()
155
+		);
156
+		// add filter for map_meta_caps but only if models can query.
157
+		if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
158
+			add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
159
+		}
160
+	}
161
+
162
+
163
+	/**
164
+	 * This builds and returns the default meta_caps array only once.
165
+	 *
166
+	 * @since  4.8.28.rc.012
167
+	 * @return array
168
+	 * @throws EE_Error
169
+	 */
170
+	private function _get_default_meta_caps_array()
171
+	{
172
+		static $default_meta_caps = array();
173
+		// make sure we're only ever initializing the default _meta_caps array once if it's empty.
174
+		if (empty($default_meta_caps)) {
175
+			$default_meta_caps = array(
176
+				// edits
177
+				new EE_Meta_Capability_Map_Edit(
178
+					'ee_edit_event',
179
+					array('Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events')
180
+				),
181
+				new EE_Meta_Capability_Map_Edit(
182
+					'ee_edit_venue',
183
+					array('Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues')
184
+				),
185
+				new EE_Meta_Capability_Map_Edit(
186
+					'ee_edit_registration',
187
+					array('Registration', '', 'ee_edit_others_registrations', '')
188
+				),
189
+				new EE_Meta_Capability_Map_Edit(
190
+					'ee_edit_checkin',
191
+					array('Registration', '', 'ee_edit_others_checkins', '')
192
+				),
193
+				new EE_Meta_Capability_Map_Messages_Cap(
194
+					'ee_edit_message',
195
+					array('Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages')
196
+				),
197
+				new EE_Meta_Capability_Map_Edit(
198
+					'ee_edit_default_ticket',
199
+					array('Ticket', '', 'ee_edit_others_default_tickets', '')
200
+				),
201
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
202
+					'ee_edit_question',
203
+					array('Question', '', '', 'ee_edit_system_questions')
204
+				),
205
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
206
+					'ee_edit_question_group',
207
+					array('Question_Group', '', '', 'ee_edit_system_question_groups')
208
+				),
209
+				new EE_Meta_Capability_Map_Edit(
210
+					'ee_edit_payment_method',
211
+					array('Payment_Method', '', 'ee_edit_others_payment_methods', '')
212
+				),
213
+				// reads
214
+				new EE_Meta_Capability_Map_Read(
215
+					'ee_read_event',
216
+					array('Event', '', 'ee_read_others_events', 'ee_read_private_events')
217
+				),
218
+				new EE_Meta_Capability_Map_Read(
219
+					'ee_read_venue',
220
+					array('Venue', '', 'ee_read_others_venues', 'ee_read_private_venues')
221
+				),
222
+				new EE_Meta_Capability_Map_Read(
223
+					'ee_read_registration',
224
+					array('Registration', '', 'ee_read_others_registrations', '')
225
+				),
226
+				new EE_Meta_Capability_Map_Read(
227
+					'ee_read_checkin',
228
+					array('Registration', '', 'ee_read_others_checkins', '')
229
+				),
230
+				new EE_Meta_Capability_Map_Messages_Cap(
231
+					'ee_read_message',
232
+					array('Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages')
233
+				),
234
+				new EE_Meta_Capability_Map_Read(
235
+					'ee_read_default_ticket',
236
+					array('Ticket', '', 'ee_read_others_default_tickets', '')
237
+				),
238
+				new EE_Meta_Capability_Map_Read(
239
+					'ee_read_payment_method',
240
+					array('Payment_Method', '', 'ee_read_others_payment_methods', '')
241
+				),
242
+				// deletes
243
+				new EE_Meta_Capability_Map_Delete(
244
+					'ee_delete_event',
245
+					array(
246
+						'Event',
247
+						'ee_delete_published_events',
248
+						'ee_delete_others_events',
249
+						'ee_delete_private_events',
250
+					)
251
+				),
252
+				new EE_Meta_Capability_Map_Delete(
253
+					'ee_delete_venue',
254
+					array(
255
+						'Venue',
256
+						'ee_delete_published_venues',
257
+						'ee_delete_others_venues',
258
+						'ee_delete_private_venues',
259
+					)
260
+				),
261
+				new EE_Meta_Capability_Map_Delete(
262
+					'ee_delete_registration',
263
+					array('Registration', '', 'ee_delete_others_registrations', '')
264
+				),
265
+				new EE_Meta_Capability_Map_Delete(
266
+					'ee_delete_checkin',
267
+					array('Registration', '', 'ee_delete_others_checkins', '')
268
+				),
269
+				new EE_Meta_Capability_Map_Messages_Cap(
270
+					'ee_delete_message',
271
+					array('Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages')
272
+				),
273
+				new EE_Meta_Capability_Map_Delete(
274
+					'ee_delete_default_ticket',
275
+					array('Ticket', '', 'ee_delete_others_default_tickets', '')
276
+				),
277
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
278
+					'ee_delete_question',
279
+					array('Question', '', '', 'delete_system_questions')
280
+				),
281
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
282
+					'ee_delete_question_group',
283
+					array('Question_Group', '', '', 'delete_system_question_groups')
284
+				),
285
+				new EE_Meta_Capability_Map_Delete(
286
+					'ee_delete_payment_method',
287
+					array('Payment_Method', '', 'ee_delete_others_payment_methods', '')
288
+				),
289
+			);
290
+		}
291
+		return $default_meta_caps;
292
+	}
293
+
294
+
295
+	/**
296
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
297
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
298
+	 *
299
+	 * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
300
+	 *
301
+	 * @since 4.5.0
302
+	 * @see   wp-includes/capabilities.php
303
+	 *
304
+	 * @param array  $caps    actual users capabilities
305
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
306
+	 * @param int    $user_id The user id
307
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
308
+	 * @return array actual users capabilities
309
+	 * @throws EE_Error
310
+	 */
311
+	public function map_meta_caps($caps, $cap, $user_id, $args)
312
+	{
313
+		if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
314
+			// loop through our _meta_caps array
315
+			foreach ($this->_meta_caps as $meta_map) {
316
+				if (! $meta_map instanceof EE_Meta_Capability_Map) {
317
+					continue;
318
+				}
319
+				// don't load models if there is no object ID in the args
320
+				if (! empty($args[0])) {
321
+					$meta_map->ensure_is_model();
322
+				}
323
+				$caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
324
+			}
325
+		}
326
+		return $caps;
327
+	}
328
+
329
+
330
+	/**
331
+	 * This sets up and returns the initial capabilities map for Event Espresso
332
+	 * Note this array is filtered.
333
+	 * It is assumed that all available EE capabilities are assigned to the administrator role.
334
+	 *
335
+	 * @since 4.5.0
336
+	 *
337
+	 * @return array
338
+	 */
339
+	private function _init_caps_map()
340
+	{
341
+		return apply_filters(
342
+			'FHEE__EE_Capabilities__init_caps_map__caps',
343
+			array(
344
+				'administrator'           => array(
345
+					// basic access
346
+					'ee_read_ee',
347
+					// gateways
348
+					/**
349
+					 * note that with payment method capabilities, although we've implemented
350
+					 * capability mapping which will be used for accessing payment methods owned by
351
+					 * other users.  This is not fully implemented yet in the payment method ui.
352
+					 * Currently only the "plural" caps are in active use.
353
+					 * (Specific payment method caps are in use as well).
354
+					 **/
355
+					'ee_manage_gateways',
356
+					'ee_read_payment_methods',
357
+					'ee_read_others_payment_methods',
358
+					'ee_edit_payment_methods',
359
+					'ee_edit_others_payment_methods',
360
+					'ee_delete_payment_methods',
361
+					// events
362
+					'ee_publish_events',
363
+					'ee_read_private_events',
364
+					'ee_read_others_events',
365
+					'ee_read_events',
366
+					'ee_edit_events',
367
+					'ee_edit_published_events',
368
+					'ee_edit_others_events',
369
+					'ee_edit_private_events',
370
+					'ee_delete_published_events',
371
+					'ee_delete_private_events',
372
+					'ee_delete_events',
373
+					'ee_delete_others_events',
374
+					// event categories
375
+					'ee_manage_event_categories',
376
+					'ee_edit_event_category',
377
+					'ee_delete_event_category',
378
+					'ee_assign_event_category',
379
+					// venues
380
+					'ee_publish_venues',
381
+					'ee_read_venues',
382
+					'ee_read_others_venues',
383
+					'ee_read_private_venues',
384
+					'ee_edit_venues',
385
+					'ee_edit_others_venues',
386
+					'ee_edit_published_venues',
387
+					'ee_edit_private_venues',
388
+					'ee_delete_venues',
389
+					'ee_delete_others_venues',
390
+					'ee_delete_private_venues',
391
+					'ee_delete_published_venues',
392
+					// venue categories
393
+					'ee_manage_venue_categories',
394
+					'ee_edit_venue_category',
395
+					'ee_delete_venue_category',
396
+					'ee_assign_venue_category',
397
+					// contacts
398
+					'ee_read_contacts',
399
+					'ee_edit_contacts',
400
+					'ee_delete_contacts',
401
+					// registrations
402
+					'ee_read_registrations',
403
+					'ee_read_others_registrations',
404
+					'ee_edit_registrations',
405
+					'ee_edit_others_registrations',
406
+					'ee_delete_registrations',
407
+					'ee_delete_others_registrations',
408
+					// checkins
409
+					'ee_read_others_checkins',
410
+					'ee_read_checkins',
411
+					'ee_edit_checkins',
412
+					'ee_edit_others_checkins',
413
+					'ee_delete_checkins',
414
+					'ee_delete_others_checkins',
415
+					// transactions && payments
416
+					'ee_read_transaction',
417
+					'ee_read_transactions',
418
+					'ee_edit_payments',
419
+					'ee_delete_payments',
420
+					// messages
421
+					'ee_read_messages',
422
+					'ee_read_others_messages',
423
+					'ee_read_global_messages',
424
+					'ee_edit_global_messages',
425
+					'ee_edit_messages',
426
+					'ee_edit_others_messages',
427
+					'ee_delete_messages',
428
+					'ee_delete_others_messages',
429
+					'ee_delete_global_messages',
430
+					'ee_send_message',
431
+					// tickets
432
+					'ee_read_default_tickets',
433
+					'ee_read_others_default_tickets',
434
+					'ee_edit_default_tickets',
435
+					'ee_edit_others_default_tickets',
436
+					'ee_delete_default_tickets',
437
+					'ee_delete_others_default_tickets',
438
+					// prices
439
+					'ee_edit_default_price',
440
+					'ee_edit_default_prices',
441
+					'ee_delete_default_price',
442
+					'ee_delete_default_prices',
443
+					'ee_edit_default_price_type',
444
+					'ee_edit_default_price_types',
445
+					'ee_delete_default_price_type',
446
+					'ee_delete_default_price_types',
447
+					'ee_read_default_prices',
448
+					'ee_read_default_price_types',
449
+					// registration form
450
+					'ee_edit_questions',
451
+					'ee_edit_system_questions',
452
+					'ee_read_questions',
453
+					'ee_delete_questions',
454
+					'ee_edit_question_groups',
455
+					'ee_read_question_groups',
456
+					'ee_edit_system_question_groups',
457
+					'ee_delete_question_groups',
458
+					// event_type taxonomy
459
+					'ee_assign_event_type',
460
+					'ee_manage_event_types',
461
+					'ee_edit_event_type',
462
+					'ee_delete_event_type',
463
+				),
464
+				'ee_events_administrator' => array(
465
+					// core wp caps
466
+					'read',
467
+					'read_private_pages',
468
+					'read_private_posts',
469
+					'edit_users',
470
+					'edit_posts',
471
+					'edit_pages',
472
+					'edit_published_posts',
473
+					'edit_published_pages',
474
+					'edit_private_pages',
475
+					'edit_private_posts',
476
+					'edit_others_posts',
477
+					'edit_others_pages',
478
+					'publish_posts',
479
+					'publish_pages',
480
+					'delete_posts',
481
+					'delete_pages',
482
+					'delete_private_pages',
483
+					'delete_private_posts',
484
+					'delete_published_pages',
485
+					'delete_published_posts',
486
+					'delete_others_posts',
487
+					'delete_others_pages',
488
+					'manage_categories',
489
+					'manage_links',
490
+					'moderate_comments',
491
+					'unfiltered_html',
492
+					'upload_files',
493
+					'export',
494
+					'import',
495
+					'list_users',
496
+					'level_1', // required if user with this role shows up in author dropdowns
497
+					// basic ee access
498
+					'ee_read_ee',
499
+					// events
500
+					'ee_publish_events',
501
+					'ee_read_private_events',
502
+					'ee_read_others_events',
503
+					'ee_read_event',
504
+					'ee_read_events',
505
+					'ee_edit_event',
506
+					'ee_edit_events',
507
+					'ee_edit_published_events',
508
+					'ee_edit_others_events',
509
+					'ee_edit_private_events',
510
+					'ee_delete_published_events',
511
+					'ee_delete_private_events',
512
+					'ee_delete_event',
513
+					'ee_delete_events',
514
+					'ee_delete_others_events',
515
+					// event categories
516
+					'ee_manage_event_categories',
517
+					'ee_edit_event_category',
518
+					'ee_delete_event_category',
519
+					'ee_assign_event_category',
520
+					// venues
521
+					'ee_publish_venues',
522
+					'ee_read_venue',
523
+					'ee_read_venues',
524
+					'ee_read_others_venues',
525
+					'ee_read_private_venues',
526
+					'ee_edit_venue',
527
+					'ee_edit_venues',
528
+					'ee_edit_others_venues',
529
+					'ee_edit_published_venues',
530
+					'ee_edit_private_venues',
531
+					'ee_delete_venue',
532
+					'ee_delete_venues',
533
+					'ee_delete_others_venues',
534
+					'ee_delete_private_venues',
535
+					'ee_delete_published_venues',
536
+					// venue categories
537
+					'ee_manage_venue_categories',
538
+					'ee_edit_venue_category',
539
+					'ee_delete_venue_category',
540
+					'ee_assign_venue_category',
541
+					// contacts
542
+					'ee_read_contacts',
543
+					'ee_edit_contacts',
544
+					'ee_delete_contacts',
545
+					// registrations
546
+					'ee_read_registrations',
547
+					'ee_read_others_registrations',
548
+					'ee_edit_registration',
549
+					'ee_edit_registrations',
550
+					'ee_edit_others_registrations',
551
+					'ee_delete_registration',
552
+					'ee_delete_registrations',
553
+					'ee_delete_others_registrations',
554
+					// checkins
555
+					'ee_read_others_checkins',
556
+					'ee_read_checkins',
557
+					'ee_edit_checkins',
558
+					'ee_edit_others_checkins',
559
+					'ee_delete_checkins',
560
+					'ee_delete_others_checkins',
561
+					// transactions && payments
562
+					'ee_read_transaction',
563
+					'ee_read_transactions',
564
+					'ee_edit_payments',
565
+					'ee_delete_payments',
566
+					// messages
567
+					'ee_read_messages',
568
+					'ee_read_others_messages',
569
+					'ee_read_global_messages',
570
+					'ee_edit_global_messages',
571
+					'ee_edit_messages',
572
+					'ee_edit_others_messages',
573
+					'ee_delete_messages',
574
+					'ee_delete_others_messages',
575
+					'ee_delete_global_messages',
576
+					'ee_send_message',
577
+					// tickets
578
+					'ee_read_default_tickets',
579
+					'ee_read_others_default_tickets',
580
+					'ee_edit_default_tickets',
581
+					'ee_edit_others_default_tickets',
582
+					'ee_delete_default_tickets',
583
+					'ee_delete_others_default_tickets',
584
+					// prices
585
+					'ee_edit_default_price',
586
+					'ee_edit_default_prices',
587
+					'ee_delete_default_price',
588
+					'ee_delete_default_prices',
589
+					'ee_edit_default_price_type',
590
+					'ee_edit_default_price_types',
591
+					'ee_delete_default_price_type',
592
+					'ee_delete_default_price_types',
593
+					'ee_read_default_prices',
594
+					'ee_read_default_price_types',
595
+					// registration form
596
+					'ee_edit_questions',
597
+					'ee_edit_system_questions',
598
+					'ee_read_questions',
599
+					'ee_delete_questions',
600
+					'ee_edit_question_groups',
601
+					'ee_read_question_groups',
602
+					'ee_edit_system_question_groups',
603
+					'ee_delete_question_groups',
604
+					// event_type taxonomy
605
+					'ee_assign_event_type',
606
+					'ee_manage_event_types',
607
+					'ee_edit_event_type',
608
+					'ee_delete_event_type',
609
+				),
610
+			)
611
+		);
612
+	}
613
+
614
+
615
+	/**
616
+	 * @return bool
617
+	 * @throws EE_Error
618
+	 */
619
+	private function setupCapabilitiesMap()
620
+	{
621
+		// if the initialization process hasn't even started, then we need to call init_caps()
622
+		if ($this->initialized === null) {
623
+			return $this->init_caps();
624
+		}
625
+		// unless resetting, get caps from db if we haven't already
626
+		$this->capabilities_map = $this->reset || ! empty($this->capabilities_map)
627
+			? $this->capabilities_map
628
+			: get_option(self::option_name, array());
629
+		return true;
630
+	}
631
+
632
+
633
+	/**
634
+	 * @param bool $update
635
+	 * @return bool
636
+	 */
637
+	private function updateCapabilitiesMap($update = true)
638
+	{
639
+		return $update ? update_option(self::option_name, $this->capabilities_map) : false;
640
+	}
641
+
642
+
643
+	/**
644
+	 * Adds capabilities to roles.
645
+	 *
646
+	 * @since 4.9.42
647
+	 * @param array $capabilities_to_add array of capabilities to add, indexed by roles.
648
+	 *                                   Note that this should ONLY be called on activation hook
649
+	 *                                   otherwise the caps will be added on every request.
650
+	 * @return bool
651
+	 * @throws \EE_Error
652
+	 */
653
+	public function addCaps(array $capabilities_to_add)
654
+	{
655
+		// don't do anything if the capabilities map can not be initialized
656
+		if (! $this->setupCapabilitiesMap()) {
657
+			return false;
658
+		}
659
+		// and filter the array so others can get in on the fun during resets
660
+		$capabilities_to_add = apply_filters(
661
+			'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
662
+			$capabilities_to_add,
663
+			$this->reset,
664
+			$this->capabilities_map
665
+		);
666
+		$update_capabilities_map = false;
667
+		// if not reset, see what caps are new for each role. if they're new, add them.
668
+		foreach ($capabilities_to_add as $role => $caps_for_role) {
669
+			if (is_array($caps_for_role)) {
670
+				foreach ($caps_for_role as $cap) {
671
+					if (
672
+						! $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 (
706
+						$this->capHasBeenAddedToRole($role, $cap)
707
+						&& $this->remove_cap_from_role($role, $cap, false)
708
+					) {
709
+						$update_capabilities_map = true;
710
+					}
711
+				}
712
+			}
713
+		}
714
+		// maybe resave the caps
715
+		$updated = $this->updateCapabilitiesMap($update_capabilities_map);
716
+		$this->flushWpUser($updated);
717
+		return $updated;
718
+	}
719
+
720
+
721
+	/**
722
+	 * This ensures that the WP User object cached on the $current_user global in WP has the latest capabilities from
723
+	 * the roles on that user.
724
+	 *
725
+	 * @param bool $flush Default is to flush the WP_User object.  If false, then this method effectively does nothing.
726
+	 */
727
+	private function flushWpUser($flush = true)
728
+	{
729
+		if ($flush) {
730
+			$user = wp_get_current_user();
731
+			if ($user instanceof WP_User) {
732
+				$user->get_role_caps();
733
+			}
734
+		}
735
+	}
736
+
737
+
738
+	/**
739
+	 * This method sets a capability on a role.  Note this should only be done on activation, or if you have something
740
+	 * specific to prevent the cap from being added on every page load (adding caps are persistent to the db). Note.
741
+	 * this is a wrapper for $wp_role->add_cap()
742
+	 *
743
+	 * @see   wp-includes/capabilities.php
744
+	 * @since 4.5.0
745
+	 * @param string|WP_Role $role  A WordPress role the capability is being added to
746
+	 * @param string         $cap   The capability being added to the role
747
+	 * @param bool           $grant Whether to grant access to this cap on this role.
748
+	 * @param bool           $update_capabilities_map
749
+	 * @return bool
750
+	 * @throws \EE_Error
751
+	 */
752
+	public function add_cap_to_role($role, $cap, $grant = true, $update_capabilities_map = true)
753
+	{
754
+		// capture incoming value for $role because we may need it to create a new WP_Role
755
+		$orig_role = $role;
756
+		$role = $role instanceof WP_Role ? $role : get_role($role);
757
+		// if the role isn't available then we create it.
758
+		if (! $role instanceof WP_Role) {
759
+			// if a plugin wants to create a specific role name then they should create the role before
760
+			// EE_Capabilities does.  Otherwise this function will create the role name from the slug:
761
+			// - removes any `ee_` namespacing from the start of the slug.
762
+			// - replaces `_` with ` ` (empty space).
763
+			// - sentence case on the resulting string.
764
+			$role_label = ucwords(str_replace(array('ee_', '_'), array('', ' '), $orig_role));
765
+			$role = add_role($orig_role, $role_label);
766
+		}
767
+		if ($role instanceof WP_Role) {
768
+			// don't do anything if the capabilities map can not be initialized
769
+			if (! $this->setupCapabilitiesMap()) {
770
+				return false;
771
+			}
772
+			if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
773
+				$role->add_cap($cap, $grant);
774
+				$this->capabilities_map[ $role->name ][] = $cap;
775
+				$this->updateCapabilitiesMap($update_capabilities_map);
776
+				return true;
777
+			}
778
+		}
779
+		return false;
780
+	}
781
+
782
+
783
+	/**
784
+	 * Functions similarly to add_cap_to_role except removes cap from given role.
785
+	 * Wrapper for $wp_role->remove_cap()
786
+	 *
787
+	 * @see   wp-includes/capabilities.php
788
+	 * @since 4.5.0
789
+	 * @param string|WP_Role $role A WordPress role the capability is being removed from.
790
+	 * @param string         $cap  The capability being removed
791
+	 * @param bool           $update_capabilities_map
792
+	 * @return bool
793
+	 * @throws \EE_Error
794
+	 */
795
+	public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
796
+	{
797
+		// don't do anything if the capabilities map can not be initialized
798
+		if (! $this->setupCapabilitiesMap()) {
799
+			return false;
800
+		}
801
+
802
+		$role = $role instanceof WP_Role ? $role : get_role($role);
803
+		if ($role instanceof WP_Role && $index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
804
+			$role->remove_cap($cap);
805
+			unset($this->capabilities_map[ $role->name ][ $index ]);
806
+			$this->updateCapabilitiesMap($update_capabilities_map);
807
+			return true;
808
+		}
809
+		return false;
810
+	}
811
+
812
+
813
+	/**
814
+	 * @param string $role_name
815
+	 * @param string $cap
816
+	 * @param bool   $get_index
817
+	 * @return bool|mixed
818
+	 */
819
+	private function capHasBeenAddedToRole($role_name = '', $cap = '', $get_index = false)
820
+	{
821
+		if (
822
+			isset($this->capabilities_map[ $role_name ])
823
+			&& ($index = array_search($cap, $this->capabilities_map[ $role_name ], true)) !== false
824
+		) {
825
+			return $get_index ? $index : true;
826
+		}
827
+		return false;
828
+	}
829
+
830
+
831
+	/**
832
+	 * Wrapper for the native WP current_user_can() method.
833
+	 * This is provided as a handy method for a couple things:
834
+	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
835
+	 * write those filters wherever current_user_can is called).
836
+	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
837
+	 *
838
+	 * @since 4.5.0
839
+	 *
840
+	 * @param string $cap     The cap being checked.
841
+	 * @param string $context The context where the current_user_can is being called from.
842
+	 * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
843
+	 *                        filters.
844
+	 *
845
+	 * @return bool  Whether user can or not.
846
+	 */
847
+	public function current_user_can($cap, $context, $id = 0)
848
+	{
849
+		// apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
850
+		$filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
851
+		$filtered_cap = apply_filters(
852
+			'FHEE__EE_Capabilities__current_user_can__cap',
853
+			$filtered_cap,
854
+			$context,
855
+			$cap,
856
+			$id
857
+		);
858
+		return ! empty($id)
859
+			? current_user_can($filtered_cap, $id)
860
+			: current_user_can($filtered_cap);
861
+	}
862
+
863
+
864
+	/**
865
+	 * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
866
+	 *
867
+	 * @param int|WP_User $user    Either the user_id or a WP_User object
868
+	 * @param string      $cap     The capability string being checked
869
+	 * @param string      $context The context where the user_can is being called from (used in filters).
870
+	 * @param int         $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap()
871
+	 *                             filters)
872
+	 *
873
+	 * @return bool Whether user can or not.
874
+	 */
875
+	public function user_can($user, $cap, $context, $id = 0)
876
+	{
877
+		// apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
878
+		$filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
879
+		$filtered_cap = apply_filters(
880
+			'FHEE__EE_Capabilities__user_can__cap',
881
+			$filtered_cap,
882
+			$context,
883
+			$cap,
884
+			$user,
885
+			$id
886
+		);
887
+		return ! empty($id)
888
+			? user_can($user, $filtered_cap, $id)
889
+			: user_can($user, $filtered_cap);
890
+	}
891
+
892
+
893
+	/**
894
+	 * Wrapper for the native WP current_user_can_for_blog() method.
895
+	 * This is provided as a handy method for a couple things:
896
+	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
897
+	 * write those filters wherever current_user_can is called).
898
+	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
899
+	 *
900
+	 * @since 4.5.0
901
+	 *
902
+	 * @param int    $blog_id The blog id that is being checked for.
903
+	 * @param string $cap     The cap being checked.
904
+	 * @param string $context The context where the current_user_can is being called from.
905
+	 * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
906
+	 *                        filters.
907
+	 *
908
+	 * @return bool  Whether user can or not.
909
+	 */
910
+	public function current_user_can_for_blog($blog_id, $cap, $context, $id = 0)
911
+	{
912
+		$user_can = ! empty($id)
913
+			? current_user_can_for_blog($blog_id, $cap, $id)
914
+			: current_user_can($blog_id, $cap);
915
+		// apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
916
+		$user_can = apply_filters(
917
+			'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
918
+			$user_can,
919
+			$blog_id,
920
+			$cap,
921
+			$id
922
+		);
923
+		$user_can = apply_filters(
924
+			'FHEE__EE_Capabilities__current_user_can_for_blog__user_can',
925
+			$user_can,
926
+			$context,
927
+			$blog_id,
928
+			$cap,
929
+			$id
930
+		);
931
+		return $user_can;
932
+	}
933
+
934
+
935
+	/**
936
+	 * This helper method just returns an array of registered EE capabilities.
937
+	 *
938
+	 * @since 4.5.0
939
+	 * @param string $role If empty then the entire role/capability map is returned.
940
+	 *                     Otherwise just the capabilities for the given role are returned.
941
+	 * @return array
942
+	 * @throws EE_Error
943
+	 */
944
+	public function get_ee_capabilities($role = 'administrator')
945
+	{
946
+		if (! $this->initialized) {
947
+			$this->init_caps();
948
+		}
949
+		if (empty($role)) {
950
+			return $this->capabilities_map;
951
+		}
952
+		return isset($this->capabilities_map[ $role ])
953
+			? $this->capabilities_map[ $role ]
954
+			: array();
955
+	}
956
+
957
+
958
+	/**
959
+	 * @deprecated 4.9.42
960
+	 * @param bool  $reset      If you need to reset Event Espresso's capabilities,
961
+	 *                          then please use the init_caps() method with the "$reset" parameter set to "true"
962
+	 * @param array $caps_map   Optional.
963
+	 *                          Can be used to send a custom map of roles and capabilities for setting them up.
964
+	 *                          Note that this should ONLY be called on activation hook or some other one-time
965
+	 *                          task otherwise the caps will be added on every request.
966
+	 * @return void
967
+	 * @throws EE_Error
968
+	 */
969
+	public function init_role_caps($reset = false, $caps_map = array())
970
+	{
971
+		// If this method is called directly and reset is set as 'true',
972
+		// then display a doing it wrong notice, because we want resets to go through init_caps()
973
+		// to guarantee that everything is set up correctly.
974
+		// This prevents the capabilities map getting reset incorrectly by direct calls to this method.
975
+		if ($reset) {
976
+			EE_Error::doing_it_wrong(
977
+				__METHOD__,
978
+				sprintf(
979
+					esc_html__(
980
+						'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".',
981
+						'event_espresso'
982
+					),
983
+					'$reset',
984
+					__METHOD__ . '()',
985
+					'EE_Capabilities::init_caps()',
986
+					'true'
987
+				),
988
+				'4.9.42',
989
+				'5.0.0'
990
+			);
991
+		}
992
+		$this->addCaps($caps_map);
993
+	}
994 994
 }
995 995
 
996 996
 
@@ -1006,142 +1006,142 @@  discard block
 block discarded – undo
1006 1006
  */
1007 1007
 abstract class EE_Meta_Capability_Map
1008 1008
 {
1009
-    public $meta_cap;
1010
-
1011
-    /**
1012
-     * @var EEM_Base
1013
-     */
1014
-    protected $_model;
1015
-
1016
-    protected $_model_name;
1017
-
1018
-    public $published_cap = '';
1019
-
1020
-    public $others_cap = '';
1021
-
1022
-    public $private_cap = '';
1023
-
1024
-
1025
-    /**
1026
-     * constructor.
1027
-     * Receives the setup arguments for the map.
1028
-     *
1029
-     * @since                        4.5.0
1030
-     *
1031
-     * @param string $meta_cap   What meta capability is this mapping.
1032
-     * @param array  $map_values array {
1033
-     *                           //array of values that MUST match a count of 4.  It's okay to send an empty string for
1034
-     *                           capabilities that don't get mapped to.
1035
-     *
1036
-     * @type         $map_values [0] string A string representing the model name. Required.  String's
1037
-     *                               should always be used when Menu Maps are registered via the
1038
-     *                               plugin API as models are not allowed to be instantiated when
1039
-     *                               in maintenance mode 2 (migrations).
1040
-     * @type         $map_values [1] string represents the capability used for published. Optional.
1041
-     * @type         $map_values [2] string represents the capability used for "others". Optional.
1042
-     * @type         $map_values [3] string represents the capability used for private. Optional.
1043
-     *                               }
1044
-     * @throws EE_Error
1045
-     */
1046
-    public function __construct($meta_cap, $map_values)
1047
-    {
1048
-        $this->meta_cap = $meta_cap;
1049
-        // verify there are four args in the $map_values array;
1050
-        if (count($map_values) !== 4) {
1051
-            throw new EE_Error(
1052
-                sprintf(
1053
-                    esc_html__(
1054
-                        'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1055
-                        'event_espresso'
1056
-                    ),
1057
-                    '<br>' . print_r($map_values, true)
1058
-                )
1059
-            );
1060
-        }
1061
-        // set properties
1062
-        $this->_model = null;
1063
-        $this->_model_name = $map_values[0];
1064
-        $this->published_cap = (string) $map_values[1];
1065
-        $this->others_cap = (string) $map_values[2];
1066
-        $this->private_cap = (string) $map_values[3];
1067
-    }
1068
-
1069
-    /**
1070
-     * Makes it so this object stops filtering caps
1071
-     */
1072
-    public function remove_filters()
1073
-    {
1074
-        remove_filter('map_meta_cap', array($this, 'map_meta_caps'), 10);
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
1080
-     *
1081
-     * @since 4.5.0
1082
-     * @throws EE_Error
1083
-     *
1084
-     * @return void
1085
-     */
1086
-    public function ensure_is_model()
1087
-    {
1088
-        // is it already instantiated?
1089
-        if ($this->_model instanceof EEM_Base) {
1090
-            return;
1091
-        }
1092
-        // ensure model name is string
1093
-        $this->_model_name = (string) $this->_model_name;
1094
-        // error proof if the name has EEM in it
1095
-        $this->_model_name = str_replace('EEM', '', $this->_model_name);
1096
-        $this->_model = EE_Registry::instance()->load_model($this->_model_name);
1097
-        if (! $this->_model instanceof EEM_Base) {
1098
-            throw new EE_Error(
1099
-                sprintf(
1100
-                    esc_html__(
1101
-                        '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',
1102
-                        'event_espresso'
1103
-                    ),
1104
-                    get_class($this),
1105
-                    $this->_model
1106
-                )
1107
-            );
1108
-        }
1109
-    }
1110
-
1111
-
1112
-    /**
1113
-     *
1114
-     * @see   EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
1115
-     * @since 4.6.x
1116
-     *
1117
-     * @param $caps
1118
-     * @param $cap
1119
-     * @param $user_id
1120
-     * @param $args
1121
-     *
1122
-     * @return array
1123
-     */
1124
-    public function map_meta_caps($caps, $cap, $user_id, $args)
1125
-    {
1126
-        return $this->_map_meta_caps($caps, $cap, $user_id, $args);
1127
-    }
1128
-
1129
-
1130
-    /**
1131
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1132
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1133
-     *
1134
-     * @since 4.5.0
1135
-     * @see   wp-includes/capabilities.php
1136
-     *
1137
-     * @param array  $caps    actual users capabilities
1138
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1139
-     * @param int    $user_id The user id
1140
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1141
-     *
1142
-     * @return array   actual users capabilities
1143
-     */
1144
-    abstract protected function _map_meta_caps($caps, $cap, $user_id, $args);
1009
+	public $meta_cap;
1010
+
1011
+	/**
1012
+	 * @var EEM_Base
1013
+	 */
1014
+	protected $_model;
1015
+
1016
+	protected $_model_name;
1017
+
1018
+	public $published_cap = '';
1019
+
1020
+	public $others_cap = '';
1021
+
1022
+	public $private_cap = '';
1023
+
1024
+
1025
+	/**
1026
+	 * constructor.
1027
+	 * Receives the setup arguments for the map.
1028
+	 *
1029
+	 * @since                        4.5.0
1030
+	 *
1031
+	 * @param string $meta_cap   What meta capability is this mapping.
1032
+	 * @param array  $map_values array {
1033
+	 *                           //array of values that MUST match a count of 4.  It's okay to send an empty string for
1034
+	 *                           capabilities that don't get mapped to.
1035
+	 *
1036
+	 * @type         $map_values [0] string A string representing the model name. Required.  String's
1037
+	 *                               should always be used when Menu Maps are registered via the
1038
+	 *                               plugin API as models are not allowed to be instantiated when
1039
+	 *                               in maintenance mode 2 (migrations).
1040
+	 * @type         $map_values [1] string represents the capability used for published. Optional.
1041
+	 * @type         $map_values [2] string represents the capability used for "others". Optional.
1042
+	 * @type         $map_values [3] string represents the capability used for private. Optional.
1043
+	 *                               }
1044
+	 * @throws EE_Error
1045
+	 */
1046
+	public function __construct($meta_cap, $map_values)
1047
+	{
1048
+		$this->meta_cap = $meta_cap;
1049
+		// verify there are four args in the $map_values array;
1050
+		if (count($map_values) !== 4) {
1051
+			throw new EE_Error(
1052
+				sprintf(
1053
+					esc_html__(
1054
+						'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1055
+						'event_espresso'
1056
+					),
1057
+					'<br>' . print_r($map_values, true)
1058
+				)
1059
+			);
1060
+		}
1061
+		// set properties
1062
+		$this->_model = null;
1063
+		$this->_model_name = $map_values[0];
1064
+		$this->published_cap = (string) $map_values[1];
1065
+		$this->others_cap = (string) $map_values[2];
1066
+		$this->private_cap = (string) $map_values[3];
1067
+	}
1068
+
1069
+	/**
1070
+	 * Makes it so this object stops filtering caps
1071
+	 */
1072
+	public function remove_filters()
1073
+	{
1074
+		remove_filter('map_meta_cap', array($this, 'map_meta_caps'), 10);
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
1080
+	 *
1081
+	 * @since 4.5.0
1082
+	 * @throws EE_Error
1083
+	 *
1084
+	 * @return void
1085
+	 */
1086
+	public function ensure_is_model()
1087
+	{
1088
+		// is it already instantiated?
1089
+		if ($this->_model instanceof EEM_Base) {
1090
+			return;
1091
+		}
1092
+		// ensure model name is string
1093
+		$this->_model_name = (string) $this->_model_name;
1094
+		// error proof if the name has EEM in it
1095
+		$this->_model_name = str_replace('EEM', '', $this->_model_name);
1096
+		$this->_model = EE_Registry::instance()->load_model($this->_model_name);
1097
+		if (! $this->_model instanceof EEM_Base) {
1098
+			throw new EE_Error(
1099
+				sprintf(
1100
+					esc_html__(
1101
+						'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',
1102
+						'event_espresso'
1103
+					),
1104
+					get_class($this),
1105
+					$this->_model
1106
+				)
1107
+			);
1108
+		}
1109
+	}
1110
+
1111
+
1112
+	/**
1113
+	 *
1114
+	 * @see   EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
1115
+	 * @since 4.6.x
1116
+	 *
1117
+	 * @param $caps
1118
+	 * @param $cap
1119
+	 * @param $user_id
1120
+	 * @param $args
1121
+	 *
1122
+	 * @return array
1123
+	 */
1124
+	public function map_meta_caps($caps, $cap, $user_id, $args)
1125
+	{
1126
+		return $this->_map_meta_caps($caps, $cap, $user_id, $args);
1127
+	}
1128
+
1129
+
1130
+	/**
1131
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1132
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1133
+	 *
1134
+	 * @since 4.5.0
1135
+	 * @see   wp-includes/capabilities.php
1136
+	 *
1137
+	 * @param array  $caps    actual users capabilities
1138
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1139
+	 * @param int    $user_id The user id
1140
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1141
+	 *
1142
+	 * @return array   actual users capabilities
1143
+	 */
1144
+	abstract protected function _map_meta_caps($caps, $cap, $user_id, $args);
1145 1145
 }
1146 1146
 
1147 1147
 
@@ -1156,81 +1156,81 @@  discard block
 block discarded – undo
1156 1156
  */
1157 1157
 class EE_Meta_Capability_Map_Edit extends EE_Meta_Capability_Map
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
 
@@ -1246,24 +1246,24 @@  discard block
 block discarded – undo
1246 1246
  */
1247 1247
 class EE_Meta_Capability_Map_Delete extends EE_Meta_Capability_Map_Edit
1248 1248
 {
1249
-    /**
1250
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1251
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1252
-     *
1253
-     * @since 4.5.0
1254
-     * @see   wp-includes/capabilities.php
1255
-     *
1256
-     * @param array  $caps    actual users capabilities
1257
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1258
-     * @param int    $user_id The user id
1259
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1260
-     *
1261
-     * @return array   actual users capabilities
1262
-     */
1263
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1264
-    {
1265
-        return parent::_map_meta_caps($caps, $cap, $user_id, $args);
1266
-    }
1249
+	/**
1250
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1251
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1252
+	 *
1253
+	 * @since 4.5.0
1254
+	 * @see   wp-includes/capabilities.php
1255
+	 *
1256
+	 * @param array  $caps    actual users capabilities
1257
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1258
+	 * @param int    $user_id The user id
1259
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1260
+	 *
1261
+	 * @return array   actual users capabilities
1262
+	 */
1263
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1264
+	{
1265
+		return parent::_map_meta_caps($caps, $cap, $user_id, $args);
1266
+	}
1267 1267
 }
1268 1268
 
1269 1269
 
@@ -1278,86 +1278,86 @@  discard block
 block discarded – undo
1278 1278
  */
1279 1279
 class EE_Meta_Capability_Map_Read extends EE_Meta_Capability_Map
1280 1280
 {
1281
-    /**
1282
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1283
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1284
-     *
1285
-     * @since 4.5.0
1286
-     * @see   wp-includes/capabilities.php
1287
-     *
1288
-     * @param array  $caps    actual users capabilities
1289
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1290
-     * @param int    $user_id The user id
1291
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1292
-     *
1293
-     * @return array   actual users capabilities
1294
-     */
1295
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1296
-    {
1297
-        // only process if we're checking our mapped cap;
1298
-        if ($cap !== $this->meta_cap) {
1299
-            return $caps;
1300
-        }
1301
-
1302
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1303
-        if (($key = array_search($cap, $caps)) !== false) {
1304
-            unset($caps[ $key ]);
1305
-        }
1306
-
1307
-        // cast $user_id to int for later explicit comparisons
1308
-        $user_id = (int) $user_id;
1309
-
1310
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1311
-        // if no obj then let's just do cap
1312
-        if (! $obj instanceof EE_Base_Class) {
1313
-            $caps[] = 'do_not_allow';
1314
-            return $caps;
1315
-        }
1316
-
1317
-        $caps[] = $cap . 's';
1318
-        if ($obj instanceof EE_CPT_Base) {
1319
-            $status_obj = get_post_status_object($obj->status());
1320
-            if ($status_obj->public) {
1321
-                return $caps;
1322
-            }
1323
-            // if the item author is set and the user is not the author...
1324
-            if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1325
-                if (! empty($this->others_cap)) {
1326
-                    $caps[] = $this->others_cap;
1327
-                }
1328
-            }
1329
-            // yes this means that if users created the private post, they are able to see it regardless of private cap.
1330
-            if (
1331
-                $status_obj->private
1332
-                && ! empty($this->private_cap)
1333
-                && $obj->wp_user() !== $user_id
1334
-            ) {
1335
-                // the user is trying to view a private object for an object they don't own.
1336
-                $caps[] = $this->private_cap;
1337
-            }
1338
-        } else {
1339
-            // not a cpt object so handled differently
1340
-            $has_cap = false;
1341
-            try {
1342
-                $has_cap = method_exists($obj, 'wp_user')
1343
-                           && $obj->wp_user()
1344
-                           && $obj->wp_user() === $user_id;
1345
-            } catch (Exception $e) {
1346
-                if (WP_DEBUG) {
1347
-                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1348
-                }
1349
-            }
1350
-            if (! $has_cap) {
1351
-                if (! empty($this->private_cap)) {
1352
-                    $caps[] = $this->private_cap;
1353
-                }
1354
-                if (! empty($this->others_cap)) {
1355
-                    $caps[] = $this->others_cap;
1356
-                }
1357
-            }
1358
-        }
1359
-        return $caps;
1360
-    }
1281
+	/**
1282
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1283
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1284
+	 *
1285
+	 * @since 4.5.0
1286
+	 * @see   wp-includes/capabilities.php
1287
+	 *
1288
+	 * @param array  $caps    actual users capabilities
1289
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1290
+	 * @param int    $user_id The user id
1291
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1292
+	 *
1293
+	 * @return array   actual users capabilities
1294
+	 */
1295
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1296
+	{
1297
+		// only process if we're checking our mapped cap;
1298
+		if ($cap !== $this->meta_cap) {
1299
+			return $caps;
1300
+		}
1301
+
1302
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1303
+		if (($key = array_search($cap, $caps)) !== false) {
1304
+			unset($caps[ $key ]);
1305
+		}
1306
+
1307
+		// cast $user_id to int for later explicit comparisons
1308
+		$user_id = (int) $user_id;
1309
+
1310
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1311
+		// if no obj then let's just do cap
1312
+		if (! $obj instanceof EE_Base_Class) {
1313
+			$caps[] = 'do_not_allow';
1314
+			return $caps;
1315
+		}
1316
+
1317
+		$caps[] = $cap . 's';
1318
+		if ($obj instanceof EE_CPT_Base) {
1319
+			$status_obj = get_post_status_object($obj->status());
1320
+			if ($status_obj->public) {
1321
+				return $caps;
1322
+			}
1323
+			// if the item author is set and the user is not the author...
1324
+			if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1325
+				if (! empty($this->others_cap)) {
1326
+					$caps[] = $this->others_cap;
1327
+				}
1328
+			}
1329
+			// yes this means that if users created the private post, they are able to see it regardless of private cap.
1330
+			if (
1331
+				$status_obj->private
1332
+				&& ! empty($this->private_cap)
1333
+				&& $obj->wp_user() !== $user_id
1334
+			) {
1335
+				// the user is trying to view a private object for an object they don't own.
1336
+				$caps[] = $this->private_cap;
1337
+			}
1338
+		} else {
1339
+			// not a cpt object so handled differently
1340
+			$has_cap = false;
1341
+			try {
1342
+				$has_cap = method_exists($obj, 'wp_user')
1343
+						   && $obj->wp_user()
1344
+						   && $obj->wp_user() === $user_id;
1345
+			} catch (Exception $e) {
1346
+				if (WP_DEBUG) {
1347
+					EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1348
+				}
1349
+			}
1350
+			if (! $has_cap) {
1351
+				if (! empty($this->private_cap)) {
1352
+					$caps[] = $this->private_cap;
1353
+				}
1354
+				if (! empty($this->others_cap)) {
1355
+					$caps[] = $this->others_cap;
1356
+				}
1357
+			}
1358
+		}
1359
+		return $caps;
1360
+	}
1361 1361
 }
1362 1362
 
1363 1363
 
@@ -1373,56 +1373,56 @@  discard block
 block discarded – undo
1373 1373
  */
1374 1374
 class EE_Meta_Capability_Map_Messages_Cap extends EE_Meta_Capability_Map
1375 1375
 {
1376
-    /**
1377
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1378
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1379
-     *
1380
-     * @since 4.5.0
1381
-     * @see   wp-includes/capabilities.php
1382
-     *
1383
-     * @param array  $caps    actual users capabilities
1384
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1385
-     * @param int    $user_id The user id
1386
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1387
-     *
1388
-     * @return array   actual users capabilities
1389
-     */
1390
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1391
-    {
1392
-        // only process if we're checking our mapped_cap
1393
-        if ($cap !== $this->meta_cap) {
1394
-            return $caps;
1395
-        }
1396
-
1397
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1398
-        if (($key = array_search($cap, $caps)) !== false) {
1399
-            unset($caps[ $key ]);
1400
-        }
1401
-
1402
-        // cast $user_id to int for later explicit comparisons
1403
-        $user_id = (int) $user_id;
1404
-
1405
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1406
-        // if no obj then let's just do cap
1407
-        if (! $obj instanceof EE_Message_Template_Group) {
1408
-            $caps[] = 'do_not_allow';
1409
-            return $caps;
1410
-        }
1411
-        $caps[] = $cap . 's';
1412
-        $is_global = $obj->is_global();
1413
-        if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1414
-            if ($is_global) {
1415
-                $caps[] = $this->private_cap;
1416
-            }
1417
-        } else {
1418
-            if ($is_global) {
1419
-                $caps[] = $this->private_cap;
1420
-            } else {
1421
-                $caps[] = $this->others_cap;
1422
-            }
1423
-        }
1424
-        return $caps;
1425
-    }
1376
+	/**
1377
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1378
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1379
+	 *
1380
+	 * @since 4.5.0
1381
+	 * @see   wp-includes/capabilities.php
1382
+	 *
1383
+	 * @param array  $caps    actual users capabilities
1384
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1385
+	 * @param int    $user_id The user id
1386
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1387
+	 *
1388
+	 * @return array   actual users capabilities
1389
+	 */
1390
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1391
+	{
1392
+		// only process if we're checking our mapped_cap
1393
+		if ($cap !== $this->meta_cap) {
1394
+			return $caps;
1395
+		}
1396
+
1397
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1398
+		if (($key = array_search($cap, $caps)) !== false) {
1399
+			unset($caps[ $key ]);
1400
+		}
1401
+
1402
+		// cast $user_id to int for later explicit comparisons
1403
+		$user_id = (int) $user_id;
1404
+
1405
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1406
+		// if no obj then let's just do cap
1407
+		if (! $obj instanceof EE_Message_Template_Group) {
1408
+			$caps[] = 'do_not_allow';
1409
+			return $caps;
1410
+		}
1411
+		$caps[] = $cap . 's';
1412
+		$is_global = $obj->is_global();
1413
+		if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1414
+			if ($is_global) {
1415
+				$caps[] = $this->private_cap;
1416
+			}
1417
+		} else {
1418
+			if ($is_global) {
1419
+				$caps[] = $this->private_cap;
1420
+			} else {
1421
+				$caps[] = $this->others_cap;
1422
+			}
1423
+		}
1424
+		return $caps;
1425
+	}
1426 1426
 }
1427 1427
 
1428 1428
 
@@ -1438,40 +1438,40 @@  discard block
 block discarded – undo
1438 1438
  */
1439 1439
 class EE_Meta_Capability_Map_Registration_Form_Cap extends EE_Meta_Capability_Map
1440 1440
 {
1441
-    /**
1442
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1443
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1444
-     *
1445
-     * @since 4.5.0
1446
-     * @see   wp-includes/capabilities.php
1447
-     * @param array  $caps    actual users capabilities
1448
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1449
-     * @param int    $user_id The user id
1450
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1451
-     * @return array   actual users capabilities
1452
-     */
1453
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1454
-    {
1455
-        // only process if we're checking our mapped_cap
1456
-        if ($cap !== $this->meta_cap) {
1457
-            return $caps;
1458
-        }
1459
-        // okay it is a meta cap so let's first remove that cap from the $caps array.
1460
-        if (($key = array_search($cap, $caps)) !== false) {
1461
-            unset($caps[ $key ]);
1462
-        }
1463
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1464
-        // if no obj then let's just do cap
1465
-        if (! $obj instanceof EE_Base_Class) {
1466
-            $caps[] = 'do_not_allow';
1467
-            return $caps;
1468
-        }
1469
-        $caps[] = $cap . 's';
1470
-        $is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1471
-        $is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1472
-        if ($is_system) {
1473
-            $caps[] = $this->private_cap;
1474
-        }
1475
-        return $caps;
1476
-    }
1441
+	/**
1442
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1443
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1444
+	 *
1445
+	 * @since 4.5.0
1446
+	 * @see   wp-includes/capabilities.php
1447
+	 * @param array  $caps    actual users capabilities
1448
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1449
+	 * @param int    $user_id The user id
1450
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1451
+	 * @return array   actual users capabilities
1452
+	 */
1453
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1454
+	{
1455
+		// only process if we're checking our mapped_cap
1456
+		if ($cap !== $this->meta_cap) {
1457
+			return $caps;
1458
+		}
1459
+		// okay it is a meta cap so let's first remove that cap from the $caps array.
1460
+		if (($key = array_search($cap, $caps)) !== false) {
1461
+			unset($caps[ $key ]);
1462
+		}
1463
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1464
+		// if no obj then let's just do cap
1465
+		if (! $obj instanceof EE_Base_Class) {
1466
+			$caps[] = 'do_not_allow';
1467
+			return $caps;
1468
+		}
1469
+		$caps[] = $cap . 's';
1470
+		$is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1471
+		$is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1472
+		if ($is_system) {
1473
+			$caps[] = $this->private_cap;
1474
+		}
1475
+		return $caps;
1476
+	}
1477 1477
 }
Please login to merge, or discard this patch.
shortcodes/espresso_checkout/EES_Espresso_Checkout.shortcode.php 1 patch
Indentation   +49 added lines, -50 removed lines patch added patch discarded remove patch
@@ -7,66 +7,65 @@
 block discarded – undo
7 7
  * @package     Event Espresso
8 8
  * @subpackage  /shortcodes/
9 9
  * @author      Brent Christensen
10
-
11 10
  * ------------------------------------------------------------------------
12 11
  */
13 12
 class EES_Espresso_Checkout extends EES_Shortcode
14 13
 {
15 14
 
16
-    /**
17
-     *  set_hooks - for hooking into EE Core, modules, etc
18
-     *
19
-     *  @access     public
20
-     *  @return     void
21
-     */
22
-    public static function set_hooks()
23
-    {
24
-    }
15
+	/**
16
+	 *  set_hooks - for hooking into EE Core, modules, etc
17
+	 *
18
+	 *  @access     public
19
+	 *  @return     void
20
+	 */
21
+	public static function set_hooks()
22
+	{
23
+	}
25 24
 
26
-    /**
27
-     *  set_hooks_admin - for hooking into EE Admin Core, modules, etc
28
-     *
29
-     *  @access     public
30
-     *  @return     void
31
-     */
32
-    public static function set_hooks_admin()
33
-    {
34
-    }
25
+	/**
26
+	 *  set_hooks_admin - for hooking into EE Admin Core, modules, etc
27
+	 *
28
+	 *  @access     public
29
+	 *  @return     void
30
+	 */
31
+	public static function set_hooks_admin()
32
+	{
33
+	}
35 34
 
36 35
 
37 36
 
38
-    /**
39
-     *    run - initial shortcode module setup called during "wp_loaded" hook
40
-     *    this method is primarily used for loading resources that will be required by the shortcode when it is actually processed
41
-     *
42
-     * @access    public
43
-     * @param WP $WP
44
-     * @return    void
45
-     * @throws \EE_Error
46
-     */
47
-    public function run(WP $WP)
48
-    {
49
-    }
37
+	/**
38
+	 *    run - initial shortcode module setup called during "wp_loaded" hook
39
+	 *    this method is primarily used for loading resources that will be required by the shortcode when it is actually processed
40
+	 *
41
+	 * @access    public
42
+	 * @param WP $WP
43
+	 * @return    void
44
+	 * @throws \EE_Error
45
+	 */
46
+	public function run(WP $WP)
47
+	{
48
+	}
50 49
 
51 50
 
52 51
 
53
-    /**
54
-     *  process_shortcode - ESPRESSO_CHECKOUT
55
-     *
56
-     *  @access     public
57
-     *  @param      array   $attributes
58
-     *  @return     string
59
-     */
60
-    public function process_shortcode($attributes = array())
61
-    {
62
-        \EE_Error::doing_it_wrong(
63
-            __METHOD__,
64
-            esc_html__(
65
-                'Usage is deprecated. Please use \EventEspresso\core\domain\entities\shortcodes\EspressoCheckout::processShortcode() instead.',
66
-                'event_espresso'
67
-            ),
68
-            '4.9.27'
69
-        );
70
-        return '';
71
-    }
52
+	/**
53
+	 *  process_shortcode - ESPRESSO_CHECKOUT
54
+	 *
55
+	 *  @access     public
56
+	 *  @param      array   $attributes
57
+	 *  @return     string
58
+	 */
59
+	public function process_shortcode($attributes = array())
60
+	{
61
+		\EE_Error::doing_it_wrong(
62
+			__METHOD__,
63
+			esc_html__(
64
+				'Usage is deprecated. Please use \EventEspresso\core\domain\entities\shortcodes\EspressoCheckout::processShortcode() instead.',
65
+				'event_espresso'
66
+			),
67
+			'4.9.27'
68
+		);
69
+		return '';
70
+	}
72 71
 }
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/templates/paypal_express_intro.template.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -1,10 +1,10 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 printf(
4
-    esc_html__(
5
-        'PayPal Express (Express Checkout) is an off-site payment method for accepting payments via PayPal and is available to event organizers in many countries. A PayPal premier or business account is needed to accept payments. Need a PayPal account? Call 1-855-456-1338 or %1$sclick here to sign up for a merchant account%2$s.',
6
-        'event_espresso'
7
-    ),
8
-    '<a href="https://eventespresso.com/go/paypalexpress/" target="_blank">',
9
-    '</a>'
4
+	esc_html__(
5
+		'PayPal Express (Express Checkout) is an off-site payment method for accepting payments via PayPal and is available to event organizers in many countries. A PayPal premier or business account is needed to accept payments. Need a PayPal account? Call 1-855-456-1338 or %1$sclick here to sign up for a merchant account%2$s.',
6
+		'event_espresso'
7
+	),
8
+	'<a href="https://eventespresso.com/go/paypalexpress/" target="_blank">',
9
+	'</a>'
10 10
 );
Please login to merge, or discard this patch.
payment_methods/Paypal_Standard/EEG_Paypal_Standard.gateway.php 2 patches
Spacing   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -137,17 +137,17 @@  discard block
 block discarded – undo
137 137
                         $shipping_previously_added = $line_item->total();
138 138
                         continue;
139 139
                     }
140
-                    $redirect_args[ 'item_name_' . $item_num ] = substr(
140
+                    $redirect_args['item_name_'.$item_num] = substr(
141 141
                         $gateway_formatter->formatLineItemName($line_item, $payment),
142 142
                         0,
143 143
                         127
144 144
                     );
145
-                    $redirect_args[ 'amount_' . $item_num ] = $line_item->unit_price();
146
-                    $redirect_args[ 'quantity_' . $item_num ] = $line_item->quantity();
145
+                    $redirect_args['amount_'.$item_num] = $line_item->unit_price();
146
+                    $redirect_args['quantity_'.$item_num] = $line_item->quantity();
147 147
                     // if we're not letting PayPal calculate shipping, tell them its 0
148
-                    if (! $this->_paypal_shipping) {
149
-                        $redirect_args[ 'shipping_' . $item_num ] = '0';
150
-                        $redirect_args[ 'shipping2_' . $item_num ] = '0';
148
+                    if ( ! $this->_paypal_shipping) {
149
+                        $redirect_args['shipping_'.$item_num] = '0';
150
+                        $redirect_args['shipping2_'.$item_num] = '0';
151 151
                     }
152 152
                     $item_num++;
153 153
                     $itemized_sum += $line_item->total();
@@ -167,15 +167,15 @@  discard block
 block discarded – undo
167 167
                 // itemized sum is too big
168 168
                 $total_discounts_to_cart_total += abs($itemized_sum_diff_from_txn_total);
169 169
             } elseif ($itemized_sum_diff_from_txn_total > 0) {
170
-                $redirect_args[ 'item_name_' . $item_num ] = substr(
170
+                $redirect_args['item_name_'.$item_num] = substr(
171 171
                     esc_html__('Other charges', 'event_espresso'),
172 172
                     0,
173 173
                     127
174 174
                 );
175
-                $redirect_args[ 'amount_' . $item_num ] = $gateway_formatter->formatCurrency(
175
+                $redirect_args['amount_'.$item_num] = $gateway_formatter->formatCurrency(
176 176
                     $itemized_sum_diff_from_txn_total
177 177
                 );
178
-                $redirect_args[ 'quantity_' . $item_num ] = 1;
178
+                $redirect_args['quantity_'.$item_num] = 1;
179 179
                 $item_num++;
180 180
             }
181 181
             if ($total_discounts_to_cart_total > 0) {
@@ -184,34 +184,34 @@  discard block
 block discarded – undo
184 184
                 );
185 185
             }
186 186
             // add our taxes to the order if we're NOT using PayPal's
187
-            if (! $this->_paypal_taxes) {
187
+            if ( ! $this->_paypal_taxes) {
188 188
                 $redirect_args['tax_cart'] = $total_line_item->get_total_tax();
189 189
             }
190 190
         } else {
191 191
             $payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, false);
192 192
             // partial payment that's not for the remaining amount, so we can't send an itemized list
193
-            $redirect_args[ 'item_name_' . $item_num ] = substr(
193
+            $redirect_args['item_name_'.$item_num] = substr(
194 194
                 $gateway_formatter->formatPartialPaymentLineItemName($payment),
195 195
                 0,
196 196
                 127
197 197
             );
198
-            $redirect_args[ 'amount_' . $item_num ] = $payment->amount();
199
-            $redirect_args[ 'shipping_' . $item_num ] = '0';
200
-            $redirect_args[ 'shipping2_' . $item_num ] = '0';
198
+            $redirect_args['amount_'.$item_num] = $payment->amount();
199
+            $redirect_args['shipping_'.$item_num] = '0';
200
+            $redirect_args['shipping2_'.$item_num] = '0';
201 201
             $redirect_args['tax_cart'] = '0';
202 202
             $item_num++;
203 203
         }
204 204
 
205 205
         if ($this->_debug_mode) {
206
-            $redirect_args[ 'item_name_' . $item_num ] = 'DEBUG INFO (this item only added in sandbox mode';
207
-            $redirect_args[ 'amount_' . $item_num ] = 0;
208
-            $redirect_args[ 'on0_' . $item_num ] = 'NOTIFY URL';
209
-            $redirect_args[ 'os0_' . $item_num ] = $notify_url;
210
-            $redirect_args[ 'on1_' . $item_num ] = 'RETURN URL';
211
-            $redirect_args[ 'os1_' . $item_num ] = $return_url;
206
+            $redirect_args['item_name_'.$item_num] = 'DEBUG INFO (this item only added in sandbox mode';
207
+            $redirect_args['amount_'.$item_num] = 0;
208
+            $redirect_args['on0_'.$item_num] = 'NOTIFY URL';
209
+            $redirect_args['os0_'.$item_num] = $notify_url;
210
+            $redirect_args['on1_'.$item_num] = 'RETURN URL';
211
+            $redirect_args['os1_'.$item_num] = $return_url;
212 212
 //          $redirect_args['option_index_' . $item_num] = 1; // <-- dunno if this is needed ?
213
-            $redirect_args[ 'shipping_' . $item_num ] = '0';
214
-            $redirect_args[ 'shipping2_' . $item_num ] = '0';
213
+            $redirect_args['shipping_'.$item_num] = '0';
214
+            $redirect_args['shipping2_'.$item_num] = '0';
215 215
         }
216 216
 
217 217
         $redirect_args['business'] = $this->_paypal_id;
@@ -221,12 +221,12 @@  discard block
 block discarded – undo
221 221
         $redirect_args['cmd'] = '_cart';
222 222
         $redirect_args['upload'] = 1;
223 223
         $redirect_args['currency_code'] = $payment->currency_code();
224
-        $redirect_args['rm'] = 2;// makes the user return with method=POST
224
+        $redirect_args['rm'] = 2; // makes the user return with method=POST
225 225
         if ($this->_image_url) {
226 226
             $redirect_args['image_url'] = $this->_image_url;
227 227
         }
228 228
         $redirect_args['no_shipping'] = $this->_shipping_details;
229
-        $redirect_args['bn'] = 'EventEspresso_SP';// EE will blow up if you change this
229
+        $redirect_args['bn'] = 'EventEspresso_SP'; // EE will blow up if you change this
230 230
 
231 231
         $redirect_args = apply_filters("FHEE__EEG_Paypal_Standard__set_redirection_info__arguments", $redirect_args, $this);
232 232
 
@@ -281,12 +281,12 @@  discard block
 block discarded – undo
281 281
             }
282 282
         }
283 283
         $payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
284
-        if (! $payment instanceof EEI_Payment) {
284
+        if ( ! $payment instanceof EEI_Payment) {
285 285
             $payment = $transaction->last_payment();
286 286
         }
287 287
         // ok, then validate the IPN. Even if we've already processed this payment,
288 288
         // let PayPal know we don't want to hear from them anymore!
289
-        if (! $this->validate_ipn($update_info, $payment)) {
289
+        if ( ! $this->validate_ipn($update_info, $payment)) {
290 290
             return $payment;
291 291
         }
292 292
         // kill request here if this is a refund, we don't support them yet (we'd need to adjust the transaction,
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
         foreach ($raw_post_array as $keyval) {
427 427
             $keyval = explode('=', $keyval);
428 428
             if (count($keyval) === 2) {
429
-                $update_info[ $keyval[0] ] = urldecode($keyval[1]);
429
+                $update_info[$keyval[0]] = urldecode($keyval[1]);
430 430
             }
431 431
         }
432 432
         // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
@@ -447,7 +447,7 @@  discard block
 block discarded – undo
447 447
                 'timeout'           => 60,
448 448
                 // make sure to set a site specific unique "user-agent" string since the WordPres default gets declined by PayPal
449 449
                 // plz see: https://github.com/websharks/s2member/issues/610
450
-                'user-agent'        => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(),
450
+                'user-agent'        => 'Event Espresso v'.EVENT_ESPRESSO_VERSION.'; '.home_url(),
451 451
                 'httpversion'       => '1.1'
452 452
             )
453 453
         );
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
         /** @var EE_Transaction $transaction */
525 525
         $transaction = $payment->transaction();
526 526
         $payment_was_itemized = $payment->get_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true, false);
527
-        if (! $transaction) {
527
+        if ( ! $transaction) {
528 528
             $this->log(
529 529
                 esc_html__(
530 530
                     // @codingStandardsIgnoreStart
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
                 esc_html__('Shipping charges calculated by Paypal', 'event_espresso'),
600 600
                 1,
601 601
                 false,
602
-                'paypal_shipping_' . $transaction->ID()
602
+                'paypal_shipping_'.$transaction->ID()
603 603
             );
604 604
             $grand_total_needs_resaving = true;
605 605
         }
Please login to merge, or discard this patch.
Indentation   +603 added lines, -603 removed lines patch added patch discarded remove patch
@@ -18,608 +18,608 @@
 block discarded – undo
18 18
  */
19 19
 class EEG_Paypal_Standard extends EE_Offsite_Gateway
20 20
 {
21
-    /**
22
-     * Name for the wp option used to save the itemized payment
23
-     */
24
-    const itemized_payment_option_name = '_itemized_payment';
25
-
26
-    protected $_paypal_id;
27
-
28
-    protected $_image_url;
29
-
30
-    protected $_shipping_details;
31
-
32
-    protected $_paypal_shipping;
33
-
34
-    protected $_paypal_taxes;
35
-
36
-    protected $_gateway_url;
37
-
38
-    protected $_currencies_supported = array(
39
-        'USD',
40
-        'GBP',
41
-        'CAD',
42
-        'AUD',
43
-        'BRL',
44
-        'CHF',
45
-        'CZK',
46
-        'DKK',
47
-        'EUR',
48
-        'HKD',
49
-        'HUF',
50
-        'ILS',
51
-        'JPY',
52
-        'MXN',
53
-        'MYR',
54
-        'NOK',
55
-        'NZD',
56
-        'PHP',
57
-        'PLN',
58
-        'SEK',
59
-        'SGD',
60
-        'THB',
61
-        'TRY',
62
-        'TWD',
63
-        'RUB'
64
-    );
65
-
66
-
67
-    /**
68
-     * EEG_Paypal_Standard constructor.
69
-     *
70
-     * @return EEG_Paypal_Standard
71
-     */
72
-    public function __construct()
73
-    {
74
-        $this->set_uses_separate_IPN_request(true);
75
-        parent::__construct();
76
-    }
77
-
78
-
79
-    /**
80
-     * Also sets the gateway url class variable based on whether debug mode is enabled or not.
81
-     *
82
-     * @param array $settings_array
83
-     */
84
-    public function set_settings($settings_array)
85
-    {
86
-        parent::set_settings($settings_array);
87
-        $this->_gateway_url = $this->_debug_mode
88
-            ? 'https://www.sandbox.paypal.com/cgi-bin/webscr'
89
-            : 'https://www.paypal.com/cgi-bin/webscr';
90
-    }
91
-
92
-
93
-    /**
94
-     * @param EEI_Payment $payment      the payment to process
95
-     * @param array       $billing_info but should be empty for this gateway
96
-     * @param string      $return_url   URL to send the user to after payment on the payment provider's website
97
-     * @param string      $notify_url   URL to send the instant payment notification
98
-     * @param string      $cancel_url   URL to send the user to after a cancelled payment attempt
99
-     *                                  on the payment provider's website
100
-     * @return EEI_Payment
101
-     * @throws \EE_Error
102
-     */
103
-    public function set_redirection_info(
104
-        $payment,
105
-        $billing_info = array(),
106
-        $return_url = null,
107
-        $notify_url = null,
108
-        $cancel_url = null
109
-    ) {
110
-        $redirect_args = array();
111
-        $transaction = $payment->transaction();
112
-        $gateway_formatter = $this->_get_gateway_formatter();
113
-        $item_num = 1;
114
-        /** @type EE_Line_Item $total_line_item */
115
-        $total_line_item = $transaction->total_line_item();
116
-
117
-        $total_discounts_to_cart_total = $transaction->paid();
118
-        // only itemize the order if we're paying for the rest of the order's amount
119
-        if (EEH_Money::compare_floats($payment->amount(), $transaction->total(), '==')) {
120
-            $payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true);
121
-            // this payment is for the remaining transaction amount,
122
-            // keep track of exactly how much the itemized order amount equals
123
-            $itemized_sum = 0;
124
-            $shipping_previously_added = 0;
125
-            // so let's show all the line items
126
-            foreach ($total_line_item->get_items() as $line_item) {
127
-                if ($line_item instanceof EE_Line_Item) {
128
-                    // it's some kind of discount
129
-                    if ($line_item->total() < 0) {
130
-                        $total_discounts_to_cart_total += abs($line_item->total());
131
-                        $itemized_sum += $line_item->total();
132
-                        continue;
133
-                    }
134
-                    // dont include shipping again.
135
-                    if (strpos($line_item->code(), 'paypal_shipping_') === 0) {
136
-                        $shipping_previously_added = $line_item->total();
137
-                        continue;
138
-                    }
139
-                    $redirect_args[ 'item_name_' . $item_num ] = substr(
140
-                        $gateway_formatter->formatLineItemName($line_item, $payment),
141
-                        0,
142
-                        127
143
-                    );
144
-                    $redirect_args[ 'amount_' . $item_num ] = $line_item->unit_price();
145
-                    $redirect_args[ 'quantity_' . $item_num ] = $line_item->quantity();
146
-                    // if we're not letting PayPal calculate shipping, tell them its 0
147
-                    if (! $this->_paypal_shipping) {
148
-                        $redirect_args[ 'shipping_' . $item_num ] = '0';
149
-                        $redirect_args[ 'shipping2_' . $item_num ] = '0';
150
-                    }
151
-                    $item_num++;
152
-                    $itemized_sum += $line_item->total();
153
-                }
154
-            }
155
-            $taxes_li = $this->_line_item->get_taxes_subtotal($total_line_item);
156
-            // ideally itemized sum equals the transaction total. but if not (which is weird)
157
-            // and the itemized sum is LESS than the transaction total
158
-            // add another line item
159
-            // if the itemized sum is MORE than the transaction total,
160
-            // add the difference it to the discounts
161
-            $itemized_sum_diff_from_txn_total = round(
162
-                $transaction->total() - $itemized_sum - $taxes_li->total() - $shipping_previously_added,
163
-                2
164
-            );
165
-            if ($itemized_sum_diff_from_txn_total < 0) {
166
-                // itemized sum is too big
167
-                $total_discounts_to_cart_total += abs($itemized_sum_diff_from_txn_total);
168
-            } elseif ($itemized_sum_diff_from_txn_total > 0) {
169
-                $redirect_args[ 'item_name_' . $item_num ] = substr(
170
-                    esc_html__('Other charges', 'event_espresso'),
171
-                    0,
172
-                    127
173
-                );
174
-                $redirect_args[ 'amount_' . $item_num ] = $gateway_formatter->formatCurrency(
175
-                    $itemized_sum_diff_from_txn_total
176
-                );
177
-                $redirect_args[ 'quantity_' . $item_num ] = 1;
178
-                $item_num++;
179
-            }
180
-            if ($total_discounts_to_cart_total > 0) {
181
-                $redirect_args['discount_amount_cart'] = $gateway_formatter->formatCurrency(
182
-                    $total_discounts_to_cart_total
183
-                );
184
-            }
185
-            // add our taxes to the order if we're NOT using PayPal's
186
-            if (! $this->_paypal_taxes) {
187
-                $redirect_args['tax_cart'] = $total_line_item->get_total_tax();
188
-            }
189
-        } else {
190
-            $payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, false);
191
-            // partial payment that's not for the remaining amount, so we can't send an itemized list
192
-            $redirect_args[ 'item_name_' . $item_num ] = substr(
193
-                $gateway_formatter->formatPartialPaymentLineItemName($payment),
194
-                0,
195
-                127
196
-            );
197
-            $redirect_args[ 'amount_' . $item_num ] = $payment->amount();
198
-            $redirect_args[ 'shipping_' . $item_num ] = '0';
199
-            $redirect_args[ 'shipping2_' . $item_num ] = '0';
200
-            $redirect_args['tax_cart'] = '0';
201
-            $item_num++;
202
-        }
203
-
204
-        if ($this->_debug_mode) {
205
-            $redirect_args[ 'item_name_' . $item_num ] = 'DEBUG INFO (this item only added in sandbox mode';
206
-            $redirect_args[ 'amount_' . $item_num ] = 0;
207
-            $redirect_args[ 'on0_' . $item_num ] = 'NOTIFY URL';
208
-            $redirect_args[ 'os0_' . $item_num ] = $notify_url;
209
-            $redirect_args[ 'on1_' . $item_num ] = 'RETURN URL';
210
-            $redirect_args[ 'os1_' . $item_num ] = $return_url;
21
+	/**
22
+	 * Name for the wp option used to save the itemized payment
23
+	 */
24
+	const itemized_payment_option_name = '_itemized_payment';
25
+
26
+	protected $_paypal_id;
27
+
28
+	protected $_image_url;
29
+
30
+	protected $_shipping_details;
31
+
32
+	protected $_paypal_shipping;
33
+
34
+	protected $_paypal_taxes;
35
+
36
+	protected $_gateway_url;
37
+
38
+	protected $_currencies_supported = array(
39
+		'USD',
40
+		'GBP',
41
+		'CAD',
42
+		'AUD',
43
+		'BRL',
44
+		'CHF',
45
+		'CZK',
46
+		'DKK',
47
+		'EUR',
48
+		'HKD',
49
+		'HUF',
50
+		'ILS',
51
+		'JPY',
52
+		'MXN',
53
+		'MYR',
54
+		'NOK',
55
+		'NZD',
56
+		'PHP',
57
+		'PLN',
58
+		'SEK',
59
+		'SGD',
60
+		'THB',
61
+		'TRY',
62
+		'TWD',
63
+		'RUB'
64
+	);
65
+
66
+
67
+	/**
68
+	 * EEG_Paypal_Standard constructor.
69
+	 *
70
+	 * @return EEG_Paypal_Standard
71
+	 */
72
+	public function __construct()
73
+	{
74
+		$this->set_uses_separate_IPN_request(true);
75
+		parent::__construct();
76
+	}
77
+
78
+
79
+	/**
80
+	 * Also sets the gateway url class variable based on whether debug mode is enabled or not.
81
+	 *
82
+	 * @param array $settings_array
83
+	 */
84
+	public function set_settings($settings_array)
85
+	{
86
+		parent::set_settings($settings_array);
87
+		$this->_gateway_url = $this->_debug_mode
88
+			? 'https://www.sandbox.paypal.com/cgi-bin/webscr'
89
+			: 'https://www.paypal.com/cgi-bin/webscr';
90
+	}
91
+
92
+
93
+	/**
94
+	 * @param EEI_Payment $payment      the payment to process
95
+	 * @param array       $billing_info but should be empty for this gateway
96
+	 * @param string      $return_url   URL to send the user to after payment on the payment provider's website
97
+	 * @param string      $notify_url   URL to send the instant payment notification
98
+	 * @param string      $cancel_url   URL to send the user to after a cancelled payment attempt
99
+	 *                                  on the payment provider's website
100
+	 * @return EEI_Payment
101
+	 * @throws \EE_Error
102
+	 */
103
+	public function set_redirection_info(
104
+		$payment,
105
+		$billing_info = array(),
106
+		$return_url = null,
107
+		$notify_url = null,
108
+		$cancel_url = null
109
+	) {
110
+		$redirect_args = array();
111
+		$transaction = $payment->transaction();
112
+		$gateway_formatter = $this->_get_gateway_formatter();
113
+		$item_num = 1;
114
+		/** @type EE_Line_Item $total_line_item */
115
+		$total_line_item = $transaction->total_line_item();
116
+
117
+		$total_discounts_to_cart_total = $transaction->paid();
118
+		// only itemize the order if we're paying for the rest of the order's amount
119
+		if (EEH_Money::compare_floats($payment->amount(), $transaction->total(), '==')) {
120
+			$payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true);
121
+			// this payment is for the remaining transaction amount,
122
+			// keep track of exactly how much the itemized order amount equals
123
+			$itemized_sum = 0;
124
+			$shipping_previously_added = 0;
125
+			// so let's show all the line items
126
+			foreach ($total_line_item->get_items() as $line_item) {
127
+				if ($line_item instanceof EE_Line_Item) {
128
+					// it's some kind of discount
129
+					if ($line_item->total() < 0) {
130
+						$total_discounts_to_cart_total += abs($line_item->total());
131
+						$itemized_sum += $line_item->total();
132
+						continue;
133
+					}
134
+					// dont include shipping again.
135
+					if (strpos($line_item->code(), 'paypal_shipping_') === 0) {
136
+						$shipping_previously_added = $line_item->total();
137
+						continue;
138
+					}
139
+					$redirect_args[ 'item_name_' . $item_num ] = substr(
140
+						$gateway_formatter->formatLineItemName($line_item, $payment),
141
+						0,
142
+						127
143
+					);
144
+					$redirect_args[ 'amount_' . $item_num ] = $line_item->unit_price();
145
+					$redirect_args[ 'quantity_' . $item_num ] = $line_item->quantity();
146
+					// if we're not letting PayPal calculate shipping, tell them its 0
147
+					if (! $this->_paypal_shipping) {
148
+						$redirect_args[ 'shipping_' . $item_num ] = '0';
149
+						$redirect_args[ 'shipping2_' . $item_num ] = '0';
150
+					}
151
+					$item_num++;
152
+					$itemized_sum += $line_item->total();
153
+				}
154
+			}
155
+			$taxes_li = $this->_line_item->get_taxes_subtotal($total_line_item);
156
+			// ideally itemized sum equals the transaction total. but if not (which is weird)
157
+			// and the itemized sum is LESS than the transaction total
158
+			// add another line item
159
+			// if the itemized sum is MORE than the transaction total,
160
+			// add the difference it to the discounts
161
+			$itemized_sum_diff_from_txn_total = round(
162
+				$transaction->total() - $itemized_sum - $taxes_li->total() - $shipping_previously_added,
163
+				2
164
+			);
165
+			if ($itemized_sum_diff_from_txn_total < 0) {
166
+				// itemized sum is too big
167
+				$total_discounts_to_cart_total += abs($itemized_sum_diff_from_txn_total);
168
+			} elseif ($itemized_sum_diff_from_txn_total > 0) {
169
+				$redirect_args[ 'item_name_' . $item_num ] = substr(
170
+					esc_html__('Other charges', 'event_espresso'),
171
+					0,
172
+					127
173
+				);
174
+				$redirect_args[ 'amount_' . $item_num ] = $gateway_formatter->formatCurrency(
175
+					$itemized_sum_diff_from_txn_total
176
+				);
177
+				$redirect_args[ 'quantity_' . $item_num ] = 1;
178
+				$item_num++;
179
+			}
180
+			if ($total_discounts_to_cart_total > 0) {
181
+				$redirect_args['discount_amount_cart'] = $gateway_formatter->formatCurrency(
182
+					$total_discounts_to_cart_total
183
+				);
184
+			}
185
+			// add our taxes to the order if we're NOT using PayPal's
186
+			if (! $this->_paypal_taxes) {
187
+				$redirect_args['tax_cart'] = $total_line_item->get_total_tax();
188
+			}
189
+		} else {
190
+			$payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, false);
191
+			// partial payment that's not for the remaining amount, so we can't send an itemized list
192
+			$redirect_args[ 'item_name_' . $item_num ] = substr(
193
+				$gateway_formatter->formatPartialPaymentLineItemName($payment),
194
+				0,
195
+				127
196
+			);
197
+			$redirect_args[ 'amount_' . $item_num ] = $payment->amount();
198
+			$redirect_args[ 'shipping_' . $item_num ] = '0';
199
+			$redirect_args[ 'shipping2_' . $item_num ] = '0';
200
+			$redirect_args['tax_cart'] = '0';
201
+			$item_num++;
202
+		}
203
+
204
+		if ($this->_debug_mode) {
205
+			$redirect_args[ 'item_name_' . $item_num ] = 'DEBUG INFO (this item only added in sandbox mode';
206
+			$redirect_args[ 'amount_' . $item_num ] = 0;
207
+			$redirect_args[ 'on0_' . $item_num ] = 'NOTIFY URL';
208
+			$redirect_args[ 'os0_' . $item_num ] = $notify_url;
209
+			$redirect_args[ 'on1_' . $item_num ] = 'RETURN URL';
210
+			$redirect_args[ 'os1_' . $item_num ] = $return_url;
211 211
 //          $redirect_args['option_index_' . $item_num] = 1; // <-- dunno if this is needed ?
212
-            $redirect_args[ 'shipping_' . $item_num ] = '0';
213
-            $redirect_args[ 'shipping2_' . $item_num ] = '0';
214
-        }
215
-
216
-        $redirect_args['business'] = $this->_paypal_id;
217
-        $redirect_args['return'] = $return_url;
218
-        $redirect_args['cancel_return'] = $cancel_url;
219
-        $redirect_args['notify_url'] = $notify_url;
220
-        $redirect_args['cmd'] = '_cart';
221
-        $redirect_args['upload'] = 1;
222
-        $redirect_args['currency_code'] = $payment->currency_code();
223
-        $redirect_args['rm'] = 2;// makes the user return with method=POST
224
-        if ($this->_image_url) {
225
-            $redirect_args['image_url'] = $this->_image_url;
226
-        }
227
-        $redirect_args['no_shipping'] = $this->_shipping_details;
228
-        $redirect_args['bn'] = 'EventEspresso_SP';// EE will blow up if you change this
229
-
230
-        $redirect_args = apply_filters("FHEE__EEG_Paypal_Standard__set_redirection_info__arguments", $redirect_args, $this);
231
-
232
-        $payment->set_redirect_url($this->_gateway_url);
233
-        $payment->set_redirect_args($redirect_args);
234
-        // log the results
235
-        $this->log(
236
-            array(
237
-                'message'     => sprintf(
238
-                    esc_html__('PayPal payment request initiated.', 'event_espresso')
239
-                ),
240
-                'transaction' => $transaction->model_field_array(),
241
-            ),
242
-            $payment
243
-        );
244
-        return $payment;
245
-    }
246
-
247
-
248
-    /**
249
-     * Often used for IPNs. But applies the info in $update_info to the payment.
250
-     * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
251
-     * the payment method passes in.
252
-     *
253
-     * @param array $update_info like $_POST
254
-     * @param EEI_Transaction $transaction
255
-     * @return \EEI_Payment updated
256
-     * @throws \EE_Error, IpnException
257
-     */
258
-    public function handle_payment_update($update_info, $transaction)
259
-    {
260
-        // verify there's payment data that's been sent
261
-        if (empty($update_info['payment_status']) || empty($update_info['txn_id'])) {
262
-            // log the results
263
-            $this->log(
264
-                array(
265
-                    'message'     => sprintf(
266
-                        // @codingStandardsIgnoreStart
267
-                        esc_html__('PayPal IPN response is missing critical payment data. This may indicate a PDT request and require your PayPal account settings to be corrected.', 'event_espresso')
268
-                        // @codingStandardsIgnoreEnd
269
-                    ),
270
-                    'update_info' => $update_info,
271
-                ),
272
-                $transaction
273
-            );
274
-            // waaaait... is this a PDT request? (see https://developer.paypal.com/docs/classic/products/payment-data-transfer/)
275
-            // indicated by the "tx" argument? If so, we don't need it. We'll just use the IPN data when it comes
276
-            if (isset($update_info['tx'])) {
277
-                return $transaction->last_payment();
278
-            } else {
279
-                return null;
280
-            }
281
-        }
282
-        $payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
283
-        if (! $payment instanceof EEI_Payment) {
284
-            $payment = $transaction->last_payment();
285
-        }
286
-        // ok, then validate the IPN. Even if we've already processed this payment,
287
-        // let PayPal know we don't want to hear from them anymore!
288
-        if (! $this->validate_ipn($update_info, $payment)) {
289
-            return $payment;
290
-        }
291
-        // kill request here if this is a refund, we don't support them yet (we'd need to adjust the transaction,
292
-        // registrations, ticket counts, etc)
293
-        if (
294
-            (
295
-                $update_info['payment_status'] === 'Refunded'
296
-                || $update_info['payment_status'] === 'Partially_Refunded'
297
-            )
298
-            && apply_filters('FHEE__EEG_Paypal_Standard__handle_payment_update__kill_refund_request', true)
299
-        ) {
300
-            throw new EventEspresso\core\exceptions\IpnException(
301
-                sprintf(
302
-                    esc_html__('Event Espresso does not yet support %1$s IPNs from PayPal', 'event_espresso'),
303
-                    $update_info['payment_status']
304
-                ),
305
-                EventEspresso\core\exceptions\IpnException::UNSUPPORTED,
306
-                null,
307
-                $payment,
308
-                $update_info
309
-            );
310
-        }
311
-        // ok, well let's process this payment then!
312
-        switch ($update_info['payment_status']) {
313
-            case 'Completed':
314
-                $status = $this->_pay_model->approved_status();
315
-                $gateway_response = esc_html__('The payment is approved.', 'event_espresso');
316
-                break;
317
-
318
-            case 'Pending':
319
-                $status = $this->_pay_model->pending_status();
320
-                $gateway_response = esc_html__(
321
-                    'The payment is in progress. Another message will be sent when payment is approved.',
322
-                    'event_espresso'
323
-                );
324
-                break;
325
-
326
-            case 'Denied':
327
-                $status = $this->_pay_model->declined_status();
328
-                $gateway_response = esc_html__('The payment has been declined.', 'event_espresso');
329
-                break;
330
-
331
-            case 'Expired':
332
-            case 'Failed':
333
-                $status = $this->_pay_model->failed_status();
334
-                $gateway_response = esc_html__('The payment failed for technical reasons or expired.', 'event_espresso');
335
-                break;
336
-
337
-            case 'Refunded':
338
-            case 'Partially_Refunded':
339
-                // even though it's a refund, we consider the payment as approved, it just has a negative value
340
-                $status = $this->_pay_model->approved_status();
341
-                $gateway_response = esc_html__(
342
-                    'The payment has been refunded. Please update registrations accordingly.',
343
-                    'event_espresso'
344
-                );
345
-                break;
346
-
347
-            case 'Voided':
348
-            case 'Reversed':
349
-            case 'Canceled_Reversal':
350
-            default:
351
-                $status = $this->_pay_model->cancelled_status();
352
-                $gateway_response = esc_html__(
353
-                    'The payment was cancelled, reversed, or voided. Please update registrations accordingly.',
354
-                    'event_espresso'
355
-                );
356
-                break;
357
-        }
358
-
359
-        // check if we've already processed this payment
360
-        if ($payment instanceof EEI_Payment) {
361
-            // payment exists. if this has the exact same status and amount, don't bother updating. just return
362
-            if ($payment->status() === $status && (float) $payment->amount() === (float) $update_info['mc_gross']) {
363
-                // DUPLICATED IPN! don't bother updating transaction
364
-                throw new IpnException(
365
-                    sprintf(
366
-                        esc_html__(
367
-                            'It appears we have received a duplicate IPN from PayPal for payment %d',
368
-                            'event_espresso'
369
-                        ),
370
-                        $payment->ID()
371
-                    ),
372
-                    IpnException::DUPLICATE,
373
-                    null,
374
-                    $payment,
375
-                    $update_info
376
-                );
377
-            } else {
378
-                // new payment yippee !!!
379
-                $payment->set_status($status);
380
-                $payment->set_amount((float) $update_info['mc_gross']);
381
-                $payment->set_gateway_response($gateway_response);
382
-                $payment->set_details($update_info);
383
-                $payment->set_txn_id_chq_nmbr($update_info['txn_id']);
384
-                $this->log(
385
-                    array(
386
-                        'message'  => esc_html__(
387
-                            'Updated payment either from IPN or as part of POST from PayPal',
388
-                            'event_espresso'
389
-                        ),
390
-                        'url'      => $this->_process_response_url(),
391
-                        'payment'  => $payment->model_field_array(),
392
-                        'IPN_data' => $update_info
393
-                    ),
394
-                    $payment
395
-                );
396
-            }
397
-        }
398
-        do_action('FHEE__EEG_Paypal_Standard__handle_payment_update__payment_processed', $payment, $this);
399
-        return $payment;
400
-    }
401
-
402
-
403
-    /**
404
-     * Validate the IPN notification.
405
-     *
406
-     * @param array                  $update_info like $_REQUEST
407
-     * @param EE_Payment|EEI_Payment $payment
408
-     * @return boolean
409
-     * @throws \EE_Error
410
-     */
411
-    public function validate_ipn($update_info, $payment)
412
-    {
413
-        // allow us to skip validating IPNs with PayPal (useful for testing)
414
-        if (apply_filters('FHEE__EEG_Paypal_Standard__validate_ipn__skip', false)) {
415
-            return true;
416
-        }
417
-        // ...otherwise, we actually don't care what the $update_info is, we need to look
418
-        // at the request directly because we can't use $update_info because it has issues with quotes
419
-        // Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
420
-        // Instead, read raw POST data from the input stream.
421
-        // @see https://gist.github.com/xcommerce-gists/3440401
422
-        $raw_post_data = file_get_contents('php://input');
423
-        $raw_post_array = explode('&', $raw_post_data);
424
-        $update_info = array();
425
-        foreach ($raw_post_array as $keyval) {
426
-            $keyval = explode('=', $keyval);
427
-            if (count($keyval) === 2) {
428
-                $update_info[ $keyval[0] ] = urldecode($keyval[1]);
429
-            }
430
-        }
431
-        // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
432
-        $req = 'cmd=_notify-validate';
433
-        $uses_get_magic_quotes = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() === 1
434
-            ? true
435
-            : false;
436
-        foreach ($update_info as $key => $value) {
437
-            $value = $uses_get_magic_quotes ? urlencode(stripslashes($value)) : urlencode($value);
438
-            $req .= "&$key=$value";
439
-        }
440
-        // HTTP POST the complete, unaltered IPN back to PayPal
441
-        $response = wp_remote_post(
442
-            $this->_gateway_url,
443
-            array(
444
-                'body'              => $req,
445
-                'sslverify'         => false,
446
-                'timeout'           => 60,
447
-                // make sure to set a site specific unique "user-agent" string since the WordPres default gets declined by PayPal
448
-                // plz see: https://github.com/websharks/s2member/issues/610
449
-                'user-agent'        => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(),
450
-                'httpversion'       => '1.1'
451
-            )
452
-        );
453
-        // then check the response
454
-        if (
455
-            array_key_exists('body', $response)
456
-            && ! is_wp_error($response)
457
-            && strcmp($response['body'], "VERIFIED") === 0
458
-        ) {
459
-            return true;
460
-        }
461
-        // huh, something's wack... the IPN didn't validate. We must have replied to the IPN incorrectly,
462
-        // or their API must have changed: http://www.paypalobjects.com/en_US/ebook/PP_OrderManagement_IntegrationGuide/ipn.html
463
-        if ($response instanceof WP_Error) {
464
-            $error_msg = sprintf(
465
-                esc_html__('WP Error. Code: "%1$s", Message: "%2$s", Data: "%3$s"', 'event_espresso'),
466
-                $response->get_error_code(),
467
-                $response->get_error_message(),
468
-                print_r($response->get_error_data(), true)
469
-            );
470
-        } elseif (is_array($response) && isset($response['body'])) {
471
-            $error_msg = $response['body'];
472
-        } else {
473
-            $error_msg = print_r($response, true);
474
-        }
475
-        $payment->set_gateway_response(
476
-            sprintf(
477
-                esc_html__("IPN Validation failed! Paypal responded with '%s'", "event_espresso"),
478
-                $error_msg
479
-            )
480
-        );
481
-        $payment->set_details(array('REQUEST' => $update_info, 'VALIDATION_RESPONSE' => $response));
482
-        $payment->set_status(EEM_Payment::status_id_failed);
483
-        // log the results
484
-        $this->log(
485
-            array(
486
-                'url'     => $this->_process_response_url(),
487
-                'message' => $payment->gateway_response(),
488
-                'details' => $payment->details(),
489
-            ),
490
-            $payment
491
-        );
492
-        return false;
493
-    }
494
-
495
-
496
-    /**
497
-     * _process_response_url
498
-     * @return string
499
-     */
500
-    protected function _process_response_url()
501
-    {
502
-        if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
503
-            $url = is_ssl() ? 'https://' : 'http://';
504
-            $url .= EEH_URL::filter_input_server_url('HTTP_HOST');
505
-            $url .= EEH_URL::filter_input_server_url();
506
-        } else {
507
-            $url = 'unknown';
508
-        }
509
-        return $url;
510
-    }
511
-
512
-
513
-    /**
514
-     * Updates the transaction and line items based on the payment IPN data from PayPal,
515
-     * like the taxes or shipping
516
-     *
517
-     * @param EEI_Payment $payment
518
-     * @throws \EE_Error
519
-     */
520
-    public function update_txn_based_on_payment($payment)
521
-    {
522
-        $update_info = $payment->details();
523
-        /** @var EE_Transaction $transaction */
524
-        $transaction = $payment->transaction();
525
-        $payment_was_itemized = $payment->get_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true, false);
526
-        if (! $transaction) {
527
-            $this->log(
528
-                esc_html__(
529
-                    // @codingStandardsIgnoreStart
530
-                    'Payment with ID %d has no related transaction, and so update_txn_based_on_payment couldn\'t be executed properly',
531
-                    // @codingStandardsIgnoreEnd
532
-                    'event_espresso'
533
-                ),
534
-                $payment
535
-            );
536
-            return;
537
-        }
538
-        if (
539
-            ! is_array($update_info)
540
-            || ! isset($update_info['mc_shipping'])
541
-            || ! isset($update_info['tax'])
542
-        ) {
543
-            $this->log(
544
-                array(
545
-                    'message' => esc_html__(
546
-                        // @codingStandardsIgnoreStart
547
-                        'Could not update transaction based on payment because the payment details have not yet been put on the payment. This normally happens during the IPN or returning from PayPal',
548
-                        // @codingStandardsIgnoreEnd
549
-                        'event_espresso'
550
-                    ),
551
-                    'url'     => $this->_process_response_url(),
552
-                    'payment' => $payment->model_field_array()
553
-                ),
554
-                $payment
555
-            );
556
-            return;
557
-        }
558
-        if ($payment->status() !== $this->_pay_model->approved_status()) {
559
-            $this->log(
560
-                array(
561
-                    'message' => esc_html__(
562
-                        'We shouldn\'t update transactions taxes or shipping data from non-approved payments',
563
-                        'event_espresso'
564
-                    ),
565
-                    'url'     => $this->_process_response_url(),
566
-                    'payment' => $payment->model_field_array()
567
-                ),
568
-                $payment
569
-            );
570
-            return;
571
-        }
572
-        $grand_total_needs_resaving = false;
573
-        /** @var EE_Line_Item $transaction_total_line_item */
574
-        $transaction_total_line_item = $transaction->total_line_item();
575
-
576
-        // might paypal have changed the taxes?
577
-        if ($this->_paypal_taxes && $payment_was_itemized) {
578
-            // note that we're doing this BEFORE adding shipping;
579
-            // we actually want PayPal's shipping to remain non-taxable
580
-            $this->_line_item->set_line_items_taxable($transaction_total_line_item, true, 'paypal_shipping');
581
-            $this->_line_item->set_total_tax_to(
582
-                $transaction_total_line_item,
583
-                (float) $update_info['tax'],
584
-                esc_html__('Taxes', 'event_espresso'),
585
-                esc_html__('Calculated by Paypal', 'event_espresso'),
586
-                'paypal_tax'
587
-            );
588
-            $grand_total_needs_resaving = true;
589
-        }
590
-
591
-        $shipping_amount = (float) $update_info['mc_shipping'];
592
-        // might paypal have added shipping?
593
-        if ($this->_paypal_shipping && $shipping_amount && $payment_was_itemized) {
594
-            $this->_line_item->add_unrelated_item(
595
-                $transaction_total_line_item,
596
-                sprintf(esc_html__('Shipping for transaction %1$s', 'event_espresso'), $transaction->ID()),
597
-                $shipping_amount,
598
-                esc_html__('Shipping charges calculated by Paypal', 'event_espresso'),
599
-                1,
600
-                false,
601
-                'paypal_shipping_' . $transaction->ID()
602
-            );
603
-            $grand_total_needs_resaving = true;
604
-        }
605
-
606
-        if ($grand_total_needs_resaving) {
607
-            $transaction_total_line_item->save_this_and_descendants_to_txn($transaction->ID());
608
-            /** @var EE_Registration_Processor $registration_processor */
609
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
610
-            $registration_processor->update_registration_final_prices($transaction);
611
-        }
612
-        $this->log(
613
-            array(
614
-                'message'                     => esc_html__('Updated transaction related to payment', 'event_espresso'),
615
-                'url'                         => $this->_process_response_url(),
616
-                'transaction (updated)'       => $transaction->model_field_array(),
617
-                'payment (updated)'           => $payment->model_field_array(),
618
-                'use_paypal_shipping'         => $this->_paypal_shipping,
619
-                'use_paypal_tax'              => $this->_paypal_taxes,
620
-                'grand_total_needed_resaving' => $grand_total_needs_resaving,
621
-            ),
622
-            $payment
623
-        );
624
-    }
212
+			$redirect_args[ 'shipping_' . $item_num ] = '0';
213
+			$redirect_args[ 'shipping2_' . $item_num ] = '0';
214
+		}
215
+
216
+		$redirect_args['business'] = $this->_paypal_id;
217
+		$redirect_args['return'] = $return_url;
218
+		$redirect_args['cancel_return'] = $cancel_url;
219
+		$redirect_args['notify_url'] = $notify_url;
220
+		$redirect_args['cmd'] = '_cart';
221
+		$redirect_args['upload'] = 1;
222
+		$redirect_args['currency_code'] = $payment->currency_code();
223
+		$redirect_args['rm'] = 2;// makes the user return with method=POST
224
+		if ($this->_image_url) {
225
+			$redirect_args['image_url'] = $this->_image_url;
226
+		}
227
+		$redirect_args['no_shipping'] = $this->_shipping_details;
228
+		$redirect_args['bn'] = 'EventEspresso_SP';// EE will blow up if you change this
229
+
230
+		$redirect_args = apply_filters("FHEE__EEG_Paypal_Standard__set_redirection_info__arguments", $redirect_args, $this);
231
+
232
+		$payment->set_redirect_url($this->_gateway_url);
233
+		$payment->set_redirect_args($redirect_args);
234
+		// log the results
235
+		$this->log(
236
+			array(
237
+				'message'     => sprintf(
238
+					esc_html__('PayPal payment request initiated.', 'event_espresso')
239
+				),
240
+				'transaction' => $transaction->model_field_array(),
241
+			),
242
+			$payment
243
+		);
244
+		return $payment;
245
+	}
246
+
247
+
248
+	/**
249
+	 * Often used for IPNs. But applies the info in $update_info to the payment.
250
+	 * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
251
+	 * the payment method passes in.
252
+	 *
253
+	 * @param array $update_info like $_POST
254
+	 * @param EEI_Transaction $transaction
255
+	 * @return \EEI_Payment updated
256
+	 * @throws \EE_Error, IpnException
257
+	 */
258
+	public function handle_payment_update($update_info, $transaction)
259
+	{
260
+		// verify there's payment data that's been sent
261
+		if (empty($update_info['payment_status']) || empty($update_info['txn_id'])) {
262
+			// log the results
263
+			$this->log(
264
+				array(
265
+					'message'     => sprintf(
266
+						// @codingStandardsIgnoreStart
267
+						esc_html__('PayPal IPN response is missing critical payment data. This may indicate a PDT request and require your PayPal account settings to be corrected.', 'event_espresso')
268
+						// @codingStandardsIgnoreEnd
269
+					),
270
+					'update_info' => $update_info,
271
+				),
272
+				$transaction
273
+			);
274
+			// waaaait... is this a PDT request? (see https://developer.paypal.com/docs/classic/products/payment-data-transfer/)
275
+			// indicated by the "tx" argument? If so, we don't need it. We'll just use the IPN data when it comes
276
+			if (isset($update_info['tx'])) {
277
+				return $transaction->last_payment();
278
+			} else {
279
+				return null;
280
+			}
281
+		}
282
+		$payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
283
+		if (! $payment instanceof EEI_Payment) {
284
+			$payment = $transaction->last_payment();
285
+		}
286
+		// ok, then validate the IPN. Even if we've already processed this payment,
287
+		// let PayPal know we don't want to hear from them anymore!
288
+		if (! $this->validate_ipn($update_info, $payment)) {
289
+			return $payment;
290
+		}
291
+		// kill request here if this is a refund, we don't support them yet (we'd need to adjust the transaction,
292
+		// registrations, ticket counts, etc)
293
+		if (
294
+			(
295
+				$update_info['payment_status'] === 'Refunded'
296
+				|| $update_info['payment_status'] === 'Partially_Refunded'
297
+			)
298
+			&& apply_filters('FHEE__EEG_Paypal_Standard__handle_payment_update__kill_refund_request', true)
299
+		) {
300
+			throw new EventEspresso\core\exceptions\IpnException(
301
+				sprintf(
302
+					esc_html__('Event Espresso does not yet support %1$s IPNs from PayPal', 'event_espresso'),
303
+					$update_info['payment_status']
304
+				),
305
+				EventEspresso\core\exceptions\IpnException::UNSUPPORTED,
306
+				null,
307
+				$payment,
308
+				$update_info
309
+			);
310
+		}
311
+		// ok, well let's process this payment then!
312
+		switch ($update_info['payment_status']) {
313
+			case 'Completed':
314
+				$status = $this->_pay_model->approved_status();
315
+				$gateway_response = esc_html__('The payment is approved.', 'event_espresso');
316
+				break;
317
+
318
+			case 'Pending':
319
+				$status = $this->_pay_model->pending_status();
320
+				$gateway_response = esc_html__(
321
+					'The payment is in progress. Another message will be sent when payment is approved.',
322
+					'event_espresso'
323
+				);
324
+				break;
325
+
326
+			case 'Denied':
327
+				$status = $this->_pay_model->declined_status();
328
+				$gateway_response = esc_html__('The payment has been declined.', 'event_espresso');
329
+				break;
330
+
331
+			case 'Expired':
332
+			case 'Failed':
333
+				$status = $this->_pay_model->failed_status();
334
+				$gateway_response = esc_html__('The payment failed for technical reasons or expired.', 'event_espresso');
335
+				break;
336
+
337
+			case 'Refunded':
338
+			case 'Partially_Refunded':
339
+				// even though it's a refund, we consider the payment as approved, it just has a negative value
340
+				$status = $this->_pay_model->approved_status();
341
+				$gateway_response = esc_html__(
342
+					'The payment has been refunded. Please update registrations accordingly.',
343
+					'event_espresso'
344
+				);
345
+				break;
346
+
347
+			case 'Voided':
348
+			case 'Reversed':
349
+			case 'Canceled_Reversal':
350
+			default:
351
+				$status = $this->_pay_model->cancelled_status();
352
+				$gateway_response = esc_html__(
353
+					'The payment was cancelled, reversed, or voided. Please update registrations accordingly.',
354
+					'event_espresso'
355
+				);
356
+				break;
357
+		}
358
+
359
+		// check if we've already processed this payment
360
+		if ($payment instanceof EEI_Payment) {
361
+			// payment exists. if this has the exact same status and amount, don't bother updating. just return
362
+			if ($payment->status() === $status && (float) $payment->amount() === (float) $update_info['mc_gross']) {
363
+				// DUPLICATED IPN! don't bother updating transaction
364
+				throw new IpnException(
365
+					sprintf(
366
+						esc_html__(
367
+							'It appears we have received a duplicate IPN from PayPal for payment %d',
368
+							'event_espresso'
369
+						),
370
+						$payment->ID()
371
+					),
372
+					IpnException::DUPLICATE,
373
+					null,
374
+					$payment,
375
+					$update_info
376
+				);
377
+			} else {
378
+				// new payment yippee !!!
379
+				$payment->set_status($status);
380
+				$payment->set_amount((float) $update_info['mc_gross']);
381
+				$payment->set_gateway_response($gateway_response);
382
+				$payment->set_details($update_info);
383
+				$payment->set_txn_id_chq_nmbr($update_info['txn_id']);
384
+				$this->log(
385
+					array(
386
+						'message'  => esc_html__(
387
+							'Updated payment either from IPN or as part of POST from PayPal',
388
+							'event_espresso'
389
+						),
390
+						'url'      => $this->_process_response_url(),
391
+						'payment'  => $payment->model_field_array(),
392
+						'IPN_data' => $update_info
393
+					),
394
+					$payment
395
+				);
396
+			}
397
+		}
398
+		do_action('FHEE__EEG_Paypal_Standard__handle_payment_update__payment_processed', $payment, $this);
399
+		return $payment;
400
+	}
401
+
402
+
403
+	/**
404
+	 * Validate the IPN notification.
405
+	 *
406
+	 * @param array                  $update_info like $_REQUEST
407
+	 * @param EE_Payment|EEI_Payment $payment
408
+	 * @return boolean
409
+	 * @throws \EE_Error
410
+	 */
411
+	public function validate_ipn($update_info, $payment)
412
+	{
413
+		// allow us to skip validating IPNs with PayPal (useful for testing)
414
+		if (apply_filters('FHEE__EEG_Paypal_Standard__validate_ipn__skip', false)) {
415
+			return true;
416
+		}
417
+		// ...otherwise, we actually don't care what the $update_info is, we need to look
418
+		// at the request directly because we can't use $update_info because it has issues with quotes
419
+		// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
420
+		// Instead, read raw POST data from the input stream.
421
+		// @see https://gist.github.com/xcommerce-gists/3440401
422
+		$raw_post_data = file_get_contents('php://input');
423
+		$raw_post_array = explode('&', $raw_post_data);
424
+		$update_info = array();
425
+		foreach ($raw_post_array as $keyval) {
426
+			$keyval = explode('=', $keyval);
427
+			if (count($keyval) === 2) {
428
+				$update_info[ $keyval[0] ] = urldecode($keyval[1]);
429
+			}
430
+		}
431
+		// read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
432
+		$req = 'cmd=_notify-validate';
433
+		$uses_get_magic_quotes = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() === 1
434
+			? true
435
+			: false;
436
+		foreach ($update_info as $key => $value) {
437
+			$value = $uses_get_magic_quotes ? urlencode(stripslashes($value)) : urlencode($value);
438
+			$req .= "&$key=$value";
439
+		}
440
+		// HTTP POST the complete, unaltered IPN back to PayPal
441
+		$response = wp_remote_post(
442
+			$this->_gateway_url,
443
+			array(
444
+				'body'              => $req,
445
+				'sslverify'         => false,
446
+				'timeout'           => 60,
447
+				// make sure to set a site specific unique "user-agent" string since the WordPres default gets declined by PayPal
448
+				// plz see: https://github.com/websharks/s2member/issues/610
449
+				'user-agent'        => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(),
450
+				'httpversion'       => '1.1'
451
+			)
452
+		);
453
+		// then check the response
454
+		if (
455
+			array_key_exists('body', $response)
456
+			&& ! is_wp_error($response)
457
+			&& strcmp($response['body'], "VERIFIED") === 0
458
+		) {
459
+			return true;
460
+		}
461
+		// huh, something's wack... the IPN didn't validate. We must have replied to the IPN incorrectly,
462
+		// or their API must have changed: http://www.paypalobjects.com/en_US/ebook/PP_OrderManagement_IntegrationGuide/ipn.html
463
+		if ($response instanceof WP_Error) {
464
+			$error_msg = sprintf(
465
+				esc_html__('WP Error. Code: "%1$s", Message: "%2$s", Data: "%3$s"', 'event_espresso'),
466
+				$response->get_error_code(),
467
+				$response->get_error_message(),
468
+				print_r($response->get_error_data(), true)
469
+			);
470
+		} elseif (is_array($response) && isset($response['body'])) {
471
+			$error_msg = $response['body'];
472
+		} else {
473
+			$error_msg = print_r($response, true);
474
+		}
475
+		$payment->set_gateway_response(
476
+			sprintf(
477
+				esc_html__("IPN Validation failed! Paypal responded with '%s'", "event_espresso"),
478
+				$error_msg
479
+			)
480
+		);
481
+		$payment->set_details(array('REQUEST' => $update_info, 'VALIDATION_RESPONSE' => $response));
482
+		$payment->set_status(EEM_Payment::status_id_failed);
483
+		// log the results
484
+		$this->log(
485
+			array(
486
+				'url'     => $this->_process_response_url(),
487
+				'message' => $payment->gateway_response(),
488
+				'details' => $payment->details(),
489
+			),
490
+			$payment
491
+		);
492
+		return false;
493
+	}
494
+
495
+
496
+	/**
497
+	 * _process_response_url
498
+	 * @return string
499
+	 */
500
+	protected function _process_response_url()
501
+	{
502
+		if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
503
+			$url = is_ssl() ? 'https://' : 'http://';
504
+			$url .= EEH_URL::filter_input_server_url('HTTP_HOST');
505
+			$url .= EEH_URL::filter_input_server_url();
506
+		} else {
507
+			$url = 'unknown';
508
+		}
509
+		return $url;
510
+	}
511
+
512
+
513
+	/**
514
+	 * Updates the transaction and line items based on the payment IPN data from PayPal,
515
+	 * like the taxes or shipping
516
+	 *
517
+	 * @param EEI_Payment $payment
518
+	 * @throws \EE_Error
519
+	 */
520
+	public function update_txn_based_on_payment($payment)
521
+	{
522
+		$update_info = $payment->details();
523
+		/** @var EE_Transaction $transaction */
524
+		$transaction = $payment->transaction();
525
+		$payment_was_itemized = $payment->get_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true, false);
526
+		if (! $transaction) {
527
+			$this->log(
528
+				esc_html__(
529
+					// @codingStandardsIgnoreStart
530
+					'Payment with ID %d has no related transaction, and so update_txn_based_on_payment couldn\'t be executed properly',
531
+					// @codingStandardsIgnoreEnd
532
+					'event_espresso'
533
+				),
534
+				$payment
535
+			);
536
+			return;
537
+		}
538
+		if (
539
+			! is_array($update_info)
540
+			|| ! isset($update_info['mc_shipping'])
541
+			|| ! isset($update_info['tax'])
542
+		) {
543
+			$this->log(
544
+				array(
545
+					'message' => esc_html__(
546
+						// @codingStandardsIgnoreStart
547
+						'Could not update transaction based on payment because the payment details have not yet been put on the payment. This normally happens during the IPN or returning from PayPal',
548
+						// @codingStandardsIgnoreEnd
549
+						'event_espresso'
550
+					),
551
+					'url'     => $this->_process_response_url(),
552
+					'payment' => $payment->model_field_array()
553
+				),
554
+				$payment
555
+			);
556
+			return;
557
+		}
558
+		if ($payment->status() !== $this->_pay_model->approved_status()) {
559
+			$this->log(
560
+				array(
561
+					'message' => esc_html__(
562
+						'We shouldn\'t update transactions taxes or shipping data from non-approved payments',
563
+						'event_espresso'
564
+					),
565
+					'url'     => $this->_process_response_url(),
566
+					'payment' => $payment->model_field_array()
567
+				),
568
+				$payment
569
+			);
570
+			return;
571
+		}
572
+		$grand_total_needs_resaving = false;
573
+		/** @var EE_Line_Item $transaction_total_line_item */
574
+		$transaction_total_line_item = $transaction->total_line_item();
575
+
576
+		// might paypal have changed the taxes?
577
+		if ($this->_paypal_taxes && $payment_was_itemized) {
578
+			// note that we're doing this BEFORE adding shipping;
579
+			// we actually want PayPal's shipping to remain non-taxable
580
+			$this->_line_item->set_line_items_taxable($transaction_total_line_item, true, 'paypal_shipping');
581
+			$this->_line_item->set_total_tax_to(
582
+				$transaction_total_line_item,
583
+				(float) $update_info['tax'],
584
+				esc_html__('Taxes', 'event_espresso'),
585
+				esc_html__('Calculated by Paypal', 'event_espresso'),
586
+				'paypal_tax'
587
+			);
588
+			$grand_total_needs_resaving = true;
589
+		}
590
+
591
+		$shipping_amount = (float) $update_info['mc_shipping'];
592
+		// might paypal have added shipping?
593
+		if ($this->_paypal_shipping && $shipping_amount && $payment_was_itemized) {
594
+			$this->_line_item->add_unrelated_item(
595
+				$transaction_total_line_item,
596
+				sprintf(esc_html__('Shipping for transaction %1$s', 'event_espresso'), $transaction->ID()),
597
+				$shipping_amount,
598
+				esc_html__('Shipping charges calculated by Paypal', 'event_espresso'),
599
+				1,
600
+				false,
601
+				'paypal_shipping_' . $transaction->ID()
602
+			);
603
+			$grand_total_needs_resaving = true;
604
+		}
605
+
606
+		if ($grand_total_needs_resaving) {
607
+			$transaction_total_line_item->save_this_and_descendants_to_txn($transaction->ID());
608
+			/** @var EE_Registration_Processor $registration_processor */
609
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
610
+			$registration_processor->update_registration_final_prices($transaction);
611
+		}
612
+		$this->log(
613
+			array(
614
+				'message'                     => esc_html__('Updated transaction related to payment', 'event_espresso'),
615
+				'url'                         => $this->_process_response_url(),
616
+				'transaction (updated)'       => $transaction->model_field_array(),
617
+				'payment (updated)'           => $payment->model_field_array(),
618
+				'use_paypal_shipping'         => $this->_paypal_shipping,
619
+				'use_paypal_tax'              => $this->_paypal_taxes,
620
+				'grand_total_needed_resaving' => $grand_total_needs_resaving,
621
+			),
622
+			$payment
623
+		);
624
+	}
625 625
 }
Please login to merge, or discard this patch.
payment_methods/Paypal_Standard/EE_Paypal_Standard_Form.form.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -67,7 +67,7 @@  discard block
 block discarded – undo
67 67
         $paypal_calculates_taxes = $this->get_input_value('paypal_taxes');
68 68
         $paypal_requests_address_info = $this->get_input_value('shipping_details');
69 69
         if (
70
-            ( $paypal_calculates_shipping || $paypal_calculates_taxes ) &&
70
+            ($paypal_calculates_shipping || $paypal_calculates_taxes) &&
71 71
             $paypal_requests_address_info == EE_PMT_Paypal_Standard::shipping_info_none
72 72
         ) {
73 73
             // they want paypal to calculate taxes or shipping. They need to ask for
@@ -80,8 +80,8 @@  discard block
 block discarded – undo
80 80
                 sprintf(
81 81
                     esc_html__('Automatically set "%s" to "%s" because Paypal requires address info in order to calculate shipping or taxes.', 'event_espresso'),
82 82
                     strip_tags($shipping_details_input->html_label_text()),
83
-                    isset($shipping_details_input_options[ EE_PMT_Paypal_Standard::shipping_info_optional ])
84
-                        ? $shipping_details_input_options[ EE_PMT_Paypal_Standard::shipping_info_optional ]
83
+                    isset($shipping_details_input_options[EE_PMT_Paypal_Standard::shipping_info_optional])
84
+                        ? $shipping_details_input_options[EE_PMT_Paypal_Standard::shipping_info_optional]
85 85
                         : esc_html__('Unknown', 'event_espresso')
86 86
                 ),
87 87
                 __FILE__,
Please login to merge, or discard this patch.
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -13,78 +13,78 @@
 block discarded – undo
13 13
  */
14 14
 class EE_Paypal_Standard_Form extends EE_Payment_Method_Form
15 15
 {
16
-    /**
17
-     * @param EE_PMT_Paypal_Standard $payment_method_type
18
-     */
19
-    public function __construct($payment_method_type)
20
-    {
21
-        parent::__construct(
22
-            array(
23
-                'payment_method_type'          => $payment_method_type,
24
-                'extra_meta_inputs'            => array(
25
-                    'paypal_id'        => new EE_Text_Input(array(
26
-                        'html_label_text' => sprintf(esc_html__("Paypal Email %s", 'event_espresso'), $payment_method_type->get_help_tab_link()),
27
-                        'html_help_text'  => esc_html__("Typically [email protected]", 'event_espresso'),
28
-                        'required'        => true
29
-                    )),
30
-                    'image_url'        => new EE_Admin_File_Uploader_Input(array(
31
-                        'html_help_text'  => esc_html__("Used for your business/personal logo on the PayPal page", 'event_espresso'),
32
-                        'html_label_text' => esc_html__('Image URL', 'event_espresso')
33
-                    )),
34
-                    'paypal_taxes'     => new EE_Yes_No_Input(array(
35
-                        'html_label_text' => sprintf(esc_html__('Paypal Calculates Taxes %s', 'event_espresso'), $payment_method_type->get_help_tab_link()),
36
-                        'html_help_text'  => esc_html__('Whether Paypal should add taxes to the order', 'event_espresso'),
37
-                        'default'         => false
38
-                    )),
39
-                    'paypal_shipping'  => new EE_Yes_No_Input(array(
40
-                        'html_label_text' => sprintf(esc_html__('Paypal Calculates Shipping %s', 'event_espresso'), $payment_method_type->get_help_tab_link()),
41
-                        'html_help_text'  => esc_html__('Whether Paypal should add shipping surcharges', 'event_espresso'),
42
-                        'default'         => false
43
-                    )),
44
-                    'shipping_details' => new EE_Select_Input(array(
45
-                        EE_PMT_Paypal_Standard::shipping_info_none     => esc_html__("Do not prompt for an address", 'event_espresso'),
46
-                        EE_PMT_Paypal_Standard::shipping_info_optional => esc_html__("Prompt for an address, but do not require it", 'event_espresso'),
47
-                        EE_PMT_Paypal_Standard::shipping_info_required => esc_html__("Prompt for an address, and require it", 'event_espresso')
48
-                    ))
49
-                )
50
-            )
51
-        );
52
-    }
16
+	/**
17
+	 * @param EE_PMT_Paypal_Standard $payment_method_type
18
+	 */
19
+	public function __construct($payment_method_type)
20
+	{
21
+		parent::__construct(
22
+			array(
23
+				'payment_method_type'          => $payment_method_type,
24
+				'extra_meta_inputs'            => array(
25
+					'paypal_id'        => new EE_Text_Input(array(
26
+						'html_label_text' => sprintf(esc_html__("Paypal Email %s", 'event_espresso'), $payment_method_type->get_help_tab_link()),
27
+						'html_help_text'  => esc_html__("Typically [email protected]", 'event_espresso'),
28
+						'required'        => true
29
+					)),
30
+					'image_url'        => new EE_Admin_File_Uploader_Input(array(
31
+						'html_help_text'  => esc_html__("Used for your business/personal logo on the PayPal page", 'event_espresso'),
32
+						'html_label_text' => esc_html__('Image URL', 'event_espresso')
33
+					)),
34
+					'paypal_taxes'     => new EE_Yes_No_Input(array(
35
+						'html_label_text' => sprintf(esc_html__('Paypal Calculates Taxes %s', 'event_espresso'), $payment_method_type->get_help_tab_link()),
36
+						'html_help_text'  => esc_html__('Whether Paypal should add taxes to the order', 'event_espresso'),
37
+						'default'         => false
38
+					)),
39
+					'paypal_shipping'  => new EE_Yes_No_Input(array(
40
+						'html_label_text' => sprintf(esc_html__('Paypal Calculates Shipping %s', 'event_espresso'), $payment_method_type->get_help_tab_link()),
41
+						'html_help_text'  => esc_html__('Whether Paypal should add shipping surcharges', 'event_espresso'),
42
+						'default'         => false
43
+					)),
44
+					'shipping_details' => new EE_Select_Input(array(
45
+						EE_PMT_Paypal_Standard::shipping_info_none     => esc_html__("Do not prompt for an address", 'event_espresso'),
46
+						EE_PMT_Paypal_Standard::shipping_info_optional => esc_html__("Prompt for an address, but do not require it", 'event_espresso'),
47
+						EE_PMT_Paypal_Standard::shipping_info_required => esc_html__("Prompt for an address, and require it", 'event_espresso')
48
+					))
49
+				)
50
+			)
51
+		);
52
+	}
53 53
 
54 54
 
55 55
 
56
-    /**
57
-     * @param array $req_data
58
-     * @throws EE_Error
59
-     */
60
-    public function _normalize($req_data)
61
-    {
62
-        parent::_normalize($req_data);
63
-        $paypal_calculates_shipping = $this->get_input_value('paypal_shipping');
64
-        $paypal_calculates_taxes = $this->get_input_value('paypal_taxes');
65
-        $paypal_requests_address_info = $this->get_input_value('shipping_details');
66
-        if (
67
-            ( $paypal_calculates_shipping || $paypal_calculates_taxes ) &&
68
-            $paypal_requests_address_info == EE_PMT_Paypal_Standard::shipping_info_none
69
-        ) {
70
-            // they want paypal to calculate taxes or shipping. They need to ask for
71
-            // address info, otherwise paypal can't calculate taxes or shipping
72
-            /** @type EE_Select_Input $shipping_details_input */
73
-            $shipping_details_input = $this->get_input('shipping_details');
74
-            $shipping_details_input->set_default(EE_PMT_Paypal_Standard::shipping_info_optional);
75
-            $shipping_details_input_options = $shipping_details_input->options();
76
-            EE_Error::add_attention(
77
-                sprintf(
78
-                    esc_html__('Automatically set "%s" to "%s" because Paypal requires address info in order to calculate shipping or taxes.', 'event_espresso'),
79
-                    strip_tags($shipping_details_input->html_label_text()),
80
-                    isset($shipping_details_input_options[ EE_PMT_Paypal_Standard::shipping_info_optional ])
81
-                        ? $shipping_details_input_options[ EE_PMT_Paypal_Standard::shipping_info_optional ]
82
-                        : esc_html__('Unknown', 'event_espresso')
83
-                ),
84
-                __FILE__,
85
-                __FUNCTION__,
86
-                __LINE__
87
-            );
88
-        }
89
-    }
56
+	/**
57
+	 * @param array $req_data
58
+	 * @throws EE_Error
59
+	 */
60
+	public function _normalize($req_data)
61
+	{
62
+		parent::_normalize($req_data);
63
+		$paypal_calculates_shipping = $this->get_input_value('paypal_shipping');
64
+		$paypal_calculates_taxes = $this->get_input_value('paypal_taxes');
65
+		$paypal_requests_address_info = $this->get_input_value('shipping_details');
66
+		if (
67
+			( $paypal_calculates_shipping || $paypal_calculates_taxes ) &&
68
+			$paypal_requests_address_info == EE_PMT_Paypal_Standard::shipping_info_none
69
+		) {
70
+			// they want paypal to calculate taxes or shipping. They need to ask for
71
+			// address info, otherwise paypal can't calculate taxes or shipping
72
+			/** @type EE_Select_Input $shipping_details_input */
73
+			$shipping_details_input = $this->get_input('shipping_details');
74
+			$shipping_details_input->set_default(EE_PMT_Paypal_Standard::shipping_info_optional);
75
+			$shipping_details_input_options = $shipping_details_input->options();
76
+			EE_Error::add_attention(
77
+				sprintf(
78
+					esc_html__('Automatically set "%s" to "%s" because Paypal requires address info in order to calculate shipping or taxes.', 'event_espresso'),
79
+					strip_tags($shipping_details_input->html_label_text()),
80
+					isset($shipping_details_input_options[ EE_PMT_Paypal_Standard::shipping_info_optional ])
81
+						? $shipping_details_input_options[ EE_PMT_Paypal_Standard::shipping_info_optional ]
82
+						: esc_html__('Unknown', 'event_espresso')
83
+				),
84
+				__FILE__,
85
+				__FUNCTION__,
86
+				__LINE__
87
+			);
88
+		}
89
+	}
90 90
 }
Please login to merge, or discard this patch.
payment_methods/Check/EE_PMT_Check.pm.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
         $this->_pretty_name = esc_html__("Check", 'event_espresso');
23 23
         $this->_default_description = esc_html__('After clicking "Finalize Registration", you will be given instructions on how to complete your payment.', 'event_espresso');
24 24
         parent::__construct($pm_instance);
25
-        $this->_default_button_url = $this->file_url() . 'lib/check-logo.png';
25
+        $this->_default_button_url = $this->file_url().'lib/check-logo.png';
26 26
     }
27 27
 
28 28
 
@@ -48,14 +48,14 @@  discard block
 block discarded – undo
48 48
         if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
49 49
             $organization = EE_Registry::instance()->CFG->organization;
50 50
             $organization_name = $organization->get_pretty('name');
51
-            $default_address = $organization->address_1 != '' ? $organization->get_pretty('address_1') . '<br />' : '';
52
-            $default_address .= $organization->address_2 != '' ? $organization->get_pretty('address_2') . '<br />' : '';
51
+            $default_address = $organization->address_1 != '' ? $organization->get_pretty('address_1').'<br />' : '';
52
+            $default_address .= $organization->address_2 != '' ? $organization->get_pretty('address_2').'<br />' : '';
53 53
             $default_address .= $organization->city != '' ? $organization->get_pretty('city') : '';
54
-            $default_address .= ( $organization->city != '' && $organization->STA_ID != '') ? ', ' : '<br />';
54
+            $default_address .= ($organization->city != '' && $organization->STA_ID != '') ? ', ' : '<br />';
55 55
             $state = EE_Registry::instance()->load_model('State')->get_one_by_ID($organization->STA_ID);
56
-            $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($organization->CNT_ISO) ;
57
-            $default_address .=  $state ? $state->name() . '<br />' : '';
58
-            $default_address .= $country ? $country->name() . '<br />' : '';
56
+            $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($organization->CNT_ISO);
57
+            $default_address .= $state ? $state->name().'<br />' : '';
58
+            $default_address .= $country ? $country->name().'<br />' : '';
59 59
             $default_address .= $organization->zip != '' ? $organization->get_pretty('zip') : '';
60 60
         } else {
61 61
             $default_address = 'unknown';
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
                 'payment_instructions' => new EE_Text_Area_Input(array(
71 71
                     'html_label_text' =>  sprintf(esc_html__("Instructions %s", "event_espresso"), $this->get_help_tab_link()),
72 72
                     'default' => esc_html__("Please send Check/Money Order to the address below. Payment must be received within 48 hours of event date.", 'event_espresso'),
73
-                    'validation_strategies' => array( new EE_Full_HTML_Validation_Strategy() ),
73
+                    'validation_strategies' => array(new EE_Full_HTML_Validation_Strategy()),
74 74
                 )),
75 75
                 'payable_to' => new EE_Text_Input(array(
76 76
                     'html_label_text' =>  sprintf(esc_html__("Payable To %s", "event_espresso"), $this->get_help_tab_link()),
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
                 'address_to_send_payment' => new EE_Text_Area_Input(array(
80 80
                     'html_label_text' =>  sprintf(esc_html__("Address Payable %s", "event_espresso"), $this->get_help_tab_link()),
81 81
                     'default' => $default_address,
82
-                    'validation_strategies' => array( new EE_Full_HTML_Validation_Strategy() ),
82
+                    'validation_strategies' => array(new EE_Full_HTML_Validation_Strategy()),
83 83
                 )),
84 84
             ),
85 85
             'exclude' => array('PMD_debug_mode')
Please login to merge, or discard this patch.
Indentation   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -11,121 +11,121 @@
 block discarded – undo
11 11
  */
12 12
 class EE_PMT_Check extends EE_PMT_Base
13 13
 {
14
-    /**
15
-     * @param null $pm_instance
16
-     * @return EE_PMT_Check
17
-     */
18
-    public function __construct($pm_instance = null)
19
-    {
20
-        $this->_pretty_name = esc_html__("Check", 'event_espresso');
21
-        $this->_default_description = esc_html__('After clicking "Finalize Registration", you will be given instructions on how to complete your payment.', 'event_espresso');
22
-        parent::__construct($pm_instance);
23
-        $this->_default_button_url = $this->file_url() . 'lib/check-logo.png';
24
-    }
14
+	/**
15
+	 * @param null $pm_instance
16
+	 * @return EE_PMT_Check
17
+	 */
18
+	public function __construct($pm_instance = null)
19
+	{
20
+		$this->_pretty_name = esc_html__("Check", 'event_espresso');
21
+		$this->_default_description = esc_html__('After clicking "Finalize Registration", you will be given instructions on how to complete your payment.', 'event_espresso');
22
+		parent::__construct($pm_instance);
23
+		$this->_default_button_url = $this->file_url() . 'lib/check-logo.png';
24
+	}
25 25
 
26 26
 
27 27
 
28
-    /**
29
-     * Creates the billing form for this payment method type
30
-     * @param \EE_Transaction $transaction
31
-     * @return NULL
32
-     */
33
-    public function generate_new_billing_form(EE_Transaction $transaction = null)
34
-    {
35
-        return null;
36
-    }
28
+	/**
29
+	 * Creates the billing form for this payment method type
30
+	 * @param \EE_Transaction $transaction
31
+	 * @return NULL
32
+	 */
33
+	public function generate_new_billing_form(EE_Transaction $transaction = null)
34
+	{
35
+		return null;
36
+	}
37 37
 
38 38
 
39 39
 
40
-    /**
41
-     * Overrides parent to dynamically set some defaults, but only when the form is requested
42
-     * @return EE_Form_Section_Proper
43
-     */
44
-    public function generate_new_settings_form()
45
-    {
46
-        if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
47
-            $organization = EE_Registry::instance()->CFG->organization;
48
-            $organization_name = $organization->get_pretty('name');
49
-            $default_address = $organization->address_1 != '' ? $organization->get_pretty('address_1') . '<br />' : '';
50
-            $default_address .= $organization->address_2 != '' ? $organization->get_pretty('address_2') . '<br />' : '';
51
-            $default_address .= $organization->city != '' ? $organization->get_pretty('city') : '';
52
-            $default_address .= ( $organization->city != '' && $organization->STA_ID != '') ? ', ' : '<br />';
53
-            $state = EE_Registry::instance()->load_model('State')->get_one_by_ID($organization->STA_ID);
54
-            $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($organization->CNT_ISO) ;
55
-            $default_address .=  $state ? $state->name() . '<br />' : '';
56
-            $default_address .= $country ? $country->name() . '<br />' : '';
57
-            $default_address .= $organization->zip != '' ? $organization->get_pretty('zip') : '';
58
-        } else {
59
-            $default_address = 'unknown';
60
-            $organization_name = 'unknown';
61
-        }
62
-            return new EE_Payment_Method_Form(array(
63
-            'extra_meta_inputs' => array(
64
-                'check_title' => new EE_Text_Input(array(
65
-                    'html_label_text' =>  sprintf(esc_html__("Title %s", "event_espresso"), $this->get_help_tab_link()),
66
-                    'default' =>  esc_html__("Check/Money Order Payments", 'event_espresso'),
67
-                )),
68
-                'payment_instructions' => new EE_Text_Area_Input(array(
69
-                    'html_label_text' =>  sprintf(esc_html__("Instructions %s", "event_espresso"), $this->get_help_tab_link()),
70
-                    'default' => esc_html__("Please send Check/Money Order to the address below. Payment must be received within 48 hours of event date.", 'event_espresso'),
71
-                    'validation_strategies' => array( new EE_Full_HTML_Validation_Strategy() ),
72
-                )),
73
-                'payable_to' => new EE_Text_Input(array(
74
-                    'html_label_text' =>  sprintf(esc_html__("Payable To %s", "event_espresso"), $this->get_help_tab_link()),
75
-                    'default' => $organization_name
76
-                )),
77
-                'address_to_send_payment' => new EE_Text_Area_Input(array(
78
-                    'html_label_text' =>  sprintf(esc_html__("Address Payable %s", "event_espresso"), $this->get_help_tab_link()),
79
-                    'default' => $default_address,
80
-                    'validation_strategies' => array( new EE_Full_HTML_Validation_Strategy() ),
81
-                )),
82
-            ),
83
-            'exclude' => array('PMD_debug_mode')
84
-            ));
85
-    }
40
+	/**
41
+	 * Overrides parent to dynamically set some defaults, but only when the form is requested
42
+	 * @return EE_Form_Section_Proper
43
+	 */
44
+	public function generate_new_settings_form()
45
+	{
46
+		if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
47
+			$organization = EE_Registry::instance()->CFG->organization;
48
+			$organization_name = $organization->get_pretty('name');
49
+			$default_address = $organization->address_1 != '' ? $organization->get_pretty('address_1') . '<br />' : '';
50
+			$default_address .= $organization->address_2 != '' ? $organization->get_pretty('address_2') . '<br />' : '';
51
+			$default_address .= $organization->city != '' ? $organization->get_pretty('city') : '';
52
+			$default_address .= ( $organization->city != '' && $organization->STA_ID != '') ? ', ' : '<br />';
53
+			$state = EE_Registry::instance()->load_model('State')->get_one_by_ID($organization->STA_ID);
54
+			$country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($organization->CNT_ISO) ;
55
+			$default_address .=  $state ? $state->name() . '<br />' : '';
56
+			$default_address .= $country ? $country->name() . '<br />' : '';
57
+			$default_address .= $organization->zip != '' ? $organization->get_pretty('zip') : '';
58
+		} else {
59
+			$default_address = 'unknown';
60
+			$organization_name = 'unknown';
61
+		}
62
+			return new EE_Payment_Method_Form(array(
63
+			'extra_meta_inputs' => array(
64
+				'check_title' => new EE_Text_Input(array(
65
+					'html_label_text' =>  sprintf(esc_html__("Title %s", "event_espresso"), $this->get_help_tab_link()),
66
+					'default' =>  esc_html__("Check/Money Order Payments", 'event_espresso'),
67
+				)),
68
+				'payment_instructions' => new EE_Text_Area_Input(array(
69
+					'html_label_text' =>  sprintf(esc_html__("Instructions %s", "event_espresso"), $this->get_help_tab_link()),
70
+					'default' => esc_html__("Please send Check/Money Order to the address below. Payment must be received within 48 hours of event date.", 'event_espresso'),
71
+					'validation_strategies' => array( new EE_Full_HTML_Validation_Strategy() ),
72
+				)),
73
+				'payable_to' => new EE_Text_Input(array(
74
+					'html_label_text' =>  sprintf(esc_html__("Payable To %s", "event_espresso"), $this->get_help_tab_link()),
75
+					'default' => $organization_name
76
+				)),
77
+				'address_to_send_payment' => new EE_Text_Area_Input(array(
78
+					'html_label_text' =>  sprintf(esc_html__("Address Payable %s", "event_espresso"), $this->get_help_tab_link()),
79
+					'default' => $default_address,
80
+					'validation_strategies' => array( new EE_Full_HTML_Validation_Strategy() ),
81
+				)),
82
+			),
83
+			'exclude' => array('PMD_debug_mode')
84
+			));
85
+	}
86 86
 
87 87
 
88 88
 
89
-    /**
90
-     * Adds the help tab
91
-     * @see EE_PMT_Base::help_tabs_config()
92
-     * @return array
93
-     */
94
-    public function help_tabs_config()
95
-    {
96
-        return array(
97
-            $this->get_help_tab_name() => array(
98
-                        'title' => esc_html__('Check Settings', 'event_espresso'),
99
-                        'filename' => 'payment_methods_overview_check'
100
-                        ),
101
-        );
102
-    }
89
+	/**
90
+	 * Adds the help tab
91
+	 * @see EE_PMT_Base::help_tabs_config()
92
+	 * @return array
93
+	 */
94
+	public function help_tabs_config()
95
+	{
96
+		return array(
97
+			$this->get_help_tab_name() => array(
98
+						'title' => esc_html__('Check Settings', 'event_espresso'),
99
+						'filename' => 'payment_methods_overview_check'
100
+						),
101
+		);
102
+	}
103 103
 
104 104
 
105 105
 
106
-    /**
107
-     * For adding any html output ab ove the payment overview.
108
-     * Many gateways won't want ot display anything, so this function just returns an empty string.
109
-     * Other gateways may want to override this, such as offline gateways.
110
-     * @return string
111
-     */
112
-    public function payment_overview_content(EE_Payment $payment)
113
-    {
114
-        $extra_meta_for_payment_method = $this->_pm_instance->all_extra_meta_array();
115
-        $template_vars = array_merge(
116
-            array(
117
-                            'payment_method' => $this->_pm_instance,
118
-                            'payment' => $payment,
119
-                            'check_title' => '',
120
-                            'payment_instructions' => '',
121
-                            'payable_to' => '',
122
-                            'address_to_send_payment' => '',
123
-                            ),
124
-            $extra_meta_for_payment_method
125
-        );
126
-        return EEH_Template::locate_template(
127
-            'payment_methods/Check/templates/check_payment_details_content.template.php',
128
-            $template_vars
129
-        );
130
-    }
106
+	/**
107
+	 * For adding any html output ab ove the payment overview.
108
+	 * Many gateways won't want ot display anything, so this function just returns an empty string.
109
+	 * Other gateways may want to override this, such as offline gateways.
110
+	 * @return string
111
+	 */
112
+	public function payment_overview_content(EE_Payment $payment)
113
+	{
114
+		$extra_meta_for_payment_method = $this->_pm_instance->all_extra_meta_array();
115
+		$template_vars = array_merge(
116
+			array(
117
+							'payment_method' => $this->_pm_instance,
118
+							'payment' => $payment,
119
+							'check_title' => '',
120
+							'payment_instructions' => '',
121
+							'payable_to' => '',
122
+							'address_to_send_payment' => '',
123
+							),
124
+			$extra_meta_for_payment_method
125
+		);
126
+		return EEH_Template::locate_template(
127
+			'payment_methods/Check/templates/check_payment_details_content.template.php',
128
+			$template_vars
129
+		);
130
+	}
131 131
 }
Please login to merge, or discard this patch.
admin_pages/messages/EE_Message_List_Table.class.php 2 patches
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
     {
79 79
         $class = parent::_get_row_class($item);
80 80
         // add status class
81
-        $class .= ' ee-status-strip msg-status-' . $item->STS_ID();
81
+        $class .= ' ee-status-strip msg-status-'.$item->STS_ID();
82 82
         if ($this->_has_checkbox_column) {
83 83
             $class .= ' has-checkbox-column';
84 84
         }
@@ -120,7 +120,7 @@  discard block
 block discarded – undo
120 120
     protected function _add_view_counts()
121 121
     {
122 122
         foreach ($this->_views as $view => $args) {
123
-            $this->_views[ $view ]['count'] = $this->_get_messages($this->_per_page, $view, true, true);
123
+            $this->_views[$view]['count'] = $this->_get_messages($this->_per_page, $view, true, true);
124 124
         }
125 125
     }
126 126
 
@@ -165,8 +165,8 @@  discard block
 block discarded – undo
165 165
                                  ),
166 166
                                  admin_url('admin.php')
167 167
                              )
168
-                             . '">' . esc_html__('Delete', 'event_espresso') . '</a>';
169
-        return esc_html($message->to()) . $this->row_actions($actions);
168
+                             . '">'.esc_html__('Delete', 'event_espresso').'</a>';
169
+        return esc_html($message->to()).$this->row_actions($actions);
170 170
     }
171 171
 
172 172
 
@@ -238,23 +238,23 @@  discard block
 block discarded – undo
238 238
         $content = '';
239 239
         switch ($message->STS_ID()) {
240 240
             case EEM_Message::status_sent:
241
-                $content = $action_links['view'] . $action_links['queue_for_resending'] . $action_links['view_transaction'];
241
+                $content = $action_links['view'].$action_links['queue_for_resending'].$action_links['view_transaction'];
242 242
                 break;
243 243
             case EEM_Message::status_resend:
244
-                $content = $action_links['view'] . $action_links['send_now'] . $action_links['view_transaction'];
244
+                $content = $action_links['view'].$action_links['send_now'].$action_links['view_transaction'];
245 245
                 break;
246 246
             case EEM_Message::status_retry:
247
-                $content = $action_links['view'] . $action_links['send_now'] . $action_links['error'] . $action_links['view_transaction'];
247
+                $content = $action_links['view'].$action_links['send_now'].$action_links['error'].$action_links['view_transaction'];
248 248
                 break;
249 249
             case EEM_Message::status_failed:
250 250
             case EEM_Message::status_debug_only:
251
-                $content = $action_links['error'] . $action_links['view_transaction'];
251
+                $content = $action_links['error'].$action_links['view_transaction'];
252 252
                 break;
253 253
             case EEM_Message::status_idle:
254
-                $content = $action_links['view'] . $action_links['send_now'] . $action_links['view_transaction'];
254
+                $content = $action_links['view'].$action_links['send_now'].$action_links['view_transaction'];
255 255
                 break;
256 256
             case EEM_Message::status_incomplete:
257
-                $content = $action_links['generate_now'] . $action_links['view_transaction'];
257
+                $content = $action_links['generate_now'].$action_links['view_transaction'];
258 258
                 break;
259 259
         }
260 260
         return $content;
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
          */
296 296
         if (isset($this->_req_data['filterby'])) {
297 297
             $query_params = array_merge($query_params, EEM_Message::instance()->filter_by_query_params());
298
-            if (! $count) {
298
+            if ( ! $count) {
299 299
                 $query_params['group_by'] = 'MSG_ID';
300 300
             }
301 301
         }
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
             );
308 308
         }
309 309
 
310
-        if (! $all && ! empty($this->_req_data['status']) && $this->_req_data['status'] !== 'all') {
310
+        if ( ! $all && ! empty($this->_req_data['status']) && $this->_req_data['status'] !== 'all') {
311 311
             $query_params[0]['AND*view_conditional'] = $this->_req_data === EEM_Message::status_failed
312 312
                 ? array(
313 313
                     'STS_ID' => array(
@@ -318,8 +318,8 @@  discard block
 block discarded – undo
318 318
                 : array('STS_ID' => strtoupper($this->_req_data['status']));
319 319
         }
320 320
 
321
-        if (! $all && ! empty($this->_req_data['s'])) {
322
-            $search_string = '%' . $this->_req_data['s'] . '%';
321
+        if ( ! $all && ! empty($this->_req_data['s'])) {
322
+            $search_string = '%'.$this->_req_data['s'].'%';
323 323
             $query_params[0]['OR'] = array(
324 324
                 'MSG_to'      => array('LIKE', $search_string),
325 325
                 'MSG_from'    => array('LIKE', $search_string),
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
         // the messages system is in debug mode.
333 333
         // Note: for backward compat with previous iterations, this is necessary because there may be EEM_Message::status_debug_only
334 334
         // messages in the database.
335
-        if (! EEM_Message::debug()) {
335
+        if ( ! EEM_Message::debug()) {
336 336
             $query_params[0]['AND*debug_only_conditional'] = array(
337 337
                 'STS_ID' => array('!=', EEM_Message::status_debug_only),
338 338
             );
@@ -389,7 +389,7 @@  discard block
 block discarded – undo
389 389
         // setup array of messenger options
390 390
         foreach ($active_messages_grouped_by_messenger as $active_message) {
391 391
             if ($active_message instanceof EE_Message) {
392
-                $messenger_options[ $active_message->messenger() ] = ucwords($active_message->messenger_label());
392
+                $messenger_options[$active_message->messenger()] = ucwords($active_message->messenger_label());
393 393
             }
394 394
         }
395 395
         return $this->get_admin_page()->get_messengers_select_input($messenger_options);
@@ -411,7 +411,7 @@  discard block
 block discarded – undo
411 411
         // setup array of message type options
412 412
         foreach ($active_messages_grouped_by_message_type as $active_message) {
413 413
             if ($active_message instanceof EE_Message) {
414
-                $message_type_options[ $active_message->message_type() ] = ucwords(
414
+                $message_type_options[$active_message->message_type()] = ucwords(
415 415
                     $active_message->message_type_label()
416 416
                 );
417 417
             }
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
                 if ($message_type instanceof EE_message_type) {
438 438
                     foreach ($message_type->get_contexts() as $context => $context_details) {
439 439
                         if (isset($context_details['label'])) {
440
-                            $context_options[ $context ] = $context_details['label'];
440
+                            $context_options[$context] = $context_details['label'];
441 441
                         }
442 442
                     }
443 443
                 }
Please login to merge, or discard this patch.
Indentation   +433 added lines, -433 removed lines patch added patch discarded remove patch
@@ -10,437 +10,437 @@
 block discarded – undo
10 10
  */
11 11
 class EE_Message_List_Table extends EE_Admin_List_Table
12 12
 {
13
-    /**
14
-     * @return Messages_Admin_Page
15
-     */
16
-    public function get_admin_page()
17
-    {
18
-        return $this->_admin_page;
19
-    }
20
-
21
-
22
-    protected function _setup_data()
23
-    {
24
-        $this->_data = $this->_get_messages($this->_per_page, $this->_view);
25
-        $this->_all_data_count = $this->_get_messages($this->_per_page, $this->_view, true);
26
-    }
27
-
28
-
29
-    protected function _set_properties()
30
-    {
31
-        $this->_wp_list_args = array(
32
-            'singular' => esc_html__('Message', 'event_espresso'),
33
-            'plural'   => esc_html__('Messages', 'event_espresso'),
34
-            'ajax'     => true,
35
-            'screen'   => $this->get_admin_page()->get_current_screen()->id,
36
-        );
37
-
38
-        $this->_columns = array(
39
-            'cb'           => '<input type="checkbox" />',
40
-            'to'           => esc_html__('To', 'event_espresso'),
41
-            'from'         => esc_html__('From', 'event_espresso'),
42
-            'messenger'    => esc_html__('Messenger', 'event_espresso'),
43
-            'message_type' => esc_html__('Message Type', 'event_espresso'),
44
-            'context'      => esc_html__('Context', 'event_espresso'),
45
-            'modified'     => esc_html__('Modified', 'event_espresso'),
46
-            'action'       => esc_html__('Actions', 'event_espresso'),
47
-            'msg_id'       => esc_html__('ID', 'event_espresso'),
48
-        );
49
-
50
-        $this->_sortable_columns = array(
51
-            'modified'     => array('MSG_modified' => true),
52
-            'message_type' => array('MSG_message_type' => false),
53
-            'messenger'    => array('MSG_messenger' => false),
54
-            'to'           => array('MSG_to' => false),
55
-            'from'         => array('MSG_from' => false),
56
-            'context'      => array('MSG_context' => false),
57
-            'msg_id'       => array('MSG_ID', false),
58
-        );
59
-
60
-        $this->_primary_column = 'to';
61
-
62
-        $this->_hidden_columns = array(
63
-            'msg_id',
64
-        );
65
-    }
66
-
67
-
68
-    /**
69
-     * This simply sets up the row class for the table rows.
70
-     * Allows for easier overriding of child methods for setting up sorting.
71
-     *
72
-     * @param  object $item the current item
73
-     * @return string
74
-     */
75
-    protected function _get_row_class($item)
76
-    {
77
-        $class = parent::_get_row_class($item);
78
-        // add status class
79
-        $class .= ' ee-status-strip msg-status-' . $item->STS_ID();
80
-        if ($this->_has_checkbox_column) {
81
-            $class .= ' has-checkbox-column';
82
-        }
83
-        return $class;
84
-    }
85
-
86
-
87
-    /**
88
-     * _get_table_filters
89
-     * We use this to assemble and return any filters that are associated with this table that help further refine what
90
-     * get's shown in the table.
91
-     *
92
-     * @abstract
93
-     * @access protected
94
-     * @return string
95
-     * @throws \EE_Error
96
-     */
97
-    protected function _get_table_filters()
98
-    {
99
-        $filters = array();
100
-
101
-        // get select_inputs
102
-        $select_inputs = array(
103
-            $this->_get_messengers_dropdown_filter(),
104
-            $this->_get_message_types_dropdown_filter(),
105
-            $this->_get_contexts_for_message_types_dropdown_filter(),
106
-        );
107
-
108
-        // set filters to select inputs if they aren't empty
109
-        foreach ($select_inputs as $select_input) {
110
-            if ($select_input) {
111
-                $filters[] = $select_input;
112
-            }
113
-        }
114
-        return $filters;
115
-    }
116
-
117
-
118
-    protected function _add_view_counts()
119
-    {
120
-        foreach ($this->_views as $view => $args) {
121
-            $this->_views[ $view ]['count'] = $this->_get_messages($this->_per_page, $view, true, true);
122
-        }
123
-    }
124
-
125
-
126
-    /**
127
-     * @param EE_Message $message
128
-     * @return string   checkbox
129
-     * @throws \EE_Error
130
-     */
131
-    public function column_cb($message)
132
-    {
133
-        return sprintf('<input type="checkbox" name="MSG_ID[%s]" value="1" />', $message->ID());
134
-    }
135
-
136
-
137
-    /**
138
-     * @param EE_Message $message
139
-     * @return string
140
-     * @throws \EE_Error
141
-     */
142
-    public function column_msg_id(EE_Message $message)
143
-    {
144
-        return $message->ID();
145
-    }
146
-
147
-
148
-    /**
149
-     * @param EE_Message $message
150
-     * @return string    The recipient of the message
151
-     * @throws \EE_Error
152
-     */
153
-    public function column_to(EE_Message $message)
154
-    {
155
-        EE_Registry::instance()->load_helper('URL');
156
-        $actions = array();
157
-        $actions['delete'] = '<a href="'
158
-                             . EEH_URL::add_query_args_and_nonce(
159
-                                 array(
160
-                                    'page'   => 'espresso_messages',
161
-                                    'action' => 'delete_ee_message',
162
-                                    'MSG_ID' => $message->ID(),
163
-                                 ),
164
-                                 admin_url('admin.php')
165
-                             )
166
-                             . '">' . esc_html__('Delete', 'event_espresso') . '</a>';
167
-        return esc_html($message->to()) . $this->row_actions($actions);
168
-    }
169
-
170
-
171
-    /**
172
-     * @param EE_Message $message
173
-     * @return string   The sender of the message
174
-     */
175
-    public function column_from(EE_Message $message)
176
-    {
177
-        return esc_html($message->from());
178
-    }
179
-
180
-
181
-    /**
182
-     * @param EE_Message $message
183
-     * @return string  The messenger used to send the message.
184
-     */
185
-    public function column_messenger(EE_Message $message)
186
-    {
187
-        return ucwords($message->messenger_label());
188
-    }
189
-
190
-
191
-    /**
192
-     * @param EE_Message $message
193
-     * @return string  The message type used to generate the message.
194
-     */
195
-    public function column_message_type(EE_Message $message)
196
-    {
197
-        return ucwords($message->message_type_label());
198
-    }
199
-
200
-
201
-    /**
202
-     * @param EE_Message $message
203
-     * @return string  The context the message was generated for.
204
-     */
205
-    public function column_context(EE_Message $message)
206
-    {
207
-        return $message->context_label();
208
-    }
209
-
210
-
211
-    /**
212
-     * @param EE_Message $message
213
-     * @return string    The timestamp when this message was last modified.
214
-     */
215
-    public function column_modified(EE_Message $message)
216
-    {
217
-        return $message->modified();
218
-    }
219
-
220
-
221
-    /**
222
-     * @param EE_Message $message
223
-     * @return string   Actions that can be done on the current message.
224
-     */
225
-    public function column_action(EE_Message $message)
226
-    {
227
-        EE_Registry::instance()->load_helper('MSG_Template');
228
-        $action_links = array(
229
-            'view'                => EEH_MSG_Template::get_message_action_link('view', $message),
230
-            'error'               => EEH_MSG_Template::get_message_action_link('error', $message),
231
-            'generate_now'        => EEH_MSG_Template::get_message_action_link('generate_now', $message),
232
-            'send_now'            => EEH_MSG_Template::get_message_action_link('send_now', $message),
233
-            'queue_for_resending' => EEH_MSG_Template::get_message_action_link('queue_for_resending', $message),
234
-            'view_transaction'    => EEH_MSG_Template::get_message_action_link('view_transaction', $message),
235
-        );
236
-        $content = '';
237
-        switch ($message->STS_ID()) {
238
-            case EEM_Message::status_sent:
239
-                $content = $action_links['view'] . $action_links['queue_for_resending'] . $action_links['view_transaction'];
240
-                break;
241
-            case EEM_Message::status_resend:
242
-                $content = $action_links['view'] . $action_links['send_now'] . $action_links['view_transaction'];
243
-                break;
244
-            case EEM_Message::status_retry:
245
-                $content = $action_links['view'] . $action_links['send_now'] . $action_links['error'] . $action_links['view_transaction'];
246
-                break;
247
-            case EEM_Message::status_failed:
248
-            case EEM_Message::status_debug_only:
249
-                $content = $action_links['error'] . $action_links['view_transaction'];
250
-                break;
251
-            case EEM_Message::status_idle:
252
-                $content = $action_links['view'] . $action_links['send_now'] . $action_links['view_transaction'];
253
-                break;
254
-            case EEM_Message::status_incomplete:
255
-                $content = $action_links['generate_now'] . $action_links['view_transaction'];
256
-                break;
257
-        }
258
-        return $content;
259
-    }
260
-
261
-
262
-    /**
263
-     * Retrieve the EE_Message objects for the list table.
264
-     *
265
-     * @param int    $perpage The number of items per page
266
-     * @param string $view    The view items are being retrieved for
267
-     * @param bool   $count   Whether to just return a count or not.
268
-     * @param bool   $all     Disregard any paging info (no limit on data returned).
269
-     * @return int|EE_Message[]
270
-     * @throws \EE_Error
271
-     */
272
-    protected function _get_messages($perpage = 10, $view = 'all', $count = false, $all = false)
273
-    {
274
-
275
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
276
-            ? $this->_req_data['paged']
277
-            : 1;
278
-
279
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
280
-            ? $this->_req_data['perpage']
281
-            : $perpage;
282
-
283
-        $offset = ($current_page - 1) * $per_page;
284
-        $limit = $all || $count ? null : array($offset, $per_page);
285
-        $query_params = array(
286
-            'order_by' => empty($this->_req_data['orderby']) ? 'MSG_modified' : $this->_req_data['orderby'],
287
-            'order'    => empty($this->_req_data['order']) ? 'DESC' : $this->_req_data['order'],
288
-            'limit'    => $limit,
289
-        );
290
-
291
-        /**
292
-         * Any filters coming in from other routes?
293
-         */
294
-        if (isset($this->_req_data['filterby'])) {
295
-            $query_params = array_merge($query_params, EEM_Message::instance()->filter_by_query_params());
296
-            if (! $count) {
297
-                $query_params['group_by'] = 'MSG_ID';
298
-            }
299
-        }
300
-
301
-        // view conditionals
302
-        if ($view !== 'all' && $count && $all) {
303
-            $query_params[0]['AND*view_conditional'] = array(
304
-                'STS_ID' => strtoupper($view),
305
-            );
306
-        }
307
-
308
-        if (! $all && ! empty($this->_req_data['status']) && $this->_req_data['status'] !== 'all') {
309
-            $query_params[0]['AND*view_conditional'] = $this->_req_data === EEM_Message::status_failed
310
-                ? array(
311
-                    'STS_ID' => array(
312
-                        'IN',
313
-                        array(EEM_Message::status_failed, EEM_Message::status_messenger_executing),
314
-                    ),
315
-                )
316
-                : array('STS_ID' => strtoupper($this->_req_data['status']));
317
-        }
318
-
319
-        if (! $all && ! empty($this->_req_data['s'])) {
320
-            $search_string = '%' . $this->_req_data['s'] . '%';
321
-            $query_params[0]['OR'] = array(
322
-                'MSG_to'      => array('LIKE', $search_string),
323
-                'MSG_from'    => array('LIKE', $search_string),
324
-                'MSG_subject' => array('LIKE', $search_string),
325
-                'MSG_content' => array('LIKE', $search_string),
326
-            );
327
-        }
328
-
329
-        // account for debug only status.  We don't show Messages with the EEM_Message::status_debug_only to clients when
330
-        // the messages system is in debug mode.
331
-        // Note: for backward compat with previous iterations, this is necessary because there may be EEM_Message::status_debug_only
332
-        // messages in the database.
333
-        if (! EEM_Message::debug()) {
334
-            $query_params[0]['AND*debug_only_conditional'] = array(
335
-                'STS_ID' => array('!=', EEM_Message::status_debug_only),
336
-            );
337
-        }
338
-
339
-        // account for filters
340
-        if (
341
-            ! $all
342
-            && isset($this->_req_data['ee_messenger_filter_by'])
343
-            && $this->_req_data['ee_messenger_filter_by'] !== 'none_selected'
344
-        ) {
345
-            $query_params[0]['AND*messenger_filter'] = array(
346
-                'MSG_messenger' => $this->_req_data['ee_messenger_filter_by'],
347
-            );
348
-        }
349
-        if (
350
-            ! $all
351
-            && ! empty($this->_req_data['ee_message_type_filter_by'])
352
-            && $this->_req_data['ee_message_type_filter_by'] !== 'none_selected'
353
-        ) {
354
-            $query_params[0]['AND*message_type_filter'] = array(
355
-                'MSG_message_type' => $this->_req_data['ee_message_type_filter_by'],
356
-            );
357
-        }
358
-
359
-        if (
360
-            ! $all
361
-            && ! empty($this->_req_data['ee_context_filter_by'])
362
-            && $this->_req_data['ee_context_filter_by'] !== 'none_selected'
363
-        ) {
364
-            $query_params[0]['AND*context_filter'] = array(
365
-                'MSG_context' => array('IN', explode(',', $this->_req_data['ee_context_filter_by'])),
366
-            );
367
-        }
368
-
369
-        return $count
370
-            /** @type int */
371
-            ? EEM_Message::instance()->count($query_params, null, true)
372
-            /** @type EE_Message[] */
373
-            : EEM_Message::instance()->get_all($query_params);
374
-    }
375
-
376
-
377
-    /**
378
-     * Generate dropdown filter select input for messengers.
379
-     *
380
-     * @return string
381
-     */
382
-    protected function _get_messengers_dropdown_filter()
383
-    {
384
-        $messenger_options = array();
385
-        $active_messages_grouped_by_messenger = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
386
-
387
-        // setup array of messenger options
388
-        foreach ($active_messages_grouped_by_messenger as $active_message) {
389
-            if ($active_message instanceof EE_Message) {
390
-                $messenger_options[ $active_message->messenger() ] = ucwords($active_message->messenger_label());
391
-            }
392
-        }
393
-        return $this->get_admin_page()->get_messengers_select_input($messenger_options);
394
-    }
395
-
396
-
397
-    /**
398
-     * Generate dropdown filter select input for message types
399
-     *
400
-     * @return string
401
-     */
402
-    protected function _get_message_types_dropdown_filter()
403
-    {
404
-        $message_type_options = array();
405
-        $active_messages_grouped_by_message_type = EEM_Message::instance()->get_all(
406
-            array('group_by' => 'MSG_message_type')
407
-        );
408
-
409
-        // setup array of message type options
410
-        foreach ($active_messages_grouped_by_message_type as $active_message) {
411
-            if ($active_message instanceof EE_Message) {
412
-                $message_type_options[ $active_message->message_type() ] = ucwords(
413
-                    $active_message->message_type_label()
414
-                );
415
-            }
416
-        }
417
-        return $this->get_admin_page()->get_message_types_select_input($message_type_options);
418
-    }
419
-
420
-
421
-    /**
422
-     * Generate dropdown filter select input for message type contexts
423
-     *
424
-     * @return string
425
-     */
426
-    protected function _get_contexts_for_message_types_dropdown_filter()
427
-    {
428
-        $context_options = array();
429
-        $active_messages_grouped_by_context = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
430
-
431
-        // setup array of context options
432
-        foreach ($active_messages_grouped_by_context as $active_message) {
433
-            if ($active_message instanceof EE_Message) {
434
-                $message_type = $active_message->message_type_object();
435
-                if ($message_type instanceof EE_message_type) {
436
-                    foreach ($message_type->get_contexts() as $context => $context_details) {
437
-                        if (isset($context_details['label'])) {
438
-                            $context_options[ $context ] = $context_details['label'];
439
-                        }
440
-                    }
441
-                }
442
-            }
443
-        }
444
-        return $this->get_admin_page()->get_contexts_for_message_types_select_input($context_options);
445
-    }
13
+	/**
14
+	 * @return Messages_Admin_Page
15
+	 */
16
+	public function get_admin_page()
17
+	{
18
+		return $this->_admin_page;
19
+	}
20
+
21
+
22
+	protected function _setup_data()
23
+	{
24
+		$this->_data = $this->_get_messages($this->_per_page, $this->_view);
25
+		$this->_all_data_count = $this->_get_messages($this->_per_page, $this->_view, true);
26
+	}
27
+
28
+
29
+	protected function _set_properties()
30
+	{
31
+		$this->_wp_list_args = array(
32
+			'singular' => esc_html__('Message', 'event_espresso'),
33
+			'plural'   => esc_html__('Messages', 'event_espresso'),
34
+			'ajax'     => true,
35
+			'screen'   => $this->get_admin_page()->get_current_screen()->id,
36
+		);
37
+
38
+		$this->_columns = array(
39
+			'cb'           => '<input type="checkbox" />',
40
+			'to'           => esc_html__('To', 'event_espresso'),
41
+			'from'         => esc_html__('From', 'event_espresso'),
42
+			'messenger'    => esc_html__('Messenger', 'event_espresso'),
43
+			'message_type' => esc_html__('Message Type', 'event_espresso'),
44
+			'context'      => esc_html__('Context', 'event_espresso'),
45
+			'modified'     => esc_html__('Modified', 'event_espresso'),
46
+			'action'       => esc_html__('Actions', 'event_espresso'),
47
+			'msg_id'       => esc_html__('ID', 'event_espresso'),
48
+		);
49
+
50
+		$this->_sortable_columns = array(
51
+			'modified'     => array('MSG_modified' => true),
52
+			'message_type' => array('MSG_message_type' => false),
53
+			'messenger'    => array('MSG_messenger' => false),
54
+			'to'           => array('MSG_to' => false),
55
+			'from'         => array('MSG_from' => false),
56
+			'context'      => array('MSG_context' => false),
57
+			'msg_id'       => array('MSG_ID', false),
58
+		);
59
+
60
+		$this->_primary_column = 'to';
61
+
62
+		$this->_hidden_columns = array(
63
+			'msg_id',
64
+		);
65
+	}
66
+
67
+
68
+	/**
69
+	 * This simply sets up the row class for the table rows.
70
+	 * Allows for easier overriding of child methods for setting up sorting.
71
+	 *
72
+	 * @param  object $item the current item
73
+	 * @return string
74
+	 */
75
+	protected function _get_row_class($item)
76
+	{
77
+		$class = parent::_get_row_class($item);
78
+		// add status class
79
+		$class .= ' ee-status-strip msg-status-' . $item->STS_ID();
80
+		if ($this->_has_checkbox_column) {
81
+			$class .= ' has-checkbox-column';
82
+		}
83
+		return $class;
84
+	}
85
+
86
+
87
+	/**
88
+	 * _get_table_filters
89
+	 * We use this to assemble and return any filters that are associated with this table that help further refine what
90
+	 * get's shown in the table.
91
+	 *
92
+	 * @abstract
93
+	 * @access protected
94
+	 * @return string
95
+	 * @throws \EE_Error
96
+	 */
97
+	protected function _get_table_filters()
98
+	{
99
+		$filters = array();
100
+
101
+		// get select_inputs
102
+		$select_inputs = array(
103
+			$this->_get_messengers_dropdown_filter(),
104
+			$this->_get_message_types_dropdown_filter(),
105
+			$this->_get_contexts_for_message_types_dropdown_filter(),
106
+		);
107
+
108
+		// set filters to select inputs if they aren't empty
109
+		foreach ($select_inputs as $select_input) {
110
+			if ($select_input) {
111
+				$filters[] = $select_input;
112
+			}
113
+		}
114
+		return $filters;
115
+	}
116
+
117
+
118
+	protected function _add_view_counts()
119
+	{
120
+		foreach ($this->_views as $view => $args) {
121
+			$this->_views[ $view ]['count'] = $this->_get_messages($this->_per_page, $view, true, true);
122
+		}
123
+	}
124
+
125
+
126
+	/**
127
+	 * @param EE_Message $message
128
+	 * @return string   checkbox
129
+	 * @throws \EE_Error
130
+	 */
131
+	public function column_cb($message)
132
+	{
133
+		return sprintf('<input type="checkbox" name="MSG_ID[%s]" value="1" />', $message->ID());
134
+	}
135
+
136
+
137
+	/**
138
+	 * @param EE_Message $message
139
+	 * @return string
140
+	 * @throws \EE_Error
141
+	 */
142
+	public function column_msg_id(EE_Message $message)
143
+	{
144
+		return $message->ID();
145
+	}
146
+
147
+
148
+	/**
149
+	 * @param EE_Message $message
150
+	 * @return string    The recipient of the message
151
+	 * @throws \EE_Error
152
+	 */
153
+	public function column_to(EE_Message $message)
154
+	{
155
+		EE_Registry::instance()->load_helper('URL');
156
+		$actions = array();
157
+		$actions['delete'] = '<a href="'
158
+							 . EEH_URL::add_query_args_and_nonce(
159
+								 array(
160
+									'page'   => 'espresso_messages',
161
+									'action' => 'delete_ee_message',
162
+									'MSG_ID' => $message->ID(),
163
+								 ),
164
+								 admin_url('admin.php')
165
+							 )
166
+							 . '">' . esc_html__('Delete', 'event_espresso') . '</a>';
167
+		return esc_html($message->to()) . $this->row_actions($actions);
168
+	}
169
+
170
+
171
+	/**
172
+	 * @param EE_Message $message
173
+	 * @return string   The sender of the message
174
+	 */
175
+	public function column_from(EE_Message $message)
176
+	{
177
+		return esc_html($message->from());
178
+	}
179
+
180
+
181
+	/**
182
+	 * @param EE_Message $message
183
+	 * @return string  The messenger used to send the message.
184
+	 */
185
+	public function column_messenger(EE_Message $message)
186
+	{
187
+		return ucwords($message->messenger_label());
188
+	}
189
+
190
+
191
+	/**
192
+	 * @param EE_Message $message
193
+	 * @return string  The message type used to generate the message.
194
+	 */
195
+	public function column_message_type(EE_Message $message)
196
+	{
197
+		return ucwords($message->message_type_label());
198
+	}
199
+
200
+
201
+	/**
202
+	 * @param EE_Message $message
203
+	 * @return string  The context the message was generated for.
204
+	 */
205
+	public function column_context(EE_Message $message)
206
+	{
207
+		return $message->context_label();
208
+	}
209
+
210
+
211
+	/**
212
+	 * @param EE_Message $message
213
+	 * @return string    The timestamp when this message was last modified.
214
+	 */
215
+	public function column_modified(EE_Message $message)
216
+	{
217
+		return $message->modified();
218
+	}
219
+
220
+
221
+	/**
222
+	 * @param EE_Message $message
223
+	 * @return string   Actions that can be done on the current message.
224
+	 */
225
+	public function column_action(EE_Message $message)
226
+	{
227
+		EE_Registry::instance()->load_helper('MSG_Template');
228
+		$action_links = array(
229
+			'view'                => EEH_MSG_Template::get_message_action_link('view', $message),
230
+			'error'               => EEH_MSG_Template::get_message_action_link('error', $message),
231
+			'generate_now'        => EEH_MSG_Template::get_message_action_link('generate_now', $message),
232
+			'send_now'            => EEH_MSG_Template::get_message_action_link('send_now', $message),
233
+			'queue_for_resending' => EEH_MSG_Template::get_message_action_link('queue_for_resending', $message),
234
+			'view_transaction'    => EEH_MSG_Template::get_message_action_link('view_transaction', $message),
235
+		);
236
+		$content = '';
237
+		switch ($message->STS_ID()) {
238
+			case EEM_Message::status_sent:
239
+				$content = $action_links['view'] . $action_links['queue_for_resending'] . $action_links['view_transaction'];
240
+				break;
241
+			case EEM_Message::status_resend:
242
+				$content = $action_links['view'] . $action_links['send_now'] . $action_links['view_transaction'];
243
+				break;
244
+			case EEM_Message::status_retry:
245
+				$content = $action_links['view'] . $action_links['send_now'] . $action_links['error'] . $action_links['view_transaction'];
246
+				break;
247
+			case EEM_Message::status_failed:
248
+			case EEM_Message::status_debug_only:
249
+				$content = $action_links['error'] . $action_links['view_transaction'];
250
+				break;
251
+			case EEM_Message::status_idle:
252
+				$content = $action_links['view'] . $action_links['send_now'] . $action_links['view_transaction'];
253
+				break;
254
+			case EEM_Message::status_incomplete:
255
+				$content = $action_links['generate_now'] . $action_links['view_transaction'];
256
+				break;
257
+		}
258
+		return $content;
259
+	}
260
+
261
+
262
+	/**
263
+	 * Retrieve the EE_Message objects for the list table.
264
+	 *
265
+	 * @param int    $perpage The number of items per page
266
+	 * @param string $view    The view items are being retrieved for
267
+	 * @param bool   $count   Whether to just return a count or not.
268
+	 * @param bool   $all     Disregard any paging info (no limit on data returned).
269
+	 * @return int|EE_Message[]
270
+	 * @throws \EE_Error
271
+	 */
272
+	protected function _get_messages($perpage = 10, $view = 'all', $count = false, $all = false)
273
+	{
274
+
275
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
276
+			? $this->_req_data['paged']
277
+			: 1;
278
+
279
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
280
+			? $this->_req_data['perpage']
281
+			: $perpage;
282
+
283
+		$offset = ($current_page - 1) * $per_page;
284
+		$limit = $all || $count ? null : array($offset, $per_page);
285
+		$query_params = array(
286
+			'order_by' => empty($this->_req_data['orderby']) ? 'MSG_modified' : $this->_req_data['orderby'],
287
+			'order'    => empty($this->_req_data['order']) ? 'DESC' : $this->_req_data['order'],
288
+			'limit'    => $limit,
289
+		);
290
+
291
+		/**
292
+		 * Any filters coming in from other routes?
293
+		 */
294
+		if (isset($this->_req_data['filterby'])) {
295
+			$query_params = array_merge($query_params, EEM_Message::instance()->filter_by_query_params());
296
+			if (! $count) {
297
+				$query_params['group_by'] = 'MSG_ID';
298
+			}
299
+		}
300
+
301
+		// view conditionals
302
+		if ($view !== 'all' && $count && $all) {
303
+			$query_params[0]['AND*view_conditional'] = array(
304
+				'STS_ID' => strtoupper($view),
305
+			);
306
+		}
307
+
308
+		if (! $all && ! empty($this->_req_data['status']) && $this->_req_data['status'] !== 'all') {
309
+			$query_params[0]['AND*view_conditional'] = $this->_req_data === EEM_Message::status_failed
310
+				? array(
311
+					'STS_ID' => array(
312
+						'IN',
313
+						array(EEM_Message::status_failed, EEM_Message::status_messenger_executing),
314
+					),
315
+				)
316
+				: array('STS_ID' => strtoupper($this->_req_data['status']));
317
+		}
318
+
319
+		if (! $all && ! empty($this->_req_data['s'])) {
320
+			$search_string = '%' . $this->_req_data['s'] . '%';
321
+			$query_params[0]['OR'] = array(
322
+				'MSG_to'      => array('LIKE', $search_string),
323
+				'MSG_from'    => array('LIKE', $search_string),
324
+				'MSG_subject' => array('LIKE', $search_string),
325
+				'MSG_content' => array('LIKE', $search_string),
326
+			);
327
+		}
328
+
329
+		// account for debug only status.  We don't show Messages with the EEM_Message::status_debug_only to clients when
330
+		// the messages system is in debug mode.
331
+		// Note: for backward compat with previous iterations, this is necessary because there may be EEM_Message::status_debug_only
332
+		// messages in the database.
333
+		if (! EEM_Message::debug()) {
334
+			$query_params[0]['AND*debug_only_conditional'] = array(
335
+				'STS_ID' => array('!=', EEM_Message::status_debug_only),
336
+			);
337
+		}
338
+
339
+		// account for filters
340
+		if (
341
+			! $all
342
+			&& isset($this->_req_data['ee_messenger_filter_by'])
343
+			&& $this->_req_data['ee_messenger_filter_by'] !== 'none_selected'
344
+		) {
345
+			$query_params[0]['AND*messenger_filter'] = array(
346
+				'MSG_messenger' => $this->_req_data['ee_messenger_filter_by'],
347
+			);
348
+		}
349
+		if (
350
+			! $all
351
+			&& ! empty($this->_req_data['ee_message_type_filter_by'])
352
+			&& $this->_req_data['ee_message_type_filter_by'] !== 'none_selected'
353
+		) {
354
+			$query_params[0]['AND*message_type_filter'] = array(
355
+				'MSG_message_type' => $this->_req_data['ee_message_type_filter_by'],
356
+			);
357
+		}
358
+
359
+		if (
360
+			! $all
361
+			&& ! empty($this->_req_data['ee_context_filter_by'])
362
+			&& $this->_req_data['ee_context_filter_by'] !== 'none_selected'
363
+		) {
364
+			$query_params[0]['AND*context_filter'] = array(
365
+				'MSG_context' => array('IN', explode(',', $this->_req_data['ee_context_filter_by'])),
366
+			);
367
+		}
368
+
369
+		return $count
370
+			/** @type int */
371
+			? EEM_Message::instance()->count($query_params, null, true)
372
+			/** @type EE_Message[] */
373
+			: EEM_Message::instance()->get_all($query_params);
374
+	}
375
+
376
+
377
+	/**
378
+	 * Generate dropdown filter select input for messengers.
379
+	 *
380
+	 * @return string
381
+	 */
382
+	protected function _get_messengers_dropdown_filter()
383
+	{
384
+		$messenger_options = array();
385
+		$active_messages_grouped_by_messenger = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
386
+
387
+		// setup array of messenger options
388
+		foreach ($active_messages_grouped_by_messenger as $active_message) {
389
+			if ($active_message instanceof EE_Message) {
390
+				$messenger_options[ $active_message->messenger() ] = ucwords($active_message->messenger_label());
391
+			}
392
+		}
393
+		return $this->get_admin_page()->get_messengers_select_input($messenger_options);
394
+	}
395
+
396
+
397
+	/**
398
+	 * Generate dropdown filter select input for message types
399
+	 *
400
+	 * @return string
401
+	 */
402
+	protected function _get_message_types_dropdown_filter()
403
+	{
404
+		$message_type_options = array();
405
+		$active_messages_grouped_by_message_type = EEM_Message::instance()->get_all(
406
+			array('group_by' => 'MSG_message_type')
407
+		);
408
+
409
+		// setup array of message type options
410
+		foreach ($active_messages_grouped_by_message_type as $active_message) {
411
+			if ($active_message instanceof EE_Message) {
412
+				$message_type_options[ $active_message->message_type() ] = ucwords(
413
+					$active_message->message_type_label()
414
+				);
415
+			}
416
+		}
417
+		return $this->get_admin_page()->get_message_types_select_input($message_type_options);
418
+	}
419
+
420
+
421
+	/**
422
+	 * Generate dropdown filter select input for message type contexts
423
+	 *
424
+	 * @return string
425
+	 */
426
+	protected function _get_contexts_for_message_types_dropdown_filter()
427
+	{
428
+		$context_options = array();
429
+		$active_messages_grouped_by_context = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
430
+
431
+		// setup array of context options
432
+		foreach ($active_messages_grouped_by_context as $active_message) {
433
+			if ($active_message instanceof EE_Message) {
434
+				$message_type = $active_message->message_type_object();
435
+				if ($message_type instanceof EE_message_type) {
436
+					foreach ($message_type->get_contexts() as $context => $context_details) {
437
+						if (isset($context_details['label'])) {
438
+							$context_options[ $context ] = $context_details['label'];
439
+						}
440
+					}
441
+				}
442
+			}
443
+		}
444
+		return $this->get_admin_page()->get_contexts_for_message_types_select_input($context_options);
445
+	}
446 446
 }
Please login to merge, or discard this patch.