Completed
Branch BUG/fix-ee-rest-debug-headers (1355bc)
by
unknown
03:29 queued 18s
created
core/helpers/EEH_Autoloader.helper.php 2 patches
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -53,7 +53,7 @@  discard block
 block discarded – undo
53 53
         if (self::$_autoloaders === null) {
54 54
             self::$_autoloaders = array();
55 55
             $this->_register_custom_autoloaders();
56
-            spl_autoload_register(array( $this, 'espresso_autoloader' ));
56
+            spl_autoload_register(array($this, 'espresso_autoloader'));
57 57
         }
58 58
     }
59 59
 
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
     public static function instance()
67 67
     {
68 68
         // check if class object is instantiated
69
-        if (! self::$_instance instanceof EEH_Autoloader) {
69
+        if ( ! self::$_instance instanceof EEH_Autoloader) {
70 70
             self::$_instance = new self();
71 71
         }
72 72
         return self::$_instance;
@@ -85,8 +85,8 @@  discard block
 block discarded – undo
85 85
      */
86 86
     public static function espresso_autoloader($class_name)
87 87
     {
88
-        if (isset(self::$_autoloaders[ $class_name ])) {
89
-            require_once(self::$_autoloaders[ $class_name ]);
88
+        if (isset(self::$_autoloaders[$class_name])) {
89
+            require_once(self::$_autoloaders[$class_name]);
90 90
         }
91 91
     }
92 92
 
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
      */
104 104
     public static function register_autoloader($class_paths, $read_check = true, $debug = false)
105 105
     {
106
-        $class_paths = is_array($class_paths) ? $class_paths : array( $class_paths );
106
+        $class_paths = is_array($class_paths) ? $class_paths : array($class_paths);
107 107
         foreach ($class_paths as $class => $path) {
108 108
             // skip all files that are not PHP
109 109
             if (substr($path, strlen($path) - 3) !== 'php') {
@@ -122,10 +122,10 @@  discard block
 block discarded – undo
122 122
             if ($read_check && ! is_readable($path)) {
123 123
                 throw new EE_Error(sprintf(esc_html__('The file for the %s class could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s', 'event_espresso'), $class, $path));
124 124
             }
125
-            if (! isset(self::$_autoloaders[ $class ])) {
126
-                self::$_autoloaders[ $class ] = str_replace(array( '/', '\\' ), '/', $path);
127
-                if (EE_DEBUG && ( EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug )) {
128
-                    EEH_Debug_Tools::printr(self::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
125
+            if ( ! isset(self::$_autoloaders[$class])) {
126
+                self::$_autoloaders[$class] = str_replace(array('/', '\\'), '/', $path);
127
+                if (EE_DEBUG && (EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug)) {
128
+                    EEH_Debug_Tools::printr(self::$_autoloaders[$class], $class, __FILE__, __LINE__);
129 129
                 }
130 130
             }
131 131
         }
@@ -157,13 +157,13 @@  discard block
 block discarded – undo
157 157
     {
158 158
         EEH_Autoloader::$debug = '';
159 159
         \EEH_Autoloader::register_helpers_autoloaders();
160
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
160
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE.'interfaces');
161 161
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
162 162
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
163 163
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
164 164
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
165 165
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
166
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
166
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'messages');
167 167
         if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
168 168
             EEH_Debug_Tools::instance()->show_times();
169 169
         }
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
      */
206 206
     public static function register_line_item_display_autoloaders()
207 207
     {
208
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
208
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'line_item_display', true);
209 209
     }
210 210
 
211 211
 
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
      */
219 219
     public static function register_line_item_filter_autoloaders()
220 220
     {
221
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
221
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'line_item_filters', true);
222 222
     }
223 223
 
224 224
 
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
      */
232 232
     public static function register_template_part_autoloaders()
233 233
     {
234
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
234
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'template_parts', true);
235 235
     }
236 236
 
237 237
 
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
      */
242 242
     public static function register_business_classes()
243 243
     {
244
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
244
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE.'business');
245 245
     }
246 246
 
247 247
 
@@ -264,11 +264,11 @@  discard block
 block discarded – undo
264 264
             EEH_Debug_Tools::instance()->start_timer(basename($folder));
265 265
         }
266 266
         // make sure last char is a /
267
-        $folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
267
+        $folder .= $folder[strlen($folder) - 1] !== '/' ? '/' : '';
268 268
         $class_to_filepath_map = array();
269
-        $exclude = array( 'index' );
269
+        $exclude = array('index');
270 270
         // get all the files in that folder that end in php
271
-        $filepaths = glob($folder . '*');
271
+        $filepaths = glob($folder.'*');
272 272
 
273 273
         if (empty($filepaths)) {
274 274
             return;
@@ -277,8 +277,8 @@  discard block
 block discarded – undo
277 277
         foreach ($filepaths as $filepath) {
278 278
             if (substr($filepath, -4, 4) === '.php') {
279 279
                 $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
280
-                if (! in_array($class_name, $exclude)) {
281
-                    $class_to_filepath_map [ $class_name ] = $filepath;
280
+                if ( ! in_array($class_name, $exclude)) {
281
+                    $class_to_filepath_map [$class_name] = $filepath;
282 282
                 }
283 283
             } elseif ($recursive) {
284 284
                 EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
@@ -303,8 +303,8 @@  discard block
 block discarded – undo
303 303
      */
304 304
     public static function add_alias($class_name, $alias)
305 305
     {
306
-        if (isset(self::$_autoloaders[ $class_name ])) {
307
-            self::$_autoloaders[ $alias ] = self::$_autoloaders[ $class_name ];
306
+        if (isset(self::$_autoloaders[$class_name])) {
307
+            self::$_autoloaders[$alias] = self::$_autoloaders[$class_name];
308 308
         }
309 309
     }
310 310
 }
Please login to merge, or discard this patch.
Indentation   +292 added lines, -292 removed lines patch added patch discarded remove patch
@@ -13,296 +13,296 @@
 block discarded – undo
13 13
  */
14 14
 class EEH_Autoloader extends EEH_Base
15 15
 {
16
-    /**
17
-     *    instance of the EE_System object
18
-     *
19
-     * @var    $_instance
20
-     * @access    private
21
-     */
22
-    private static $_instance = null;
23
-
24
-    /**
25
-    *   $_autoloaders
26
-    *   @var array $_autoloaders
27
-    *   @access     private
28
-    */
29
-    private static $_autoloaders;
30
-
31
-    /**
32
-     * set to "paths" to display autoloader class => path mappings
33
-     * set to "times" to display autoloader loading times
34
-     * set to "all" to display both
35
-     *
36
-     * @var string $debug
37
-     * @access    private
38
-     */
39
-    public static $debug = false;
40
-
41
-
42
-    /**
43
-     *    class constructor
44
-     *
45
-     * @access    private
46
-     * @return \EEH_Autoloader
47
-     * @throws Exception
48
-     */
49
-    private function __construct()
50
-    {
51
-        if (self::$_autoloaders === null) {
52
-            self::$_autoloaders = array();
53
-            $this->_register_custom_autoloaders();
54
-            spl_autoload_register(array( $this, 'espresso_autoloader' ));
55
-        }
56
-    }
57
-
58
-
59
-
60
-    /**
61
-     * @access public
62
-     * @return EEH_Autoloader
63
-     */
64
-    public static function instance()
65
-    {
66
-        // check if class object is instantiated
67
-        if (! self::$_instance instanceof EEH_Autoloader) {
68
-            self::$_instance = new self();
69
-        }
70
-        return self::$_instance;
71
-    }
72
-
73
-
74
-
75
-    /**
76
-     *    espresso_autoloader
77
-     *
78
-     * @access    public
79
-     * @param   $class_name
80
-     * @internal  param $className
81
-     * @internal  param string $class_name - simple class name ie: session
82
-     * @return  void
83
-     */
84
-    public static function espresso_autoloader($class_name)
85
-    {
86
-        if (isset(self::$_autoloaders[ $class_name ])) {
87
-            require_once(self::$_autoloaders[ $class_name ]);
88
-        }
89
-    }
90
-
91
-
92
-
93
-    /**
94
-     *    register_autoloader
95
-     *
96
-     * @access    public
97
-     * @param array | string $class_paths - array of key => value pairings between class names and paths
98
-     * @param bool           $read_check  true if we need to check whether the file is readable or not.
99
-     * @param bool           $debug **deprecated**
100
-     * @throws \EE_Error
101
-     */
102
-    public static function register_autoloader($class_paths, $read_check = true, $debug = false)
103
-    {
104
-        $class_paths = is_array($class_paths) ? $class_paths : array( $class_paths );
105
-        foreach ($class_paths as $class => $path) {
106
-            // skip all files that are not PHP
107
-            if (substr($path, strlen($path) - 3) !== 'php') {
108
-                continue;
109
-            }
110
-            // don't give up! you gotta...
111
-            // get some class
112
-            if (empty($class)) {
113
-                throw new EE_Error(sprintf(esc_html__('No Class name was specified while registering an autoloader for the following path: %s.', 'event_espresso'), $path));
114
-            }
115
-            // one day you will find the path young grasshopper
116
-            if (empty($path)) {
117
-                throw new EE_Error(sprintf(esc_html__('No path was specified while registering an autoloader for the %s class.', 'event_espresso'), $class));
118
-            }
119
-            // is file readable ?
120
-            if ($read_check && ! is_readable($path)) {
121
-                throw new EE_Error(sprintf(esc_html__('The file for the %s class could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s', 'event_espresso'), $class, $path));
122
-            }
123
-            if (! isset(self::$_autoloaders[ $class ])) {
124
-                self::$_autoloaders[ $class ] = str_replace(array( '/', '\\' ), '/', $path);
125
-                if (EE_DEBUG && ( EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug )) {
126
-                    EEH_Debug_Tools::printr(self::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
127
-                }
128
-            }
129
-        }
130
-    }
131
-
132
-
133
-
134
-
135
-    /**
136
-     *  get_autoloaders
137
-     *
138
-     *  @access public
139
-     *  @return array
140
-     */
141
-    public static function get_autoloaders()
142
-    {
143
-        return self::$_autoloaders;
144
-    }
145
-
146
-
147
-    /**
148
-     *  register core, model and class 'autoloaders'
149
-     *
150
-     * @access private
151
-     * @return void
152
-     * @throws EE_Error
153
-     */
154
-    private function _register_custom_autoloaders()
155
-    {
156
-        EEH_Autoloader::$debug = '';
157
-        \EEH_Autoloader::register_helpers_autoloaders();
158
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
159
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
160
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
161
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
162
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
163
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
164
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
165
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
166
-            EEH_Debug_Tools::instance()->show_times();
167
-        }
168
-    }
169
-
170
-
171
-
172
-    /**
173
-     *    register core, model and class 'autoloaders'
174
-     *
175
-     * @access public
176
-     */
177
-    public static function register_helpers_autoloaders()
178
-    {
179
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
180
-    }
181
-
182
-
183
-
184
-
185
-    /**
186
-     *  register core, model and class 'autoloaders'
187
-     *
188
-     *  @access public
189
-     *  @return void
190
-     */
191
-    public static function register_form_sections_autoloaders()
192
-    {
193
-        // EEH_Autoloader::register_autoloaders_for_each_file_in_folder( EE_FORM_SECTIONS, true );
194
-    }
195
-
196
-
197
-    /**
198
-     *  register core, model and class 'autoloaders'
199
-     *
200
-     * @access public
201
-     * @return void
202
-     * @throws EE_Error
203
-     */
204
-    public static function register_line_item_display_autoloaders()
205
-    {
206
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
207
-    }
208
-
209
-
210
-    /**
211
-     *  register core, model and class 'autoloaders'
212
-     *
213
-     * @access public
214
-     * @return void
215
-     * @throws EE_Error
216
-     */
217
-    public static function register_line_item_filter_autoloaders()
218
-    {
219
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
220
-    }
221
-
222
-
223
-    /**
224
-     *  register template part 'autoloaders'
225
-     *
226
-     * @access public
227
-     * @return void
228
-     * @throws EE_Error
229
-     */
230
-    public static function register_template_part_autoloaders()
231
-    {
232
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
233
-    }
234
-
235
-
236
-    /**
237
-     * @return void
238
-     * @throws EE_Error
239
-     */
240
-    public static function register_business_classes()
241
-    {
242
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
243
-    }
244
-
245
-
246
-
247
-    /**
248
-     * Assumes all the files in this folder have the normal naming scheme (namely that their classname
249
-     * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
250
-     * If that's not the case, you'll need to improve this function or just use EEH_File::get_classname_from_filepath_with_standard_filename() directly.
251
-     * Yes this has to scan the directory for files, but it only does it once -- not on EACH
252
-     * time the autoloader is used
253
-     *
254
-     * @param string $folder name, with or without trailing /, doesn't matter
255
-     * @param bool   $recursive
256
-     * @param bool   $debug  **deprecated**
257
-     * @throws \EE_Error
258
-     */
259
-    public static function register_autoloaders_for_each_file_in_folder($folder, $recursive = false, $debug = false)
260
-    {
261
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all' || $debug) {
262
-            EEH_Debug_Tools::instance()->start_timer(basename($folder));
263
-        }
264
-        // make sure last char is a /
265
-        $folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
266
-        $class_to_filepath_map = array();
267
-        $exclude = array( 'index' );
268
-        // get all the files in that folder that end in php
269
-        $filepaths = glob($folder . '*');
270
-
271
-        if (empty($filepaths)) {
272
-            return;
273
-        }
274
-
275
-        foreach ($filepaths as $filepath) {
276
-            if (substr($filepath, -4, 4) === '.php') {
277
-                $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
278
-                if (! in_array($class_name, $exclude)) {
279
-                    $class_to_filepath_map [ $class_name ] = $filepath;
280
-                }
281
-            } elseif ($recursive) {
282
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
283
-            }
284
-        }
285
-        // we remove the necessity to do a is_readable() check via the $read_check flag because glob by nature will not return non_readable files/directories.
286
-        self::register_autoloader($class_to_filepath_map, false, $debug);
287
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
288
-            EEH_Debug_Tools::instance()->stop_timer(basename($folder));
289
-        }
290
-    }
291
-
292
-
293
-
294
-    /**
295
-     * add_alias
296
-     * register additional autoloader based on variation of the classname for an existing autoloader
297
-     *
298
-     * @access    public
299
-     * @param string $class_name - simple class name ie: EE_Session
300
-     * @param string $alias - variation on class name ie: EE_session, session, etc
301
-     */
302
-    public static function add_alias($class_name, $alias)
303
-    {
304
-        if (isset(self::$_autoloaders[ $class_name ])) {
305
-            self::$_autoloaders[ $alias ] = self::$_autoloaders[ $class_name ];
306
-        }
307
-    }
16
+	/**
17
+	 *    instance of the EE_System object
18
+	 *
19
+	 * @var    $_instance
20
+	 * @access    private
21
+	 */
22
+	private static $_instance = null;
23
+
24
+	/**
25
+	 *   $_autoloaders
26
+	 *   @var array $_autoloaders
27
+	 *   @access     private
28
+	 */
29
+	private static $_autoloaders;
30
+
31
+	/**
32
+	 * set to "paths" to display autoloader class => path mappings
33
+	 * set to "times" to display autoloader loading times
34
+	 * set to "all" to display both
35
+	 *
36
+	 * @var string $debug
37
+	 * @access    private
38
+	 */
39
+	public static $debug = false;
40
+
41
+
42
+	/**
43
+	 *    class constructor
44
+	 *
45
+	 * @access    private
46
+	 * @return \EEH_Autoloader
47
+	 * @throws Exception
48
+	 */
49
+	private function __construct()
50
+	{
51
+		if (self::$_autoloaders === null) {
52
+			self::$_autoloaders = array();
53
+			$this->_register_custom_autoloaders();
54
+			spl_autoload_register(array( $this, 'espresso_autoloader' ));
55
+		}
56
+	}
57
+
58
+
59
+
60
+	/**
61
+	 * @access public
62
+	 * @return EEH_Autoloader
63
+	 */
64
+	public static function instance()
65
+	{
66
+		// check if class object is instantiated
67
+		if (! self::$_instance instanceof EEH_Autoloader) {
68
+			self::$_instance = new self();
69
+		}
70
+		return self::$_instance;
71
+	}
72
+
73
+
74
+
75
+	/**
76
+	 *    espresso_autoloader
77
+	 *
78
+	 * @access    public
79
+	 * @param   $class_name
80
+	 * @internal  param $className
81
+	 * @internal  param string $class_name - simple class name ie: session
82
+	 * @return  void
83
+	 */
84
+	public static function espresso_autoloader($class_name)
85
+	{
86
+		if (isset(self::$_autoloaders[ $class_name ])) {
87
+			require_once(self::$_autoloaders[ $class_name ]);
88
+		}
89
+	}
90
+
91
+
92
+
93
+	/**
94
+	 *    register_autoloader
95
+	 *
96
+	 * @access    public
97
+	 * @param array | string $class_paths - array of key => value pairings between class names and paths
98
+	 * @param bool           $read_check  true if we need to check whether the file is readable or not.
99
+	 * @param bool           $debug **deprecated**
100
+	 * @throws \EE_Error
101
+	 */
102
+	public static function register_autoloader($class_paths, $read_check = true, $debug = false)
103
+	{
104
+		$class_paths = is_array($class_paths) ? $class_paths : array( $class_paths );
105
+		foreach ($class_paths as $class => $path) {
106
+			// skip all files that are not PHP
107
+			if (substr($path, strlen($path) - 3) !== 'php') {
108
+				continue;
109
+			}
110
+			// don't give up! you gotta...
111
+			// get some class
112
+			if (empty($class)) {
113
+				throw new EE_Error(sprintf(esc_html__('No Class name was specified while registering an autoloader for the following path: %s.', 'event_espresso'), $path));
114
+			}
115
+			// one day you will find the path young grasshopper
116
+			if (empty($path)) {
117
+				throw new EE_Error(sprintf(esc_html__('No path was specified while registering an autoloader for the %s class.', 'event_espresso'), $class));
118
+			}
119
+			// is file readable ?
120
+			if ($read_check && ! is_readable($path)) {
121
+				throw new EE_Error(sprintf(esc_html__('The file for the %s class could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s', 'event_espresso'), $class, $path));
122
+			}
123
+			if (! isset(self::$_autoloaders[ $class ])) {
124
+				self::$_autoloaders[ $class ] = str_replace(array( '/', '\\' ), '/', $path);
125
+				if (EE_DEBUG && ( EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug )) {
126
+					EEH_Debug_Tools::printr(self::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
127
+				}
128
+			}
129
+		}
130
+	}
131
+
132
+
133
+
134
+
135
+	/**
136
+	 *  get_autoloaders
137
+	 *
138
+	 *  @access public
139
+	 *  @return array
140
+	 */
141
+	public static function get_autoloaders()
142
+	{
143
+		return self::$_autoloaders;
144
+	}
145
+
146
+
147
+	/**
148
+	 *  register core, model and class 'autoloaders'
149
+	 *
150
+	 * @access private
151
+	 * @return void
152
+	 * @throws EE_Error
153
+	 */
154
+	private function _register_custom_autoloaders()
155
+	{
156
+		EEH_Autoloader::$debug = '';
157
+		\EEH_Autoloader::register_helpers_autoloaders();
158
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
159
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
160
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
161
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
162
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
163
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
164
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
165
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
166
+			EEH_Debug_Tools::instance()->show_times();
167
+		}
168
+	}
169
+
170
+
171
+
172
+	/**
173
+	 *    register core, model and class 'autoloaders'
174
+	 *
175
+	 * @access public
176
+	 */
177
+	public static function register_helpers_autoloaders()
178
+	{
179
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
180
+	}
181
+
182
+
183
+
184
+
185
+	/**
186
+	 *  register core, model and class 'autoloaders'
187
+	 *
188
+	 *  @access public
189
+	 *  @return void
190
+	 */
191
+	public static function register_form_sections_autoloaders()
192
+	{
193
+		// EEH_Autoloader::register_autoloaders_for_each_file_in_folder( EE_FORM_SECTIONS, true );
194
+	}
195
+
196
+
197
+	/**
198
+	 *  register core, model and class 'autoloaders'
199
+	 *
200
+	 * @access public
201
+	 * @return void
202
+	 * @throws EE_Error
203
+	 */
204
+	public static function register_line_item_display_autoloaders()
205
+	{
206
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
207
+	}
208
+
209
+
210
+	/**
211
+	 *  register core, model and class 'autoloaders'
212
+	 *
213
+	 * @access public
214
+	 * @return void
215
+	 * @throws EE_Error
216
+	 */
217
+	public static function register_line_item_filter_autoloaders()
218
+	{
219
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
220
+	}
221
+
222
+
223
+	/**
224
+	 *  register template part 'autoloaders'
225
+	 *
226
+	 * @access public
227
+	 * @return void
228
+	 * @throws EE_Error
229
+	 */
230
+	public static function register_template_part_autoloaders()
231
+	{
232
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
233
+	}
234
+
235
+
236
+	/**
237
+	 * @return void
238
+	 * @throws EE_Error
239
+	 */
240
+	public static function register_business_classes()
241
+	{
242
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
243
+	}
244
+
245
+
246
+
247
+	/**
248
+	 * Assumes all the files in this folder have the normal naming scheme (namely that their classname
249
+	 * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
250
+	 * If that's not the case, you'll need to improve this function or just use EEH_File::get_classname_from_filepath_with_standard_filename() directly.
251
+	 * Yes this has to scan the directory for files, but it only does it once -- not on EACH
252
+	 * time the autoloader is used
253
+	 *
254
+	 * @param string $folder name, with or without trailing /, doesn't matter
255
+	 * @param bool   $recursive
256
+	 * @param bool   $debug  **deprecated**
257
+	 * @throws \EE_Error
258
+	 */
259
+	public static function register_autoloaders_for_each_file_in_folder($folder, $recursive = false, $debug = false)
260
+	{
261
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all' || $debug) {
262
+			EEH_Debug_Tools::instance()->start_timer(basename($folder));
263
+		}
264
+		// make sure last char is a /
265
+		$folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
266
+		$class_to_filepath_map = array();
267
+		$exclude = array( 'index' );
268
+		// get all the files in that folder that end in php
269
+		$filepaths = glob($folder . '*');
270
+
271
+		if (empty($filepaths)) {
272
+			return;
273
+		}
274
+
275
+		foreach ($filepaths as $filepath) {
276
+			if (substr($filepath, -4, 4) === '.php') {
277
+				$class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
278
+				if (! in_array($class_name, $exclude)) {
279
+					$class_to_filepath_map [ $class_name ] = $filepath;
280
+				}
281
+			} elseif ($recursive) {
282
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
283
+			}
284
+		}
285
+		// we remove the necessity to do a is_readable() check via the $read_check flag because glob by nature will not return non_readable files/directories.
286
+		self::register_autoloader($class_to_filepath_map, false, $debug);
287
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
288
+			EEH_Debug_Tools::instance()->stop_timer(basename($folder));
289
+		}
290
+	}
291
+
292
+
293
+
294
+	/**
295
+	 * add_alias
296
+	 * register additional autoloader based on variation of the classname for an existing autoloader
297
+	 *
298
+	 * @access    public
299
+	 * @param string $class_name - simple class name ie: EE_Session
300
+	 * @param string $alias - variation on class name ie: EE_session, session, etc
301
+	 */
302
+	public static function add_alias($class_name, $alias)
303
+	{
304
+		if (isset(self::$_autoloaders[ $class_name ])) {
305
+			self::$_autoloaders[ $alias ] = self::$_autoloaders[ $class_name ];
306
+		}
307
+	}
308 308
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Template_Validator.helper.php 2 patches
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -40,10 +40,10 @@  discard block
 block discarded – undo
40 40
      */
41 41
     public static function verify_is_array_of($variable_to_test, $name_of_variable, $class_name, $allow_null = 'allow_null')
42 42
     {
43
-        if (!WP_DEBUG) {
43
+        if ( ! WP_DEBUG) {
44 44
             return;
45 45
         }
46
-        self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null','do_not_allow_null'));
46
+        self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null', 'do_not_allow_null'));
47 47
         if ('allow_null' == $allow_null && is_null($variable_to_test)) {
48 48
             return;
49 49
         }
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
      */
67 67
     public static function verify_isnt_null($variable_to_test, $name_of_variable)
68 68
     {
69
-        if (!WP_DEBUG) {
69
+        if ( ! WP_DEBUG) {
70 70
             return;
71 71
         }
72 72
         if ($variable_to_test == null && $variable_to_test != 0 && $variable_to_test != false) {
@@ -86,10 +86,10 @@  discard block
 block discarded – undo
86 86
      */
87 87
     public static function verify_is_true($expression_to_test, $expression_string_representation)
88 88
     {
89
-        if (!WP_DEBUG) {
89
+        if ( ! WP_DEBUG) {
90 90
             return;
91 91
         }
92
-        if (!$expression_to_test) {
92
+        if ( ! $expression_to_test) {
93 93
             $error[] = esc_html__('Template error.', 'event_espresso');
94 94
             $error[] = esc_html__("%s evaluated to false, but it must be true!", 'event_espresso');
95 95
             throw new EE_Error(sprintf(implode(",", $error), $expression_string_representation));
@@ -110,14 +110,14 @@  discard block
 block discarded – undo
110 110
      */
111 111
     public static function verify_instanceof($variable_to_test, $name_of_variable, $class_name, $allow_null = 'do_not_allow_null')
112 112
     {
113
-        if (!WP_DEBUG) {
113
+        if ( ! WP_DEBUG) {
114 114
             return;
115 115
         }
116
-        self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null','do_not_allow_null'));
116
+        self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null', 'do_not_allow_null'));
117 117
         if ($allow_null == 'allow_null' && is_null($variable_to_test)) {
118 118
             return;
119 119
         }
120
-        if ($variable_to_test == null ||  ! ( $variable_to_test instanceof $class_name )) {
120
+        if ($variable_to_test == null || ! ($variable_to_test instanceof $class_name)) {
121 121
             $msg[] = esc_html__('Variable %s is not of the correct type.', 'event_espresso');
122 122
             $msg[] = esc_html__("It should be of type %s", 'event_espresso');
123 123
             throw new EE_Error(sprintf(implode(",", $msg), $name_of_variable, $name_of_variable, $class_name));
@@ -138,14 +138,14 @@  discard block
 block discarded – undo
138 138
      */
139 139
     public static function verify_is_array($variable_to_test, $variable_name, $allow_empty = 'allow_empty')
140 140
     {
141
-        if (!WP_DEBUG) {
141
+        if ( ! WP_DEBUG) {
142 142
             return;
143 143
         }
144
-        self::verify_argument_is_one_of($allow_empty, $variable_name, array('allow_empty','do_not_allow_empty'));
144
+        self::verify_argument_is_one_of($allow_empty, $variable_name, array('allow_empty', 'do_not_allow_empty'));
145 145
         if (empty($variable_to_test) && 'allow_empty' == $allow_empty) {
146 146
             return;
147 147
         }
148
-        if (!is_array($variable_to_test)) {
148
+        if ( ! is_array($variable_to_test)) {
149 149
             $error[] = esc_html__('Variable %s should be an array, but it is not.', 'event_espresso');
150 150
             $error[] = esc_html__("Its value is, instead '%s'", 'event_espresso');
151 151
             throw new EE_Error(sprintf(implode(",", $error), $variable_name, $variable_name, $variable_to_test));
@@ -168,10 +168,10 @@  discard block
 block discarded – undo
168 168
      */
169 169
     public static function verify_argument_is_one_of($variable_to_test, $variable_name, $string_options)
170 170
     {
171
-        if (!WP_DEBUG) {
171
+        if ( ! WP_DEBUG) {
172 172
             return;
173 173
         }
174
-        if (!in_array($variable_to_test, $string_options)) {
174
+        if ( ! in_array($variable_to_test, $string_options)) {
175 175
             $msg[0] = esc_html__('Malconfigured template.', 'event_espresso');
176 176
             $msg[1] = esc_html__("Variable named '%s' was set to '%s'. It can only be one of '%s'", 'event_espresso');
177 177
             throw new EE_Error(sprintf(implode("||", $msg), $variable_name, $variable_to_test, implode("', '", $string_options)));
Please login to merge, or discard this patch.
Indentation   +148 added lines, -148 removed lines patch added patch discarded remove patch
@@ -24,152 +24,152 @@
 block discarded – undo
24 24
  */
25 25
 class EEH_Template_Validator
26 26
 {
27
-    /**
28
-     * Throws an EE_Error if $variabel_to_test isn't an array of objects of class $class_name
29
-     * @param mixed $variable_to_test
30
-     * @param string $name_of_variable helpful in throwing intelligent errors
31
-     * @param string $class_name eg EE_Answer, EE_Transaction, etc.
32
-     * @param string $allow_null one of 'allow_null', or 'do_not_allow_null'
33
-     * @return void
34
-     * @throws EE_Error (indirectly)
35
-     */
36
-    public static function verify_is_array_of($variable_to_test, $name_of_variable, $class_name, $allow_null = 'allow_null')
37
-    {
38
-        if (!WP_DEBUG) {
39
-            return;
40
-        }
41
-        self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null','do_not_allow_null'));
42
-        if ('allow_null' == $allow_null && is_null($variable_to_test)) {
43
-            return;
44
-        }
45
-        self::verify_is_array($variable_to_test, $name_of_variable);
46
-        foreach ($variable_to_test as $key => $array_element) {
47
-            self::verify_instanceof($array_element, $key, $class_name);
48
-        }
49
-    }
50
-
51
-
52
-
53
-
54
-
55
-    /**
56
-     * throws an EE_Error if $variable_to_test is null
57
-     * @param mixed $variable_to_test
58
-     * @param string $name_of_variable helpful for throwing intelligent errors
59
-     * @return void
60
-     * @throws EE_Error
61
-     */
62
-    public static function verify_isnt_null($variable_to_test, $name_of_variable)
63
-    {
64
-        if (!WP_DEBUG) {
65
-            return;
66
-        }
67
-        if ($variable_to_test == null && $variable_to_test != 0 && $variable_to_test != false) {
68
-            $error[] = esc_html__('Variable named %s is null.', 'event_espresso');
69
-            $error[] = esc_html__("Consider looking at the stack trace to see why it wasn't set.", 'event_espresso');
70
-            throw new EE_Error(sprintf(implode(",", $error), $name_of_variable, $name_of_variable));
71
-        }
72
-    }
73
-
74
-    /**
75
-     * When WP_DEBUG is activted, throws an error if $expression_to_test is false.
76
-     * @param boolean $expression_to_test
77
-     * @param string $expression_string_representation a string representation of your expression
78
-     * for example, if your expression were $var1==23, then this should be '$var1==23'
79
-     * @return void
80
-     * @throws EE_Error
81
-     */
82
-    public static function verify_is_true($expression_to_test, $expression_string_representation)
83
-    {
84
-        if (!WP_DEBUG) {
85
-            return;
86
-        }
87
-        if (!$expression_to_test) {
88
-            $error[] = esc_html__('Template error.', 'event_espresso');
89
-            $error[] = esc_html__("%s evaluated to false, but it must be true!", 'event_espresso');
90
-            throw new EE_Error(sprintf(implode(",", $error), $expression_string_representation));
91
-        }
92
-    }
93
-
94
-
95
-
96
-
97
-
98
-    /**
99
-     * For verifying that a variable is indeed an object of class $class_name
100
-     * @param mixed $variable_to_test
101
-     * @param string $name_of_variable helpful when throwing errors
102
-     * @param string $class_name eg, EE_Answer,
103
-     * @return void
104
-     * @throws EE_Error
105
-     */
106
-    public static function verify_instanceof($variable_to_test, $name_of_variable, $class_name, $allow_null = 'do_not_allow_null')
107
-    {
108
-        if (!WP_DEBUG) {
109
-            return;
110
-        }
111
-        self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null','do_not_allow_null'));
112
-        if ($allow_null == 'allow_null' && is_null($variable_to_test)) {
113
-            return;
114
-        }
115
-        if ($variable_to_test == null ||  ! ( $variable_to_test instanceof $class_name )) {
116
-            $msg[] = esc_html__('Variable %s is not of the correct type.', 'event_espresso');
117
-            $msg[] = esc_html__("It should be of type %s", 'event_espresso');
118
-            throw new EE_Error(sprintf(implode(",", $msg), $name_of_variable, $name_of_variable, $class_name));
119
-        }
120
-    }
121
-
122
-
123
-
124
-
125
-
126
-    /**
127
-     * For verifying that a variable is indeed an array, else throw an EE_Error
128
-     * @param type $variable_to_test
129
-     * @param type $variable_name
130
-     * @param type $allow_empty one of 'allow_empty' or 'do_not_allow_empty'
131
-     * @return void
132
-     * @throws EE_Error
133
-     */
134
-    public static function verify_is_array($variable_to_test, $variable_name, $allow_empty = 'allow_empty')
135
-    {
136
-        if (!WP_DEBUG) {
137
-            return;
138
-        }
139
-        self::verify_argument_is_one_of($allow_empty, $variable_name, array('allow_empty','do_not_allow_empty'));
140
-        if (empty($variable_to_test) && 'allow_empty' == $allow_empty) {
141
-            return;
142
-        }
143
-        if (!is_array($variable_to_test)) {
144
-            $error[] = esc_html__('Variable %s should be an array, but it is not.', 'event_espresso');
145
-            $error[] = esc_html__("Its value is, instead '%s'", 'event_espresso');
146
-            throw new EE_Error(sprintf(implode(",", $error), $variable_name, $variable_name, $variable_to_test));
147
-        }
148
-    }
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-    /**
157
-     * for verifying that a variable is one of the string optiosn supplied
158
-     * @param mixed $variable_to_test
159
-     * @param mixed $variable_name the name you've given the variable. Eg, '$foo'. THis helps in producing better error messages
160
-     * @param array $string_options an array of acceptable values
161
-     * @return void
162
-     * @throws EE_Error
163
-     */
164
-    public static function verify_argument_is_one_of($variable_to_test, $variable_name, $string_options)
165
-    {
166
-        if (!WP_DEBUG) {
167
-            return;
168
-        }
169
-        if (!in_array($variable_to_test, $string_options)) {
170
-            $msg[0] = esc_html__('Malconfigured template.', 'event_espresso');
171
-            $msg[1] = esc_html__("Variable named '%s' was set to '%s'. It can only be one of '%s'", 'event_espresso');
172
-            throw new EE_Error(sprintf(implode("||", $msg), $variable_name, $variable_to_test, implode("', '", $string_options)));
173
-        }
174
-    }
27
+	/**
28
+	 * Throws an EE_Error if $variabel_to_test isn't an array of objects of class $class_name
29
+	 * @param mixed $variable_to_test
30
+	 * @param string $name_of_variable helpful in throwing intelligent errors
31
+	 * @param string $class_name eg EE_Answer, EE_Transaction, etc.
32
+	 * @param string $allow_null one of 'allow_null', or 'do_not_allow_null'
33
+	 * @return void
34
+	 * @throws EE_Error (indirectly)
35
+	 */
36
+	public static function verify_is_array_of($variable_to_test, $name_of_variable, $class_name, $allow_null = 'allow_null')
37
+	{
38
+		if (!WP_DEBUG) {
39
+			return;
40
+		}
41
+		self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null','do_not_allow_null'));
42
+		if ('allow_null' == $allow_null && is_null($variable_to_test)) {
43
+			return;
44
+		}
45
+		self::verify_is_array($variable_to_test, $name_of_variable);
46
+		foreach ($variable_to_test as $key => $array_element) {
47
+			self::verify_instanceof($array_element, $key, $class_name);
48
+		}
49
+	}
50
+
51
+
52
+
53
+
54
+
55
+	/**
56
+	 * throws an EE_Error if $variable_to_test is null
57
+	 * @param mixed $variable_to_test
58
+	 * @param string $name_of_variable helpful for throwing intelligent errors
59
+	 * @return void
60
+	 * @throws EE_Error
61
+	 */
62
+	public static function verify_isnt_null($variable_to_test, $name_of_variable)
63
+	{
64
+		if (!WP_DEBUG) {
65
+			return;
66
+		}
67
+		if ($variable_to_test == null && $variable_to_test != 0 && $variable_to_test != false) {
68
+			$error[] = esc_html__('Variable named %s is null.', 'event_espresso');
69
+			$error[] = esc_html__("Consider looking at the stack trace to see why it wasn't set.", 'event_espresso');
70
+			throw new EE_Error(sprintf(implode(",", $error), $name_of_variable, $name_of_variable));
71
+		}
72
+	}
73
+
74
+	/**
75
+	 * When WP_DEBUG is activted, throws an error if $expression_to_test is false.
76
+	 * @param boolean $expression_to_test
77
+	 * @param string $expression_string_representation a string representation of your expression
78
+	 * for example, if your expression were $var1==23, then this should be '$var1==23'
79
+	 * @return void
80
+	 * @throws EE_Error
81
+	 */
82
+	public static function verify_is_true($expression_to_test, $expression_string_representation)
83
+	{
84
+		if (!WP_DEBUG) {
85
+			return;
86
+		}
87
+		if (!$expression_to_test) {
88
+			$error[] = esc_html__('Template error.', 'event_espresso');
89
+			$error[] = esc_html__("%s evaluated to false, but it must be true!", 'event_espresso');
90
+			throw new EE_Error(sprintf(implode(",", $error), $expression_string_representation));
91
+		}
92
+	}
93
+
94
+
95
+
96
+
97
+
98
+	/**
99
+	 * For verifying that a variable is indeed an object of class $class_name
100
+	 * @param mixed $variable_to_test
101
+	 * @param string $name_of_variable helpful when throwing errors
102
+	 * @param string $class_name eg, EE_Answer,
103
+	 * @return void
104
+	 * @throws EE_Error
105
+	 */
106
+	public static function verify_instanceof($variable_to_test, $name_of_variable, $class_name, $allow_null = 'do_not_allow_null')
107
+	{
108
+		if (!WP_DEBUG) {
109
+			return;
110
+		}
111
+		self::verify_argument_is_one_of($allow_null, 'allow_null', array('allow_null','do_not_allow_null'));
112
+		if ($allow_null == 'allow_null' && is_null($variable_to_test)) {
113
+			return;
114
+		}
115
+		if ($variable_to_test == null ||  ! ( $variable_to_test instanceof $class_name )) {
116
+			$msg[] = esc_html__('Variable %s is not of the correct type.', 'event_espresso');
117
+			$msg[] = esc_html__("It should be of type %s", 'event_espresso');
118
+			throw new EE_Error(sprintf(implode(",", $msg), $name_of_variable, $name_of_variable, $class_name));
119
+		}
120
+	}
121
+
122
+
123
+
124
+
125
+
126
+	/**
127
+	 * For verifying that a variable is indeed an array, else throw an EE_Error
128
+	 * @param type $variable_to_test
129
+	 * @param type $variable_name
130
+	 * @param type $allow_empty one of 'allow_empty' or 'do_not_allow_empty'
131
+	 * @return void
132
+	 * @throws EE_Error
133
+	 */
134
+	public static function verify_is_array($variable_to_test, $variable_name, $allow_empty = 'allow_empty')
135
+	{
136
+		if (!WP_DEBUG) {
137
+			return;
138
+		}
139
+		self::verify_argument_is_one_of($allow_empty, $variable_name, array('allow_empty','do_not_allow_empty'));
140
+		if (empty($variable_to_test) && 'allow_empty' == $allow_empty) {
141
+			return;
142
+		}
143
+		if (!is_array($variable_to_test)) {
144
+			$error[] = esc_html__('Variable %s should be an array, but it is not.', 'event_espresso');
145
+			$error[] = esc_html__("Its value is, instead '%s'", 'event_espresso');
146
+			throw new EE_Error(sprintf(implode(",", $error), $variable_name, $variable_name, $variable_to_test));
147
+		}
148
+	}
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+	/**
157
+	 * for verifying that a variable is one of the string optiosn supplied
158
+	 * @param mixed $variable_to_test
159
+	 * @param mixed $variable_name the name you've given the variable. Eg, '$foo'. THis helps in producing better error messages
160
+	 * @param array $string_options an array of acceptable values
161
+	 * @return void
162
+	 * @throws EE_Error
163
+	 */
164
+	public static function verify_argument_is_one_of($variable_to_test, $variable_name, $string_options)
165
+	{
166
+		if (!WP_DEBUG) {
167
+			return;
168
+		}
169
+		if (!in_array($variable_to_test, $string_options)) {
170
+			$msg[0] = esc_html__('Malconfigured template.', 'event_espresso');
171
+			$msg[1] = esc_html__("Variable named '%s' was set to '%s'. It can only be one of '%s'", 'event_espresso');
172
+			throw new EE_Error(sprintf(implode("||", $msg), $variable_name, $variable_to_test, implode("', '", $string_options)));
173
+		}
174
+	}
175 175
 }
Please login to merge, or discard this patch.
core/helpers/EEH_File.helper.php 2 patches
Spacing   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -48,16 +48,16 @@  discard block
 block discarded – undo
48 48
                 $filepath
49 49
             )
50 50
         ) {
51
-            if (! EEH_File::$_wp_filesystem_direct instanceof WP_Filesystem_Direct) {
52
-                require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
51
+            if ( ! EEH_File::$_wp_filesystem_direct instanceof WP_Filesystem_Direct) {
52
+                require_once(ABSPATH.'wp-admin/includes/class-wp-filesystem-base.php');
53 53
                 $method = 'direct';
54
-                $wp_filesystem_direct_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method);
54
+                $wp_filesystem_direct_file = apply_filters('filesystem_method_file', ABSPATH.'wp-admin/includes/class-wp-filesystem-'.$method.'.php', $method);
55 55
                 // check constants defined, just like in wp-admin/includes/file.php's WP_Filesystem()
56
-                if (! defined('FS_CHMOD_DIR')) {
57
-                    define('FS_CHMOD_DIR', ( fileperms(ABSPATH) & 0777 | 0755 ));
56
+                if ( ! defined('FS_CHMOD_DIR')) {
57
+                    define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0777 | 0755));
58 58
                 }
59
-                if (! defined('FS_CHMOD_FILE')) {
60
-                    define('FS_CHMOD_FILE', ( fileperms(ABSPATH . 'index.php') & 0777 | 0644 ));
59
+                if ( ! defined('FS_CHMOD_FILE')) {
60
+                    define('FS_CHMOD_FILE', (fileperms(ABSPATH.'index.php') & 0777 | 0644));
61 61
                 }
62 62
                 require_once($wp_filesystem_direct_file);
63 63
                 EEH_File::$_wp_filesystem_direct = new WP_Filesystem_Direct(array());
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
         }
67 67
         global $wp_filesystem;
68 68
         // no filesystem setup ???
69
-        if (! $wp_filesystem instanceof WP_Filesystem_Base) {
69
+        if ( ! $wp_filesystem instanceof WP_Filesystem_Base) {
70 70
             // if some eager beaver's just trying to get in there too early...
71 71
             // let them do it, because we are one of those eager beavers! :P
72 72
             /**
@@ -82,14 +82,14 @@  discard block
 block discarded – undo
82 82
             if (false && ! did_action('wp_loaded')) {
83 83
                 $msg = esc_html__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso');
84 84
                 if (WP_DEBUG) {
85
-                    $msg .= '<br />' .  esc_html__('The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.', 'event_espresso');
85
+                    $msg .= '<br />'.esc_html__('The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.', 'event_espresso');
86 86
                 }
87 87
                 throw new EE_Error($msg);
88 88
             } else {
89 89
                 // should be loaded if we are past the wp_loaded hook...
90
-                if (! function_exists('WP_Filesystem')) {
91
-                    require_once(ABSPATH . 'wp-admin/includes/file.php');
92
-                    require_once(ABSPATH . 'wp-admin/includes/template.php');
90
+                if ( ! function_exists('WP_Filesystem')) {
91
+                    require_once(ABSPATH.'wp-admin/includes/file.php');
92
+                    require_once(ABSPATH.'wp-admin/includes/template.php');
93 93
                 }
94 94
                 // turn on output buffering so that we can capture the credentials form
95 95
                 ob_start();
@@ -97,13 +97,13 @@  discard block
 block discarded – undo
97 97
                 // store credentials form for the time being
98 98
                 EEH_File::$_credentials_form = ob_get_clean();
99 99
                 // basically check for direct or previously configured access
100
-                if (! WP_Filesystem($credentials)) {
100
+                if ( ! WP_Filesystem($credentials)) {
101 101
                     // if credentials do NOT exist
102 102
                     if ($credentials === false) {
103
-                        add_action('admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999);
103
+                        add_action('admin_notices', array('EEH_File', 'display_request_filesystem_credentials_form'), 999);
104 104
                         throw new EE_Error(esc_html__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso'));
105 105
                     } elseif (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
106
-                        add_action('admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999);
106
+                        add_action('admin_notices', array('EEH_File', 'display_request_filesystem_credentials_form'), 999);
107 107
                         throw new EE_Error(
108 108
                             sprintf(
109 109
                                 esc_html__('WP Filesystem Error: $1%s', 'event_espresso'),
@@ -122,8 +122,8 @@  discard block
 block discarded – undo
122 122
      */
123 123
     public static function display_request_filesystem_credentials_form()
124 124
     {
125
-        if (! empty(EEH_File::$_credentials_form)) {
126
-            echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
125
+        if ( ! empty(EEH_File::$_credentials_form)) {
126
+            echo '<div class="updated espresso-notices-attention"><p>'.EEH_File::$_credentials_form.'</p></div>';
127 127
         }
128 128
     }
129 129
 
@@ -146,8 +146,8 @@  discard block
 block discarded – undo
146 146
         // load WP_Filesystem and set file permissions
147 147
         $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
148 148
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
149
-        if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
150
-            $file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
149
+        if ( ! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
150
+            $file_name = ! empty($type_of_file) ? $file_name.' '.$type_of_file : $file_name;
151 151
             $file_name .= ! empty($file_ext) ? ' file' : ' folder';
152 152
             $msg = sprintf(
153 153
                 esc_html__('The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s', 'event_espresso'),
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
                 );
165 165
             }
166 166
             if (defined('WP_DEBUG') && WP_DEBUG) {
167
-                throw new EE_Error($msg . '||' . $msg);
167
+                throw new EE_Error($msg.'||'.$msg);
168 168
             }
169 169
             return false;
170 170
         }
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
         $perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
191 191
         if ($perms) {
192 192
             // file permissions exist, but way be set incorrectly
193
-            $type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
193
+            $type_of_file = ! empty($type_of_file) ? $type_of_file.' ' : '';
194 194
             $type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
195 195
             return sprintf(
196 196
                 esc_html__('File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.', 'event_espresso'),
@@ -229,15 +229,15 @@  discard block
 block discarded – undo
229 229
         // add / to folder
230 230
         $folder = EEH_File::end_with_directory_separator($folder);
231 231
         $wp_filesystem = EEH_File::_get_wp_filesystem($folder);
232
-        if (! $wp_filesystem->is_dir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
232
+        if ( ! $wp_filesystem->is_dir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
233 233
             // ok so it doesn't exist. Does its parent? Can we write to it?
234
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
234
+            if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
235 235
                 return false;
236 236
             }
237
-            if (! EEH_File::verify_is_writable($parent_folder, 'folder')) {
237
+            if ( ! EEH_File::verify_is_writable($parent_folder, 'folder')) {
238 238
                 return false;
239 239
             } else {
240
-                if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
240
+                if ( ! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
241 241
                     if (defined('WP_DEBUG') && WP_DEBUG) {
242 242
                         $msg = sprintf(esc_html__('"%s" could not be created.', 'event_espresso'), $folder);
243 243
                         $msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
                 }
248 248
                 EEH_File::add_index_file($folder);
249 249
             }
250
-        } elseif (! EEH_File::verify_is_writable($folder, 'folder')) {
250
+        } elseif ( ! EEH_File::verify_is_writable($folder, 'folder')) {
251 251
             return false;
252 252
         }
253 253
         return true;
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
         // load WP_Filesystem and set file permissions
268 268
         $wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
269 269
         $full_path = EEH_File::standardise_directory_separators($full_path);
270
-        if (! $wp_filesystem->is_writable(EEH_File::convert_local_filepath_to_remote_filepath($full_path))) {
270
+        if ( ! $wp_filesystem->is_writable(EEH_File::convert_local_filepath_to_remote_filepath($full_path))) {
271 271
             if (defined('WP_DEBUG') && WP_DEBUG) {
272 272
                 $msg = sprintf(esc_html__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
273 273
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
@@ -294,11 +294,11 @@  discard block
 block discarded – undo
294 294
         $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
295 295
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
296 296
         $parent_folder = EEH_File::get_parent_folder($full_file_path);
297
-        if (! EEH_File::exists($full_file_path)) {
298
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
297
+        if ( ! EEH_File::exists($full_file_path)) {
298
+            if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
299 299
                 return false;
300 300
             }
301
-            if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
301
+            if ( ! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
302 302
                 if (defined('WP_DEBUG') && WP_DEBUG) {
303 303
                     $msg = sprintf(esc_html__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
304 304
                     $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
                 return false;
308 308
             }
309 309
         }
310
-        if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
310
+        if ( ! EEH_File::verify_is_writable($full_file_path, 'file')) {
311 311
             return false;
312 312
         }
313 313
         return true;
@@ -366,9 +366,9 @@  discard block
 block discarded – undo
366 366
     public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '')
367 367
     {
368 368
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
369
-        $file_type = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
369
+        $file_type = ! empty($file_type) ? rtrim($file_type, ' ').' ' : '';
370 370
         $folder = EEH_File::remove_filename_from_filepath($full_file_path);
371
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
371
+        if ( ! EEH_File::verify_is_writable($folder, 'folder')) {
372 372
             if (defined('WP_DEBUG') && WP_DEBUG) {
373 373
                 $msg = sprintf(esc_html__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'), $file_type, $full_file_path);
374 374
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
         // load WP_Filesystem and set file permissions
380 380
         $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
381 381
         // write the file
382
-        if (! $wp_filesystem->put_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path), $file_contents)) {
382
+        if ( ! $wp_filesystem->put_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path), $file_contents)) {
383 383
             if (defined('WP_DEBUG') && WP_DEBUG) {
384 384
                 $msg = sprintf(esc_html__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'), $file_type, $full_file_path);
385 385
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
@@ -489,8 +489,8 @@  discard block
 block discarded – undo
489 489
     public static function add_htaccess_deny_from_all($folder = '')
490 490
     {
491 491
         $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
492
-        if (! EEH_File::exists($folder . '.htaccess')) {
493
-            if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
492
+        if ( ! EEH_File::exists($folder.'.htaccess')) {
493
+            if ( ! EEH_File::write_to_file($folder.'.htaccess', 'deny from all', '.htaccess')) {
494 494
                 return false;
495 495
             }
496 496
         }
@@ -507,8 +507,8 @@  discard block
 block discarded – undo
507 507
     public static function add_index_file($folder)
508 508
     {
509 509
         $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
510
-        if (! EEH_File::exists($folder . 'index.php')) {
511
-            if (! EEH_File::write_to_file($folder . 'index.php', 'You are not permitted to read from this folder', '.php')) {
510
+        if ( ! EEH_File::exists($folder.'index.php')) {
511
+            if ( ! EEH_File::write_to_file($folder.'index.php', 'You are not permitted to read from this folder', '.php')) {
512 512
                 return false;
513 513
             }
514 514
         }
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
      */
543 543
     public static function standardise_directory_separators($file_path)
544 544
     {
545
-        return str_replace(array( '\\', '/' ), '/', $file_path);
545
+        return str_replace(array('\\', '/'), '/', $file_path);
546 546
     }
547 547
 
548 548
 
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
      */
556 556
     public static function end_with_directory_separator($file_path)
557 557
     {
558
-        return rtrim($file_path, '/\\') . '/';
558
+        return rtrim($file_path, '/\\').'/';
559 559
     }
560 560
 
561 561
 
@@ -590,17 +590,17 @@  discard block
 block discarded – undo
590 590
         foreach ($folder_paths as $folder_path) {
591 591
             $folder_path = self::standardise_and_end_with_directory_separator($folder_path);
592 592
             // load WP_Filesystem and set file permissions
593
-            $files_in_folder = glob($folder_path . '*.php');
593
+            $files_in_folder = glob($folder_path.'*.php');
594 594
             $class_to_folder_path = array();
595 595
             if ($files_in_folder) {
596 596
                 foreach ($files_in_folder as $file_path) {
597 597
                     // only add files, not folders
598
-                    if (! is_dir($file_path)) {
598
+                    if ( ! is_dir($file_path)) {
599 599
                         if ($index_numerically) {
600 600
                             $class_to_folder_path[] = $file_path;
601 601
                         } else {
602 602
                             $classname = self::get_classname_from_filepath_with_standard_filename($file_path);
603
-                            $class_to_folder_path[ $classname ] = $file_path;
603
+                            $class_to_folder_path[$classname] = $file_path;
604 604
                         }
605 605
                     }
606 606
                 }
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
     public static function copy($source_file, $destination_file, $overwrite = false)
623 623
     {
624 624
         $full_source_path = EEH_File::standardise_directory_separators($source_file);
625
-        if (! EEH_File::exists($full_source_path)) {
625
+        if ( ! EEH_File::exists($full_source_path)) {
626 626
             if (defined('WP_DEBUG') && WP_DEBUG) {
627 627
                 $msg = sprintf(esc_html__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'), $full_source_path);
628 628
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
@@ -634,7 +634,7 @@  discard block
 block discarded – undo
634 634
         $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
635 635
         $folder = EEH_File::remove_filename_from_filepath($full_dest_path);
636 636
         EEH_File::ensure_folder_exists_and_is_writable($folder);
637
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
637
+        if ( ! EEH_File::verify_is_writable($folder, 'folder')) {
638 638
             if (defined('WP_DEBUG') && WP_DEBUG) {
639 639
                 $msg = sprintf(esc_html__('The file located at "%2$s" is not writable.', 'event_espresso'), $full_dest_path);
640 640
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
@@ -689,6 +689,6 @@  discard block
 block discarded – undo
689 689
     public static function convert_local_filepath_to_remote_filepath($local_filepath)
690 690
     {
691 691
         $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
692
-        return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
692
+        return str_replace(WP_CONTENT_DIR.'/', $wp_filesystem->wp_content_dir(), $local_filepath);
693 693
     }
694 694
 }
Please login to merge, or discard this patch.
Indentation   +666 added lines, -666 removed lines patch added patch discarded remove patch
@@ -24,670 +24,670 @@
 block discarded – undo
24 24
  */
25 25
 class EEH_File extends EEH_Base implements EEHI_File
26 26
 {
27
-    /**
28
-     * @var string $_credentials_form
29
-     */
30
-    private static $_credentials_form;
31
-
32
-    protected static $_wp_filesystem_direct;
33
-
34
-    /**
35
-     * @param string|null $filepath the filepath we want to work in. If its in the
36
-     * wp uploads directory, we'll want to just use the filesystem directly.
37
-     * If not provided, we have to assume its not in the uploads directory
38
-     * @throws EE_Error if filesystem credentials are required
39
-     * @return WP_Filesystem_Base
40
-     */
41
-    private static function _get_wp_filesystem($filepath = null)
42
-    {
43
-        if (
44
-            apply_filters(
45
-                'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
46
-                $filepath && EEH_File::is_in_uploads_folder($filepath),
47
-                $filepath
48
-            )
49
-        ) {
50
-            if (! EEH_File::$_wp_filesystem_direct instanceof WP_Filesystem_Direct) {
51
-                require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
52
-                $method = 'direct';
53
-                $wp_filesystem_direct_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method);
54
-                // check constants defined, just like in wp-admin/includes/file.php's WP_Filesystem()
55
-                if (! defined('FS_CHMOD_DIR')) {
56
-                    define('FS_CHMOD_DIR', ( fileperms(ABSPATH) & 0777 | 0755 ));
57
-                }
58
-                if (! defined('FS_CHMOD_FILE')) {
59
-                    define('FS_CHMOD_FILE', ( fileperms(ABSPATH . 'index.php') & 0777 | 0644 ));
60
-                }
61
-                require_once($wp_filesystem_direct_file);
62
-                EEH_File::$_wp_filesystem_direct = new WP_Filesystem_Direct(array());
63
-            }
64
-            return EEH_File::$_wp_filesystem_direct;
65
-        }
66
-        global $wp_filesystem;
67
-        // no filesystem setup ???
68
-        if (! $wp_filesystem instanceof WP_Filesystem_Base) {
69
-            // if some eager beaver's just trying to get in there too early...
70
-            // let them do it, because we are one of those eager beavers! :P
71
-            /**
72
-             * more explanations are probably merited. http://codex.wordpress.org/Filesystem_API#Initializing_WP_Filesystem_Base
73
-             * says WP_Filesystem should be used after 'wp_loaded', but currently EE's activation process
74
-             * is setup to mostly happen on 'init', and refactoring to have it happen on
75
-             * 'wp_loaded' is too much work on a BETA milestone.
76
-             * So this fix is expected to work if the WP files are owned by the server user,
77
-             * but probably not if the user needs to enter their FTP credentials to modify files
78
-             * and there may be troubles if the WP files are owned by a different user
79
-             * than the server user. But both of these issues should exist in 4.4 and earlier too
80
-             */
81
-            if (false && ! did_action('wp_loaded')) {
82
-                $msg = esc_html__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso');
83
-                if (WP_DEBUG) {
84
-                    $msg .= '<br />' .  esc_html__('The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.', 'event_espresso');
85
-                }
86
-                throw new EE_Error($msg);
87
-            } else {
88
-                // should be loaded if we are past the wp_loaded hook...
89
-                if (! function_exists('WP_Filesystem')) {
90
-                    require_once(ABSPATH . 'wp-admin/includes/file.php');
91
-                    require_once(ABSPATH . 'wp-admin/includes/template.php');
92
-                }
93
-                // turn on output buffering so that we can capture the credentials form
94
-                ob_start();
95
-                $credentials = request_filesystem_credentials('');
96
-                // store credentials form for the time being
97
-                EEH_File::$_credentials_form = ob_get_clean();
98
-                // basically check for direct or previously configured access
99
-                if (! WP_Filesystem($credentials)) {
100
-                    // if credentials do NOT exist
101
-                    if ($credentials === false) {
102
-                        add_action('admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999);
103
-                        throw new EE_Error(esc_html__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso'));
104
-                    } elseif (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
105
-                        add_action('admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999);
106
-                        throw new EE_Error(
107
-                            sprintf(
108
-                                esc_html__('WP Filesystem Error: $1%s', 'event_espresso'),
109
-                                $wp_filesystem->errors->get_error_message()
110
-                            )
111
-                        );
112
-                    }
113
-                }
114
-            }
115
-        }
116
-        return $wp_filesystem;
117
-    }
118
-
119
-    /**
120
-     * display_request_filesystem_credentials_form
121
-     */
122
-    public static function display_request_filesystem_credentials_form()
123
-    {
124
-        if (! empty(EEH_File::$_credentials_form)) {
125
-            echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
126
-        }
127
-    }
128
-
129
-
130
-
131
-    /**
132
-     *    verify_filepath_and_permissions
133
-     *    checks that a file is readable and has sufficient file permissions set to access
134
-     *
135
-     * @access public
136
-     * @param string $full_file_path - full server path to the folder or file
137
-     * @param string $file_name      - name of file if checking a file
138
-     * @param string $file_ext       - file extension (ie: "php") if checking a file
139
-     * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
140
-     * @throws EE_Error if filesystem credentials are required
141
-     * @return bool
142
-     */
143
-    public static function verify_filepath_and_permissions($full_file_path = '', $file_name = '', $file_ext = '', $type_of_file = '')
144
-    {
145
-        // load WP_Filesystem and set file permissions
146
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
147
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
148
-        if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
149
-            $file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
150
-            $file_name .= ! empty($file_ext) ? ' file' : ' folder';
151
-            $msg = sprintf(
152
-                esc_html__('The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s', 'event_espresso'),
153
-                $file_name,
154
-                '<br />'
155
-            );
156
-            if (EEH_File::exists($full_file_path)) {
157
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
158
-            } else {
159
-                // no file permissions means the file was not found
160
-                $msg .= sprintf(
161
-                    esc_html__('Please ensure the following path is correct: "%s".', 'event_espresso'),
162
-                    $full_file_path
163
-                );
164
-            }
165
-            if (defined('WP_DEBUG') && WP_DEBUG) {
166
-                throw new EE_Error($msg . '||' . $msg);
167
-            }
168
-            return false;
169
-        }
170
-        return true;
171
-    }
172
-
173
-
174
-
175
-    /**
176
-     * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a file or folder
177
-     *
178
-     * @access private
179
-     * @param string $full_file_path - full server path to the folder or file
180
-     * @param string $type_of_file - general type of file (ie: "module"), this is only used to improve error messages
181
-     * @throws EE_Error if filesystem credentials are required
182
-     * @return string
183
-     */
184
-    private static function _permissions_error_for_unreadable_filepath($full_file_path = '', $type_of_file = '')
185
-    {
186
-        // load WP_Filesystem and set file permissions
187
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
188
-        // check file permissions
189
-        $perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
190
-        if ($perms) {
191
-            // file permissions exist, but way be set incorrectly
192
-            $type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
193
-            $type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
194
-            return sprintf(
195
-                esc_html__('File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.', 'event_espresso'),
196
-                $type_of_file,
197
-                $perms
198
-            );
199
-        } else {
200
-            // file exists but file permissions could not be read ?!?!
201
-            return sprintf(
202
-                esc_html__('Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".', 'event_espresso'),
203
-                $full_file_path
204
-            );
205
-        }
206
-    }
207
-
208
-
209
-
210
-    /**
211
-     * ensure_folder_exists_and_is_writable
212
-     * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
213
-     * Also ensures all the parent folders exist, and if not tries to create them.
214
-     * Also, if this function creates the folder, adds a .htaccess file and index.html file
215
-     * @param string $folder
216
-     * @throws EE_Error if the folder exists and is writeable, but for some reason we
217
-     * can't write to it
218
-     * @return bool false if folder isn't writable; true if it exists and is writeable,
219
-     */
220
-    public static function ensure_folder_exists_and_is_writable($folder = '')
221
-    {
222
-        if (empty($folder)) {
223
-            return false;
224
-        }
225
-        // remove ending /
226
-        $folder = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
227
-        $parent_folder = EEH_File::get_parent_folder($folder);
228
-        // add / to folder
229
-        $folder = EEH_File::end_with_directory_separator($folder);
230
-        $wp_filesystem = EEH_File::_get_wp_filesystem($folder);
231
-        if (! $wp_filesystem->is_dir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
232
-            // ok so it doesn't exist. Does its parent? Can we write to it?
233
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
234
-                return false;
235
-            }
236
-            if (! EEH_File::verify_is_writable($parent_folder, 'folder')) {
237
-                return false;
238
-            } else {
239
-                if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
240
-                    if (defined('WP_DEBUG') && WP_DEBUG) {
241
-                        $msg = sprintf(esc_html__('"%s" could not be created.', 'event_espresso'), $folder);
242
-                        $msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
243
-                        throw new EE_Error($msg);
244
-                    }
245
-                    return false;
246
-                }
247
-                EEH_File::add_index_file($folder);
248
-            }
249
-        } elseif (! EEH_File::verify_is_writable($folder, 'folder')) {
250
-            return false;
251
-        }
252
-        return true;
253
-    }
254
-
255
-
256
-
257
-    /**
258
-     * verify_is_writable - checks if a file or folder is writable
259
-     * @param string $full_path      - full server path to file or folder
260
-     * @param string $file_or_folder - whether checking a file or folder
261
-     * @throws EE_Error if filesystem credentials are required
262
-     * @return bool
263
-     */
264
-    public static function verify_is_writable($full_path = '', $file_or_folder = 'folder')
265
-    {
266
-        // load WP_Filesystem and set file permissions
267
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
268
-        $full_path = EEH_File::standardise_directory_separators($full_path);
269
-        if (! $wp_filesystem->is_writable(EEH_File::convert_local_filepath_to_remote_filepath($full_path))) {
270
-            if (defined('WP_DEBUG') && WP_DEBUG) {
271
-                $msg = sprintf(esc_html__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
272
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
273
-                throw new EE_Error($msg);
274
-            }
275
-            return false;
276
-        }
277
-        return true;
278
-    }
279
-
280
-
281
-
282
-    /**
283
-     * ensure_file_exists_and_is_writable
284
-     * ensures that a file exists and is writable, will attempt to create file if it does not exist.
285
-     * Also ensures all the parent folders exist, and if not tries to create them.
286
-     * @param string $full_file_path
287
-     * @throws EE_Error if filesystem credentials are required
288
-     * @return bool
289
-     */
290
-    public static function ensure_file_exists_and_is_writable($full_file_path = '')
291
-    {
292
-        // load WP_Filesystem and set file permissions
293
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
294
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
295
-        $parent_folder = EEH_File::get_parent_folder($full_file_path);
296
-        if (! EEH_File::exists($full_file_path)) {
297
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
298
-                return false;
299
-            }
300
-            if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
301
-                if (defined('WP_DEBUG') && WP_DEBUG) {
302
-                    $msg = sprintf(esc_html__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
303
-                    $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
304
-                    throw new EE_Error($msg);
305
-                }
306
-                return false;
307
-            }
308
-        }
309
-        if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
310
-            return false;
311
-        }
312
-        return true;
313
-    }
314
-
315
-    /**
316
-     * Gets the parent folder. If provided with file, gets the folder that contains it.
317
-     * If provided a folder, gets its parent folder.
318
-     * @param string $file_or_folder_path
319
-     * @return string parent folder, ENDING with a directory separator
320
-     */
321
-    public static function get_parent_folder($file_or_folder_path)
322
-    {
323
-        // find the last /, ignoring a / on the very end
324
-        // eg if given "/var/something/somewhere/", we want to get "somewhere"'s
325
-        // parent folder, "/var/something/"
326
-        $ds = strlen($file_or_folder_path) > 1
327
-            ? strrpos($file_or_folder_path, '/', -2)
328
-            : strlen($file_or_folder_path);
329
-        return substr($file_or_folder_path, 0, $ds + 1);
330
-    }
331
-
332
-    // public static function ensure_folder_exists_recursively( $folder ) {
333
-    //
334
-    // }
335
-
336
-
337
-
338
-    /**
339
-     * get_file_contents
340
-     * @param string $full_file_path
341
-     * @throws EE_Error if filesystem credentials are required
342
-     * @return string
343
-     */
344
-    public static function get_file_contents($full_file_path = '')
345
-    {
346
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
347
-        if (EEH_File::verify_filepath_and_permissions($full_file_path, EEH_File::get_filename_from_filepath($full_file_path), EEH_File::get_file_extension($full_file_path))) {
348
-            // load WP_Filesystem and set file permissions
349
-            $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
350
-            return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
351
-        }
352
-        return '';
353
-    }
354
-
355
-
356
-
357
-    /**
358
-     * write_file
359
-     * @param string $full_file_path
360
-     * @param string $file_contents - the content to be written to the file
361
-     * @param string $file_type
362
-     * @throws EE_Error if filesystem credentials are required
363
-     * @return bool
364
-     */
365
-    public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '')
366
-    {
367
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
368
-        $file_type = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
369
-        $folder = EEH_File::remove_filename_from_filepath($full_file_path);
370
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
371
-            if (defined('WP_DEBUG') && WP_DEBUG) {
372
-                $msg = sprintf(esc_html__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'), $file_type, $full_file_path);
373
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
374
-                throw new EE_Error($msg);
375
-            }
376
-            return false;
377
-        }
378
-        // load WP_Filesystem and set file permissions
379
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
380
-        // write the file
381
-        if (! $wp_filesystem->put_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path), $file_contents)) {
382
-            if (defined('WP_DEBUG') && WP_DEBUG) {
383
-                $msg = sprintf(esc_html__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'), $file_type, $full_file_path);
384
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
385
-                throw new EE_Error($msg);
386
-            }
387
-            return false;
388
-        }
389
-        return true;
390
-    }
391
-
392
-    /**
393
-     * Wrapper for WP_Filesystem_Base::delete
394
-     *
395
-     * @param string $filepath
396
-     * @param boolean $recursive
397
-     * @param boolean|string $type 'd' for directory, 'f' for file
398
-     * @throws EE_Error if filesystem credentials are required
399
-     * @return boolean
400
-     */
401
-    public static function delete($filepath, $recursive = false, $type = false)
402
-    {
403
-        $wp_filesystem = EEH_File::_get_wp_filesystem();
404
-        return $wp_filesystem->delete($filepath, $recursive, $type) ? true : false;
405
-    }
406
-
407
-
408
-
409
-    /**
410
-     * exists
411
-     * checks if a file exists using the WP filesystem
412
-     * @param string $full_file_path
413
-     * @throws EE_Error if filesystem credentials are required
414
-     * @return bool
415
-     */
416
-    public static function exists($full_file_path = '')
417
-    {
418
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
419
-        return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path)) ? true : false;
420
-    }
421
-
422
-
423
-
424
-    /**
425
-     * is_readable
426
-     * checks if a file is_readable using the WP filesystem
427
-     *
428
-     * @param string $full_file_path
429
-     * @throws EE_Error if filesystem credentials are required
430
-     * @return bool
431
-     */
432
-    public static function is_readable($full_file_path = '')
433
-    {
434
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
435
-        if ($wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
436
-            return true;
437
-        } else {
438
-            return false;
439
-        }
440
-    }
441
-
442
-
443
-
444
-    /**
445
-     * remove_filename_from_filepath
446
-     * given a full path to a file including the filename itself, this removes  the filename and returns the path, up to, but NOT including the filename OR slash
447
-     *
448
-     * @param string $full_file_path
449
-     * @return string
450
-     */
451
-    public static function remove_filename_from_filepath($full_file_path = '')
452
-    {
453
-        return pathinfo($full_file_path, PATHINFO_DIRNAME);
454
-    }
455
-
456
-
457
-    /**
458
-     * get_filename_from_filepath. Arguably the same as basename()
459
-     *
460
-     * @param string $full_file_path
461
-     * @return string
462
-     */
463
-    public static function get_filename_from_filepath($full_file_path = '')
464
-    {
465
-        return pathinfo($full_file_path, PATHINFO_BASENAME);
466
-    }
467
-
468
-
469
-    /**
470
-     * get_file_extension
471
-     *
472
-     * @param string $full_file_path
473
-     * @return string
474
-     */
475
-    public static function get_file_extension($full_file_path = '')
476
-    {
477
-        return pathinfo($full_file_path, PATHINFO_EXTENSION);
478
-    }
479
-
480
-
481
-
482
-    /**
483
-     * add_htaccess_deny_from_all so the webserver cannot access this folder
484
-     * @param string $folder
485
-     * @throws EE_Error if filesystem credentials are required
486
-     * @return bool
487
-     */
488
-    public static function add_htaccess_deny_from_all($folder = '')
489
-    {
490
-        $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
491
-        if (! EEH_File::exists($folder . '.htaccess')) {
492
-            if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
493
-                return false;
494
-            }
495
-        }
496
-
497
-        return true;
498
-    }
499
-
500
-    /**
501
-     * Adds an index file to this folder, so folks can't list all the file's contents
502
-     * @param string $folder
503
-     * @throws EE_Error if filesystem credentials are required
504
-     * @return boolean
505
-     */
506
-    public static function add_index_file($folder)
507
-    {
508
-        $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
509
-        if (! EEH_File::exists($folder . 'index.php')) {
510
-            if (! EEH_File::write_to_file($folder . 'index.php', 'You are not permitted to read from this folder', '.php')) {
511
-                return false;
512
-            }
513
-        }
514
-        return true;
515
-    }
516
-
517
-
518
-
519
-    /**
520
-     * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php),
521
-     * extract that classname.
522
-     * @param string $file_path
523
-     * @return string
524
-     */
525
-    public static function get_classname_from_filepath_with_standard_filename($file_path)
526
-    {
527
-        // extract file from path
528
-        $filename = basename($file_path);
529
-        // now remove the first period and everything after
530
-        $pos_of_first_period = strpos($filename, '.');
531
-        return substr($filename, 0, $pos_of_first_period);
532
-    }
533
-
534
-
535
-
536
-    /**
537
-     * standardise_directory_separators
538
-     *  convert all directory separators in a file path.
539
-     * @param string $file_path
540
-     * @return string
541
-     */
542
-    public static function standardise_directory_separators($file_path)
543
-    {
544
-        return str_replace(array( '\\', '/' ), '/', $file_path);
545
-    }
546
-
547
-
548
-
549
-    /**
550
-     * end_with_directory_separator
551
-     *  ensures that file path ends with '/'
552
-     * @param string $file_path
553
-     * @return string
554
-     */
555
-    public static function end_with_directory_separator($file_path)
556
-    {
557
-        return rtrim($file_path, '/\\') . '/';
558
-    }
559
-
560
-
561
-
562
-    /**
563
-     * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators
564
-     * @param $file_path
565
-     * @return string
566
-     */
567
-    public static function standardise_and_end_with_directory_separator($file_path)
568
-    {
569
-        return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
570
-    }
571
-
572
-
573
-
574
-    /**
575
-     * takes the folder name (with or without trailing slash) and finds the files it in,
576
-     * and what the class's name inside of each should be.
577
-     * @param array $folder_paths
578
-     * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically;
579
-     *      if FALSE (Default), returned array will be indexed by the filenames minus extensions.
580
-     *      Set it TRUE if you know there are files in the directory with the same name but different extensions
581
-     * @throws EE_Error if filesystem credentials are required
582
-     * @return array if $index_numerically == TRUE keys are numeric ,
583
-     *      if $index_numerically == FALSE (Default) keys are what the class names SHOULD be;
584
-     *       and values are their filepaths
585
-     */
586
-    public static function get_contents_of_folders($folder_paths = array(), $index_numerically = false)
587
-    {
588
-        $class_to_folder_path = array();
589
-        foreach ($folder_paths as $folder_path) {
590
-            $folder_path = self::standardise_and_end_with_directory_separator($folder_path);
591
-            // load WP_Filesystem and set file permissions
592
-            $files_in_folder = glob($folder_path . '*.php');
593
-            $class_to_folder_path = array();
594
-            if ($files_in_folder) {
595
-                foreach ($files_in_folder as $file_path) {
596
-                    // only add files, not folders
597
-                    if (! is_dir($file_path)) {
598
-                        if ($index_numerically) {
599
-                            $class_to_folder_path[] = $file_path;
600
-                        } else {
601
-                            $classname = self::get_classname_from_filepath_with_standard_filename($file_path);
602
-                            $class_to_folder_path[ $classname ] = $file_path;
603
-                        }
604
-                    }
605
-                }
606
-            }
607
-        }
608
-        return $class_to_folder_path;
609
-    }
610
-
611
-
612
-
613
-    /**
614
-     * Copies a file. Mostly a wrapper of WP_Filesystem::copy
615
-     * @param string $source_file
616
-     * @param string $destination_file
617
-     * @param boolean $overwrite
618
-     * @throws EE_Error if filesystem credentials are required
619
-     * @return boolean success
620
-     */
621
-    public static function copy($source_file, $destination_file, $overwrite = false)
622
-    {
623
-        $full_source_path = EEH_File::standardise_directory_separators($source_file);
624
-        if (! EEH_File::exists($full_source_path)) {
625
-            if (defined('WP_DEBUG') && WP_DEBUG) {
626
-                $msg = sprintf(esc_html__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'), $full_source_path);
627
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
628
-                throw new EE_Error($msg);
629
-            }
630
-            return false;
631
-        }
632
-
633
-        $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
634
-        $folder = EEH_File::remove_filename_from_filepath($full_dest_path);
635
-        EEH_File::ensure_folder_exists_and_is_writable($folder);
636
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
637
-            if (defined('WP_DEBUG') && WP_DEBUG) {
638
-                $msg = sprintf(esc_html__('The file located at "%2$s" is not writable.', 'event_espresso'), $full_dest_path);
639
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
640
-                throw new EE_Error($msg);
641
-            }
642
-            return false;
643
-        }
644
-
645
-        // load WP_Filesystem and set file permissions
646
-        $wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
647
-        // write the file
648
-        if (
649
-            ! $wp_filesystem->copy(
650
-                EEH_File::convert_local_filepath_to_remote_filepath($full_source_path),
651
-                EEH_File::convert_local_filepath_to_remote_filepath($full_dest_path),
652
-                $overwrite
653
-            )
654
-        ) {
655
-            if (defined('WP_DEBUG') && WP_DEBUG) {
656
-                $msg = sprintf(esc_html__('Attempted writing to file %1$s, but could not, probably because of permissions issues', 'event_espresso'), $full_source_path);
657
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path, 'f');
658
-                throw new EE_Error($msg);
659
-            }
660
-            return false;
661
-        }
662
-        return true;
663
-    }
664
-
665
-    /**
666
-     * Reports whether or not the filepath is in the EE uploads folder or not
667
-     * @param string $filepath
668
-     * @return boolean
669
-     */
670
-    public static function is_in_uploads_folder($filepath)
671
-    {
672
-        $uploads = wp_upload_dir();
673
-        return strpos($filepath, $uploads['basedir']) === 0 ? true : false;
674
-    }
675
-
676
-    /**
677
-     * Given a "local" filepath (what you probably thought was the only filepath),
678
-     * converts it into a "remote" filepath (the filepath the currently-in-use
679
-     * $wp_filesystem needs to use access the folder or file).
680
-     * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
681
-     * @param WP_Filesystem_Base $wp_filesystem we aren't initially sure which one
682
-     * is in use, so you need to provide it
683
-     * @param string $local_filepath the filepath to the folder/file locally
684
-     * @throws EE_Error if filesystem credentials are required
685
-     * @return string the remote filepath (eg the filepath the filesystem method, eg
686
-     * ftp or ssh, will use to access the folder
687
-     */
688
-    public static function convert_local_filepath_to_remote_filepath($local_filepath)
689
-    {
690
-        $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
691
-        return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
692
-    }
27
+	/**
28
+	 * @var string $_credentials_form
29
+	 */
30
+	private static $_credentials_form;
31
+
32
+	protected static $_wp_filesystem_direct;
33
+
34
+	/**
35
+	 * @param string|null $filepath the filepath we want to work in. If its in the
36
+	 * wp uploads directory, we'll want to just use the filesystem directly.
37
+	 * If not provided, we have to assume its not in the uploads directory
38
+	 * @throws EE_Error if filesystem credentials are required
39
+	 * @return WP_Filesystem_Base
40
+	 */
41
+	private static function _get_wp_filesystem($filepath = null)
42
+	{
43
+		if (
44
+			apply_filters(
45
+				'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
46
+				$filepath && EEH_File::is_in_uploads_folder($filepath),
47
+				$filepath
48
+			)
49
+		) {
50
+			if (! EEH_File::$_wp_filesystem_direct instanceof WP_Filesystem_Direct) {
51
+				require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
52
+				$method = 'direct';
53
+				$wp_filesystem_direct_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method);
54
+				// check constants defined, just like in wp-admin/includes/file.php's WP_Filesystem()
55
+				if (! defined('FS_CHMOD_DIR')) {
56
+					define('FS_CHMOD_DIR', ( fileperms(ABSPATH) & 0777 | 0755 ));
57
+				}
58
+				if (! defined('FS_CHMOD_FILE')) {
59
+					define('FS_CHMOD_FILE', ( fileperms(ABSPATH . 'index.php') & 0777 | 0644 ));
60
+				}
61
+				require_once($wp_filesystem_direct_file);
62
+				EEH_File::$_wp_filesystem_direct = new WP_Filesystem_Direct(array());
63
+			}
64
+			return EEH_File::$_wp_filesystem_direct;
65
+		}
66
+		global $wp_filesystem;
67
+		// no filesystem setup ???
68
+		if (! $wp_filesystem instanceof WP_Filesystem_Base) {
69
+			// if some eager beaver's just trying to get in there too early...
70
+			// let them do it, because we are one of those eager beavers! :P
71
+			/**
72
+			 * more explanations are probably merited. http://codex.wordpress.org/Filesystem_API#Initializing_WP_Filesystem_Base
73
+			 * says WP_Filesystem should be used after 'wp_loaded', but currently EE's activation process
74
+			 * is setup to mostly happen on 'init', and refactoring to have it happen on
75
+			 * 'wp_loaded' is too much work on a BETA milestone.
76
+			 * So this fix is expected to work if the WP files are owned by the server user,
77
+			 * but probably not if the user needs to enter their FTP credentials to modify files
78
+			 * and there may be troubles if the WP files are owned by a different user
79
+			 * than the server user. But both of these issues should exist in 4.4 and earlier too
80
+			 */
81
+			if (false && ! did_action('wp_loaded')) {
82
+				$msg = esc_html__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso');
83
+				if (WP_DEBUG) {
84
+					$msg .= '<br />' .  esc_html__('The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.', 'event_espresso');
85
+				}
86
+				throw new EE_Error($msg);
87
+			} else {
88
+				// should be loaded if we are past the wp_loaded hook...
89
+				if (! function_exists('WP_Filesystem')) {
90
+					require_once(ABSPATH . 'wp-admin/includes/file.php');
91
+					require_once(ABSPATH . 'wp-admin/includes/template.php');
92
+				}
93
+				// turn on output buffering so that we can capture the credentials form
94
+				ob_start();
95
+				$credentials = request_filesystem_credentials('');
96
+				// store credentials form for the time being
97
+				EEH_File::$_credentials_form = ob_get_clean();
98
+				// basically check for direct or previously configured access
99
+				if (! WP_Filesystem($credentials)) {
100
+					// if credentials do NOT exist
101
+					if ($credentials === false) {
102
+						add_action('admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999);
103
+						throw new EE_Error(esc_html__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso'));
104
+					} elseif (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
105
+						add_action('admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999);
106
+						throw new EE_Error(
107
+							sprintf(
108
+								esc_html__('WP Filesystem Error: $1%s', 'event_espresso'),
109
+								$wp_filesystem->errors->get_error_message()
110
+							)
111
+						);
112
+					}
113
+				}
114
+			}
115
+		}
116
+		return $wp_filesystem;
117
+	}
118
+
119
+	/**
120
+	 * display_request_filesystem_credentials_form
121
+	 */
122
+	public static function display_request_filesystem_credentials_form()
123
+	{
124
+		if (! empty(EEH_File::$_credentials_form)) {
125
+			echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
126
+		}
127
+	}
128
+
129
+
130
+
131
+	/**
132
+	 *    verify_filepath_and_permissions
133
+	 *    checks that a file is readable and has sufficient file permissions set to access
134
+	 *
135
+	 * @access public
136
+	 * @param string $full_file_path - full server path to the folder or file
137
+	 * @param string $file_name      - name of file if checking a file
138
+	 * @param string $file_ext       - file extension (ie: "php") if checking a file
139
+	 * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
140
+	 * @throws EE_Error if filesystem credentials are required
141
+	 * @return bool
142
+	 */
143
+	public static function verify_filepath_and_permissions($full_file_path = '', $file_name = '', $file_ext = '', $type_of_file = '')
144
+	{
145
+		// load WP_Filesystem and set file permissions
146
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
147
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
148
+		if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
149
+			$file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
150
+			$file_name .= ! empty($file_ext) ? ' file' : ' folder';
151
+			$msg = sprintf(
152
+				esc_html__('The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s', 'event_espresso'),
153
+				$file_name,
154
+				'<br />'
155
+			);
156
+			if (EEH_File::exists($full_file_path)) {
157
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
158
+			} else {
159
+				// no file permissions means the file was not found
160
+				$msg .= sprintf(
161
+					esc_html__('Please ensure the following path is correct: "%s".', 'event_espresso'),
162
+					$full_file_path
163
+				);
164
+			}
165
+			if (defined('WP_DEBUG') && WP_DEBUG) {
166
+				throw new EE_Error($msg . '||' . $msg);
167
+			}
168
+			return false;
169
+		}
170
+		return true;
171
+	}
172
+
173
+
174
+
175
+	/**
176
+	 * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a file or folder
177
+	 *
178
+	 * @access private
179
+	 * @param string $full_file_path - full server path to the folder or file
180
+	 * @param string $type_of_file - general type of file (ie: "module"), this is only used to improve error messages
181
+	 * @throws EE_Error if filesystem credentials are required
182
+	 * @return string
183
+	 */
184
+	private static function _permissions_error_for_unreadable_filepath($full_file_path = '', $type_of_file = '')
185
+	{
186
+		// load WP_Filesystem and set file permissions
187
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
188
+		// check file permissions
189
+		$perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
190
+		if ($perms) {
191
+			// file permissions exist, but way be set incorrectly
192
+			$type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
193
+			$type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
194
+			return sprintf(
195
+				esc_html__('File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.', 'event_espresso'),
196
+				$type_of_file,
197
+				$perms
198
+			);
199
+		} else {
200
+			// file exists but file permissions could not be read ?!?!
201
+			return sprintf(
202
+				esc_html__('Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".', 'event_espresso'),
203
+				$full_file_path
204
+			);
205
+		}
206
+	}
207
+
208
+
209
+
210
+	/**
211
+	 * ensure_folder_exists_and_is_writable
212
+	 * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
213
+	 * Also ensures all the parent folders exist, and if not tries to create them.
214
+	 * Also, if this function creates the folder, adds a .htaccess file and index.html file
215
+	 * @param string $folder
216
+	 * @throws EE_Error if the folder exists and is writeable, but for some reason we
217
+	 * can't write to it
218
+	 * @return bool false if folder isn't writable; true if it exists and is writeable,
219
+	 */
220
+	public static function ensure_folder_exists_and_is_writable($folder = '')
221
+	{
222
+		if (empty($folder)) {
223
+			return false;
224
+		}
225
+		// remove ending /
226
+		$folder = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
227
+		$parent_folder = EEH_File::get_parent_folder($folder);
228
+		// add / to folder
229
+		$folder = EEH_File::end_with_directory_separator($folder);
230
+		$wp_filesystem = EEH_File::_get_wp_filesystem($folder);
231
+		if (! $wp_filesystem->is_dir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
232
+			// ok so it doesn't exist. Does its parent? Can we write to it?
233
+			if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
234
+				return false;
235
+			}
236
+			if (! EEH_File::verify_is_writable($parent_folder, 'folder')) {
237
+				return false;
238
+			} else {
239
+				if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
240
+					if (defined('WP_DEBUG') && WP_DEBUG) {
241
+						$msg = sprintf(esc_html__('"%s" could not be created.', 'event_espresso'), $folder);
242
+						$msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
243
+						throw new EE_Error($msg);
244
+					}
245
+					return false;
246
+				}
247
+				EEH_File::add_index_file($folder);
248
+			}
249
+		} elseif (! EEH_File::verify_is_writable($folder, 'folder')) {
250
+			return false;
251
+		}
252
+		return true;
253
+	}
254
+
255
+
256
+
257
+	/**
258
+	 * verify_is_writable - checks if a file or folder is writable
259
+	 * @param string $full_path      - full server path to file or folder
260
+	 * @param string $file_or_folder - whether checking a file or folder
261
+	 * @throws EE_Error if filesystem credentials are required
262
+	 * @return bool
263
+	 */
264
+	public static function verify_is_writable($full_path = '', $file_or_folder = 'folder')
265
+	{
266
+		// load WP_Filesystem and set file permissions
267
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
268
+		$full_path = EEH_File::standardise_directory_separators($full_path);
269
+		if (! $wp_filesystem->is_writable(EEH_File::convert_local_filepath_to_remote_filepath($full_path))) {
270
+			if (defined('WP_DEBUG') && WP_DEBUG) {
271
+				$msg = sprintf(esc_html__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
272
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
273
+				throw new EE_Error($msg);
274
+			}
275
+			return false;
276
+		}
277
+		return true;
278
+	}
279
+
280
+
281
+
282
+	/**
283
+	 * ensure_file_exists_and_is_writable
284
+	 * ensures that a file exists and is writable, will attempt to create file if it does not exist.
285
+	 * Also ensures all the parent folders exist, and if not tries to create them.
286
+	 * @param string $full_file_path
287
+	 * @throws EE_Error if filesystem credentials are required
288
+	 * @return bool
289
+	 */
290
+	public static function ensure_file_exists_and_is_writable($full_file_path = '')
291
+	{
292
+		// load WP_Filesystem and set file permissions
293
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
294
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
295
+		$parent_folder = EEH_File::get_parent_folder($full_file_path);
296
+		if (! EEH_File::exists($full_file_path)) {
297
+			if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
298
+				return false;
299
+			}
300
+			if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
301
+				if (defined('WP_DEBUG') && WP_DEBUG) {
302
+					$msg = sprintf(esc_html__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
303
+					$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
304
+					throw new EE_Error($msg);
305
+				}
306
+				return false;
307
+			}
308
+		}
309
+		if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
310
+			return false;
311
+		}
312
+		return true;
313
+	}
314
+
315
+	/**
316
+	 * Gets the parent folder. If provided with file, gets the folder that contains it.
317
+	 * If provided a folder, gets its parent folder.
318
+	 * @param string $file_or_folder_path
319
+	 * @return string parent folder, ENDING with a directory separator
320
+	 */
321
+	public static function get_parent_folder($file_or_folder_path)
322
+	{
323
+		// find the last /, ignoring a / on the very end
324
+		// eg if given "/var/something/somewhere/", we want to get "somewhere"'s
325
+		// parent folder, "/var/something/"
326
+		$ds = strlen($file_or_folder_path) > 1
327
+			? strrpos($file_or_folder_path, '/', -2)
328
+			: strlen($file_or_folder_path);
329
+		return substr($file_or_folder_path, 0, $ds + 1);
330
+	}
331
+
332
+	// public static function ensure_folder_exists_recursively( $folder ) {
333
+	//
334
+	// }
335
+
336
+
337
+
338
+	/**
339
+	 * get_file_contents
340
+	 * @param string $full_file_path
341
+	 * @throws EE_Error if filesystem credentials are required
342
+	 * @return string
343
+	 */
344
+	public static function get_file_contents($full_file_path = '')
345
+	{
346
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
347
+		if (EEH_File::verify_filepath_and_permissions($full_file_path, EEH_File::get_filename_from_filepath($full_file_path), EEH_File::get_file_extension($full_file_path))) {
348
+			// load WP_Filesystem and set file permissions
349
+			$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
350
+			return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
351
+		}
352
+		return '';
353
+	}
354
+
355
+
356
+
357
+	/**
358
+	 * write_file
359
+	 * @param string $full_file_path
360
+	 * @param string $file_contents - the content to be written to the file
361
+	 * @param string $file_type
362
+	 * @throws EE_Error if filesystem credentials are required
363
+	 * @return bool
364
+	 */
365
+	public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '')
366
+	{
367
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
368
+		$file_type = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
369
+		$folder = EEH_File::remove_filename_from_filepath($full_file_path);
370
+		if (! EEH_File::verify_is_writable($folder, 'folder')) {
371
+			if (defined('WP_DEBUG') && WP_DEBUG) {
372
+				$msg = sprintf(esc_html__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'), $file_type, $full_file_path);
373
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
374
+				throw new EE_Error($msg);
375
+			}
376
+			return false;
377
+		}
378
+		// load WP_Filesystem and set file permissions
379
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
380
+		// write the file
381
+		if (! $wp_filesystem->put_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path), $file_contents)) {
382
+			if (defined('WP_DEBUG') && WP_DEBUG) {
383
+				$msg = sprintf(esc_html__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'), $file_type, $full_file_path);
384
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
385
+				throw new EE_Error($msg);
386
+			}
387
+			return false;
388
+		}
389
+		return true;
390
+	}
391
+
392
+	/**
393
+	 * Wrapper for WP_Filesystem_Base::delete
394
+	 *
395
+	 * @param string $filepath
396
+	 * @param boolean $recursive
397
+	 * @param boolean|string $type 'd' for directory, 'f' for file
398
+	 * @throws EE_Error if filesystem credentials are required
399
+	 * @return boolean
400
+	 */
401
+	public static function delete($filepath, $recursive = false, $type = false)
402
+	{
403
+		$wp_filesystem = EEH_File::_get_wp_filesystem();
404
+		return $wp_filesystem->delete($filepath, $recursive, $type) ? true : false;
405
+	}
406
+
407
+
408
+
409
+	/**
410
+	 * exists
411
+	 * checks if a file exists using the WP filesystem
412
+	 * @param string $full_file_path
413
+	 * @throws EE_Error if filesystem credentials are required
414
+	 * @return bool
415
+	 */
416
+	public static function exists($full_file_path = '')
417
+	{
418
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
419
+		return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path)) ? true : false;
420
+	}
421
+
422
+
423
+
424
+	/**
425
+	 * is_readable
426
+	 * checks if a file is_readable using the WP filesystem
427
+	 *
428
+	 * @param string $full_file_path
429
+	 * @throws EE_Error if filesystem credentials are required
430
+	 * @return bool
431
+	 */
432
+	public static function is_readable($full_file_path = '')
433
+	{
434
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
435
+		if ($wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
436
+			return true;
437
+		} else {
438
+			return false;
439
+		}
440
+	}
441
+
442
+
443
+
444
+	/**
445
+	 * remove_filename_from_filepath
446
+	 * given a full path to a file including the filename itself, this removes  the filename and returns the path, up to, but NOT including the filename OR slash
447
+	 *
448
+	 * @param string $full_file_path
449
+	 * @return string
450
+	 */
451
+	public static function remove_filename_from_filepath($full_file_path = '')
452
+	{
453
+		return pathinfo($full_file_path, PATHINFO_DIRNAME);
454
+	}
455
+
456
+
457
+	/**
458
+	 * get_filename_from_filepath. Arguably the same as basename()
459
+	 *
460
+	 * @param string $full_file_path
461
+	 * @return string
462
+	 */
463
+	public static function get_filename_from_filepath($full_file_path = '')
464
+	{
465
+		return pathinfo($full_file_path, PATHINFO_BASENAME);
466
+	}
467
+
468
+
469
+	/**
470
+	 * get_file_extension
471
+	 *
472
+	 * @param string $full_file_path
473
+	 * @return string
474
+	 */
475
+	public static function get_file_extension($full_file_path = '')
476
+	{
477
+		return pathinfo($full_file_path, PATHINFO_EXTENSION);
478
+	}
479
+
480
+
481
+
482
+	/**
483
+	 * add_htaccess_deny_from_all so the webserver cannot access this folder
484
+	 * @param string $folder
485
+	 * @throws EE_Error if filesystem credentials are required
486
+	 * @return bool
487
+	 */
488
+	public static function add_htaccess_deny_from_all($folder = '')
489
+	{
490
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
491
+		if (! EEH_File::exists($folder . '.htaccess')) {
492
+			if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
493
+				return false;
494
+			}
495
+		}
496
+
497
+		return true;
498
+	}
499
+
500
+	/**
501
+	 * Adds an index file to this folder, so folks can't list all the file's contents
502
+	 * @param string $folder
503
+	 * @throws EE_Error if filesystem credentials are required
504
+	 * @return boolean
505
+	 */
506
+	public static function add_index_file($folder)
507
+	{
508
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
509
+		if (! EEH_File::exists($folder . 'index.php')) {
510
+			if (! EEH_File::write_to_file($folder . 'index.php', 'You are not permitted to read from this folder', '.php')) {
511
+				return false;
512
+			}
513
+		}
514
+		return true;
515
+	}
516
+
517
+
518
+
519
+	/**
520
+	 * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php),
521
+	 * extract that classname.
522
+	 * @param string $file_path
523
+	 * @return string
524
+	 */
525
+	public static function get_classname_from_filepath_with_standard_filename($file_path)
526
+	{
527
+		// extract file from path
528
+		$filename = basename($file_path);
529
+		// now remove the first period and everything after
530
+		$pos_of_first_period = strpos($filename, '.');
531
+		return substr($filename, 0, $pos_of_first_period);
532
+	}
533
+
534
+
535
+
536
+	/**
537
+	 * standardise_directory_separators
538
+	 *  convert all directory separators in a file path.
539
+	 * @param string $file_path
540
+	 * @return string
541
+	 */
542
+	public static function standardise_directory_separators($file_path)
543
+	{
544
+		return str_replace(array( '\\', '/' ), '/', $file_path);
545
+	}
546
+
547
+
548
+
549
+	/**
550
+	 * end_with_directory_separator
551
+	 *  ensures that file path ends with '/'
552
+	 * @param string $file_path
553
+	 * @return string
554
+	 */
555
+	public static function end_with_directory_separator($file_path)
556
+	{
557
+		return rtrim($file_path, '/\\') . '/';
558
+	}
559
+
560
+
561
+
562
+	/**
563
+	 * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators
564
+	 * @param $file_path
565
+	 * @return string
566
+	 */
567
+	public static function standardise_and_end_with_directory_separator($file_path)
568
+	{
569
+		return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
570
+	}
571
+
572
+
573
+
574
+	/**
575
+	 * takes the folder name (with or without trailing slash) and finds the files it in,
576
+	 * and what the class's name inside of each should be.
577
+	 * @param array $folder_paths
578
+	 * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically;
579
+	 *      if FALSE (Default), returned array will be indexed by the filenames minus extensions.
580
+	 *      Set it TRUE if you know there are files in the directory with the same name but different extensions
581
+	 * @throws EE_Error if filesystem credentials are required
582
+	 * @return array if $index_numerically == TRUE keys are numeric ,
583
+	 *      if $index_numerically == FALSE (Default) keys are what the class names SHOULD be;
584
+	 *       and values are their filepaths
585
+	 */
586
+	public static function get_contents_of_folders($folder_paths = array(), $index_numerically = false)
587
+	{
588
+		$class_to_folder_path = array();
589
+		foreach ($folder_paths as $folder_path) {
590
+			$folder_path = self::standardise_and_end_with_directory_separator($folder_path);
591
+			// load WP_Filesystem and set file permissions
592
+			$files_in_folder = glob($folder_path . '*.php');
593
+			$class_to_folder_path = array();
594
+			if ($files_in_folder) {
595
+				foreach ($files_in_folder as $file_path) {
596
+					// only add files, not folders
597
+					if (! is_dir($file_path)) {
598
+						if ($index_numerically) {
599
+							$class_to_folder_path[] = $file_path;
600
+						} else {
601
+							$classname = self::get_classname_from_filepath_with_standard_filename($file_path);
602
+							$class_to_folder_path[ $classname ] = $file_path;
603
+						}
604
+					}
605
+				}
606
+			}
607
+		}
608
+		return $class_to_folder_path;
609
+	}
610
+
611
+
612
+
613
+	/**
614
+	 * Copies a file. Mostly a wrapper of WP_Filesystem::copy
615
+	 * @param string $source_file
616
+	 * @param string $destination_file
617
+	 * @param boolean $overwrite
618
+	 * @throws EE_Error if filesystem credentials are required
619
+	 * @return boolean success
620
+	 */
621
+	public static function copy($source_file, $destination_file, $overwrite = false)
622
+	{
623
+		$full_source_path = EEH_File::standardise_directory_separators($source_file);
624
+		if (! EEH_File::exists($full_source_path)) {
625
+			if (defined('WP_DEBUG') && WP_DEBUG) {
626
+				$msg = sprintf(esc_html__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'), $full_source_path);
627
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
628
+				throw new EE_Error($msg);
629
+			}
630
+			return false;
631
+		}
632
+
633
+		$full_dest_path = EEH_File::standardise_directory_separators($destination_file);
634
+		$folder = EEH_File::remove_filename_from_filepath($full_dest_path);
635
+		EEH_File::ensure_folder_exists_and_is_writable($folder);
636
+		if (! EEH_File::verify_is_writable($folder, 'folder')) {
637
+			if (defined('WP_DEBUG') && WP_DEBUG) {
638
+				$msg = sprintf(esc_html__('The file located at "%2$s" is not writable.', 'event_espresso'), $full_dest_path);
639
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
640
+				throw new EE_Error($msg);
641
+			}
642
+			return false;
643
+		}
644
+
645
+		// load WP_Filesystem and set file permissions
646
+		$wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
647
+		// write the file
648
+		if (
649
+			! $wp_filesystem->copy(
650
+				EEH_File::convert_local_filepath_to_remote_filepath($full_source_path),
651
+				EEH_File::convert_local_filepath_to_remote_filepath($full_dest_path),
652
+				$overwrite
653
+			)
654
+		) {
655
+			if (defined('WP_DEBUG') && WP_DEBUG) {
656
+				$msg = sprintf(esc_html__('Attempted writing to file %1$s, but could not, probably because of permissions issues', 'event_espresso'), $full_source_path);
657
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path, 'f');
658
+				throw new EE_Error($msg);
659
+			}
660
+			return false;
661
+		}
662
+		return true;
663
+	}
664
+
665
+	/**
666
+	 * Reports whether or not the filepath is in the EE uploads folder or not
667
+	 * @param string $filepath
668
+	 * @return boolean
669
+	 */
670
+	public static function is_in_uploads_folder($filepath)
671
+	{
672
+		$uploads = wp_upload_dir();
673
+		return strpos($filepath, $uploads['basedir']) === 0 ? true : false;
674
+	}
675
+
676
+	/**
677
+	 * Given a "local" filepath (what you probably thought was the only filepath),
678
+	 * converts it into a "remote" filepath (the filepath the currently-in-use
679
+	 * $wp_filesystem needs to use access the folder or file).
680
+	 * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
681
+	 * @param WP_Filesystem_Base $wp_filesystem we aren't initially sure which one
682
+	 * is in use, so you need to provide it
683
+	 * @param string $local_filepath the filepath to the folder/file locally
684
+	 * @throws EE_Error if filesystem credentials are required
685
+	 * @return string the remote filepath (eg the filepath the filesystem method, eg
686
+	 * ftp or ssh, will use to access the folder
687
+	 */
688
+	public static function convert_local_filepath_to_remote_filepath($local_filepath)
689
+	{
690
+		$wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
691
+		return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
692
+	}
693 693
 }
Please login to merge, or discard this patch.
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.