Completed
Branch new-addon-api (b7bde0)
by
unknown
18:29 queued 08:41
created
core/helpers/EEH_URL.helper.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -241,7 +241,7 @@
 block discarded – undo
241 241
     /**
242 242
      * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
243 243
      *
244
-     * @param array $query_parameters An array of query_parameters to remove from the current url.
244
+     * @param string[] $query_parameters An array of query_parameters to remove from the current url.
245 245
      * @return string
246 246
      * @since 4.9.46.rc.029
247 247
      */
Please login to merge, or discard this patch.
Indentation   +252 added lines, -252 removed lines patch added patch discarded remove patch
@@ -12,278 +12,278 @@
 block discarded – undo
12 12
 class EEH_URL
13 13
 {
14 14
 
15
-    /**
16
-     * _add_query_arg
17
-     * adds nonce to array of arguments then calls WP add_query_arg function
18
-     *
19
-     * @param array  $args
20
-     * @param string $url
21
-     * @param bool   $exclude_nonce If true then the nonce will be excluded from the generated url.
22
-     * @return string
23
-     */
24
-    public static function add_query_args_and_nonce(
25
-        array $args = [],
26
-        string $url = '',
27
-        bool $exclude_nonce = false
28
-    ): string {
29
-        // check that an action exists and add nonce
30
-        if (! $exclude_nonce) {
31
-            if (isset($args['action']) && ! empty($args['action'])) {
32
-                $args = array_merge(
33
-                    $args,
34
-                    [
35
-                        $args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce'),
36
-                    ]
37
-                );
38
-            } else {
39
-                $args = array_merge(
40
-                    $args,
41
-                    [
42
-                        'action'        => 'default',
43
-                        'default_nonce' => wp_create_nonce('default_nonce'),
44
-                    ]
45
-                );
46
-            }
47
-        }
15
+	/**
16
+	 * _add_query_arg
17
+	 * adds nonce to array of arguments then calls WP add_query_arg function
18
+	 *
19
+	 * @param array  $args
20
+	 * @param string $url
21
+	 * @param bool   $exclude_nonce If true then the nonce will be excluded from the generated url.
22
+	 * @return string
23
+	 */
24
+	public static function add_query_args_and_nonce(
25
+		array $args = [],
26
+		string $url = '',
27
+		bool $exclude_nonce = false
28
+	): string {
29
+		// check that an action exists and add nonce
30
+		if (! $exclude_nonce) {
31
+			if (isset($args['action']) && ! empty($args['action'])) {
32
+				$args = array_merge(
33
+					$args,
34
+					[
35
+						$args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce'),
36
+					]
37
+				);
38
+			} else {
39
+				$args = array_merge(
40
+					$args,
41
+					[
42
+						'action'        => 'default',
43
+						'default_nonce' => wp_create_nonce('default_nonce'),
44
+					]
45
+				);
46
+			}
47
+		}
48 48
 
49
-        // finally, let's always add a return address (if present) :)
50
-        $args = ! empty($_REQUEST['action']) && ! isset($_REQUEST['return'])
51
-            ? array_merge($args, ['return' => $_REQUEST['action']])
52
-            : $args;
49
+		// finally, let's always add a return address (if present) :)
50
+		$args = ! empty($_REQUEST['action']) && ! isset($_REQUEST['return'])
51
+			? array_merge($args, ['return' => $_REQUEST['action']])
52
+			: $args;
53 53
 
54
-        return add_query_arg($args, $url);
55
-    }
54
+		return add_query_arg($args, $url);
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * Returns whether not the remote file exists.
60
-     * Checking via GET because HEAD requests are blocked on some server configurations.
61
-     *
62
-     * @param string $url
63
-     * @param array  $args the arguments that should be passed through to the wp_remote_request call.
64
-     * @return boolean
65
-     */
66
-    public static function remote_file_exists(string $url, array $args = []): bool
67
-    {
68
-        $results = wp_remote_request(
69
-            $url,
70
-            array_merge(
71
-                [
72
-                    'method'      => 'GET',
73
-                    'redirection' => 1,
74
-                ],
75
-                $args
76
-            )
77
-        );
78
-        if (! $results instanceof WP_Error
79
-            && isset($results['response'])
80
-            && isset($results['response']['code'])
81
-            && $results['response']['code'] == '200'
82
-        ) {
83
-            return true;
84
-        } else {
85
-            return false;
86
-        }
87
-    }
58
+	/**
59
+	 * Returns whether not the remote file exists.
60
+	 * Checking via GET because HEAD requests are blocked on some server configurations.
61
+	 *
62
+	 * @param string $url
63
+	 * @param array  $args the arguments that should be passed through to the wp_remote_request call.
64
+	 * @return boolean
65
+	 */
66
+	public static function remote_file_exists(string $url, array $args = []): bool
67
+	{
68
+		$results = wp_remote_request(
69
+			$url,
70
+			array_merge(
71
+				[
72
+					'method'      => 'GET',
73
+					'redirection' => 1,
74
+				],
75
+				$args
76
+			)
77
+		);
78
+		if (! $results instanceof WP_Error
79
+			&& isset($results['response'])
80
+			&& isset($results['response']['code'])
81
+			&& $results['response']['code'] == '200'
82
+		) {
83
+			return true;
84
+		} else {
85
+			return false;
86
+		}
87
+	}
88 88
 
89 89
 
90
-    /**
91
-     * refactor_url
92
-     * primarily used for removing the query string from a URL
93
-     *
94
-     * @param string $url
95
-     * @param bool   $remove_query  - TRUE (default) will strip off any URL params, ie: ?this=1&that=2
96
-     * @param bool   $base_url_only - TRUE will only return the scheme and host with no other parameters
97
-     * @return string
98
-     */
99
-    public static function refactor_url(
100
-        string $url = '',
101
-        bool $remove_query = true,
102
-        bool $base_url_only = false
103
-    ): string {
104
-        // break apart incoming URL
105
-        $url_bits = parse_url($url);
106
-        // HTTP or HTTPS ?
107
-        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'http://';
108
-        // domain
109
-        $host = isset($url_bits['host']) ? $url_bits['host'] : '';
110
-        // if only the base URL is requested, then return that now
111
-        if ($base_url_only) {
112
-            return $scheme . $host;
113
-        }
114
-        $port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
115
-        $user = isset($url_bits['user']) ? $url_bits['user'] : '';
116
-        $pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
117
-        $pass = ($user || $pass) ? $pass . '@' : '';
118
-        $path = isset($url_bits['path']) ? $url_bits['path'] : '';
119
-        // if the query string is not required, then return what we have so far
120
-        if ($remove_query) {
121
-            return $scheme . $user . $pass . $host . $port . $path;
122
-        }
123
-        $query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
124
-        $fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
125
-        return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
126
-    }
90
+	/**
91
+	 * refactor_url
92
+	 * primarily used for removing the query string from a URL
93
+	 *
94
+	 * @param string $url
95
+	 * @param bool   $remove_query  - TRUE (default) will strip off any URL params, ie: ?this=1&that=2
96
+	 * @param bool   $base_url_only - TRUE will only return the scheme and host with no other parameters
97
+	 * @return string
98
+	 */
99
+	public static function refactor_url(
100
+		string $url = '',
101
+		bool $remove_query = true,
102
+		bool $base_url_only = false
103
+	): string {
104
+		// break apart incoming URL
105
+		$url_bits = parse_url($url);
106
+		// HTTP or HTTPS ?
107
+		$scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'http://';
108
+		// domain
109
+		$host = isset($url_bits['host']) ? $url_bits['host'] : '';
110
+		// if only the base URL is requested, then return that now
111
+		if ($base_url_only) {
112
+			return $scheme . $host;
113
+		}
114
+		$port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
115
+		$user = isset($url_bits['user']) ? $url_bits['user'] : '';
116
+		$pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
117
+		$pass = ($user || $pass) ? $pass . '@' : '';
118
+		$path = isset($url_bits['path']) ? $url_bits['path'] : '';
119
+		// if the query string is not required, then return what we have so far
120
+		if ($remove_query) {
121
+			return $scheme . $user . $pass . $host . $port . $path;
122
+		}
123
+		$query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
124
+		$fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
125
+		return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
126
+	}
127 127
 
128 128
 
129
-    /**
130
-     * get_query_string
131
-     * returns just the query string from a URL, formatted by default into an array of key value pairs
132
-     *
133
-     * @param string $url
134
-     * @param bool   $as_array TRUE (default) will return query params as an array of key value pairs, FALSE will
135
-     *                         simply return the query string
136
-     * @return string|array
137
-     */
138
-    public static function get_query_string(string $url = '', bool $as_array = true)
139
-    {
140
-        // decode, then break apart incoming URL
141
-        $url_bits = parse_url(html_entity_decode($url));
142
-        // grab query string from URL
143
-        $query = isset($url_bits['query']) ? $url_bits['query'] : '';
144
-        // if we don't want the query string formatted into an array of key => value pairs, then just return it as is
145
-        if (! $as_array) {
146
-            return $query;
147
-        }
148
-        // if no query string exists then just return an empty array now
149
-        if (empty($query)) {
150
-            return [];
151
-        }
152
-        // empty array to hold results
153
-        $query_params = [];
154
-        // now break apart the query string into separate params
155
-        $query = explode('&', $query);
156
-        // loop thru our query params
157
-        foreach ($query as $query_args) {
158
-            // break apart the key value pairs
159
-            $query_args = explode('=', $query_args);
160
-            // and add to our results array
161
-            $query_params[ $query_args[0] ] = $query_args[1];
162
-        }
163
-        return $query_params;
164
-    }
129
+	/**
130
+	 * get_query_string
131
+	 * returns just the query string from a URL, formatted by default into an array of key value pairs
132
+	 *
133
+	 * @param string $url
134
+	 * @param bool   $as_array TRUE (default) will return query params as an array of key value pairs, FALSE will
135
+	 *                         simply return the query string
136
+	 * @return string|array
137
+	 */
138
+	public static function get_query_string(string $url = '', bool $as_array = true)
139
+	{
140
+		// decode, then break apart incoming URL
141
+		$url_bits = parse_url(html_entity_decode($url));
142
+		// grab query string from URL
143
+		$query = isset($url_bits['query']) ? $url_bits['query'] : '';
144
+		// if we don't want the query string formatted into an array of key => value pairs, then just return it as is
145
+		if (! $as_array) {
146
+			return $query;
147
+		}
148
+		// if no query string exists then just return an empty array now
149
+		if (empty($query)) {
150
+			return [];
151
+		}
152
+		// empty array to hold results
153
+		$query_params = [];
154
+		// now break apart the query string into separate params
155
+		$query = explode('&', $query);
156
+		// loop thru our query params
157
+		foreach ($query as $query_args) {
158
+			// break apart the key value pairs
159
+			$query_args = explode('=', $query_args);
160
+			// and add to our results array
161
+			$query_params[ $query_args[0] ] = $query_args[1];
162
+		}
163
+		return $query_params;
164
+	}
165 165
 
166 166
 
167
-    /**
168
-     * prevent_prefetching
169
-     *
170
-     * @return void
171
-     */
172
-    public static function prevent_prefetching()
173
-    {
174
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes
175
-        // with the registration process
176
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
177
-    }
167
+	/**
168
+	 * prevent_prefetching
169
+	 *
170
+	 * @return void
171
+	 */
172
+	public static function prevent_prefetching()
173
+	{
174
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes
175
+		// with the registration process
176
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
177
+	}
178 178
 
179 179
 
180
-    /**
181
-     * This generates a unique site-specific string.
182
-     * An example usage for this string would be to save as a unique identifier for a record in the db for usage in
183
-     * urls.
184
-     *
185
-     * @param string $prefix Use this to prefix the string with something.
186
-     * @return string
187
-     */
188
-    public static function generate_unique_token(string $prefix = ''): string
189
-    {
190
-        $token = md5(uniqid() . mt_rand());
191
-        return $prefix ? $prefix . '_' . $token : $token;
192
-    }
180
+	/**
181
+	 * This generates a unique site-specific string.
182
+	 * An example usage for this string would be to save as a unique identifier for a record in the db for usage in
183
+	 * urls.
184
+	 *
185
+	 * @param string $prefix Use this to prefix the string with something.
186
+	 * @return string
187
+	 */
188
+	public static function generate_unique_token(string $prefix = ''): string
189
+	{
190
+		$token = md5(uniqid() . mt_rand());
191
+		return $prefix ? $prefix . '_' . $token : $token;
192
+	}
193 193
 
194 194
 
195
-    /**
196
-     * filter_input_server_url
197
-     * uses filter_input() to sanitize one of the INPUT_SERVER URL values
198
-     * but adds a backup in case filter_input() returns nothing, which can erringly happen on some servers
199
-     *
200
-     * @param string $server_variable
201
-     * @return string
202
-     */
203
-    public static function filter_input_server_url(string $server_variable = 'REQUEST_URI'): string
204
-    {
205
-        $URL              = '';
206
-        $server_variables = [
207
-            'REQUEST_URI' => 1,
208
-            'HTTP_HOST'   => 1,
209
-            'PHP_SELF'    => 1,
210
-        ];
211
-        $server_variable  = strtoupper($server_variable);
212
-        // whitelist INPUT_SERVER var
213
-        if (isset($server_variables[ $server_variable ])) {
214
-            $URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
215
-            if (empty($URL)) {
216
-                // fallback sanitization if the above fails
217
-                $URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
218
-            }
219
-        }
220
-        return $URL;
221
-    }
195
+	/**
196
+	 * filter_input_server_url
197
+	 * uses filter_input() to sanitize one of the INPUT_SERVER URL values
198
+	 * but adds a backup in case filter_input() returns nothing, which can erringly happen on some servers
199
+	 *
200
+	 * @param string $server_variable
201
+	 * @return string
202
+	 */
203
+	public static function filter_input_server_url(string $server_variable = 'REQUEST_URI'): string
204
+	{
205
+		$URL              = '';
206
+		$server_variables = [
207
+			'REQUEST_URI' => 1,
208
+			'HTTP_HOST'   => 1,
209
+			'PHP_SELF'    => 1,
210
+		];
211
+		$server_variable  = strtoupper($server_variable);
212
+		// whitelist INPUT_SERVER var
213
+		if (isset($server_variables[ $server_variable ])) {
214
+			$URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
215
+			if (empty($URL)) {
216
+				// fallback sanitization if the above fails
217
+				$URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
218
+			}
219
+		}
220
+		return $URL;
221
+	}
222 222
 
223 223
 
224
-    /**
225
-     * Gets the current page's full URL.
226
-     *
227
-     * @return string
228
-     */
229
-    public static function current_url(): string
230
-    {
231
-        $url = '';
232
-        if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
233
-            $url = is_ssl() ? 'https://' : 'http://';
234
-            $url .= EEH_URL::filter_input_server_url('HTTP_HOST');
235
-            $url .= EEH_URL::filter_input_server_url('REQUEST_URI');
236
-        }
237
-        return $url;
238
-    }
224
+	/**
225
+	 * Gets the current page's full URL.
226
+	 *
227
+	 * @return string
228
+	 */
229
+	public static function current_url(): string
230
+	{
231
+		$url = '';
232
+		if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
233
+			$url = is_ssl() ? 'https://' : 'http://';
234
+			$url .= EEH_URL::filter_input_server_url('HTTP_HOST');
235
+			$url .= EEH_URL::filter_input_server_url('REQUEST_URI');
236
+		}
237
+		return $url;
238
+	}
239 239
 
240 240
 
241
-    /**
242
-     * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
243
-     *
244
-     * @param array $query_parameters An array of query_parameters to remove from the current url.
245
-     * @return string
246
-     * @since 4.9.46.rc.029
247
-     */
248
-    public static function current_url_without_query_paramaters(array $query_parameters): string
249
-    {
250
-        return remove_query_arg($query_parameters, EEH_URL::current_url());
251
-    }
241
+	/**
242
+	 * Identical in functionality to EEH_current_url except it removes any provided query_parameters from it.
243
+	 *
244
+	 * @param array $query_parameters An array of query_parameters to remove from the current url.
245
+	 * @return string
246
+	 * @since 4.9.46.rc.029
247
+	 */
248
+	public static function current_url_without_query_paramaters(array $query_parameters): string
249
+	{
250
+		return remove_query_arg($query_parameters, EEH_URL::current_url());
251
+	}
252 252
 
253 253
 
254
-    /**
255
-     * @param string $location
256
-     * @param int    $status
257
-     * @param string $exit_notice
258
-     */
259
-    public static function safeRedirectAndExit(string $location, int $status = 302, string $exit_notice = '')
260
-    {
261
-        EE_Error::get_notices(false, true);
262
-        wp_safe_redirect($location, $status);
263
-        exit($exit_notice);
264
-    }
254
+	/**
255
+	 * @param string $location
256
+	 * @param int    $status
257
+	 * @param string $exit_notice
258
+	 */
259
+	public static function safeRedirectAndExit(string $location, int $status = 302, string $exit_notice = '')
260
+	{
261
+		EE_Error::get_notices(false, true);
262
+		wp_safe_redirect($location, $status);
263
+		exit($exit_notice);
264
+	}
265 265
 
266 266
 
267
-    /**
268
-     * Slugifies text for usage in a URL.
269
-     *
270
-     * Currently, this isn't just calling `sanitize_title()` on it, because that percent-encodes unicode characters,
271
-     * and WordPress chokes on them when used as CPT and custom taxonomy slugs.
272
-     *
273
-     * @param string $text
274
-     * @param string $fallback
275
-     * @return string which can be used in a URL
276
-     * @since 4.9.66.p
277
-     */
278
-    public static function slugify(string $text, string $fallback): string
279
-    {
280
-        // url decode after sanitizing title to restore unicode characters,
281
-        // see https://github.com/eventespresso/event-espresso-core/issues/575
282
-        return urldecode(
283
-            sanitize_title(
284
-                $text,
285
-                $fallback
286
-            )
287
-        );
288
-    }
267
+	/**
268
+	 * Slugifies text for usage in a URL.
269
+	 *
270
+	 * Currently, this isn't just calling `sanitize_title()` on it, because that percent-encodes unicode characters,
271
+	 * and WordPress chokes on them when used as CPT and custom taxonomy slugs.
272
+	 *
273
+	 * @param string $text
274
+	 * @param string $fallback
275
+	 * @return string which can be used in a URL
276
+	 * @since 4.9.66.p
277
+	 */
278
+	public static function slugify(string $text, string $fallback): string
279
+	{
280
+		// url decode after sanitizing title to restore unicode characters,
281
+		// see https://github.com/eventespresso/event-espresso-core/issues/575
282
+		return urldecode(
283
+			sanitize_title(
284
+				$text,
285
+				$fallback
286
+			)
287
+		);
288
+	}
289 289
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -27,12 +27,12 @@  discard block
 block discarded – undo
27 27
         bool $exclude_nonce = false
28 28
     ): string {
29 29
         // check that an action exists and add nonce
30
-        if (! $exclude_nonce) {
30
+        if ( ! $exclude_nonce) {
31 31
             if (isset($args['action']) && ! empty($args['action'])) {
32 32
                 $args = array_merge(
33 33
                     $args,
34 34
                     [
35
-                        $args['action'] . '_nonce' => wp_create_nonce($args['action'] . '_nonce'),
35
+                        $args['action'].'_nonce' => wp_create_nonce($args['action'].'_nonce'),
36 36
                     ]
37 37
                 );
38 38
             } else {
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
                 $args
76 76
             )
77 77
         );
78
-        if (! $results instanceof WP_Error
78
+        if ( ! $results instanceof WP_Error
79 79
             && isset($results['response'])
80 80
             && isset($results['response']['code'])
81 81
             && $results['response']['code'] == '200'
@@ -104,25 +104,25 @@  discard block
 block discarded – undo
104 104
         // break apart incoming URL
105 105
         $url_bits = parse_url($url);
106 106
         // HTTP or HTTPS ?
107
-        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'] . '://' : 'http://';
107
+        $scheme = isset($url_bits['scheme']) ? $url_bits['scheme'].'://' : 'http://';
108 108
         // domain
109 109
         $host = isset($url_bits['host']) ? $url_bits['host'] : '';
110 110
         // if only the base URL is requested, then return that now
111 111
         if ($base_url_only) {
112
-            return $scheme . $host;
112
+            return $scheme.$host;
113 113
         }
114
-        $port = isset($url_bits['port']) ? ':' . $url_bits['port'] : '';
114
+        $port = isset($url_bits['port']) ? ':'.$url_bits['port'] : '';
115 115
         $user = isset($url_bits['user']) ? $url_bits['user'] : '';
116
-        $pass = isset($url_bits['pass']) ? ':' . $url_bits['pass'] : '';
117
-        $pass = ($user || $pass) ? $pass . '@' : '';
116
+        $pass = isset($url_bits['pass']) ? ':'.$url_bits['pass'] : '';
117
+        $pass = ($user || $pass) ? $pass.'@' : '';
118 118
         $path = isset($url_bits['path']) ? $url_bits['path'] : '';
119 119
         // if the query string is not required, then return what we have so far
120 120
         if ($remove_query) {
121
-            return $scheme . $user . $pass . $host . $port . $path;
121
+            return $scheme.$user.$pass.$host.$port.$path;
122 122
         }
123
-        $query    = isset($url_bits['query']) ? '?' . $url_bits['query'] : '';
124
-        $fragment = isset($url_bits['fragment']) ? '#' . $url_bits['fragment'] : '';
125
-        return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
123
+        $query    = isset($url_bits['query']) ? '?'.$url_bits['query'] : '';
124
+        $fragment = isset($url_bits['fragment']) ? '#'.$url_bits['fragment'] : '';
125
+        return $scheme.$user.$pass.$host.$port.$path.$query.$fragment;
126 126
     }
127 127
 
128 128
 
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
         // grab query string from URL
143 143
         $query = isset($url_bits['query']) ? $url_bits['query'] : '';
144 144
         // if we don't want the query string formatted into an array of key => value pairs, then just return it as is
145
-        if (! $as_array) {
145
+        if ( ! $as_array) {
146 146
             return $query;
147 147
         }
148 148
         // if no query string exists then just return an empty array now
@@ -158,7 +158,7 @@  discard block
 block discarded – undo
158 158
             // break apart the key value pairs
159 159
             $query_args = explode('=', $query_args);
160 160
             // and add to our results array
161
-            $query_params[ $query_args[0] ] = $query_args[1];
161
+            $query_params[$query_args[0]] = $query_args[1];
162 162
         }
163 163
         return $query_params;
164 164
     }
@@ -187,8 +187,8 @@  discard block
 block discarded – undo
187 187
      */
188 188
     public static function generate_unique_token(string $prefix = ''): string
189 189
     {
190
-        $token = md5(uniqid() . mt_rand());
191
-        return $prefix ? $prefix . '_' . $token : $token;
190
+        $token = md5(uniqid().mt_rand());
191
+        return $prefix ? $prefix.'_'.$token : $token;
192 192
     }
193 193
 
194 194
 
@@ -208,13 +208,13 @@  discard block
 block discarded – undo
208 208
             'HTTP_HOST'   => 1,
209 209
             'PHP_SELF'    => 1,
210 210
         ];
211
-        $server_variable  = strtoupper($server_variable);
211
+        $server_variable = strtoupper($server_variable);
212 212
         // whitelist INPUT_SERVER var
213
-        if (isset($server_variables[ $server_variable ])) {
213
+        if (isset($server_variables[$server_variable])) {
214 214
             $URL = filter_input(INPUT_SERVER, $server_variable, FILTER_SANITIZE_URL, FILTER_NULL_ON_FAILURE);
215 215
             if (empty($URL)) {
216 216
                 // fallback sanitization if the above fails
217
-                $URL = wp_sanitize_redirect($_SERVER[ $server_variable ]);
217
+                $URL = wp_sanitize_redirect($_SERVER[$server_variable]);
218 218
             }
219 219
         }
220 220
         return $URL;
Please login to merge, or discard this patch.
core/libraries/plugin_api/EE_Register_CPT.lib.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -31,7 +31,7 @@
 block discarded – undo
31 31
      *                                        An array of required values for registering the cpts and taxonomies
32 32
      * @type array   $cpts                    {
33 33
      *                                        An array of cpts and their arguments.(short example below)
34
-     * @return void
34
+     * @return boolean
35 35
      * @throws  EE_Error
36 36
      * @see CustomPostTypeDefinitions::setDefinitions for a more complete example.
37 37
      *                                        'people' => array(
Please login to merge, or discard this patch.
Indentation   +229 added lines, -229 removed lines patch added patch discarded remove patch
@@ -13,256 +13,256 @@
 block discarded – undo
13 13
 class EE_Register_CPT implements EEI_Plugin_API
14 14
 {
15 15
 
16
-    /**
17
-     * Holds values for registered variations
18
-     *
19
-     * @since 4.5.0
20
-     *
21
-     * @var array[][][]
22
-     */
23
-    protected static $_registry = [];
16
+	/**
17
+	 * Holds values for registered variations
18
+	 *
19
+	 * @since 4.5.0
20
+	 *
21
+	 * @var array[][][]
22
+	 */
23
+	protected static $_registry = [];
24 24
 
25 25
 
26
-    /**
27
-     * Used to register new CPTs and Taxonomies.
28
-     *
29
-     * @param string $cpt_ref                 reference used for the addon registering cpts and cts
30
-     * @param array  $setup_args              {
31
-     *                                        An array of required values for registering the cpts and taxonomies
32
-     * @type array   $cpts                    {
33
-     *                                        An array of cpts and their arguments.(short example below)
34
-     * @return void
35
-     * @throws  EE_Error
36
-     * @see CustomPostTypeDefinitions::setDefinitions for a more complete example.
37
-     *                                        'people' => array(
38
-     *                                        'singular_name' => __('People', 'event_espresso'),
39
-     *                                        'plural_name' => __('People', 'event_espresso'),
40
-     *                                        'singular_slug' => __('people', 'event_espresso'),
41
-     *                                        'plural_slug' => __('peoples', 'event_espresso'),
42
-     *                                        'class_name' => 'EE_People'
43
-     *                                        )
44
-     *                                        },
45
-     * @type array   $cts                     {
46
-     *                                        An array of custom taxonomies and their arguments (short example below).
47
-     * @see CustomTaxonomyDefinitions::setTaxonomies() for a more complete example.
48
-     *                                        'espresso_people_type' => array(
49
-     *                                        'singular_name' => __('People Type', 'event_espresso'),
50
-     *                                        'plural_name' => __('People Types', 'event_espresso'),
51
-     *                                        'args' => array()
52
-     *                                        )
53
-     *                                        },
54
-     * @type array   $default_terms           {
55
-     *                                        An array of terms to set as the default for a given taxonomy and the
56
-     *                                        custom post types applied to.
57
-     *                                        'taxonomy_name' => array(
58
-     *                                        'term' => array( 'cpt_a_name', 'cpt_b_name' )
59
-     *                                        )
60
-     *                                        }
61
-     *                                        }
62
-     */
63
-    public static function register(string $cpt_ref = '', array $setup_args = []): bool
64
-    {
26
+	/**
27
+	 * Used to register new CPTs and Taxonomies.
28
+	 *
29
+	 * @param string $cpt_ref                 reference used for the addon registering cpts and cts
30
+	 * @param array  $setup_args              {
31
+	 *                                        An array of required values for registering the cpts and taxonomies
32
+	 * @type array   $cpts                    {
33
+	 *                                        An array of cpts and their arguments.(short example below)
34
+	 * @return void
35
+	 * @throws  EE_Error
36
+	 * @see CustomPostTypeDefinitions::setDefinitions for a more complete example.
37
+	 *                                        'people' => array(
38
+	 *                                        'singular_name' => __('People', 'event_espresso'),
39
+	 *                                        'plural_name' => __('People', 'event_espresso'),
40
+	 *                                        'singular_slug' => __('people', 'event_espresso'),
41
+	 *                                        'plural_slug' => __('peoples', 'event_espresso'),
42
+	 *                                        'class_name' => 'EE_People'
43
+	 *                                        )
44
+	 *                                        },
45
+	 * @type array   $cts                     {
46
+	 *                                        An array of custom taxonomies and their arguments (short example below).
47
+	 * @see CustomTaxonomyDefinitions::setTaxonomies() for a more complete example.
48
+	 *                                        'espresso_people_type' => array(
49
+	 *                                        'singular_name' => __('People Type', 'event_espresso'),
50
+	 *                                        'plural_name' => __('People Types', 'event_espresso'),
51
+	 *                                        'args' => array()
52
+	 *                                        )
53
+	 *                                        },
54
+	 * @type array   $default_terms           {
55
+	 *                                        An array of terms to set as the default for a given taxonomy and the
56
+	 *                                        custom post types applied to.
57
+	 *                                        'taxonomy_name' => array(
58
+	 *                                        'term' => array( 'cpt_a_name', 'cpt_b_name' )
59
+	 *                                        )
60
+	 *                                        }
61
+	 *                                        }
62
+	 */
63
+	public static function register(string $cpt_ref = '', array $setup_args = []): bool
64
+	{
65 65
 
66
-        // check for required params
67
-        if (empty($cpt_ref)) {
68
-            throw new EE_Error(
69
-                __(
70
-                    'In order to register custom post types and custom taxonomies, you must include a value to reference what had been registered',
71
-                    'event_espresso'
72
-                )
73
-            );
74
-        }
66
+		// check for required params
67
+		if (empty($cpt_ref)) {
68
+			throw new EE_Error(
69
+				__(
70
+					'In order to register custom post types and custom taxonomies, you must include a value to reference what had been registered',
71
+					'event_espresso'
72
+				)
73
+			);
74
+		}
75 75
 
76
-        if (! is_array($setup_args) || (empty($setup_args['cpts']) && empty($setup_args['cts']))) {
77
-            throw new EE_Error(
78
-                __(
79
-                    'In order to register custom post types or custom taxonomies, you must include an array containing either an array of custom post types to register (key "cpts"), an array of custom taxonomies ("cts") or both.',
80
-                    'event_espresso'
81
-                )
82
-            );
83
-        }
76
+		if (! is_array($setup_args) || (empty($setup_args['cpts']) && empty($setup_args['cts']))) {
77
+			throw new EE_Error(
78
+				__(
79
+					'In order to register custom post types or custom taxonomies, you must include an array containing either an array of custom post types to register (key "cpts"), an array of custom taxonomies ("cts") or both.',
80
+					'event_espresso'
81
+				)
82
+			);
83
+		}
84 84
 
85
-        // make sure we don't register twice
86
-        if (isset(self::$_registry[ $cpt_ref ])) {
87
-            return true;
88
-        }
85
+		// make sure we don't register twice
86
+		if (isset(self::$_registry[ $cpt_ref ])) {
87
+			return true;
88
+		}
89 89
 
90
-        // make sure cpt ref is unique.
91
-        if (isset(self::$_registry[ $cpt_ref ])) {
92
-            $cpt_ref = uniqid() . '_' . $cpt_ref;
93
-        }
90
+		// make sure cpt ref is unique.
91
+		if (isset(self::$_registry[ $cpt_ref ])) {
92
+			$cpt_ref = uniqid() . '_' . $cpt_ref;
93
+		}
94 94
 
95
-        // make sure this was called in the right place!
96
-        if (did_action('AHEE__EE_System__load_CPTs_and_session__complete')) {
97
-            EE_Error::doing_it_wrong(
98
-                __METHOD__,
99
-                sprintf(
100
-                    __(
101
-                        'EE_Register_CPT has been called and given a reference of "%s".  It may or may not work because it should be called on or before "AHEE__EE_System__load_CPTs_and_session__complete" action hook.',
102
-                        'event_espresso'
103
-                    ),
104
-                    $cpt_ref
105
-                ),
106
-                '4.5.0'
107
-            );
108
-        }
109
-        // validate incoming args
110
-        $validated = [
111
-            'cpts'          => isset($setup_args['cpts'])
112
-                ? (array) $setup_args['cpts']
113
-                : [],
114
-            'cts'           => isset($setup_args['cts'])
115
-                ? (array) $setup_args['cts']
116
-                : [],
117
-            'default_terms' => isset($setup_args['default_terms'])
118
-                ? (array) $setup_args['default_terms']
119
-                : [],
120
-        ];
95
+		// make sure this was called in the right place!
96
+		if (did_action('AHEE__EE_System__load_CPTs_and_session__complete')) {
97
+			EE_Error::doing_it_wrong(
98
+				__METHOD__,
99
+				sprintf(
100
+					__(
101
+						'EE_Register_CPT has been called and given a reference of "%s".  It may or may not work because it should be called on or before "AHEE__EE_System__load_CPTs_and_session__complete" action hook.',
102
+						'event_espresso'
103
+					),
104
+					$cpt_ref
105
+				),
106
+				'4.5.0'
107
+			);
108
+		}
109
+		// validate incoming args
110
+		$validated = [
111
+			'cpts'          => isset($setup_args['cpts'])
112
+				? (array) $setup_args['cpts']
113
+				: [],
114
+			'cts'           => isset($setup_args['cts'])
115
+				? (array) $setup_args['cts']
116
+				: [],
117
+			'default_terms' => isset($setup_args['default_terms'])
118
+				? (array) $setup_args['default_terms']
119
+				: [],
120
+		];
121 121
 
122
-        self::$_registry[ $cpt_ref ] = $validated;
122
+		self::$_registry[ $cpt_ref ] = $validated;
123 123
 
124
-        // hook into to cpt system
125
-        add_filter(
126
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
127
-            [__CLASS__, 'filterCustomPostTypeDefinitions'],
128
-            5
129
-        );
130
-        add_filter(
131
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
132
-            [__CLASS__, 'filterCustomTaxonomyDefinitions'],
133
-            5
134
-        );
135
-        add_action(
136
-            'AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end',
137
-            [__CLASS__, 'registerCustomTaxonomyTerm'],
138
-            5
139
-        );
140
-        return true;
141
-    }
124
+		// hook into to cpt system
125
+		add_filter(
126
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
127
+			[__CLASS__, 'filterCustomPostTypeDefinitions'],
128
+			5
129
+		);
130
+		add_filter(
131
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
132
+			[__CLASS__, 'filterCustomTaxonomyDefinitions'],
133
+			5
134
+		);
135
+		add_action(
136
+			'AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end',
137
+			[__CLASS__, 'registerCustomTaxonomyTerm'],
138
+			5
139
+		);
140
+		return true;
141
+	}
142 142
 
143 143
 
144
-    /**
145
-     * Callback for
146
-     * FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes
147
-     * that adds additional custom post types to be registered.
148
-     *
149
-     * @param array $custom_post_type_definitions array of cpts that are already set
150
-     * @return array new array of cpts and their registration information
151
-     */
152
-    public static function filterCustomPostTypeDefinitions(array $custom_post_type_definitions): array
153
-    {
154
-        foreach (self::$_registry as $registries) {
155
-            foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
156
-                $custom_post_type_definitions[ $cpt_name ] = $cpt_settings;
157
-            }
158
-        }
159
-        return $custom_post_type_definitions;
160
-    }
144
+	/**
145
+	 * Callback for
146
+	 * FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes
147
+	 * that adds additional custom post types to be registered.
148
+	 *
149
+	 * @param array $custom_post_type_definitions array of cpts that are already set
150
+	 * @return array new array of cpts and their registration information
151
+	 */
152
+	public static function filterCustomPostTypeDefinitions(array $custom_post_type_definitions): array
153
+	{
154
+		foreach (self::$_registry as $registries) {
155
+			foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
156
+				$custom_post_type_definitions[ $cpt_name ] = $cpt_settings;
157
+			}
158
+		}
159
+		return $custom_post_type_definitions;
160
+	}
161 161
 
162 162
 
163
-    /**
164
-     * Callback for
165
-     * FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies
166
-     * that adds additional custom taxonomies to be registered.
167
-     *
168
-     * @param array $custom_taxonomy_definitions array of cts that are already set.
169
-     * @return array new array of cts and their registration information.
170
-     */
171
-    public static function filterCustomTaxonomyDefinitions(array $custom_taxonomy_definitions): array
172
-    {
173
-        foreach (self::$_registry as $registries) {
174
-            foreach ($registries['cts'] as $ct_name => $ct_settings) {
175
-                $custom_taxonomy_definitions[ $ct_name ] = $ct_settings;
176
-            }
177
-        }
178
-        return $custom_taxonomy_definitions;
179
-    }
163
+	/**
164
+	 * Callback for
165
+	 * FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies
166
+	 * that adds additional custom taxonomies to be registered.
167
+	 *
168
+	 * @param array $custom_taxonomy_definitions array of cts that are already set.
169
+	 * @return array new array of cts and their registration information.
170
+	 */
171
+	public static function filterCustomTaxonomyDefinitions(array $custom_taxonomy_definitions): array
172
+	{
173
+		foreach (self::$_registry as $registries) {
174
+			foreach ($registries['cts'] as $ct_name => $ct_settings) {
175
+				$custom_taxonomy_definitions[ $ct_name ] = $ct_settings;
176
+			}
177
+		}
178
+		return $custom_taxonomy_definitions;
179
+	}
180 180
 
181 181
 
182
-    /**
183
-     * Callback for
184
-     * AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end
185
-     * which is used to set the default terms
186
-     *
187
-     * @param RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms
188
-     * @return void
189
-     */
190
-    public static function registerCustomTaxonomyTerm(RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms)
191
-    {
192
-        foreach (self::$_registry as $registries) {
193
-            foreach ($registries['default_terms'] as $taxonomy => $terms) {
194
-                foreach ($terms as $term => $cpts) {
195
-                    $register_custom_taxonomy_terms->registerCustomTaxonomyTerm(
196
-                        $taxonomy,
197
-                        $term,
198
-                        $cpts
199
-                    );
200
-                }
201
-            }
202
-        }
203
-    }
182
+	/**
183
+	 * Callback for
184
+	 * AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end
185
+	 * which is used to set the default terms
186
+	 *
187
+	 * @param RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms
188
+	 * @return void
189
+	 */
190
+	public static function registerCustomTaxonomyTerm(RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms)
191
+	{
192
+		foreach (self::$_registry as $registries) {
193
+			foreach ($registries['default_terms'] as $taxonomy => $terms) {
194
+				foreach ($terms as $term => $cpts) {
195
+					$register_custom_taxonomy_terms->registerCustomTaxonomyTerm(
196
+						$taxonomy,
197
+						$term,
198
+						$cpts
199
+					);
200
+				}
201
+			}
202
+		}
203
+	}
204 204
 
205 205
 
206
-    /**
207
-     * @param array $cpts array of cpts that are already set
208
-     * @return array new array of cpts and their registration information
209
-     * @deprecated 4.9.62.p
210
-     */
211
-    public static function filter_cpts(array $cpts): array
212
-    {
213
-        foreach (self::$_registry as $registries) {
214
-            foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
215
-                $cpts[ $cpt_name ] = $cpt_settings;
216
-            }
217
-        }
218
-        return $cpts;
219
-    }
206
+	/**
207
+	 * @param array $cpts array of cpts that are already set
208
+	 * @return array new array of cpts and their registration information
209
+	 * @deprecated 4.9.62.p
210
+	 */
211
+	public static function filter_cpts(array $cpts): array
212
+	{
213
+		foreach (self::$_registry as $registries) {
214
+			foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
215
+				$cpts[ $cpt_name ] = $cpt_settings;
216
+			}
217
+		}
218
+		return $cpts;
219
+	}
220 220
 
221 221
 
222
-    /**
223
-     * @param array $cts array of cts that are already set.
224
-     * @return array new array of cts and their registration information.
225
-     * @deprecated 4.9.62.p
226
-     */
227
-    public static function filter_cts(array $cts): array
228
-    {
229
-        foreach (self::$_registry as $registries) {
230
-            foreach ($registries['cts'] as $ct_name => $ct_settings) {
231
-                $cts[ $ct_name ] = $ct_settings;
232
-            }
233
-        }
234
-        return $cts;
235
-    }
222
+	/**
223
+	 * @param array $cts array of cts that are already set.
224
+	 * @return array new array of cts and their registration information.
225
+	 * @deprecated 4.9.62.p
226
+	 */
227
+	public static function filter_cts(array $cts): array
228
+	{
229
+		foreach (self::$_registry as $registries) {
230
+			foreach ($registries['cts'] as $ct_name => $ct_settings) {
231
+				$cts[ $ct_name ] = $ct_settings;
232
+			}
233
+		}
234
+		return $cts;
235
+	}
236 236
 
237 237
 
238
-    /**
239
-     * @param EE_Register_CPTs $cpt_class
240
-     * @return void
241
-     * @deprecated 4.9.62.p
242
-     */
243
-    public static function default_terms(EE_Register_CPTs $cpt_class)
244
-    {
245
-        foreach (self::$_registry as $registries) {
246
-            foreach ($registries['default_terms'] as $taxonomy => $terms) {
247
-                foreach ($terms as $term => $cpts) {
248
-                    $cpt_class->set_default_term($taxonomy, $term, $cpts);
249
-                }
250
-            }
251
-        }
252
-    }
238
+	/**
239
+	 * @param EE_Register_CPTs $cpt_class
240
+	 * @return void
241
+	 * @deprecated 4.9.62.p
242
+	 */
243
+	public static function default_terms(EE_Register_CPTs $cpt_class)
244
+	{
245
+		foreach (self::$_registry as $registries) {
246
+			foreach ($registries['default_terms'] as $taxonomy => $terms) {
247
+				foreach ($terms as $term => $cpts) {
248
+					$cpt_class->set_default_term($taxonomy, $term, $cpts);
249
+				}
250
+			}
251
+		}
252
+	}
253 253
 
254 254
 
255
-    /**
256
-     * This deregisters whats been registered on this class (for the given slug).
257
-     *
258
-     * @param string $cpt_ref The reference for the item registered to be removed.
259
-     *
260
-     * @return void
261
-     * @since 4.5.0
262
-     *
263
-     */
264
-    public static function deregister(string $cpt_ref = '')
265
-    {
266
-        unset(self::$_registry[ $cpt_ref ]);
267
-    }
255
+	/**
256
+	 * This deregisters whats been registered on this class (for the given slug).
257
+	 *
258
+	 * @param string $cpt_ref The reference for the item registered to be removed.
259
+	 *
260
+	 * @return void
261
+	 * @since 4.5.0
262
+	 *
263
+	 */
264
+	public static function deregister(string $cpt_ref = '')
265
+	{
266
+		unset(self::$_registry[ $cpt_ref ]);
267
+	}
268 268
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
             );
74 74
         }
75 75
 
76
-        if (! is_array($setup_args) || (empty($setup_args['cpts']) && empty($setup_args['cts']))) {
76
+        if ( ! is_array($setup_args) || (empty($setup_args['cpts']) && empty($setup_args['cts']))) {
77 77
             throw new EE_Error(
78 78
                 __(
79 79
                     'In order to register custom post types or custom taxonomies, you must include an array containing either an array of custom post types to register (key "cpts"), an array of custom taxonomies ("cts") or both.',
@@ -83,13 +83,13 @@  discard block
 block discarded – undo
83 83
         }
84 84
 
85 85
         // make sure we don't register twice
86
-        if (isset(self::$_registry[ $cpt_ref ])) {
86
+        if (isset(self::$_registry[$cpt_ref])) {
87 87
             return true;
88 88
         }
89 89
 
90 90
         // make sure cpt ref is unique.
91
-        if (isset(self::$_registry[ $cpt_ref ])) {
92
-            $cpt_ref = uniqid() . '_' . $cpt_ref;
91
+        if (isset(self::$_registry[$cpt_ref])) {
92
+            $cpt_ref = uniqid().'_'.$cpt_ref;
93 93
         }
94 94
 
95 95
         // make sure this was called in the right place!
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
                 : [],
120 120
         ];
121 121
 
122
-        self::$_registry[ $cpt_ref ] = $validated;
122
+        self::$_registry[$cpt_ref] = $validated;
123 123
 
124 124
         // hook into to cpt system
125 125
         add_filter(
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
     {
154 154
         foreach (self::$_registry as $registries) {
155 155
             foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
156
-                $custom_post_type_definitions[ $cpt_name ] = $cpt_settings;
156
+                $custom_post_type_definitions[$cpt_name] = $cpt_settings;
157 157
             }
158 158
         }
159 159
         return $custom_post_type_definitions;
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
     {
173 173
         foreach (self::$_registry as $registries) {
174 174
             foreach ($registries['cts'] as $ct_name => $ct_settings) {
175
-                $custom_taxonomy_definitions[ $ct_name ] = $ct_settings;
175
+                $custom_taxonomy_definitions[$ct_name] = $ct_settings;
176 176
             }
177 177
         }
178 178
         return $custom_taxonomy_definitions;
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
     {
213 213
         foreach (self::$_registry as $registries) {
214 214
             foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
215
-                $cpts[ $cpt_name ] = $cpt_settings;
215
+                $cpts[$cpt_name] = $cpt_settings;
216 216
             }
217 217
         }
218 218
         return $cpts;
@@ -228,7 +228,7 @@  discard block
 block discarded – undo
228 228
     {
229 229
         foreach (self::$_registry as $registries) {
230 230
             foreach ($registries['cts'] as $ct_name => $ct_settings) {
231
-                $cts[ $ct_name ] = $ct_settings;
231
+                $cts[$ct_name] = $ct_settings;
232 232
             }
233 233
         }
234 234
         return $cts;
@@ -263,6 +263,6 @@  discard block
 block discarded – undo
263 263
      */
264 264
     public static function deregister(string $cpt_ref = '')
265 265
     {
266
-        unset(self::$_registry[ $cpt_ref ]);
266
+        unset(self::$_registry[$cpt_ref]);
267 267
     }
268 268
 }
Please login to merge, or discard this patch.
core/Psr4Autoloader.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -152,7 +152,7 @@
 block discarded – undo
152 152
      *
153 153
      * @param string $prefix            The namespace prefix.
154 154
      * @param string $relative_class    The relative class name.
155
-     * @return mixed                    Boolean false if no mapped file can be loaded,
155
+     * @return string|false                    Boolean false if no mapped file can be loaded,
156 156
      *                                  or the name of the mapped file that was loaded.
157 157
      */
158 158
     protected function loadMappedFile(string $prefix, string $relative_class)
Please login to merge, or discard this patch.
Indentation   +143 added lines, -143 removed lines patch added patch discarded remove patch
@@ -47,147 +47,147 @@
 block discarded – undo
47 47
 class Psr4Autoloader
48 48
 {
49 49
 
50
-    /**
51
-     * namespace separator
52
-     */
53
-    const NS = '\\';
54
-
55
-    /**
56
-     * An associative array where the key is a namespace prefix and the value
57
-     * is an array of base directories for classes in that namespace.
58
-     *
59
-     * @var array
60
-     */
61
-    protected $prefixes = [];
62
-
63
-
64
-    /**
65
-     * returns an array of registered namespace prefixes
66
-     *
67
-     * @param string $prefix
68
-     * @return array
69
-     */
70
-    public function prefixes(string $prefix = ''): array
71
-    {
72
-        if (! empty($prefix)) {
73
-            // are there any base directories for this namespace prefix?
74
-            return isset($this->prefixes[ $prefix ]) ? $this->prefixes[ $prefix ] : [];
75
-        }
76
-        return $this->prefixes;
77
-    }
78
-
79
-
80
-    /**
81
-     * Register loader with SPL autoloader stack.
82
-     *
83
-     * @return void
84
-     */
85
-    public function register()
86
-    {
87
-        spl_autoload_register([$this, 'loadClass']);
88
-    }
89
-
90
-
91
-    /**
92
-     * Adds a base directory for a namespace prefix.
93
-     *
94
-     * @param string $prefix    The namespace prefix.
95
-     * @param string $base_dir  A base directory for class files in the namespace.
96
-     * @param bool $prepend     If true, prepend the base directory to the stack instead of appending it;
97
-     *                          this causes it to be searched first rather than last.
98
-     * @return bool             returns TRUE if the namespace was successfully added
99
-     */
100
-    public function addNamespace(string $prefix, string $base_dir, bool $prepend = false): bool
101
-    {
102
-        // normalize namespace prefix
103
-        $prefix = trim($prefix, Psr4Autoloader::NS) . Psr4Autoloader::NS;
104
-        // normalize the base directory with a trailing separator
105
-        $base_dir = EEH_File::standardise_and_end_with_directory_separator($base_dir);
106
-        // initialize the namespace prefix array
107
-        if (! isset($this->prefixes[ $prefix ])) {
108
-            $this->prefixes[ $prefix ] = [];
109
-        }
110
-        // retain the base directory for the namespace prefix
111
-        if ($prepend) {
112
-            array_unshift($this->prefixes[ $prefix ], $base_dir);
113
-        } else {
114
-            $this->prefixes[ $prefix ][] = $base_dir;
115
-        }
116
-        return isset($this->prefixes[ $prefix ]);
117
-    }
118
-
119
-
120
-    /**
121
-     * Loads the class file for a given class name.
122
-     *
123
-     * @param string $class The fully-qualified class name.
124
-     * @return string        The mapped file name on success, or boolean false on failure.
125
-     */
126
-    public function loadClass(string $class): string
127
-    {
128
-        // the current namespace prefix
129
-        $prefix = $class;
130
-        // work backwards through the namespace names of the fully-qualified
131
-        // class name to find a mapped file name
132
-        while (false !== $pos = strrpos($prefix, Psr4Autoloader::NS)) {
133
-            // retain the trailing namespace separator in the prefix
134
-            $prefix = substr($class, 0, $pos + 1);
135
-            // the rest is the relative class name
136
-            $relative_class = substr($class, $pos + 1);
137
-            // try to load a mapped file for the prefix and relative class
138
-            $mapped_file = $this->loadMappedFile($prefix, $relative_class);
139
-            if ($mapped_file) {
140
-                return $mapped_file;
141
-            }
142
-            // remove the trailing namespace separator for the next iteration of strrpos()
143
-            $prefix = rtrim($prefix, Psr4Autoloader::NS);
144
-        }
145
-        // never found a mapped file
146
-        return '';
147
-    }
148
-
149
-
150
-    /**
151
-     * Load the mapped file for a namespace prefix and relative class.
152
-     *
153
-     * @param string $prefix            The namespace prefix.
154
-     * @param string $relative_class    The relative class name.
155
-     * @return mixed                    Boolean false if no mapped file can be loaded,
156
-     *                                  or the name of the mapped file that was loaded.
157
-     */
158
-    protected function loadMappedFile(string $prefix, string $relative_class)
159
-    {
160
-        // look through base directories for this namespace prefix
161
-        foreach ($this->prefixes($prefix) as $base_dir) {
162
-            // replace the namespace prefix with the base directory,
163
-            // replace namespace separators with directory separators
164
-            // in the relative class name, append with .php
165
-            $file = $base_dir
166
-                    . str_replace(Psr4Autoloader::NS, '/', $relative_class)
167
-                    . '.php';
168
-            // if the mapped file exists, require it
169
-            if ($this->requireFile($file)) {
170
-                // yes, we're done
171
-                return $file;
172
-            }
173
-        }
174
-        // never found it
175
-        return false;
176
-    }
177
-
178
-
179
-    /**
180
-     * If a file exists, require it from the file system.
181
-     *
182
-     * @param string $file  The file to require.
183
-     * @return bool         True if the file exists, false if not.
184
-     */
185
-    protected function requireFile(string $file): bool
186
-    {
187
-        if (file_exists($file)) {
188
-            require $file;
189
-            return true;
190
-        }
191
-        return false;
192
-    }
50
+	/**
51
+	 * namespace separator
52
+	 */
53
+	const NS = '\\';
54
+
55
+	/**
56
+	 * An associative array where the key is a namespace prefix and the value
57
+	 * is an array of base directories for classes in that namespace.
58
+	 *
59
+	 * @var array
60
+	 */
61
+	protected $prefixes = [];
62
+
63
+
64
+	/**
65
+	 * returns an array of registered namespace prefixes
66
+	 *
67
+	 * @param string $prefix
68
+	 * @return array
69
+	 */
70
+	public function prefixes(string $prefix = ''): array
71
+	{
72
+		if (! empty($prefix)) {
73
+			// are there any base directories for this namespace prefix?
74
+			return isset($this->prefixes[ $prefix ]) ? $this->prefixes[ $prefix ] : [];
75
+		}
76
+		return $this->prefixes;
77
+	}
78
+
79
+
80
+	/**
81
+	 * Register loader with SPL autoloader stack.
82
+	 *
83
+	 * @return void
84
+	 */
85
+	public function register()
86
+	{
87
+		spl_autoload_register([$this, 'loadClass']);
88
+	}
89
+
90
+
91
+	/**
92
+	 * Adds a base directory for a namespace prefix.
93
+	 *
94
+	 * @param string $prefix    The namespace prefix.
95
+	 * @param string $base_dir  A base directory for class files in the namespace.
96
+	 * @param bool $prepend     If true, prepend the base directory to the stack instead of appending it;
97
+	 *                          this causes it to be searched first rather than last.
98
+	 * @return bool             returns TRUE if the namespace was successfully added
99
+	 */
100
+	public function addNamespace(string $prefix, string $base_dir, bool $prepend = false): bool
101
+	{
102
+		// normalize namespace prefix
103
+		$prefix = trim($prefix, Psr4Autoloader::NS) . Psr4Autoloader::NS;
104
+		// normalize the base directory with a trailing separator
105
+		$base_dir = EEH_File::standardise_and_end_with_directory_separator($base_dir);
106
+		// initialize the namespace prefix array
107
+		if (! isset($this->prefixes[ $prefix ])) {
108
+			$this->prefixes[ $prefix ] = [];
109
+		}
110
+		// retain the base directory for the namespace prefix
111
+		if ($prepend) {
112
+			array_unshift($this->prefixes[ $prefix ], $base_dir);
113
+		} else {
114
+			$this->prefixes[ $prefix ][] = $base_dir;
115
+		}
116
+		return isset($this->prefixes[ $prefix ]);
117
+	}
118
+
119
+
120
+	/**
121
+	 * Loads the class file for a given class name.
122
+	 *
123
+	 * @param string $class The fully-qualified class name.
124
+	 * @return string        The mapped file name on success, or boolean false on failure.
125
+	 */
126
+	public function loadClass(string $class): string
127
+	{
128
+		// the current namespace prefix
129
+		$prefix = $class;
130
+		// work backwards through the namespace names of the fully-qualified
131
+		// class name to find a mapped file name
132
+		while (false !== $pos = strrpos($prefix, Psr4Autoloader::NS)) {
133
+			// retain the trailing namespace separator in the prefix
134
+			$prefix = substr($class, 0, $pos + 1);
135
+			// the rest is the relative class name
136
+			$relative_class = substr($class, $pos + 1);
137
+			// try to load a mapped file for the prefix and relative class
138
+			$mapped_file = $this->loadMappedFile($prefix, $relative_class);
139
+			if ($mapped_file) {
140
+				return $mapped_file;
141
+			}
142
+			// remove the trailing namespace separator for the next iteration of strrpos()
143
+			$prefix = rtrim($prefix, Psr4Autoloader::NS);
144
+		}
145
+		// never found a mapped file
146
+		return '';
147
+	}
148
+
149
+
150
+	/**
151
+	 * Load the mapped file for a namespace prefix and relative class.
152
+	 *
153
+	 * @param string $prefix            The namespace prefix.
154
+	 * @param string $relative_class    The relative class name.
155
+	 * @return mixed                    Boolean false if no mapped file can be loaded,
156
+	 *                                  or the name of the mapped file that was loaded.
157
+	 */
158
+	protected function loadMappedFile(string $prefix, string $relative_class)
159
+	{
160
+		// look through base directories for this namespace prefix
161
+		foreach ($this->prefixes($prefix) as $base_dir) {
162
+			// replace the namespace prefix with the base directory,
163
+			// replace namespace separators with directory separators
164
+			// in the relative class name, append with .php
165
+			$file = $base_dir
166
+					. str_replace(Psr4Autoloader::NS, '/', $relative_class)
167
+					. '.php';
168
+			// if the mapped file exists, require it
169
+			if ($this->requireFile($file)) {
170
+				// yes, we're done
171
+				return $file;
172
+			}
173
+		}
174
+		// never found it
175
+		return false;
176
+	}
177
+
178
+
179
+	/**
180
+	 * If a file exists, require it from the file system.
181
+	 *
182
+	 * @param string $file  The file to require.
183
+	 * @return bool         True if the file exists, false if not.
184
+	 */
185
+	protected function requireFile(string $file): bool
186
+	{
187
+		if (file_exists($file)) {
188
+			require $file;
189
+			return true;
190
+		}
191
+		return false;
192
+	}
193 193
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -69,9 +69,9 @@  discard block
 block discarded – undo
69 69
      */
70 70
     public function prefixes(string $prefix = ''): array
71 71
     {
72
-        if (! empty($prefix)) {
72
+        if ( ! empty($prefix)) {
73 73
             // are there any base directories for this namespace prefix?
74
-            return isset($this->prefixes[ $prefix ]) ? $this->prefixes[ $prefix ] : [];
74
+            return isset($this->prefixes[$prefix]) ? $this->prefixes[$prefix] : [];
75 75
         }
76 76
         return $this->prefixes;
77 77
     }
@@ -100,20 +100,20 @@  discard block
 block discarded – undo
100 100
     public function addNamespace(string $prefix, string $base_dir, bool $prepend = false): bool
101 101
     {
102 102
         // normalize namespace prefix
103
-        $prefix = trim($prefix, Psr4Autoloader::NS) . Psr4Autoloader::NS;
103
+        $prefix = trim($prefix, Psr4Autoloader::NS).Psr4Autoloader::NS;
104 104
         // normalize the base directory with a trailing separator
105 105
         $base_dir = EEH_File::standardise_and_end_with_directory_separator($base_dir);
106 106
         // initialize the namespace prefix array
107
-        if (! isset($this->prefixes[ $prefix ])) {
108
-            $this->prefixes[ $prefix ] = [];
107
+        if ( ! isset($this->prefixes[$prefix])) {
108
+            $this->prefixes[$prefix] = [];
109 109
         }
110 110
         // retain the base directory for the namespace prefix
111 111
         if ($prepend) {
112
-            array_unshift($this->prefixes[ $prefix ], $base_dir);
112
+            array_unshift($this->prefixes[$prefix], $base_dir);
113 113
         } else {
114
-            $this->prefixes[ $prefix ][] = $base_dir;
114
+            $this->prefixes[$prefix][] = $base_dir;
115 115
         }
116
-        return isset($this->prefixes[ $prefix ]);
116
+        return isset($this->prefixes[$prefix]);
117 117
     }
118 118
 
119 119
 
Please login to merge, or discard this patch.
core/helpers/EEH_Autoloader.helper.php 2 patches
Indentation   +271 added lines, -271 removed lines patch added patch discarded remove patch
@@ -15,275 +15,275 @@
 block discarded – undo
15 15
 {
16 16
 
17 17
 
18
-    /**
19
-     *    instance of the EE_System object
20
-     *
21
-     * @var    $_instance
22
-     */
23
-    private static $_instance = null;
24
-
25
-    /**
26
-     *   $_autoloaders
27
-     * @var array $_autoloaders
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
-     */
38
-    public static $debug = false;
39
-
40
-
41
-    /**
42
-     * @throws EE_Error
43
-     */
44
-    private function __construct()
45
-    {
46
-        if (EEH_Autoloader::$_autoloaders === null) {
47
-            EEH_Autoloader::$_autoloaders = [];
48
-            $this->_register_custom_autoloaders();
49
-            spl_autoload_register([$this, 'espresso_autoloader']);
50
-        }
51
-    }
52
-
53
-
54
-    /**
55
-     * @return EEH_Autoloader
56
-     */
57
-    public static function instance(): EEH_Autoloader
58
-    {
59
-        // check if class object is instantiated
60
-        if (! EEH_Autoloader::$_instance instanceof EEH_Autoloader) {
61
-            EEH_Autoloader::$_instance = new EEH_Autoloader();
62
-        }
63
-        return EEH_Autoloader::$_instance;
64
-    }
65
-
66
-
67
-    /**
68
-     * @param   $class_name
69
-     * @return  void
70
-     * @internal  param string $class_name - simple class name ie: session
71
-     * @internal  param $className
72
-     */
73
-    public static function espresso_autoloader($class_name)
74
-    {
75
-        if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
76
-            require_once(EEH_Autoloader::$_autoloaders[ $class_name ]);
77
-        }
78
-    }
79
-
80
-
81
-    /**
82
-     * @param array | string $class_paths - array of key => value pairings between class names and paths
83
-     * @param bool           $read_check  true if we need to check whether the file is readable or not.
84
-     * @param bool           $debug       **deprecated**
85
-     * @throws EE_Error
86
-     */
87
-    public static function register_autoloader($class_paths, $read_check = true, $debug = false)
88
-    {
89
-        $class_paths = is_array($class_paths) ? $class_paths : [$class_paths];
90
-        foreach ($class_paths as $class => $path) {
91
-            // skip all files that are not PHP
92
-            if (substr($path, strlen($path) - 3) !== 'php') {
93
-                continue;
94
-            }
95
-            // don't give up! you gotta...
96
-            // get some class
97
-            if (empty($class)) {
98
-                throw new EE_Error(
99
-                    sprintf(
100
-                        __(
101
-                            'No Class name was specified while registering an autoloader for the following path: %s.',
102
-                            'event_espresso'
103
-                        ),
104
-                        $path
105
-                    )
106
-                );
107
-            }
108
-            // one day you will find the path young grasshopper
109
-            if (empty($path)) {
110
-                throw new EE_Error(
111
-                    sprintf(
112
-                        __('No path was specified while registering an autoloader for the %s class.', 'event_espresso'),
113
-                        $class
114
-                    )
115
-                );
116
-            }
117
-            // is file readable ?
118
-            if ($read_check && ! is_readable($path)) {
119
-                throw new EE_Error(
120
-                    sprintf(
121
-                        __(
122
-                            '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',
123
-                            'event_espresso'
124
-                        ),
125
-                        $class,
126
-                        $path
127
-                    )
128
-                );
129
-            }
130
-            if (! isset(EEH_Autoloader::$_autoloaders[ $class ])) {
131
-                EEH_Autoloader::$_autoloaders[ $class ] = str_replace(['/', '\\'], '/', $path);
132
-                if (EE_DEBUG && (EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug)) {
133
-                    EEH_Debug_Tools::printr(EEH_Autoloader::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
134
-                }
135
-            }
136
-        }
137
-    }
138
-
139
-
140
-    /**
141
-     * @return array
142
-     */
143
-    public static function get_autoloaders(): array
144
-    {
145
-        return EEH_Autoloader::$_autoloaders;
146
-    }
147
-
148
-
149
-    /**
150
-     * @return void
151
-     * @throws EE_Error
152
-     */
153
-    private function _register_custom_autoloaders()
154
-    {
155
-        EEH_Autoloader::$debug = '';
156
-        EEH_Autoloader::register_helpers_autoloaders();
157
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
158
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
159
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
160
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
161
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
162
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
163
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
164
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
165
-            Benchmark::displayResults();
166
-        }
167
-    }
168
-
169
-
170
-    /**
171
-     * @throws EE_Error
172
-     */
173
-    public static function register_helpers_autoloaders()
174
-    {
175
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
176
-    }
177
-
178
-
179
-    /**
180
-     * @return void
181
-     */
182
-    public static function register_form_sections_autoloaders()
183
-    {
184
-        // EEH_Autoloader::register_autoloaders_for_each_file_in_folder( EE_FORM_SECTIONS, true );
185
-    }
186
-
187
-
188
-    /**
189
-     * @return void
190
-     * @throws EE_Error
191
-     */
192
-    public static function register_line_item_display_autoloaders()
193
-    {
194
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
195
-    }
196
-
197
-
198
-    /**
199
-     * @return void
200
-     * @throws EE_Error
201
-     */
202
-    public static function register_line_item_filter_autoloaders()
203
-    {
204
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
205
-    }
206
-
207
-
208
-    /**
209
-     * @return void
210
-     * @throws EE_Error
211
-     */
212
-    public static function register_template_part_autoloaders()
213
-    {
214
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
215
-    }
216
-
217
-
218
-    /**
219
-     * @return void
220
-     * @throws EE_Error
221
-     */
222
-    public static function register_business_classes()
223
-    {
224
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
225
-    }
226
-
227
-
228
-    /**
229
-     * Assumes all the files in this folder have the normal naming scheme (namely that their classname
230
-     * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
231
-     * If that's not the case, you'll need to improve this function or just use
232
-     * EEH_File::get_classname_from_filepath_with_standard_filename() directly. Yes this has to scan the directory for
233
-     * files, but it only does it once -- not on EACH time the autoloader is used
234
-     *
235
-     * @param string $folder name, with or without trailing /, doesn't matter
236
-     * @param bool   $recursive
237
-     * @param bool   $debug  **deprecated**
238
-     * @throws EE_Error
239
-     */
240
-    public static function register_autoloaders_for_each_file_in_folder(
241
-        string $folder,
242
-        bool $recursive = false,
243
-        bool $debug = false
244
-    ) {
245
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all' || $debug) {
246
-            Benchmark::startTimer(basename($folder));
247
-        }
248
-        // make sure last char is a /
249
-        $folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
250
-        $class_to_filepath_map = [];
251
-        $exclude = ['index'];
252
-        // get all the files in that folder that end in php
253
-        $filepaths = glob($folder . '*');
254
-
255
-        if (empty($filepaths)) {
256
-            return;
257
-        }
258
-
259
-        foreach ($filepaths as $filepath) {
260
-            if (substr($filepath, -4, 4) === '.php') {
261
-                $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
262
-                if (! in_array($class_name, $exclude)) {
263
-                    $class_to_filepath_map [ $class_name ] = $filepath;
264
-                }
265
-            } elseif ($recursive) {
266
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
267
-            }
268
-        }
269
-        // 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.
270
-        EEH_Autoloader::register_autoloader($class_to_filepath_map, false, $debug);
271
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
272
-            Benchmark::stopTimer(basename($folder));
273
-        }
274
-    }
275
-
276
-
277
-    /**
278
-     * register additional autoloader based on variation of the classname for an existing autoloader
279
-     *
280
-     * @param string $class_name - simple class name ie: EE_Session
281
-     * @param string $alias      - variation on class name ie: EE_session, session, etc
282
-     */
283
-    public static function add_alias(string $class_name, string $alias)
284
-    {
285
-        if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
286
-            EEH_Autoloader::$_autoloaders[ $alias ] = EEH_Autoloader::$_autoloaders[ $class_name ];
287
-        }
288
-    }
18
+	/**
19
+	 *    instance of the EE_System object
20
+	 *
21
+	 * @var    $_instance
22
+	 */
23
+	private static $_instance = null;
24
+
25
+	/**
26
+	 *   $_autoloaders
27
+	 * @var array $_autoloaders
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
+	 */
38
+	public static $debug = false;
39
+
40
+
41
+	/**
42
+	 * @throws EE_Error
43
+	 */
44
+	private function __construct()
45
+	{
46
+		if (EEH_Autoloader::$_autoloaders === null) {
47
+			EEH_Autoloader::$_autoloaders = [];
48
+			$this->_register_custom_autoloaders();
49
+			spl_autoload_register([$this, 'espresso_autoloader']);
50
+		}
51
+	}
52
+
53
+
54
+	/**
55
+	 * @return EEH_Autoloader
56
+	 */
57
+	public static function instance(): EEH_Autoloader
58
+	{
59
+		// check if class object is instantiated
60
+		if (! EEH_Autoloader::$_instance instanceof EEH_Autoloader) {
61
+			EEH_Autoloader::$_instance = new EEH_Autoloader();
62
+		}
63
+		return EEH_Autoloader::$_instance;
64
+	}
65
+
66
+
67
+	/**
68
+	 * @param   $class_name
69
+	 * @return  void
70
+	 * @internal  param string $class_name - simple class name ie: session
71
+	 * @internal  param $className
72
+	 */
73
+	public static function espresso_autoloader($class_name)
74
+	{
75
+		if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
76
+			require_once(EEH_Autoloader::$_autoloaders[ $class_name ]);
77
+		}
78
+	}
79
+
80
+
81
+	/**
82
+	 * @param array | string $class_paths - array of key => value pairings between class names and paths
83
+	 * @param bool           $read_check  true if we need to check whether the file is readable or not.
84
+	 * @param bool           $debug       **deprecated**
85
+	 * @throws EE_Error
86
+	 */
87
+	public static function register_autoloader($class_paths, $read_check = true, $debug = false)
88
+	{
89
+		$class_paths = is_array($class_paths) ? $class_paths : [$class_paths];
90
+		foreach ($class_paths as $class => $path) {
91
+			// skip all files that are not PHP
92
+			if (substr($path, strlen($path) - 3) !== 'php') {
93
+				continue;
94
+			}
95
+			// don't give up! you gotta...
96
+			// get some class
97
+			if (empty($class)) {
98
+				throw new EE_Error(
99
+					sprintf(
100
+						__(
101
+							'No Class name was specified while registering an autoloader for the following path: %s.',
102
+							'event_espresso'
103
+						),
104
+						$path
105
+					)
106
+				);
107
+			}
108
+			// one day you will find the path young grasshopper
109
+			if (empty($path)) {
110
+				throw new EE_Error(
111
+					sprintf(
112
+						__('No path was specified while registering an autoloader for the %s class.', 'event_espresso'),
113
+						$class
114
+					)
115
+				);
116
+			}
117
+			// is file readable ?
118
+			if ($read_check && ! is_readable($path)) {
119
+				throw new EE_Error(
120
+					sprintf(
121
+						__(
122
+							'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',
123
+							'event_espresso'
124
+						),
125
+						$class,
126
+						$path
127
+					)
128
+				);
129
+			}
130
+			if (! isset(EEH_Autoloader::$_autoloaders[ $class ])) {
131
+				EEH_Autoloader::$_autoloaders[ $class ] = str_replace(['/', '\\'], '/', $path);
132
+				if (EE_DEBUG && (EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug)) {
133
+					EEH_Debug_Tools::printr(EEH_Autoloader::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
134
+				}
135
+			}
136
+		}
137
+	}
138
+
139
+
140
+	/**
141
+	 * @return array
142
+	 */
143
+	public static function get_autoloaders(): array
144
+	{
145
+		return EEH_Autoloader::$_autoloaders;
146
+	}
147
+
148
+
149
+	/**
150
+	 * @return void
151
+	 * @throws EE_Error
152
+	 */
153
+	private function _register_custom_autoloaders()
154
+	{
155
+		EEH_Autoloader::$debug = '';
156
+		EEH_Autoloader::register_helpers_autoloaders();
157
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
158
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
159
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
160
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
161
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
162
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
163
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
164
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
165
+			Benchmark::displayResults();
166
+		}
167
+	}
168
+
169
+
170
+	/**
171
+	 * @throws EE_Error
172
+	 */
173
+	public static function register_helpers_autoloaders()
174
+	{
175
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
176
+	}
177
+
178
+
179
+	/**
180
+	 * @return void
181
+	 */
182
+	public static function register_form_sections_autoloaders()
183
+	{
184
+		// EEH_Autoloader::register_autoloaders_for_each_file_in_folder( EE_FORM_SECTIONS, true );
185
+	}
186
+
187
+
188
+	/**
189
+	 * @return void
190
+	 * @throws EE_Error
191
+	 */
192
+	public static function register_line_item_display_autoloaders()
193
+	{
194
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
195
+	}
196
+
197
+
198
+	/**
199
+	 * @return void
200
+	 * @throws EE_Error
201
+	 */
202
+	public static function register_line_item_filter_autoloaders()
203
+	{
204
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
205
+	}
206
+
207
+
208
+	/**
209
+	 * @return void
210
+	 * @throws EE_Error
211
+	 */
212
+	public static function register_template_part_autoloaders()
213
+	{
214
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
215
+	}
216
+
217
+
218
+	/**
219
+	 * @return void
220
+	 * @throws EE_Error
221
+	 */
222
+	public static function register_business_classes()
223
+	{
224
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
225
+	}
226
+
227
+
228
+	/**
229
+	 * Assumes all the files in this folder have the normal naming scheme (namely that their classname
230
+	 * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
231
+	 * If that's not the case, you'll need to improve this function or just use
232
+	 * EEH_File::get_classname_from_filepath_with_standard_filename() directly. Yes this has to scan the directory for
233
+	 * files, but it only does it once -- not on EACH time the autoloader is used
234
+	 *
235
+	 * @param string $folder name, with or without trailing /, doesn't matter
236
+	 * @param bool   $recursive
237
+	 * @param bool   $debug  **deprecated**
238
+	 * @throws EE_Error
239
+	 */
240
+	public static function register_autoloaders_for_each_file_in_folder(
241
+		string $folder,
242
+		bool $recursive = false,
243
+		bool $debug = false
244
+	) {
245
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all' || $debug) {
246
+			Benchmark::startTimer(basename($folder));
247
+		}
248
+		// make sure last char is a /
249
+		$folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
250
+		$class_to_filepath_map = [];
251
+		$exclude = ['index'];
252
+		// get all the files in that folder that end in php
253
+		$filepaths = glob($folder . '*');
254
+
255
+		if (empty($filepaths)) {
256
+			return;
257
+		}
258
+
259
+		foreach ($filepaths as $filepath) {
260
+			if (substr($filepath, -4, 4) === '.php') {
261
+				$class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
262
+				if (! in_array($class_name, $exclude)) {
263
+					$class_to_filepath_map [ $class_name ] = $filepath;
264
+				}
265
+			} elseif ($recursive) {
266
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
267
+			}
268
+		}
269
+		// 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.
270
+		EEH_Autoloader::register_autoloader($class_to_filepath_map, false, $debug);
271
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
272
+			Benchmark::stopTimer(basename($folder));
273
+		}
274
+	}
275
+
276
+
277
+	/**
278
+	 * register additional autoloader based on variation of the classname for an existing autoloader
279
+	 *
280
+	 * @param string $class_name - simple class name ie: EE_Session
281
+	 * @param string $alias      - variation on class name ie: EE_session, session, etc
282
+	 */
283
+	public static function add_alias(string $class_name, string $alias)
284
+	{
285
+		if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
286
+			EEH_Autoloader::$_autoloaders[ $alias ] = EEH_Autoloader::$_autoloaders[ $class_name ];
287
+		}
288
+	}
289 289
 }
Please login to merge, or discard this patch.
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
     public static function instance(): EEH_Autoloader
58 58
     {
59 59
         // check if class object is instantiated
60
-        if (! EEH_Autoloader::$_instance instanceof EEH_Autoloader) {
60
+        if ( ! EEH_Autoloader::$_instance instanceof EEH_Autoloader) {
61 61
             EEH_Autoloader::$_instance = new EEH_Autoloader();
62 62
         }
63 63
         return EEH_Autoloader::$_instance;
@@ -72,8 +72,8 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public static function espresso_autoloader($class_name)
74 74
     {
75
-        if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
76
-            require_once(EEH_Autoloader::$_autoloaders[ $class_name ]);
75
+        if (isset(EEH_Autoloader::$_autoloaders[$class_name])) {
76
+            require_once(EEH_Autoloader::$_autoloaders[$class_name]);
77 77
         }
78 78
     }
79 79
 
@@ -127,10 +127,10 @@  discard block
 block discarded – undo
127 127
                     )
128 128
                 );
129 129
             }
130
-            if (! isset(EEH_Autoloader::$_autoloaders[ $class ])) {
131
-                EEH_Autoloader::$_autoloaders[ $class ] = str_replace(['/', '\\'], '/', $path);
130
+            if ( ! isset(EEH_Autoloader::$_autoloaders[$class])) {
131
+                EEH_Autoloader::$_autoloaders[$class] = str_replace(['/', '\\'], '/', $path);
132 132
                 if (EE_DEBUG && (EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug)) {
133
-                    EEH_Debug_Tools::printr(EEH_Autoloader::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
133
+                    EEH_Debug_Tools::printr(EEH_Autoloader::$_autoloaders[$class], $class, __FILE__, __LINE__);
134 134
                 }
135 135
             }
136 136
         }
@@ -154,13 +154,13 @@  discard block
 block discarded – undo
154 154
     {
155 155
         EEH_Autoloader::$debug = '';
156 156
         EEH_Autoloader::register_helpers_autoloaders();
157
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
157
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE.'interfaces');
158 158
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
159 159
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
160 160
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
161 161
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
162 162
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
163
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
163
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'messages');
164 164
         if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
165 165
             Benchmark::displayResults();
166 166
         }
@@ -191,7 +191,7 @@  discard block
 block discarded – undo
191 191
      */
192 192
     public static function register_line_item_display_autoloaders()
193 193
     {
194
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
194
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'line_item_display', true);
195 195
     }
196 196
 
197 197
 
@@ -201,7 +201,7 @@  discard block
 block discarded – undo
201 201
      */
202 202
     public static function register_line_item_filter_autoloaders()
203 203
     {
204
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
204
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'line_item_filters', true);
205 205
     }
206 206
 
207 207
 
@@ -211,7 +211,7 @@  discard block
 block discarded – undo
211 211
      */
212 212
     public static function register_template_part_autoloaders()
213 213
     {
214
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
214
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'template_parts', true);
215 215
     }
216 216
 
217 217
 
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
      */
222 222
     public static function register_business_classes()
223 223
     {
224
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
224
+        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE.'business');
225 225
     }
226 226
 
227 227
 
@@ -246,11 +246,11 @@  discard block
 block discarded – undo
246 246
             Benchmark::startTimer(basename($folder));
247 247
         }
248 248
         // make sure last char is a /
249
-        $folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
249
+        $folder .= $folder[strlen($folder) - 1] !== '/' ? '/' : '';
250 250
         $class_to_filepath_map = [];
251 251
         $exclude = ['index'];
252 252
         // get all the files in that folder that end in php
253
-        $filepaths = glob($folder . '*');
253
+        $filepaths = glob($folder.'*');
254 254
 
255 255
         if (empty($filepaths)) {
256 256
             return;
@@ -259,8 +259,8 @@  discard block
 block discarded – undo
259 259
         foreach ($filepaths as $filepath) {
260 260
             if (substr($filepath, -4, 4) === '.php') {
261 261
                 $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
262
-                if (! in_array($class_name, $exclude)) {
263
-                    $class_to_filepath_map [ $class_name ] = $filepath;
262
+                if ( ! in_array($class_name, $exclude)) {
263
+                    $class_to_filepath_map [$class_name] = $filepath;
264 264
                 }
265 265
             } elseif ($recursive) {
266 266
                 EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
@@ -282,8 +282,8 @@  discard block
 block discarded – undo
282 282
      */
283 283
     public static function add_alias(string $class_name, string $alias)
284 284
     {
285
-        if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
286
-            EEH_Autoloader::$_autoloaders[ $alias ] = EEH_Autoloader::$_autoloaders[ $class_name ];
285
+        if (isset(EEH_Autoloader::$_autoloaders[$class_name])) {
286
+            EEH_Autoloader::$_autoloaders[$alias] = EEH_Autoloader::$_autoloaders[$class_name];
287 287
         }
288 288
     }
289 289
 }
Please login to merge, or discard this patch.
core/helpers/EEH_File.helper.php 2 patches
Indentation   +911 added lines, -911 removed lines patch added patch discarded remove patch
@@ -25,915 +25,915 @@
 block discarded – undo
25 25
 class EEH_File extends EEH_Base implements EEHI_File
26 26
 {
27 27
 
28
-    /**
29
-     * @var string $_credentials_form
30
-     */
31
-    private static $_credentials_form;
32
-
33
-    /**
34
-     * @var WP_Filesystem_Base $_wp_filesystem
35
-     */
36
-    protected static $_wp_filesystem;
37
-
38
-
39
-    /**
40
-     * @param string $filepath      the filepath we want to work in. If its in the
41
-     *                              wp uploads directory, we'll want to just use the filesystem directly.
42
-     *                              If not provided, we have to assume its not in the uploads directory
43
-     * @return WP_Filesystem_Base
44
-     */
45
-    private static function _get_wp_filesystem($filepath = ''): WP_Filesystem_Base
46
-    {
47
-        if (apply_filters(
48
-            'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
49
-            $filepath && EEH_File::is_in_uploads_folder($filepath),
50
-            $filepath
51
-        )
52
-        ) {
53
-            return EEH_File::loadAlternateWpFileSystem();
54
-        }
55
-        return EEH_File::loadWpFileSystem();
56
-    }
57
-
58
-
59
-    /**
60
-     * @return WP_Filesystem_Base
61
-     */
62
-    private static function loadAlternateWpFileSystem(): WP_Filesystem_Base
63
-    {
64
-        if (! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
65
-            require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
66
-            $method             = 'direct';
67
-            $wp_filesystem_file =
68
-                apply_filters(
69
-                    'filesystem_method_file',
70
-                    ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php',
71
-                    $method
72
-                );
73
-            // added the following validation logic
74
-            // because we allow the filesystem filepath to be filtered,
75
-            // and are loading whatever file the path pointed to,
76
-            // but we were not validating things in any way :scream_emoji:
77
-            $valid_wp_filesystem_types = [
78
-                'direct'     => 'WP_Filesystem_Direct',
79
-                'ftpext'     => 'WP_Filesystem_FTPext',
80
-                'ftpsockets' => 'WP_Filesystem_ftpsockets',
81
-                'ssh2'       => 'WP_Filesystem_SSH2',
82
-            ];
83
-            $valid                     = false;
84
-            $wp_filesystem_class       = '';
85
-            foreach ($valid_wp_filesystem_types as $method => $filesystem_class) {
86
-                // if file path matches for one of valid types, then toggle $valid to true
87
-                if (strpos($wp_filesystem_file, $method) > 0) {
88
-                    $valid               = true;
89
-                    $wp_filesystem_class = $filesystem_class;
90
-                }
91
-            }
92
-            if (! $valid || ! file_exists($wp_filesystem_file)) {
93
-                EE_Error::add_error(
94
-                    sprintf(
95
-                        esc_html__(
96
-                            'The supplied WP Filesystem filepath "%1$s" is either missing or invalid.',
97
-                            'event_espresso'
98
-                        ),
99
-                        $wp_filesystem_file
100
-                    ),
101
-                    __FILE__,
102
-                    __FUNCTION__,
103
-                    __LINE__
104
-                );
105
-            }
106
-            // check constants defined, just like in the wp-admin/includes/file.php WP_Filesystem()
107
-            if (! defined('FS_CHMOD_DIR')) {
108
-                define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0775 | 0755));
109
-            }
110
-            if (! defined('FS_CHMOD_FILE')) {
111
-                define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0775 | 0644));
112
-            }
113
-            require_once($wp_filesystem_file);
114
-            EEH_File::$_wp_filesystem = new $wp_filesystem_class([]);
115
-        }
116
-        return EEH_File::$_wp_filesystem;
117
-    }
118
-
119
-
120
-    /**
121
-     * @return WP_Filesystem_Base
122
-     */
123
-    private static function loadWpFileSystem(): WP_Filesystem_Base
124
-    {
125
-        global $wp_filesystem;
126
-        // no filesystem setup ???
127
-        if (! $wp_filesystem instanceof WP_Filesystem_Base) {
128
-            // if some eager beaver's just trying to get in there too early...
129
-            // let them do it, because we are one of those eager beavers! :P
130
-            /**
131
-             * more explanations are probably merited.
132
-             * http://codex.wordpress.org/Filesystem_API#Initializing_WP_Filesystem_Base
133
-             * says WP_Filesystem should be used after 'wp_loaded', but currently EE's activation process
134
-             * is setup to mostly happen on 'init', and refactoring to have it happen on
135
-             * 'wp_loaded' is too much work on a BETA milestone.
136
-             * So this fix is expected to work if the WP files are owned by the server user,
137
-             * but probably not if the user needs to enter their FTP credentials to modify files
138
-             * and there may be troubles if the WP files are owned by a different user
139
-             * than the server user. But both of these issues should exist in 4.4 and earlier too
140
-             */
141
-            // if (false && ! did_action('wp_loaded')) {
142
-            //     $msg =
143
-            //         esc_html__(
144
-            //             'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
145
-            //             'event_espresso'
146
-            //         );
147
-            //     if (WP_DEBUG) {
148
-            //         $msg .= '<br />' . esc_html__(
149
-            //             '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.',
150
-            //             'event_espresso'
151
-            //         );
152
-            //     }
153
-            //     EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
154
-            // }
155
-            // should be loaded if we are past the wp_loaded hook...
156
-            if (! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
157
-                require_once(ABSPATH . 'wp-admin/includes/file.php');
158
-                require_once(ABSPATH . 'wp-admin/includes/template.php');
159
-            }
160
-            // turn on output buffering so that we can capture the credentials form
161
-            ob_start();
162
-            $credentials = request_filesystem_credentials(false);
163
-            // store credentials form for the time being
164
-            EEH_File::$_credentials_form = ob_get_clean();
165
-            // if credentials do NOT exist
166
-            if ($credentials === false) {
167
-                add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
168
-                EE_Error::add_error(
169
-                    esc_html__(
170
-                        'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
171
-                        'event_espresso'
172
-                    ),
173
-                    __FILE__,
174
-                    __FUNCTION__,
175
-                    __LINE__
176
-                );
177
-            }
178
-            // basically check for direct or previously configured access
179
-            if (! WP_Filesystem($credentials)
180
-                && is_wp_error($wp_filesystem->errors)
181
-                && $wp_filesystem->errors->get_error_code()
182
-            ) {
183
-                add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
184
-                EE_Error::add_error(
185
-                    sprintf(
186
-                        esc_html__('WP Filesystem Error: $1%s', 'event_espresso'),
187
-                        $wp_filesystem->errors->get_error_message()
188
-                    ),
189
-                    __FILE__,
190
-                    __FUNCTION__,
191
-                    __LINE__
192
-                );
193
-            }
194
-        }
195
-        return $wp_filesystem;
196
-    }
197
-
198
-
199
-    /**
200
-     * display_request_filesystem_credentials_form
201
-     */
202
-    public static function display_request_filesystem_credentials_form()
203
-    {
204
-        if (! empty(EEH_File::$_credentials_form)) {
205
-            echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
206
-        }
207
-    }
208
-
209
-
210
-    /**
211
-     *    verify_filepath_and_permissions
212
-     *    checks that a file is readable and has sufficient file permissions set to access
213
-     *
214
-     * @access public
215
-     * @param string $full_file_path - full server path to the folder or file
216
-     * @param string $file_name      - name of file if checking a file
217
-     * @param string $file_ext       - file extension (ie: "php") if checking a file
218
-     * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
219
-     * @return bool
220
-     */
221
-    public static function verify_filepath_and_permissions(
222
-        string $full_file_path = '',
223
-        string $file_name = '',
224
-        string $file_ext = '',
225
-        string $type_of_file = ''
226
-    ): bool {
227
-        // load WP_Filesystem and set file permissions
228
-        $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
229
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
230
-        if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
231
-            $file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
232
-            $file_name .= ! empty($file_ext) ? ' file' : ' folder';
233
-            $msg       = sprintf(
234
-                esc_html__(
235
-                    'The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s',
236
-                    'event_espresso'
237
-                ),
238
-                $file_name,
239
-                '<br />'
240
-            );
241
-            if (EEH_File::exists($full_file_path)) {
242
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
243
-            } else {
244
-                // no file permissions means the file was not found
245
-                $msg .= sprintf(
246
-                    esc_html__('Please ensure the following path is correct: "%s".', 'event_espresso'),
247
-                    $full_file_path
248
-                );
249
-            }
250
-            if (defined('WP_DEBUG') && WP_DEBUG) {
251
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
252
-            }
253
-            return false;
254
-        }
255
-        return true;
256
-    }
257
-
258
-
259
-    /**
260
-     * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a
261
-     * file or folder
262
-     *
263
-     * @access private
264
-     * @param string $full_file_path - full server path to the folder or file
265
-     * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
266
-     * @return string
267
-     */
268
-    private static function _permissions_error_for_unreadable_filepath(
269
-        string $full_file_path = '',
270
-        string $type_of_file = ''
271
-    ): string {
272
-        // load WP_Filesystem and set file permissions
273
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
274
-        // check file permissions
275
-        $perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
276
-        if ($perms) {
277
-            // file permissions exist, but way be set incorrectly
278
-            $type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
279
-            $type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
280
-            return ' ' . sprintf(
281
-                esc_html__(
282
-                    'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.',
283
-                    'event_espresso'
284
-                ),
285
-                $type_of_file,
286
-                $perms
287
-            );
288
-        } else {
289
-            // file exists but file permissions could not be read ?!?!
290
-            return ' ' . sprintf(
291
-                esc_html__(
292
-                    'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".',
293
-                    'event_espresso'
294
-                ),
295
-                $full_file_path
296
-            );
297
-        }
298
-    }
299
-
300
-
301
-    /**
302
-     * ensure_folder_exists_and_is_writable
303
-     * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
304
-     * Also ensures all the parent folders exist, and if not tries to create them.
305
-     * Also, if this function creates the folder, adds a .htaccess file and index.html file
306
-     *
307
-     * @param string $folder
308
-     * @return bool false if folder isn't writable; true if it exists and is writeable,
309
-     */
310
-    public static function ensure_folder_exists_and_is_writable(string $folder = ''): bool
311
-    {
312
-        if (empty($folder)) {
313
-            return false;
314
-        }
315
-        // remove ending /
316
-        $folder        = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
317
-        $parent_folder = EEH_File::get_parent_folder($folder);
318
-        // add / to folder
319
-        $folder        = EEH_File::end_with_directory_separator($folder);
320
-        $wp_filesystem = EEH_File::_get_wp_filesystem($folder);
321
-        $remote_dir    = EEH_File::convert_local_filepath_to_remote_filepath($folder);
322
-        if (! $wp_filesystem->is_dir($remote_dir)) {
323
-            // ok so it doesn't exist. Does its parent? Can we write to it?
324
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
325
-                return false;
326
-            }
327
-            if (! EEH_File::verify_is_writable($parent_folder)) {
328
-                return false;
329
-            }
330
-            if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
331
-                if (defined('WP_DEBUG') && WP_DEBUG) {
332
-                    $msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
333
-                    $msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
334
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
335
-                }
336
-                return false;
337
-            }
338
-            EEH_File::add_index_file($folder);
339
-        } elseif (! EEH_File::verify_is_writable($folder)) {
340
-            return false;
341
-        }
342
-        return true;
343
-    }
344
-
345
-
346
-    /**
347
-     * verify_is_writable - checks if a file or folder is writable
348
-     *
349
-     * @param string $full_path      - full server path to file or folder
350
-     * @param string $file_or_folder - whether checking a file or folder
351
-     * @return bool
352
-     */
353
-    public static function verify_is_writable(string $full_path = '', string $file_or_folder = 'folder'): bool
354
-    {
355
-        // load WP_Filesystem and set file permissions
356
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
357
-        $full_path     = EEH_File::standardise_directory_separators($full_path);
358
-        $remote_path   = EEH_File::convert_local_filepath_to_remote_filepath($full_path);
359
-        $remote_path   = rtrim($remote_path, '/\\');
360
-        if (! $wp_filesystem->is_writable($remote_path)) {
361
-            if (defined('WP_DEBUG') && WP_DEBUG) {
362
-                $msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
363
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
364
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
365
-            }
366
-            return false;
367
-        }
368
-        return true;
369
-    }
370
-
371
-
372
-    /**
373
-     * ensure_file_exists_and_is_writable
374
-     * ensures that a file exists and is writable, will attempt to create file if it does not exist.
375
-     * Also ensures all the parent folders exist, and if not tries to create them.
376
-     *
377
-     * @param string $full_file_path
378
-     * @return bool
379
-     */
380
-    public static function ensure_file_exists_and_is_writable(string $full_file_path = ''): bool
381
-    {
382
-        // load WP_Filesystem and set file permissions
383
-        $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
384
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
385
-        $parent_folder  = EEH_File::get_parent_folder($full_file_path);
386
-        if (! EEH_File::exists($full_file_path)) {
387
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
388
-                return false;
389
-            }
390
-            if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
391
-                if (defined('WP_DEBUG') && WP_DEBUG) {
392
-                    $msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
393
-                    $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
394
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
395
-                }
396
-                return false;
397
-            }
398
-        }
399
-        if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
400
-            return false;
401
-        }
402
-        return true;
403
-    }
404
-
405
-
406
-    /**
407
-     * Gets the parent folder. If provided with file, gets the folder that contains it.
408
-     * If provided a folder, gets its parent folder.
409
-     *
410
-     * @param string $file_or_folder_path
411
-     * @return string parent folder, ENDING with a directory separator
412
-     */
413
-    public static function get_parent_folder(string $file_or_folder_path): string
414
-    {
415
-        // find the last /, ignoring a / on the very end
416
-        // eg if given "/var/something/somewhere/", we want to get "somewhere"'s
417
-        // parent folder, "/var/something/"
418
-        $ds = strlen($file_or_folder_path) > 1
419
-            ? strrpos($file_or_folder_path, '/', -2)
420
-            : strlen($file_or_folder_path);
421
-        return substr($file_or_folder_path, 0, $ds + 1);
422
-    }
423
-
424
-
425
-    /**
426
-     * get_file_contents
427
-     *
428
-     * @param string $full_file_path
429
-     * @return string
430
-     */
431
-    public static function get_file_contents(string $full_file_path = ''): string
432
-    {
433
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
434
-        if (EEH_File::verify_filepath_and_permissions(
435
-            $full_file_path,
436
-            EEH_File::get_filename_from_filepath($full_file_path),
437
-            EEH_File::get_file_extension($full_file_path)
438
-        )
439
-        ) {
440
-            // load WP_Filesystem and set file permissions
441
-            $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
442
-            return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
443
-        }
444
-        return '';
445
-    }
446
-
447
-
448
-    /**
449
-     * write_file
450
-     *
451
-     * @param string $full_file_path
452
-     * @param string $file_contents - the content to be written to the file
453
-     * @param string $file_type
454
-     * @return bool
455
-     */
456
-    public static function write_to_file(
457
-        string $full_file_path = '',
458
-        string $file_contents = '',
459
-        string $file_type = ''
460
-    ): bool {
461
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
462
-        $file_type      = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
463
-        $folder         = EEH_File::remove_filename_from_filepath($full_file_path);
464
-        if (! EEH_File::verify_is_writable($folder)) {
465
-            if (defined('WP_DEBUG') && WP_DEBUG) {
466
-                $msg =
467
-                    sprintf(
468
-                        esc_html__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'),
469
-                        $file_type,
470
-                        $full_file_path
471
-                    );
472
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
473
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
474
-            }
475
-            return false;
476
-        }
477
-        // load WP_Filesystem and set file permissions
478
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
479
-        // write the file
480
-        if (! $wp_filesystem->put_contents(
481
-            EEH_File::convert_local_filepath_to_remote_filepath($full_file_path),
482
-            $file_contents
483
-        )
484
-        ) {
485
-            if (defined('WP_DEBUG') && WP_DEBUG) {
486
-                $msg =
487
-                    sprintf(
488
-                        esc_html__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'),
489
-                        $file_type,
490
-                        $full_file_path
491
-                    );
492
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
493
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
494
-            }
495
-            return false;
496
-        }
497
-        return true;
498
-    }
499
-
500
-
501
-    /**
502
-     * Wrapper for WP_Filesystem_Base::delete
503
-     *
504
-     * @param string         $filepath
505
-     * @param boolean        $recursive
506
-     * @param boolean|string $type 'd' for directory, 'f' for file
507
-     * @return boolean
508
-     */
509
-    public static function delete(string $filepath, bool $recursive = false, $type = false): bool
510
-    {
511
-        $wp_filesystem = EEH_File::_get_wp_filesystem();
512
-        return $wp_filesystem->delete($filepath, $recursive, $type);
513
-    }
514
-
515
-
516
-    /**
517
-     * exists
518
-     * checks if a file exists using the WP filesystem
519
-     *
520
-     * @param string $full_file_path
521
-     * @return bool
522
-     */
523
-    public static function exists(string $full_file_path = ''): bool
524
-    {
525
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
526
-        return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
527
-    }
528
-
529
-
530
-    /**
531
-     * is_readable
532
-     * checks if a file is_readable using the WP filesystem
533
-     *
534
-     * @param string $full_file_path
535
-     * @return bool
536
-     */
537
-    public static function is_readable(string $full_file_path = ''): bool
538
-    {
539
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
540
-        return $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
541
-    }
542
-
543
-
544
-    /**
545
-     * remove_filename_from_filepath
546
-     * given a full path to a file including the filename itself, this removes  the filename and returns the path, up
547
-     * to, but NOT including the filename OR slash
548
-     *
549
-     * @param string $full_file_path
550
-     * @return string
551
-     */
552
-    public static function remove_filename_from_filepath(string $full_file_path = ''): string
553
-    {
554
-        return pathinfo($full_file_path, PATHINFO_DIRNAME);
555
-    }
556
-
557
-
558
-    /**
559
-     * get_filename_from_filepath. Arguably the same as basename()
560
-     *
561
-     * @param string $full_file_path
562
-     * @return string
563
-     */
564
-    public static function get_filename_from_filepath(string $full_file_path = ''): string
565
-    {
566
-        return pathinfo($full_file_path, PATHINFO_BASENAME);
567
-    }
568
-
569
-
570
-    /**
571
-     * get_file_extension
572
-     *
573
-     * @param string $full_file_path
574
-     * @return string
575
-     */
576
-    public static function get_file_extension(string $full_file_path = ''): string
577
-    {
578
-        return pathinfo($full_file_path, PATHINFO_EXTENSION);
579
-    }
580
-
581
-
582
-    /**
583
-     * add_htaccess_deny_from_all so the web server cannot access this folder
584
-     *
585
-     * @param string $folder
586
-     * @return bool
587
-     */
588
-    public static function add_htaccess_deny_from_all(string $folder = ''): bool
589
-    {
590
-        $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
591
-        if (! EEH_File::exists($folder . '.htaccess')) {
592
-            if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
593
-                return false;
594
-            }
595
-        }
596
-
597
-        return true;
598
-    }
599
-
600
-
601
-    /**
602
-     * Adds an index file to this folder, so folks can't list all the file's contents
603
-     *
604
-     * @param string $folder
605
-     * @return boolean
606
-     */
607
-    public static function add_index_file(string $folder): bool
608
-    {
609
-        $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
610
-        if (! EEH_File::exists($folder . 'index.php')) {
611
-            if (! EEH_File::write_to_file(
612
-                $folder . 'index.php',
613
-                'You are not permitted to read from this folder',
614
-                '.php'
615
-            )
616
-            ) {
617
-                return false;
618
-            }
619
-        }
620
-        return true;
621
-    }
622
-
623
-
624
-    /**
625
-     * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php),
626
-     * extract that classname.
627
-     *
628
-     * @param string $file_path
629
-     * @return string
630
-     */
631
-    public static function get_classname_from_filepath_with_standard_filename(string $file_path): string
632
-    {
633
-        // extract file from path
634
-        $filename = basename($file_path);
635
-        // now remove the first period and everything after
636
-        $pos_of_first_period = strpos($filename, '.');
637
-        return substr($filename, 0, $pos_of_first_period);
638
-    }
639
-
640
-
641
-    /**
642
-     * standardise_directory_separators
643
-     *  convert all directory separators in a file path.
644
-     *
645
-     * @param string $file_path
646
-     * @param bool   $rtrim will remove trailing backslash
647
-     * @return string
648
-     */
649
-    public static function standardise_directory_separators(string $file_path, bool $rtrim = false): string
650
-    {
651
-        $file_path = $rtrim ? rtrim($file_path, '/\\') : $file_path;
652
-        return str_replace(['\\', '/'], '/', $file_path);
653
-    }
654
-
655
-
656
-    /**
657
-     * end_with_directory_separator
658
-     *  ensures that file path ends with '/'
659
-     *
660
-     * @param string $file_path
661
-     * @return string
662
-     */
663
-    public static function end_with_directory_separator(string $file_path): string
664
-    {
665
-        return rtrim($file_path, '/\\') . '/';
666
-    }
667
-
668
-
669
-    /**
670
-     * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators
671
-     *
672
-     * @param string $file_path
673
-     * @return string
674
-     */
675
-    public static function standardise_and_end_with_directory_separator(string $file_path): string
676
-    {
677
-        return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
678
-    }
679
-
680
-
681
-    /**
682
-     * takes the folder name (with or without trailing slash) and finds the files it in,
683
-     * and what the class's name inside of each should be.
684
-     *
685
-     * @param array   $folder_paths
686
-     * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically;
687
-     *                                   if FALSE (Default), returned array will be indexed by the filenames minus
688
-     *                                   extensions. Set it TRUE if you know there are files in the directory with the
689
-     *                                   same name but different extensions
690
-     * @return array if $index_numerically == TRUE keys are numeric ,
691
-     *                                   if $index_numerically == FALSE (Default) keys are what the class names SHOULD
692
-     *                                   be; and values are their file paths
693
-     */
694
-    public static function get_contents_of_folders(array $folder_paths = [], bool $index_numerically = false): array
695
-    {
696
-        $class_to_folder_path = [];
697
-        foreach ($folder_paths as $folder_path) {
698
-            $folder_path = self::standardise_and_end_with_directory_separator($folder_path);
699
-            // load WP_Filesystem and set file permissions
700
-            $files_in_folder      = glob($folder_path . '*.php');
701
-            $class_to_folder_path = [];
702
-            if ($files_in_folder) {
703
-                foreach ($files_in_folder as $file_path) {
704
-                    // only add files, not folders
705
-                    if (! is_dir($file_path)) {
706
-                        if ($index_numerically) {
707
-                            $class_to_folder_path[] = $file_path;
708
-                        } else {
709
-                            $classname                          =
710
-                                self::get_classname_from_filepath_with_standard_filename($file_path);
711
-                            $class_to_folder_path[ $classname ] = $file_path;
712
-                        }
713
-                    }
714
-                }
715
-            }
716
-        }
717
-        return $class_to_folder_path;
718
-    }
719
-
720
-
721
-    /**
722
-     * Copies a file. Mostly a wrapper of WP_Filesystem::copy
723
-     *
724
-     * @param string  $source_file
725
-     * @param string  $destination_file
726
-     * @param boolean $overwrite
727
-     * @return boolean success
728
-     */
729
-    public static function copy(string $source_file, string $destination_file, bool $overwrite = false): bool
730
-    {
731
-        $source_file      = EEH_File::validateFileForCopyOrMove($source_file);
732
-        $destination_file = EEH_File::validateFolderForCopyOrMove($destination_file);
733
-        if (! $source_file || ! $destination_file) {
734
-            return false;
735
-        }
736
-        // load WP_Filesystem and set file permissions
737
-        $wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
738
-        // write the file
739
-        $copied = $wp_filesystem->copy(
740
-            EEH_File::convert_local_filepath_to_remote_filepath($source_file),
741
-            EEH_File::convert_local_filepath_to_remote_filepath($destination_file),
742
-            $overwrite
743
-        );
744
-        if (! $copied) {
745
-            if (defined('WP_DEBUG') && WP_DEBUG) {
746
-                $msg = sprintf(
747
-                    esc_html__(
748
-                        'Attempted writing to file %1$s, but could not, probably because of permissions issues',
749
-                        'event_espresso'
750
-                    ),
751
-                    $source_file
752
-                );
753
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($source_file, 'f');
754
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
755
-            }
756
-            return false;
757
-        }
758
-        return true;
759
-    }
760
-
761
-
762
-    /**
763
-     * Reports whether or not the filepath is in the EE uploads folder or not
764
-     *
765
-     * @param string $filepath
766
-     * @return boolean
767
-     */
768
-    public static function is_in_uploads_folder(string $filepath): bool
769
-    {
770
-        $uploads = wp_upload_dir();
771
-        return strpos($filepath, $uploads['basedir']) === 0;
772
-    }
773
-
774
-
775
-    /**
776
-     * Given a "local" filepath (what you probably thought was the only filepath),
777
-     * converts it into a "remote" filepath (the filepath the currently-in-use
778
-     * $wp_filesystem needs to use access the folder or file).
779
-     * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
780
-     *
781
-     * @param string $local_filepath the filepath to the folder/file locally
782
-     * @return string the remote filepath (eg the filepath the filesystem method, eg
783
-     *                               ftp or ssh, will use to access the folder
784
-     */
785
-    public static function convert_local_filepath_to_remote_filepath(string $local_filepath): string
786
-    {
787
-        $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
788
-        return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
789
-    }
790
-
791
-
792
-    /**
793
-     * wrapper for WP_Filesystem::chmod()
794
-     *
795
-     * @param string    $file      Path to the file.
796
-     * @param int|false $mode      Optional. The permissions as octal number, usually 0644 for files,
797
-     *                             0755 for directories. Default false.
798
-     * @param bool      $recursive Optional. If set to true, changes file permissions recursively.
799
-     *                             Default false.
800
-     * @return bool True on success, false on failure.
801
-     */
802
-    public static function chmod(string $file, $mode = false, bool $recursive = false): bool
803
-    {
804
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
805
-        return $wp_filesystem->chmod($file, $mode, $recursive);
806
-    }
807
-
808
-
809
-    /**
810
-     * wrapper for WP_Filesystem::getchmod()
811
-     *
812
-     * @param string $file Path to the file.
813
-     * @return string Mode of the file (the last 3 digits).
814
-     */
815
-    public static function permissions(string $file): string
816
-    {
817
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
818
-        return $wp_filesystem->getchmod($file);
819
-    }
820
-
821
-
822
-    /**
823
-     * wrapper for WP_Filesystem::owner()
824
-     *
825
-     * @param string $file Path to the file.
826
-     * @return string|false Username of the owner on success, false on failure.
827
-     */
828
-    public static function owner(string $file)
829
-    {
830
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
831
-        return $wp_filesystem->owner($file);
832
-    }
833
-
834
-
835
-    /**
836
-     * wrapper for WP_Filesystem::group()
837
-     *
838
-     * @param string $file Path to the file.
839
-     * @return string|false The group on success, false on failure.
840
-     */
841
-    public static function group(string $file)
842
-    {
843
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
844
-        return $wp_filesystem->group($file);
845
-    }
846
-
847
-
848
-    /**
849
-     * wrapper for WP_Filesystem::move()
850
-     *
851
-     * @param string $source      Path to the source file.
852
-     * @param string $destination Path to the destination file.
853
-     * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
854
-     *                            Default false.
855
-     * @return bool True on success, false on failure.
856
-     */
857
-    public static function move(string $source, string $destination, bool $overwrite = false): bool
858
-    {
859
-        // throw new RuntimeException("source: {$source} && destination: {$destination}");
860
-        $source      = EEH_File::validateFileForCopyOrMove($source);
861
-        $destination = EEH_File::validateFolderForCopyOrMove($destination);
862
-        if (! $source || ! $destination) {
863
-            return false;
864
-        }
865
-        $wp_filesystem = EEH_File::_get_wp_filesystem($source);
866
-        if ($wp_filesystem->move($source, $destination, $overwrite)) {
867
-            return true;
868
-        }
869
-        if (defined('WP_DEBUG') && WP_DEBUG) {
870
-            $file        = EEH_File::convert_local_filepath_to_remote_filepath($source);
871
-            $owner       = EEH_File::owner($file);
872
-            $group       = EEH_File::group($file);
873
-            $permissions = EEH_File::permissions($file);
874
-            EE_Error::add_error(
875
-                sprintf(
876
-                    esc_html__(
877
-                        'Unable to move the file "%1$s" to new location (possible permissions errors). The existing "owner:group permissions" for the file are: "%2$s"',
878
-                        'event_espresso'
879
-                    ),
880
-                    $destination,
881
-                    "{$owner}:{$group} $permissions"
882
-                ),
883
-                __FILE__,
884
-                __FUNCTION__,
885
-                __LINE__
886
-            );
887
-        }
888
-        return false;
889
-    }
890
-
891
-
892
-    /**
893
-     * @param string $source_file
894
-     * @return string
895
-     */
896
-    private static function validateFileForCopyOrMove(string $source_file): string
897
-    {
898
-        $full_source_path = EEH_File::standardise_directory_separators($source_file);
899
-        if (! EEH_File::exists($full_source_path)) {
900
-            if (defined('WP_DEBUG') && WP_DEBUG) {
901
-                $msg =
902
-                    sprintf(
903
-                        esc_html__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'),
904
-                        '',
905
-                        $full_source_path
906
-                    );
907
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
908
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
909
-            }
910
-            return '';
911
-        }
912
-        return $full_source_path;
913
-    }
914
-
915
-
916
-    /**
917
-     * @param string $destination_file
918
-     * @return string
919
-     */
920
-    private static function validateFolderForCopyOrMove(string $destination_file): string
921
-    {
922
-        $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
923
-        $folder         = EEH_File::remove_filename_from_filepath($full_dest_path);
924
-        EEH_File::ensure_folder_exists_and_is_writable($folder);
925
-        if (! EEH_File::verify_is_writable($folder)) {
926
-            if (defined('WP_DEBUG') && WP_DEBUG) {
927
-                $msg = sprintf(
928
-                    esc_html__('The file located at "%2$s" is not writable.', 'event_espresso'),
929
-                    '',
930
-                    $full_dest_path
931
-                );
932
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
933
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
934
-            }
935
-            return '';
936
-        }
937
-        return $full_dest_path;
938
-    }
28
+	/**
29
+	 * @var string $_credentials_form
30
+	 */
31
+	private static $_credentials_form;
32
+
33
+	/**
34
+	 * @var WP_Filesystem_Base $_wp_filesystem
35
+	 */
36
+	protected static $_wp_filesystem;
37
+
38
+
39
+	/**
40
+	 * @param string $filepath      the filepath we want to work in. If its in the
41
+	 *                              wp uploads directory, we'll want to just use the filesystem directly.
42
+	 *                              If not provided, we have to assume its not in the uploads directory
43
+	 * @return WP_Filesystem_Base
44
+	 */
45
+	private static function _get_wp_filesystem($filepath = ''): WP_Filesystem_Base
46
+	{
47
+		if (apply_filters(
48
+			'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
49
+			$filepath && EEH_File::is_in_uploads_folder($filepath),
50
+			$filepath
51
+		)
52
+		) {
53
+			return EEH_File::loadAlternateWpFileSystem();
54
+		}
55
+		return EEH_File::loadWpFileSystem();
56
+	}
57
+
58
+
59
+	/**
60
+	 * @return WP_Filesystem_Base
61
+	 */
62
+	private static function loadAlternateWpFileSystem(): WP_Filesystem_Base
63
+	{
64
+		if (! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
65
+			require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
66
+			$method             = 'direct';
67
+			$wp_filesystem_file =
68
+				apply_filters(
69
+					'filesystem_method_file',
70
+					ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php',
71
+					$method
72
+				);
73
+			// added the following validation logic
74
+			// because we allow the filesystem filepath to be filtered,
75
+			// and are loading whatever file the path pointed to,
76
+			// but we were not validating things in any way :scream_emoji:
77
+			$valid_wp_filesystem_types = [
78
+				'direct'     => 'WP_Filesystem_Direct',
79
+				'ftpext'     => 'WP_Filesystem_FTPext',
80
+				'ftpsockets' => 'WP_Filesystem_ftpsockets',
81
+				'ssh2'       => 'WP_Filesystem_SSH2',
82
+			];
83
+			$valid                     = false;
84
+			$wp_filesystem_class       = '';
85
+			foreach ($valid_wp_filesystem_types as $method => $filesystem_class) {
86
+				// if file path matches for one of valid types, then toggle $valid to true
87
+				if (strpos($wp_filesystem_file, $method) > 0) {
88
+					$valid               = true;
89
+					$wp_filesystem_class = $filesystem_class;
90
+				}
91
+			}
92
+			if (! $valid || ! file_exists($wp_filesystem_file)) {
93
+				EE_Error::add_error(
94
+					sprintf(
95
+						esc_html__(
96
+							'The supplied WP Filesystem filepath "%1$s" is either missing or invalid.',
97
+							'event_espresso'
98
+						),
99
+						$wp_filesystem_file
100
+					),
101
+					__FILE__,
102
+					__FUNCTION__,
103
+					__LINE__
104
+				);
105
+			}
106
+			// check constants defined, just like in the wp-admin/includes/file.php WP_Filesystem()
107
+			if (! defined('FS_CHMOD_DIR')) {
108
+				define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0775 | 0755));
109
+			}
110
+			if (! defined('FS_CHMOD_FILE')) {
111
+				define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0775 | 0644));
112
+			}
113
+			require_once($wp_filesystem_file);
114
+			EEH_File::$_wp_filesystem = new $wp_filesystem_class([]);
115
+		}
116
+		return EEH_File::$_wp_filesystem;
117
+	}
118
+
119
+
120
+	/**
121
+	 * @return WP_Filesystem_Base
122
+	 */
123
+	private static function loadWpFileSystem(): WP_Filesystem_Base
124
+	{
125
+		global $wp_filesystem;
126
+		// no filesystem setup ???
127
+		if (! $wp_filesystem instanceof WP_Filesystem_Base) {
128
+			// if some eager beaver's just trying to get in there too early...
129
+			// let them do it, because we are one of those eager beavers! :P
130
+			/**
131
+			 * more explanations are probably merited.
132
+			 * http://codex.wordpress.org/Filesystem_API#Initializing_WP_Filesystem_Base
133
+			 * says WP_Filesystem should be used after 'wp_loaded', but currently EE's activation process
134
+			 * is setup to mostly happen on 'init', and refactoring to have it happen on
135
+			 * 'wp_loaded' is too much work on a BETA milestone.
136
+			 * So this fix is expected to work if the WP files are owned by the server user,
137
+			 * but probably not if the user needs to enter their FTP credentials to modify files
138
+			 * and there may be troubles if the WP files are owned by a different user
139
+			 * than the server user. But both of these issues should exist in 4.4 and earlier too
140
+			 */
141
+			// if (false && ! did_action('wp_loaded')) {
142
+			//     $msg =
143
+			//         esc_html__(
144
+			//             'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
145
+			//             'event_espresso'
146
+			//         );
147
+			//     if (WP_DEBUG) {
148
+			//         $msg .= '<br />' . esc_html__(
149
+			//             '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.',
150
+			//             'event_espresso'
151
+			//         );
152
+			//     }
153
+			//     EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
154
+			// }
155
+			// should be loaded if we are past the wp_loaded hook...
156
+			if (! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
157
+				require_once(ABSPATH . 'wp-admin/includes/file.php');
158
+				require_once(ABSPATH . 'wp-admin/includes/template.php');
159
+			}
160
+			// turn on output buffering so that we can capture the credentials form
161
+			ob_start();
162
+			$credentials = request_filesystem_credentials(false);
163
+			// store credentials form for the time being
164
+			EEH_File::$_credentials_form = ob_get_clean();
165
+			// if credentials do NOT exist
166
+			if ($credentials === false) {
167
+				add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
168
+				EE_Error::add_error(
169
+					esc_html__(
170
+						'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
171
+						'event_espresso'
172
+					),
173
+					__FILE__,
174
+					__FUNCTION__,
175
+					__LINE__
176
+				);
177
+			}
178
+			// basically check for direct or previously configured access
179
+			if (! WP_Filesystem($credentials)
180
+				&& is_wp_error($wp_filesystem->errors)
181
+				&& $wp_filesystem->errors->get_error_code()
182
+			) {
183
+				add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
184
+				EE_Error::add_error(
185
+					sprintf(
186
+						esc_html__('WP Filesystem Error: $1%s', 'event_espresso'),
187
+						$wp_filesystem->errors->get_error_message()
188
+					),
189
+					__FILE__,
190
+					__FUNCTION__,
191
+					__LINE__
192
+				);
193
+			}
194
+		}
195
+		return $wp_filesystem;
196
+	}
197
+
198
+
199
+	/**
200
+	 * display_request_filesystem_credentials_form
201
+	 */
202
+	public static function display_request_filesystem_credentials_form()
203
+	{
204
+		if (! empty(EEH_File::$_credentials_form)) {
205
+			echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
206
+		}
207
+	}
208
+
209
+
210
+	/**
211
+	 *    verify_filepath_and_permissions
212
+	 *    checks that a file is readable and has sufficient file permissions set to access
213
+	 *
214
+	 * @access public
215
+	 * @param string $full_file_path - full server path to the folder or file
216
+	 * @param string $file_name      - name of file if checking a file
217
+	 * @param string $file_ext       - file extension (ie: "php") if checking a file
218
+	 * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
219
+	 * @return bool
220
+	 */
221
+	public static function verify_filepath_and_permissions(
222
+		string $full_file_path = '',
223
+		string $file_name = '',
224
+		string $file_ext = '',
225
+		string $type_of_file = ''
226
+	): bool {
227
+		// load WP_Filesystem and set file permissions
228
+		$wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
229
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
230
+		if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
231
+			$file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
232
+			$file_name .= ! empty($file_ext) ? ' file' : ' folder';
233
+			$msg       = sprintf(
234
+				esc_html__(
235
+					'The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s',
236
+					'event_espresso'
237
+				),
238
+				$file_name,
239
+				'<br />'
240
+			);
241
+			if (EEH_File::exists($full_file_path)) {
242
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
243
+			} else {
244
+				// no file permissions means the file was not found
245
+				$msg .= sprintf(
246
+					esc_html__('Please ensure the following path is correct: "%s".', 'event_espresso'),
247
+					$full_file_path
248
+				);
249
+			}
250
+			if (defined('WP_DEBUG') && WP_DEBUG) {
251
+				EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
252
+			}
253
+			return false;
254
+		}
255
+		return true;
256
+	}
257
+
258
+
259
+	/**
260
+	 * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a
261
+	 * file or folder
262
+	 *
263
+	 * @access private
264
+	 * @param string $full_file_path - full server path to the folder or file
265
+	 * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
266
+	 * @return string
267
+	 */
268
+	private static function _permissions_error_for_unreadable_filepath(
269
+		string $full_file_path = '',
270
+		string $type_of_file = ''
271
+	): string {
272
+		// load WP_Filesystem and set file permissions
273
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
274
+		// check file permissions
275
+		$perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
276
+		if ($perms) {
277
+			// file permissions exist, but way be set incorrectly
278
+			$type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
279
+			$type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
280
+			return ' ' . sprintf(
281
+				esc_html__(
282
+					'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.',
283
+					'event_espresso'
284
+				),
285
+				$type_of_file,
286
+				$perms
287
+			);
288
+		} else {
289
+			// file exists but file permissions could not be read ?!?!
290
+			return ' ' . sprintf(
291
+				esc_html__(
292
+					'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".',
293
+					'event_espresso'
294
+				),
295
+				$full_file_path
296
+			);
297
+		}
298
+	}
299
+
300
+
301
+	/**
302
+	 * ensure_folder_exists_and_is_writable
303
+	 * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
304
+	 * Also ensures all the parent folders exist, and if not tries to create them.
305
+	 * Also, if this function creates the folder, adds a .htaccess file and index.html file
306
+	 *
307
+	 * @param string $folder
308
+	 * @return bool false if folder isn't writable; true if it exists and is writeable,
309
+	 */
310
+	public static function ensure_folder_exists_and_is_writable(string $folder = ''): bool
311
+	{
312
+		if (empty($folder)) {
313
+			return false;
314
+		}
315
+		// remove ending /
316
+		$folder        = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
317
+		$parent_folder = EEH_File::get_parent_folder($folder);
318
+		// add / to folder
319
+		$folder        = EEH_File::end_with_directory_separator($folder);
320
+		$wp_filesystem = EEH_File::_get_wp_filesystem($folder);
321
+		$remote_dir    = EEH_File::convert_local_filepath_to_remote_filepath($folder);
322
+		if (! $wp_filesystem->is_dir($remote_dir)) {
323
+			// ok so it doesn't exist. Does its parent? Can we write to it?
324
+			if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
325
+				return false;
326
+			}
327
+			if (! EEH_File::verify_is_writable($parent_folder)) {
328
+				return false;
329
+			}
330
+			if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
331
+				if (defined('WP_DEBUG') && WP_DEBUG) {
332
+					$msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
333
+					$msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
334
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
335
+				}
336
+				return false;
337
+			}
338
+			EEH_File::add_index_file($folder);
339
+		} elseif (! EEH_File::verify_is_writable($folder)) {
340
+			return false;
341
+		}
342
+		return true;
343
+	}
344
+
345
+
346
+	/**
347
+	 * verify_is_writable - checks if a file or folder is writable
348
+	 *
349
+	 * @param string $full_path      - full server path to file or folder
350
+	 * @param string $file_or_folder - whether checking a file or folder
351
+	 * @return bool
352
+	 */
353
+	public static function verify_is_writable(string $full_path = '', string $file_or_folder = 'folder'): bool
354
+	{
355
+		// load WP_Filesystem and set file permissions
356
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
357
+		$full_path     = EEH_File::standardise_directory_separators($full_path);
358
+		$remote_path   = EEH_File::convert_local_filepath_to_remote_filepath($full_path);
359
+		$remote_path   = rtrim($remote_path, '/\\');
360
+		if (! $wp_filesystem->is_writable($remote_path)) {
361
+			if (defined('WP_DEBUG') && WP_DEBUG) {
362
+				$msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
363
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
364
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
365
+			}
366
+			return false;
367
+		}
368
+		return true;
369
+	}
370
+
371
+
372
+	/**
373
+	 * ensure_file_exists_and_is_writable
374
+	 * ensures that a file exists and is writable, will attempt to create file if it does not exist.
375
+	 * Also ensures all the parent folders exist, and if not tries to create them.
376
+	 *
377
+	 * @param string $full_file_path
378
+	 * @return bool
379
+	 */
380
+	public static function ensure_file_exists_and_is_writable(string $full_file_path = ''): bool
381
+	{
382
+		// load WP_Filesystem and set file permissions
383
+		$wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
384
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
385
+		$parent_folder  = EEH_File::get_parent_folder($full_file_path);
386
+		if (! EEH_File::exists($full_file_path)) {
387
+			if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
388
+				return false;
389
+			}
390
+			if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
391
+				if (defined('WP_DEBUG') && WP_DEBUG) {
392
+					$msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
393
+					$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
394
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
395
+				}
396
+				return false;
397
+			}
398
+		}
399
+		if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
400
+			return false;
401
+		}
402
+		return true;
403
+	}
404
+
405
+
406
+	/**
407
+	 * Gets the parent folder. If provided with file, gets the folder that contains it.
408
+	 * If provided a folder, gets its parent folder.
409
+	 *
410
+	 * @param string $file_or_folder_path
411
+	 * @return string parent folder, ENDING with a directory separator
412
+	 */
413
+	public static function get_parent_folder(string $file_or_folder_path): string
414
+	{
415
+		// find the last /, ignoring a / on the very end
416
+		// eg if given "/var/something/somewhere/", we want to get "somewhere"'s
417
+		// parent folder, "/var/something/"
418
+		$ds = strlen($file_or_folder_path) > 1
419
+			? strrpos($file_or_folder_path, '/', -2)
420
+			: strlen($file_or_folder_path);
421
+		return substr($file_or_folder_path, 0, $ds + 1);
422
+	}
423
+
424
+
425
+	/**
426
+	 * get_file_contents
427
+	 *
428
+	 * @param string $full_file_path
429
+	 * @return string
430
+	 */
431
+	public static function get_file_contents(string $full_file_path = ''): string
432
+	{
433
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
434
+		if (EEH_File::verify_filepath_and_permissions(
435
+			$full_file_path,
436
+			EEH_File::get_filename_from_filepath($full_file_path),
437
+			EEH_File::get_file_extension($full_file_path)
438
+		)
439
+		) {
440
+			// load WP_Filesystem and set file permissions
441
+			$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
442
+			return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
443
+		}
444
+		return '';
445
+	}
446
+
447
+
448
+	/**
449
+	 * write_file
450
+	 *
451
+	 * @param string $full_file_path
452
+	 * @param string $file_contents - the content to be written to the file
453
+	 * @param string $file_type
454
+	 * @return bool
455
+	 */
456
+	public static function write_to_file(
457
+		string $full_file_path = '',
458
+		string $file_contents = '',
459
+		string $file_type = ''
460
+	): bool {
461
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
462
+		$file_type      = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
463
+		$folder         = EEH_File::remove_filename_from_filepath($full_file_path);
464
+		if (! EEH_File::verify_is_writable($folder)) {
465
+			if (defined('WP_DEBUG') && WP_DEBUG) {
466
+				$msg =
467
+					sprintf(
468
+						esc_html__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'),
469
+						$file_type,
470
+						$full_file_path
471
+					);
472
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
473
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
474
+			}
475
+			return false;
476
+		}
477
+		// load WP_Filesystem and set file permissions
478
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
479
+		// write the file
480
+		if (! $wp_filesystem->put_contents(
481
+			EEH_File::convert_local_filepath_to_remote_filepath($full_file_path),
482
+			$file_contents
483
+		)
484
+		) {
485
+			if (defined('WP_DEBUG') && WP_DEBUG) {
486
+				$msg =
487
+					sprintf(
488
+						esc_html__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'),
489
+						$file_type,
490
+						$full_file_path
491
+					);
492
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
493
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
494
+			}
495
+			return false;
496
+		}
497
+		return true;
498
+	}
499
+
500
+
501
+	/**
502
+	 * Wrapper for WP_Filesystem_Base::delete
503
+	 *
504
+	 * @param string         $filepath
505
+	 * @param boolean        $recursive
506
+	 * @param boolean|string $type 'd' for directory, 'f' for file
507
+	 * @return boolean
508
+	 */
509
+	public static function delete(string $filepath, bool $recursive = false, $type = false): bool
510
+	{
511
+		$wp_filesystem = EEH_File::_get_wp_filesystem();
512
+		return $wp_filesystem->delete($filepath, $recursive, $type);
513
+	}
514
+
515
+
516
+	/**
517
+	 * exists
518
+	 * checks if a file exists using the WP filesystem
519
+	 *
520
+	 * @param string $full_file_path
521
+	 * @return bool
522
+	 */
523
+	public static function exists(string $full_file_path = ''): bool
524
+	{
525
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
526
+		return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
527
+	}
528
+
529
+
530
+	/**
531
+	 * is_readable
532
+	 * checks if a file is_readable using the WP filesystem
533
+	 *
534
+	 * @param string $full_file_path
535
+	 * @return bool
536
+	 */
537
+	public static function is_readable(string $full_file_path = ''): bool
538
+	{
539
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
540
+		return $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
541
+	}
542
+
543
+
544
+	/**
545
+	 * remove_filename_from_filepath
546
+	 * given a full path to a file including the filename itself, this removes  the filename and returns the path, up
547
+	 * to, but NOT including the filename OR slash
548
+	 *
549
+	 * @param string $full_file_path
550
+	 * @return string
551
+	 */
552
+	public static function remove_filename_from_filepath(string $full_file_path = ''): string
553
+	{
554
+		return pathinfo($full_file_path, PATHINFO_DIRNAME);
555
+	}
556
+
557
+
558
+	/**
559
+	 * get_filename_from_filepath. Arguably the same as basename()
560
+	 *
561
+	 * @param string $full_file_path
562
+	 * @return string
563
+	 */
564
+	public static function get_filename_from_filepath(string $full_file_path = ''): string
565
+	{
566
+		return pathinfo($full_file_path, PATHINFO_BASENAME);
567
+	}
568
+
569
+
570
+	/**
571
+	 * get_file_extension
572
+	 *
573
+	 * @param string $full_file_path
574
+	 * @return string
575
+	 */
576
+	public static function get_file_extension(string $full_file_path = ''): string
577
+	{
578
+		return pathinfo($full_file_path, PATHINFO_EXTENSION);
579
+	}
580
+
581
+
582
+	/**
583
+	 * add_htaccess_deny_from_all so the web server cannot access this folder
584
+	 *
585
+	 * @param string $folder
586
+	 * @return bool
587
+	 */
588
+	public static function add_htaccess_deny_from_all(string $folder = ''): bool
589
+	{
590
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
591
+		if (! EEH_File::exists($folder . '.htaccess')) {
592
+			if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
593
+				return false;
594
+			}
595
+		}
596
+
597
+		return true;
598
+	}
599
+
600
+
601
+	/**
602
+	 * Adds an index file to this folder, so folks can't list all the file's contents
603
+	 *
604
+	 * @param string $folder
605
+	 * @return boolean
606
+	 */
607
+	public static function add_index_file(string $folder): bool
608
+	{
609
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
610
+		if (! EEH_File::exists($folder . 'index.php')) {
611
+			if (! EEH_File::write_to_file(
612
+				$folder . 'index.php',
613
+				'You are not permitted to read from this folder',
614
+				'.php'
615
+			)
616
+			) {
617
+				return false;
618
+			}
619
+		}
620
+		return true;
621
+	}
622
+
623
+
624
+	/**
625
+	 * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php),
626
+	 * extract that classname.
627
+	 *
628
+	 * @param string $file_path
629
+	 * @return string
630
+	 */
631
+	public static function get_classname_from_filepath_with_standard_filename(string $file_path): string
632
+	{
633
+		// extract file from path
634
+		$filename = basename($file_path);
635
+		// now remove the first period and everything after
636
+		$pos_of_first_period = strpos($filename, '.');
637
+		return substr($filename, 0, $pos_of_first_period);
638
+	}
639
+
640
+
641
+	/**
642
+	 * standardise_directory_separators
643
+	 *  convert all directory separators in a file path.
644
+	 *
645
+	 * @param string $file_path
646
+	 * @param bool   $rtrim will remove trailing backslash
647
+	 * @return string
648
+	 */
649
+	public static function standardise_directory_separators(string $file_path, bool $rtrim = false): string
650
+	{
651
+		$file_path = $rtrim ? rtrim($file_path, '/\\') : $file_path;
652
+		return str_replace(['\\', '/'], '/', $file_path);
653
+	}
654
+
655
+
656
+	/**
657
+	 * end_with_directory_separator
658
+	 *  ensures that file path ends with '/'
659
+	 *
660
+	 * @param string $file_path
661
+	 * @return string
662
+	 */
663
+	public static function end_with_directory_separator(string $file_path): string
664
+	{
665
+		return rtrim($file_path, '/\\') . '/';
666
+	}
667
+
668
+
669
+	/**
670
+	 * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators
671
+	 *
672
+	 * @param string $file_path
673
+	 * @return string
674
+	 */
675
+	public static function standardise_and_end_with_directory_separator(string $file_path): string
676
+	{
677
+		return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
678
+	}
679
+
680
+
681
+	/**
682
+	 * takes the folder name (with or without trailing slash) and finds the files it in,
683
+	 * and what the class's name inside of each should be.
684
+	 *
685
+	 * @param array   $folder_paths
686
+	 * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically;
687
+	 *                                   if FALSE (Default), returned array will be indexed by the filenames minus
688
+	 *                                   extensions. Set it TRUE if you know there are files in the directory with the
689
+	 *                                   same name but different extensions
690
+	 * @return array if $index_numerically == TRUE keys are numeric ,
691
+	 *                                   if $index_numerically == FALSE (Default) keys are what the class names SHOULD
692
+	 *                                   be; and values are their file paths
693
+	 */
694
+	public static function get_contents_of_folders(array $folder_paths = [], bool $index_numerically = false): array
695
+	{
696
+		$class_to_folder_path = [];
697
+		foreach ($folder_paths as $folder_path) {
698
+			$folder_path = self::standardise_and_end_with_directory_separator($folder_path);
699
+			// load WP_Filesystem and set file permissions
700
+			$files_in_folder      = glob($folder_path . '*.php');
701
+			$class_to_folder_path = [];
702
+			if ($files_in_folder) {
703
+				foreach ($files_in_folder as $file_path) {
704
+					// only add files, not folders
705
+					if (! is_dir($file_path)) {
706
+						if ($index_numerically) {
707
+							$class_to_folder_path[] = $file_path;
708
+						} else {
709
+							$classname                          =
710
+								self::get_classname_from_filepath_with_standard_filename($file_path);
711
+							$class_to_folder_path[ $classname ] = $file_path;
712
+						}
713
+					}
714
+				}
715
+			}
716
+		}
717
+		return $class_to_folder_path;
718
+	}
719
+
720
+
721
+	/**
722
+	 * Copies a file. Mostly a wrapper of WP_Filesystem::copy
723
+	 *
724
+	 * @param string  $source_file
725
+	 * @param string  $destination_file
726
+	 * @param boolean $overwrite
727
+	 * @return boolean success
728
+	 */
729
+	public static function copy(string $source_file, string $destination_file, bool $overwrite = false): bool
730
+	{
731
+		$source_file      = EEH_File::validateFileForCopyOrMove($source_file);
732
+		$destination_file = EEH_File::validateFolderForCopyOrMove($destination_file);
733
+		if (! $source_file || ! $destination_file) {
734
+			return false;
735
+		}
736
+		// load WP_Filesystem and set file permissions
737
+		$wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
738
+		// write the file
739
+		$copied = $wp_filesystem->copy(
740
+			EEH_File::convert_local_filepath_to_remote_filepath($source_file),
741
+			EEH_File::convert_local_filepath_to_remote_filepath($destination_file),
742
+			$overwrite
743
+		);
744
+		if (! $copied) {
745
+			if (defined('WP_DEBUG') && WP_DEBUG) {
746
+				$msg = sprintf(
747
+					esc_html__(
748
+						'Attempted writing to file %1$s, but could not, probably because of permissions issues',
749
+						'event_espresso'
750
+					),
751
+					$source_file
752
+				);
753
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($source_file, 'f');
754
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
755
+			}
756
+			return false;
757
+		}
758
+		return true;
759
+	}
760
+
761
+
762
+	/**
763
+	 * Reports whether or not the filepath is in the EE uploads folder or not
764
+	 *
765
+	 * @param string $filepath
766
+	 * @return boolean
767
+	 */
768
+	public static function is_in_uploads_folder(string $filepath): bool
769
+	{
770
+		$uploads = wp_upload_dir();
771
+		return strpos($filepath, $uploads['basedir']) === 0;
772
+	}
773
+
774
+
775
+	/**
776
+	 * Given a "local" filepath (what you probably thought was the only filepath),
777
+	 * converts it into a "remote" filepath (the filepath the currently-in-use
778
+	 * $wp_filesystem needs to use access the folder or file).
779
+	 * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
780
+	 *
781
+	 * @param string $local_filepath the filepath to the folder/file locally
782
+	 * @return string the remote filepath (eg the filepath the filesystem method, eg
783
+	 *                               ftp or ssh, will use to access the folder
784
+	 */
785
+	public static function convert_local_filepath_to_remote_filepath(string $local_filepath): string
786
+	{
787
+		$wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
788
+		return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
789
+	}
790
+
791
+
792
+	/**
793
+	 * wrapper for WP_Filesystem::chmod()
794
+	 *
795
+	 * @param string    $file      Path to the file.
796
+	 * @param int|false $mode      Optional. The permissions as octal number, usually 0644 for files,
797
+	 *                             0755 for directories. Default false.
798
+	 * @param bool      $recursive Optional. If set to true, changes file permissions recursively.
799
+	 *                             Default false.
800
+	 * @return bool True on success, false on failure.
801
+	 */
802
+	public static function chmod(string $file, $mode = false, bool $recursive = false): bool
803
+	{
804
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
805
+		return $wp_filesystem->chmod($file, $mode, $recursive);
806
+	}
807
+
808
+
809
+	/**
810
+	 * wrapper for WP_Filesystem::getchmod()
811
+	 *
812
+	 * @param string $file Path to the file.
813
+	 * @return string Mode of the file (the last 3 digits).
814
+	 */
815
+	public static function permissions(string $file): string
816
+	{
817
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
818
+		return $wp_filesystem->getchmod($file);
819
+	}
820
+
821
+
822
+	/**
823
+	 * wrapper for WP_Filesystem::owner()
824
+	 *
825
+	 * @param string $file Path to the file.
826
+	 * @return string|false Username of the owner on success, false on failure.
827
+	 */
828
+	public static function owner(string $file)
829
+	{
830
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
831
+		return $wp_filesystem->owner($file);
832
+	}
833
+
834
+
835
+	/**
836
+	 * wrapper for WP_Filesystem::group()
837
+	 *
838
+	 * @param string $file Path to the file.
839
+	 * @return string|false The group on success, false on failure.
840
+	 */
841
+	public static function group(string $file)
842
+	{
843
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
844
+		return $wp_filesystem->group($file);
845
+	}
846
+
847
+
848
+	/**
849
+	 * wrapper for WP_Filesystem::move()
850
+	 *
851
+	 * @param string $source      Path to the source file.
852
+	 * @param string $destination Path to the destination file.
853
+	 * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
854
+	 *                            Default false.
855
+	 * @return bool True on success, false on failure.
856
+	 */
857
+	public static function move(string $source, string $destination, bool $overwrite = false): bool
858
+	{
859
+		// throw new RuntimeException("source: {$source} && destination: {$destination}");
860
+		$source      = EEH_File::validateFileForCopyOrMove($source);
861
+		$destination = EEH_File::validateFolderForCopyOrMove($destination);
862
+		if (! $source || ! $destination) {
863
+			return false;
864
+		}
865
+		$wp_filesystem = EEH_File::_get_wp_filesystem($source);
866
+		if ($wp_filesystem->move($source, $destination, $overwrite)) {
867
+			return true;
868
+		}
869
+		if (defined('WP_DEBUG') && WP_DEBUG) {
870
+			$file        = EEH_File::convert_local_filepath_to_remote_filepath($source);
871
+			$owner       = EEH_File::owner($file);
872
+			$group       = EEH_File::group($file);
873
+			$permissions = EEH_File::permissions($file);
874
+			EE_Error::add_error(
875
+				sprintf(
876
+					esc_html__(
877
+						'Unable to move the file "%1$s" to new location (possible permissions errors). The existing "owner:group permissions" for the file are: "%2$s"',
878
+						'event_espresso'
879
+					),
880
+					$destination,
881
+					"{$owner}:{$group} $permissions"
882
+				),
883
+				__FILE__,
884
+				__FUNCTION__,
885
+				__LINE__
886
+			);
887
+		}
888
+		return false;
889
+	}
890
+
891
+
892
+	/**
893
+	 * @param string $source_file
894
+	 * @return string
895
+	 */
896
+	private static function validateFileForCopyOrMove(string $source_file): string
897
+	{
898
+		$full_source_path = EEH_File::standardise_directory_separators($source_file);
899
+		if (! EEH_File::exists($full_source_path)) {
900
+			if (defined('WP_DEBUG') && WP_DEBUG) {
901
+				$msg =
902
+					sprintf(
903
+						esc_html__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'),
904
+						'',
905
+						$full_source_path
906
+					);
907
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
908
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
909
+			}
910
+			return '';
911
+		}
912
+		return $full_source_path;
913
+	}
914
+
915
+
916
+	/**
917
+	 * @param string $destination_file
918
+	 * @return string
919
+	 */
920
+	private static function validateFolderForCopyOrMove(string $destination_file): string
921
+	{
922
+		$full_dest_path = EEH_File::standardise_directory_separators($destination_file);
923
+		$folder         = EEH_File::remove_filename_from_filepath($full_dest_path);
924
+		EEH_File::ensure_folder_exists_and_is_writable($folder);
925
+		if (! EEH_File::verify_is_writable($folder)) {
926
+			if (defined('WP_DEBUG') && WP_DEBUG) {
927
+				$msg = sprintf(
928
+					esc_html__('The file located at "%2$s" is not writable.', 'event_espresso'),
929
+					'',
930
+					$full_dest_path
931
+				);
932
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
933
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
934
+			}
935
+			return '';
936
+		}
937
+		return $full_dest_path;
938
+	}
939 939
 }
Please login to merge, or discard this patch.
Spacing   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -61,13 +61,13 @@  discard block
 block discarded – undo
61 61
      */
62 62
     private static function loadAlternateWpFileSystem(): WP_Filesystem_Base
63 63
     {
64
-        if (! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
65
-            require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
64
+        if ( ! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
65
+            require_once(ABSPATH.'wp-admin/includes/class-wp-filesystem-base.php');
66 66
             $method             = 'direct';
67 67
             $wp_filesystem_file =
68 68
                 apply_filters(
69 69
                     'filesystem_method_file',
70
-                    ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php',
70
+                    ABSPATH.'wp-admin/includes/class-wp-filesystem-'.$method.'.php',
71 71
                     $method
72 72
                 );
73 73
             // added the following validation logic
@@ -89,7 +89,7 @@  discard block
 block discarded – undo
89 89
                     $wp_filesystem_class = $filesystem_class;
90 90
                 }
91 91
             }
92
-            if (! $valid || ! file_exists($wp_filesystem_file)) {
92
+            if ( ! $valid || ! file_exists($wp_filesystem_file)) {
93 93
                 EE_Error::add_error(
94 94
                     sprintf(
95 95
                         esc_html__(
@@ -104,11 +104,11 @@  discard block
 block discarded – undo
104 104
                 );
105 105
             }
106 106
             // check constants defined, just like in the wp-admin/includes/file.php WP_Filesystem()
107
-            if (! defined('FS_CHMOD_DIR')) {
107
+            if ( ! defined('FS_CHMOD_DIR')) {
108 108
                 define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0775 | 0755));
109 109
             }
110
-            if (! defined('FS_CHMOD_FILE')) {
111
-                define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0775 | 0644));
110
+            if ( ! defined('FS_CHMOD_FILE')) {
111
+                define('FS_CHMOD_FILE', (fileperms(ABSPATH.'index.php') & 0775 | 0644));
112 112
             }
113 113
             require_once($wp_filesystem_file);
114 114
             EEH_File::$_wp_filesystem = new $wp_filesystem_class([]);
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
     {
125 125
         global $wp_filesystem;
126 126
         // no filesystem setup ???
127
-        if (! $wp_filesystem instanceof WP_Filesystem_Base) {
127
+        if ( ! $wp_filesystem instanceof WP_Filesystem_Base) {
128 128
             // if some eager beaver's just trying to get in there too early...
129 129
             // let them do it, because we are one of those eager beavers! :P
130 130
             /**
@@ -153,9 +153,9 @@  discard block
 block discarded – undo
153 153
             //     EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
154 154
             // }
155 155
             // should be loaded if we are past the wp_loaded hook...
156
-            if (! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
157
-                require_once(ABSPATH . 'wp-admin/includes/file.php');
158
-                require_once(ABSPATH . 'wp-admin/includes/template.php');
156
+            if ( ! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
157
+                require_once(ABSPATH.'wp-admin/includes/file.php');
158
+                require_once(ABSPATH.'wp-admin/includes/template.php');
159 159
             }
160 160
             // turn on output buffering so that we can capture the credentials form
161 161
             ob_start();
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
                 );
177 177
             }
178 178
             // basically check for direct or previously configured access
179
-            if (! WP_Filesystem($credentials)
179
+            if ( ! WP_Filesystem($credentials)
180 180
                 && is_wp_error($wp_filesystem->errors)
181 181
                 && $wp_filesystem->errors->get_error_code()
182 182
             ) {
@@ -201,8 +201,8 @@  discard block
 block discarded – undo
201 201
      */
202 202
     public static function display_request_filesystem_credentials_form()
203 203
     {
204
-        if (! empty(EEH_File::$_credentials_form)) {
205
-            echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
204
+        if ( ! empty(EEH_File::$_credentials_form)) {
205
+            echo '<div class="updated espresso-notices-attention"><p>'.EEH_File::$_credentials_form.'</p></div>';
206 206
         }
207 207
     }
208 208
 
@@ -227,8 +227,8 @@  discard block
 block discarded – undo
227 227
         // load WP_Filesystem and set file permissions
228 228
         $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
229 229
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
230
-        if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
231
-            $file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
230
+        if ( ! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
231
+            $file_name = ! empty($type_of_file) ? $file_name.' '.$type_of_file : $file_name;
232 232
             $file_name .= ! empty($file_ext) ? ' file' : ' folder';
233 233
             $msg       = sprintf(
234 234
                 esc_html__(
@@ -248,7 +248,7 @@  discard block
 block discarded – undo
248 248
                 );
249 249
             }
250 250
             if (defined('WP_DEBUG') && WP_DEBUG) {
251
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
251
+                EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
252 252
             }
253 253
             return false;
254 254
         }
@@ -275,9 +275,9 @@  discard block
 block discarded – undo
275 275
         $perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
276 276
         if ($perms) {
277 277
             // file permissions exist, but way be set incorrectly
278
-            $type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
278
+            $type_of_file = ! empty($type_of_file) ? $type_of_file.' ' : '';
279 279
             $type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
280
-            return ' ' . sprintf(
280
+            return ' '.sprintf(
281 281
                 esc_html__(
282 282
                     'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.',
283 283
                     'event_espresso'
@@ -287,7 +287,7 @@  discard block
 block discarded – undo
287 287
             );
288 288
         } else {
289 289
             // file exists but file permissions could not be read ?!?!
290
-            return ' ' . sprintf(
290
+            return ' '.sprintf(
291 291
                 esc_html__(
292 292
                     'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".',
293 293
                     'event_espresso'
@@ -319,15 +319,15 @@  discard block
 block discarded – undo
319 319
         $folder        = EEH_File::end_with_directory_separator($folder);
320 320
         $wp_filesystem = EEH_File::_get_wp_filesystem($folder);
321 321
         $remote_dir    = EEH_File::convert_local_filepath_to_remote_filepath($folder);
322
-        if (! $wp_filesystem->is_dir($remote_dir)) {
322
+        if ( ! $wp_filesystem->is_dir($remote_dir)) {
323 323
             // ok so it doesn't exist. Does its parent? Can we write to it?
324
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
324
+            if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
325 325
                 return false;
326 326
             }
327
-            if (! EEH_File::verify_is_writable($parent_folder)) {
327
+            if ( ! EEH_File::verify_is_writable($parent_folder)) {
328 328
                 return false;
329 329
             }
330
-            if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
330
+            if ( ! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
331 331
                 if (defined('WP_DEBUG') && WP_DEBUG) {
332 332
                     $msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
333 333
                     $msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
                 return false;
337 337
             }
338 338
             EEH_File::add_index_file($folder);
339
-        } elseif (! EEH_File::verify_is_writable($folder)) {
339
+        } elseif ( ! EEH_File::verify_is_writable($folder)) {
340 340
             return false;
341 341
         }
342 342
         return true;
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
         $full_path     = EEH_File::standardise_directory_separators($full_path);
358 358
         $remote_path   = EEH_File::convert_local_filepath_to_remote_filepath($full_path);
359 359
         $remote_path   = rtrim($remote_path, '/\\');
360
-        if (! $wp_filesystem->is_writable($remote_path)) {
360
+        if ( ! $wp_filesystem->is_writable($remote_path)) {
361 361
             if (defined('WP_DEBUG') && WP_DEBUG) {
362 362
                 $msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
363 363
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
@@ -383,11 +383,11 @@  discard block
 block discarded – undo
383 383
         $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
384 384
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
385 385
         $parent_folder  = EEH_File::get_parent_folder($full_file_path);
386
-        if (! EEH_File::exists($full_file_path)) {
387
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
386
+        if ( ! EEH_File::exists($full_file_path)) {
387
+            if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
388 388
                 return false;
389 389
             }
390
-            if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
390
+            if ( ! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
391 391
                 if (defined('WP_DEBUG') && WP_DEBUG) {
392 392
                     $msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
393 393
                     $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
                 return false;
397 397
             }
398 398
         }
399
-        if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
399
+        if ( ! EEH_File::verify_is_writable($full_file_path, 'file')) {
400 400
             return false;
401 401
         }
402 402
         return true;
@@ -459,9 +459,9 @@  discard block
 block discarded – undo
459 459
         string $file_type = ''
460 460
     ): bool {
461 461
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
462
-        $file_type      = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
462
+        $file_type      = ! empty($file_type) ? rtrim($file_type, ' ').' ' : '';
463 463
         $folder         = EEH_File::remove_filename_from_filepath($full_file_path);
464
-        if (! EEH_File::verify_is_writable($folder)) {
464
+        if ( ! EEH_File::verify_is_writable($folder)) {
465 465
             if (defined('WP_DEBUG') && WP_DEBUG) {
466 466
                 $msg =
467 467
                     sprintf(
@@ -477,7 +477,7 @@  discard block
 block discarded – undo
477 477
         // load WP_Filesystem and set file permissions
478 478
         $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
479 479
         // write the file
480
-        if (! $wp_filesystem->put_contents(
480
+        if ( ! $wp_filesystem->put_contents(
481 481
             EEH_File::convert_local_filepath_to_remote_filepath($full_file_path),
482 482
             $file_contents
483 483
         )
@@ -588,8 +588,8 @@  discard block
 block discarded – undo
588 588
     public static function add_htaccess_deny_from_all(string $folder = ''): bool
589 589
     {
590 590
         $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
591
-        if (! EEH_File::exists($folder . '.htaccess')) {
592
-            if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
591
+        if ( ! EEH_File::exists($folder.'.htaccess')) {
592
+            if ( ! EEH_File::write_to_file($folder.'.htaccess', 'deny from all', '.htaccess')) {
593 593
                 return false;
594 594
             }
595 595
         }
@@ -607,9 +607,9 @@  discard block
 block discarded – undo
607 607
     public static function add_index_file(string $folder): bool
608 608
     {
609 609
         $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
610
-        if (! EEH_File::exists($folder . 'index.php')) {
611
-            if (! EEH_File::write_to_file(
612
-                $folder . 'index.php',
610
+        if ( ! EEH_File::exists($folder.'index.php')) {
611
+            if ( ! EEH_File::write_to_file(
612
+                $folder.'index.php',
613 613
                 'You are not permitted to read from this folder',
614 614
                 '.php'
615 615
             )
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
      */
663 663
     public static function end_with_directory_separator(string $file_path): string
664 664
     {
665
-        return rtrim($file_path, '/\\') . '/';
665
+        return rtrim($file_path, '/\\').'/';
666 666
     }
667 667
 
668 668
 
@@ -697,18 +697,18 @@  discard block
 block discarded – undo
697 697
         foreach ($folder_paths as $folder_path) {
698 698
             $folder_path = self::standardise_and_end_with_directory_separator($folder_path);
699 699
             // load WP_Filesystem and set file permissions
700
-            $files_in_folder      = glob($folder_path . '*.php');
700
+            $files_in_folder      = glob($folder_path.'*.php');
701 701
             $class_to_folder_path = [];
702 702
             if ($files_in_folder) {
703 703
                 foreach ($files_in_folder as $file_path) {
704 704
                     // only add files, not folders
705
-                    if (! is_dir($file_path)) {
705
+                    if ( ! is_dir($file_path)) {
706 706
                         if ($index_numerically) {
707 707
                             $class_to_folder_path[] = $file_path;
708 708
                         } else {
709 709
                             $classname                          =
710 710
                                 self::get_classname_from_filepath_with_standard_filename($file_path);
711
-                            $class_to_folder_path[ $classname ] = $file_path;
711
+                            $class_to_folder_path[$classname] = $file_path;
712 712
                         }
713 713
                     }
714 714
                 }
@@ -730,7 +730,7 @@  discard block
 block discarded – undo
730 730
     {
731 731
         $source_file      = EEH_File::validateFileForCopyOrMove($source_file);
732 732
         $destination_file = EEH_File::validateFolderForCopyOrMove($destination_file);
733
-        if (! $source_file || ! $destination_file) {
733
+        if ( ! $source_file || ! $destination_file) {
734 734
             return false;
735 735
         }
736 736
         // load WP_Filesystem and set file permissions
@@ -741,7 +741,7 @@  discard block
 block discarded – undo
741 741
             EEH_File::convert_local_filepath_to_remote_filepath($destination_file),
742 742
             $overwrite
743 743
         );
744
-        if (! $copied) {
744
+        if ( ! $copied) {
745 745
             if (defined('WP_DEBUG') && WP_DEBUG) {
746 746
                 $msg = sprintf(
747 747
                     esc_html__(
@@ -785,7 +785,7 @@  discard block
 block discarded – undo
785 785
     public static function convert_local_filepath_to_remote_filepath(string $local_filepath): string
786 786
     {
787 787
         $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
788
-        return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
788
+        return str_replace(WP_CONTENT_DIR.'/', $wp_filesystem->wp_content_dir(), $local_filepath);
789 789
     }
790 790
 
791 791
 
@@ -859,7 +859,7 @@  discard block
 block discarded – undo
859 859
         // throw new RuntimeException("source: {$source} && destination: {$destination}");
860 860
         $source      = EEH_File::validateFileForCopyOrMove($source);
861 861
         $destination = EEH_File::validateFolderForCopyOrMove($destination);
862
-        if (! $source || ! $destination) {
862
+        if ( ! $source || ! $destination) {
863 863
             return false;
864 864
         }
865 865
         $wp_filesystem = EEH_File::_get_wp_filesystem($source);
@@ -896,7 +896,7 @@  discard block
 block discarded – undo
896 896
     private static function validateFileForCopyOrMove(string $source_file): string
897 897
     {
898 898
         $full_source_path = EEH_File::standardise_directory_separators($source_file);
899
-        if (! EEH_File::exists($full_source_path)) {
899
+        if ( ! EEH_File::exists($full_source_path)) {
900 900
             if (defined('WP_DEBUG') && WP_DEBUG) {
901 901
                 $msg =
902 902
                     sprintf(
@@ -922,7 +922,7 @@  discard block
 block discarded – undo
922 922
         $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
923 923
         $folder         = EEH_File::remove_filename_from_filepath($full_dest_path);
924 924
         EEH_File::ensure_folder_exists_and_is_writable($folder);
925
-        if (! EEH_File::verify_is_writable($folder)) {
925
+        if ( ! EEH_File::verify_is_writable($folder)) {
926 926
             if (defined('WP_DEBUG') && WP_DEBUG) {
927 927
                 $msg = sprintf(
928 928
                     esc_html__('The file located at "%2$s" is not writable.', 'event_espresso'),
Please login to merge, or discard this patch.
core/EE_Addon.core.php 2 patches
Indentation   +855 added lines, -855 removed lines patch added patch discarded remove patch
@@ -19,806 +19,806 @@  discard block
 block discarded – undo
19 19
 {
20 20
 
21 21
 
22
-    /**
23
-     * prefix to be added onto an addon's plugin slug to make a wp option name
24
-     * which will be used to store the plugin's activation history
25
-     */
26
-    const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
-
28
-    /**
29
-     * @var $_version
30
-     * @type string
31
-     */
32
-    protected $_version = '';
33
-
34
-    /**
35
-     * @var $_min_core_version
36
-     * @type string
37
-     */
38
-    protected $_min_core_version = '';
39
-
40
-    /**
41
-     * derived from plugin 'main_file_path using plugin_basename()
42
-     *
43
-     * @type string $_plugin_basename
44
-     */
45
-    protected $_plugin_basename = '';
46
-
47
-    /**
48
-     * A non-internationalized name to identify this addon for use in URLs, etc
49
-     *
50
-     * @type string $_plugin_slug
51
-     */
52
-    protected $_plugin_slug = '';
53
-
54
-    /**
55
-     * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
-     *
57
-     * @type string _addon_name
58
-     */
59
-    protected $_addon_name = '';
60
-
61
-    /**
62
-     * one of the EE_System::req_type_* constants
63
-     *
64
-     * @type int $_req_type
65
-     */
66
-    protected $_req_type;
67
-
68
-    /**
69
-     * page slug to be used when generating the "Settings" link on the WP plugin page
70
-     *
71
-     * @type string $_plugin_action_slug
72
-     */
73
-    protected $_plugin_action_slug = '';
74
-
75
-    /**
76
-     * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
-     * that can be used for adding upgrading/marketing info
78
-     *
79
-     * @type array $_plugins_page_row
80
-     */
81
-    protected $_plugins_page_row = [];
82
-
83
-
84
-    /**
85
-     *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
-     *
87
-     * @type string
88
-     */
89
-    protected $_main_plugin_file;
90
-
91
-    /**
92
-     *    This is the slug used to identify this add-on within the plugin update engine.
93
-     *
94
-     * @type string
95
-     */
96
-    protected $pue_slug;
97
-
98
-
99
-    /**
100
-     * @var EE_Dependency_Map $dependency_map
101
-     */
102
-    private $dependency_map;
103
-
104
-
105
-    /**
106
-     * @var DomainInterface $domain
107
-     */
108
-    private $domain;
109
-
110
-
111
-    /**
112
-     * @param EE_Dependency_Map|null $dependency_map [optional]
113
-     * @param DomainInterface|null   $domain         [optional]
114
-     */
115
-    public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
-    {
117
-        if ($dependency_map instanceof EE_Dependency_Map) {
118
-            $this->setDependencyMap($dependency_map);
119
-        }
120
-        if ($domain instanceof DomainInterface) {
121
-            $this->setDomain($domain);
122
-        }
123
-        add_action('AHEE__EE_System__load_controllers__load_admin_controllers', [$this, 'admin_init']);
124
-    }
125
-
126
-
127
-    /**
128
-     * @param EE_Dependency_Map $dependency_map
129
-     */
130
-    public function setDependencyMap($dependency_map)
131
-    {
132
-        $this->dependency_map = $dependency_map;
133
-    }
134
-
135
-
136
-    /**
137
-     * @return EE_Dependency_Map
138
-     */
139
-    public function dependencyMap(): ?EE_Dependency_Map
140
-    {
141
-        return $this->dependency_map;
142
-    }
143
-
144
-
145
-    /**
146
-     * @param DomainInterface $domain
147
-     */
148
-    public function setDomain(DomainInterface $domain)
149
-    {
150
-        $this->domain = $domain;
151
-    }
152
-
153
-
154
-    /**
155
-     * @return DomainInterface
156
-     */
157
-    public function domain(): ?DomainInterface
158
-    {
159
-        return $this->domain;
160
-    }
161
-
162
-
163
-    /**
164
-     * @param string $version
165
-     */
166
-    public function set_version(string $version = '')
167
-    {
168
-        $this->_version = $version;
169
-    }
170
-
171
-
172
-    /**
173
-     * get__version
174
-     *
175
-     * @return string
176
-     */
177
-    public function version(): string
178
-    {
179
-        return $this->_version;
180
-    }
181
-
182
-
183
-    /**
184
-     * @param mixed $min_core_version
185
-     */
186
-    public function set_min_core_version($min_core_version = null)
187
-    {
188
-        $this->_min_core_version = $min_core_version;
189
-    }
190
-
191
-
192
-    /**
193
-     * get__min_core_version
194
-     *
195
-     * @return string
196
-     */
197
-    public function min_core_version(): string
198
-    {
199
-        return $this->_min_core_version;
200
-    }
201
-
202
-
203
-    /**
204
-     * Sets addon_name
205
-     *
206
-     * @param string $addon_name
207
-     */
208
-    public function set_name(string $addon_name)
209
-    {
210
-        $this->_addon_name = $addon_name;
211
-    }
212
-
213
-
214
-    /**
215
-     * Gets addon_name
216
-     *
217
-     * @return string
218
-     */
219
-    public function name(): string
220
-    {
221
-        return $this->_addon_name;
222
-    }
223
-
224
-
225
-    /**
226
-     * @return string
227
-     */
228
-    public function plugin_basename(): string
229
-    {
230
-
231
-        return $this->_plugin_basename;
232
-    }
233
-
234
-
235
-    /**
236
-     * @param string $plugin_basename
237
-     */
238
-    public function set_plugin_basename(string $plugin_basename)
239
-    {
240
-
241
-        $this->_plugin_basename = $plugin_basename;
242
-    }
243
-
244
-
245
-    /**
246
-     * @return string
247
-     */
248
-    public function plugin_slug(): string
249
-    {
250
-
251
-        return $this->_plugin_slug;
252
-    }
253
-
254
-
255
-    /**
256
-     * @param string $plugin_slug
257
-     */
258
-    public function set_plugin_slug(string $plugin_slug)
259
-    {
260
-
261
-        $this->_plugin_slug = $plugin_slug;
262
-    }
263
-
264
-
265
-    /**
266
-     * @return string
267
-     */
268
-    public function plugin_action_slug(): string
269
-    {
270
-
271
-        return $this->_plugin_action_slug;
272
-    }
273
-
274
-
275
-    /**
276
-     * @param string $plugin_action_slug
277
-     */
278
-    public function set_plugin_action_slug(string $plugin_action_slug)
279
-    {
280
-
281
-        $this->_plugin_action_slug = $plugin_action_slug;
282
-    }
283
-
284
-
285
-    /**
286
-     * @return array
287
-     */
288
-    public function get_plugins_page_row(): array
289
-    {
290
-
291
-        return $this->_plugins_page_row;
292
-    }
293
-
294
-
295
-    /**
296
-     * @param array|string $plugins_page_row
297
-     */
298
-    public function set_plugins_page_row(array $plugins_page_row = [])
299
-    {
300
-        // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (! is_array($plugins_page_row)
302
-            && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303
-        ) {
304
-            $plugins_page_row = [];
305
-        }
306
-        $this->_plugins_page_row = (array) $plugins_page_row;
307
-    }
308
-
309
-
310
-    /**
311
-     * Called when EE core detects this addon has been activated for the first time.
312
-     * If the site isn't in maintenance mode, should setup the addon's database
313
-     *
314
-     * @return void
315
-     */
316
-    public function new_install()
317
-    {
318
-        $classname = get_class($this);
319
-        do_action("AHEE__{$classname}__new_install");
320
-        do_action('AHEE__EE_Addon__new_install', $this);
321
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
322
-        add_action(
323
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
324
-            [$this, 'initialize_db_if_no_migrations_required']
325
-        );
326
-    }
327
-
328
-
329
-    /**
330
-     * Called when EE core detects this addon has been reactivated. When this happens,
331
-     * it's good to just check that your data is still intact
332
-     *
333
-     * @return void
334
-     */
335
-    public function reactivation()
336
-    {
337
-        $classname = get_class($this);
338
-        do_action("AHEE__{$classname}__reactivation");
339
-        do_action('AHEE__EE_Addon__reactivation', $this);
340
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
341
-        add_action(
342
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
343
-            [$this, 'initialize_db_if_no_migrations_required']
344
-        );
345
-    }
346
-
347
-
348
-    /**
349
-     * Called when the registered deactivation hook for this addon fires.
350
-     *
351
-     * @throws EE_Error
352
-     */
353
-    public function deactivation()
354
-    {
355
-        $classname = get_class($this);
356
-        do_action("AHEE__{$classname}__deactivation");
357
-        do_action('AHEE__EE_Addon__deactivation', $this);
358
-        // check if the site no longer needs to be in maintenance mode
359
-        EE_Register_Addon::deregister($this->name());
360
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
361
-    }
362
-
363
-
364
-    /**
365
-     * Takes care of double-checking that we're not in maintenance mode, and then
366
-     * initializing this addon's necessary initial data. This is called by default on new activations
367
-     * and reactivations.
368
-     *
369
-     * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
370
-     *                               This is a resource-intensive job so we prefer to only do it when necessary
371
-     * @return void
372
-     * @throws EE_Error
373
-     * @throws InvalidInterfaceException
374
-     * @throws InvalidDataTypeException
375
-     * @throws InvalidArgumentException
376
-     * @throws ReflectionException
377
-     */
378
-    public function initialize_db_if_no_migrations_required($verify_schema = true)
379
-    {
380
-        if ($verify_schema === '') {
381
-            // wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
382
-            // (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
383
-            // calls them with an argument of an empty string (ie ""), which evaluates to false
384
-            // so we need to treat the empty string as if nothing had been passed, and should instead use the default
385
-            $verify_schema = true;
386
-        }
387
-        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
388
-            if ($verify_schema) {
389
-                $this->initialize_db();
390
-            }
391
-            $this->initialize_default_data();
392
-            // @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
393
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to(
394
-                [
395
-                    'slug'    => $this->name(),
396
-                    'version' => $this->version(),
397
-                ]
398
-            );
399
-            /* make sure core's data is a-ok
22
+	/**
23
+	 * prefix to be added onto an addon's plugin slug to make a wp option name
24
+	 * which will be used to store the plugin's activation history
25
+	 */
26
+	const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
+
28
+	/**
29
+	 * @var $_version
30
+	 * @type string
31
+	 */
32
+	protected $_version = '';
33
+
34
+	/**
35
+	 * @var $_min_core_version
36
+	 * @type string
37
+	 */
38
+	protected $_min_core_version = '';
39
+
40
+	/**
41
+	 * derived from plugin 'main_file_path using plugin_basename()
42
+	 *
43
+	 * @type string $_plugin_basename
44
+	 */
45
+	protected $_plugin_basename = '';
46
+
47
+	/**
48
+	 * A non-internationalized name to identify this addon for use in URLs, etc
49
+	 *
50
+	 * @type string $_plugin_slug
51
+	 */
52
+	protected $_plugin_slug = '';
53
+
54
+	/**
55
+	 * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
+	 *
57
+	 * @type string _addon_name
58
+	 */
59
+	protected $_addon_name = '';
60
+
61
+	/**
62
+	 * one of the EE_System::req_type_* constants
63
+	 *
64
+	 * @type int $_req_type
65
+	 */
66
+	protected $_req_type;
67
+
68
+	/**
69
+	 * page slug to be used when generating the "Settings" link on the WP plugin page
70
+	 *
71
+	 * @type string $_plugin_action_slug
72
+	 */
73
+	protected $_plugin_action_slug = '';
74
+
75
+	/**
76
+	 * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
+	 * that can be used for adding upgrading/marketing info
78
+	 *
79
+	 * @type array $_plugins_page_row
80
+	 */
81
+	protected $_plugins_page_row = [];
82
+
83
+
84
+	/**
85
+	 *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
+	 *
87
+	 * @type string
88
+	 */
89
+	protected $_main_plugin_file;
90
+
91
+	/**
92
+	 *    This is the slug used to identify this add-on within the plugin update engine.
93
+	 *
94
+	 * @type string
95
+	 */
96
+	protected $pue_slug;
97
+
98
+
99
+	/**
100
+	 * @var EE_Dependency_Map $dependency_map
101
+	 */
102
+	private $dependency_map;
103
+
104
+
105
+	/**
106
+	 * @var DomainInterface $domain
107
+	 */
108
+	private $domain;
109
+
110
+
111
+	/**
112
+	 * @param EE_Dependency_Map|null $dependency_map [optional]
113
+	 * @param DomainInterface|null   $domain         [optional]
114
+	 */
115
+	public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
+	{
117
+		if ($dependency_map instanceof EE_Dependency_Map) {
118
+			$this->setDependencyMap($dependency_map);
119
+		}
120
+		if ($domain instanceof DomainInterface) {
121
+			$this->setDomain($domain);
122
+		}
123
+		add_action('AHEE__EE_System__load_controllers__load_admin_controllers', [$this, 'admin_init']);
124
+	}
125
+
126
+
127
+	/**
128
+	 * @param EE_Dependency_Map $dependency_map
129
+	 */
130
+	public function setDependencyMap($dependency_map)
131
+	{
132
+		$this->dependency_map = $dependency_map;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @return EE_Dependency_Map
138
+	 */
139
+	public function dependencyMap(): ?EE_Dependency_Map
140
+	{
141
+		return $this->dependency_map;
142
+	}
143
+
144
+
145
+	/**
146
+	 * @param DomainInterface $domain
147
+	 */
148
+	public function setDomain(DomainInterface $domain)
149
+	{
150
+		$this->domain = $domain;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @return DomainInterface
156
+	 */
157
+	public function domain(): ?DomainInterface
158
+	{
159
+		return $this->domain;
160
+	}
161
+
162
+
163
+	/**
164
+	 * @param string $version
165
+	 */
166
+	public function set_version(string $version = '')
167
+	{
168
+		$this->_version = $version;
169
+	}
170
+
171
+
172
+	/**
173
+	 * get__version
174
+	 *
175
+	 * @return string
176
+	 */
177
+	public function version(): string
178
+	{
179
+		return $this->_version;
180
+	}
181
+
182
+
183
+	/**
184
+	 * @param mixed $min_core_version
185
+	 */
186
+	public function set_min_core_version($min_core_version = null)
187
+	{
188
+		$this->_min_core_version = $min_core_version;
189
+	}
190
+
191
+
192
+	/**
193
+	 * get__min_core_version
194
+	 *
195
+	 * @return string
196
+	 */
197
+	public function min_core_version(): string
198
+	{
199
+		return $this->_min_core_version;
200
+	}
201
+
202
+
203
+	/**
204
+	 * Sets addon_name
205
+	 *
206
+	 * @param string $addon_name
207
+	 */
208
+	public function set_name(string $addon_name)
209
+	{
210
+		$this->_addon_name = $addon_name;
211
+	}
212
+
213
+
214
+	/**
215
+	 * Gets addon_name
216
+	 *
217
+	 * @return string
218
+	 */
219
+	public function name(): string
220
+	{
221
+		return $this->_addon_name;
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return string
227
+	 */
228
+	public function plugin_basename(): string
229
+	{
230
+
231
+		return $this->_plugin_basename;
232
+	}
233
+
234
+
235
+	/**
236
+	 * @param string $plugin_basename
237
+	 */
238
+	public function set_plugin_basename(string $plugin_basename)
239
+	{
240
+
241
+		$this->_plugin_basename = $plugin_basename;
242
+	}
243
+
244
+
245
+	/**
246
+	 * @return string
247
+	 */
248
+	public function plugin_slug(): string
249
+	{
250
+
251
+		return $this->_plugin_slug;
252
+	}
253
+
254
+
255
+	/**
256
+	 * @param string $plugin_slug
257
+	 */
258
+	public function set_plugin_slug(string $plugin_slug)
259
+	{
260
+
261
+		$this->_plugin_slug = $plugin_slug;
262
+	}
263
+
264
+
265
+	/**
266
+	 * @return string
267
+	 */
268
+	public function plugin_action_slug(): string
269
+	{
270
+
271
+		return $this->_plugin_action_slug;
272
+	}
273
+
274
+
275
+	/**
276
+	 * @param string $plugin_action_slug
277
+	 */
278
+	public function set_plugin_action_slug(string $plugin_action_slug)
279
+	{
280
+
281
+		$this->_plugin_action_slug = $plugin_action_slug;
282
+	}
283
+
284
+
285
+	/**
286
+	 * @return array
287
+	 */
288
+	public function get_plugins_page_row(): array
289
+	{
290
+
291
+		return $this->_plugins_page_row;
292
+	}
293
+
294
+
295
+	/**
296
+	 * @param array|string $plugins_page_row
297
+	 */
298
+	public function set_plugins_page_row(array $plugins_page_row = [])
299
+	{
300
+		// sigh.... check for example content that I stupidly merged to master and remove it if found
301
+		if (! is_array($plugins_page_row)
302
+			&& strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303
+		) {
304
+			$plugins_page_row = [];
305
+		}
306
+		$this->_plugins_page_row = (array) $plugins_page_row;
307
+	}
308
+
309
+
310
+	/**
311
+	 * Called when EE core detects this addon has been activated for the first time.
312
+	 * If the site isn't in maintenance mode, should setup the addon's database
313
+	 *
314
+	 * @return void
315
+	 */
316
+	public function new_install()
317
+	{
318
+		$classname = get_class($this);
319
+		do_action("AHEE__{$classname}__new_install");
320
+		do_action('AHEE__EE_Addon__new_install', $this);
321
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
322
+		add_action(
323
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
324
+			[$this, 'initialize_db_if_no_migrations_required']
325
+		);
326
+	}
327
+
328
+
329
+	/**
330
+	 * Called when EE core detects this addon has been reactivated. When this happens,
331
+	 * it's good to just check that your data is still intact
332
+	 *
333
+	 * @return void
334
+	 */
335
+	public function reactivation()
336
+	{
337
+		$classname = get_class($this);
338
+		do_action("AHEE__{$classname}__reactivation");
339
+		do_action('AHEE__EE_Addon__reactivation', $this);
340
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
341
+		add_action(
342
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
343
+			[$this, 'initialize_db_if_no_migrations_required']
344
+		);
345
+	}
346
+
347
+
348
+	/**
349
+	 * Called when the registered deactivation hook for this addon fires.
350
+	 *
351
+	 * @throws EE_Error
352
+	 */
353
+	public function deactivation()
354
+	{
355
+		$classname = get_class($this);
356
+		do_action("AHEE__{$classname}__deactivation");
357
+		do_action('AHEE__EE_Addon__deactivation', $this);
358
+		// check if the site no longer needs to be in maintenance mode
359
+		EE_Register_Addon::deregister($this->name());
360
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
361
+	}
362
+
363
+
364
+	/**
365
+	 * Takes care of double-checking that we're not in maintenance mode, and then
366
+	 * initializing this addon's necessary initial data. This is called by default on new activations
367
+	 * and reactivations.
368
+	 *
369
+	 * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
370
+	 *                               This is a resource-intensive job so we prefer to only do it when necessary
371
+	 * @return void
372
+	 * @throws EE_Error
373
+	 * @throws InvalidInterfaceException
374
+	 * @throws InvalidDataTypeException
375
+	 * @throws InvalidArgumentException
376
+	 * @throws ReflectionException
377
+	 */
378
+	public function initialize_db_if_no_migrations_required($verify_schema = true)
379
+	{
380
+		if ($verify_schema === '') {
381
+			// wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
382
+			// (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
383
+			// calls them with an argument of an empty string (ie ""), which evaluates to false
384
+			// so we need to treat the empty string as if nothing had been passed, and should instead use the default
385
+			$verify_schema = true;
386
+		}
387
+		if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
388
+			if ($verify_schema) {
389
+				$this->initialize_db();
390
+			}
391
+			$this->initialize_default_data();
392
+			// @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
393
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to(
394
+				[
395
+					'slug'    => $this->name(),
396
+					'version' => $this->version(),
397
+				]
398
+			);
399
+			/* make sure core's data is a-ok
400 400
              * (at the time of writing, we especially want to verify all the caps are present
401 401
              * because payment method type capabilities are added dynamically, and it's
402 402
              * possible this addon added a payment method. But it's also possible
403 403
              * other data needs to be verified)
404 404
              */
405
-            EEH_Activation::initialize_db_content();
406
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
407
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
408
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
409
-            );
410
-            $rewrite_rules->flushRewriteRules();
411
-            // in case there are lots of addons being activated at once, let's force garbage collection
412
-            // to help avoid memory limit errors
413
-            // EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
414
-            gc_collect_cycles();
415
-        } else {
416
-            // ask the data migration manager to init this addon's data
417
-            // when migrations are finished because we can't do it now
418
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
419
-        }
420
-    }
421
-
422
-
423
-    /**
424
-     * Used to setup this addon's database tables, but not necessarily any default
425
-     * data in them. The default is to actually use the most up-to-date data migration script
426
-     * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
427
-     * methods to setup the db.
428
-     *
429
-     * @throws EE_Error
430
-     * @throws ReflectionException
431
-     */
432
-    public function initialize_db()
433
-    {
434
-        // find the migration script that sets the database to be compatible with the code
435
-        $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
436
-        if ($current_dms_name) {
437
-            $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
438
-            $current_data_migration_script->set_migrating(false);
439
-            $current_data_migration_script->schema_changes_before_migration();
440
-            $current_data_migration_script->schema_changes_after_migration();
441
-            if ($current_data_migration_script->get_errors()) {
442
-                foreach ($current_data_migration_script->get_errors() as $error) {
443
-                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
444
-                }
445
-            }
446
-        }
447
-        // if not DMS was found that should be ok. This addon just doesn't require any database changes
448
-        EE_Data_Migration_Manager::instance()->update_current_database_state_to(
449
-            [
450
-                'slug'    => $this->name(),
451
-                'version' => $this->version(),
452
-            ]
453
-        );
454
-    }
455
-
456
-
457
-    /**
458
-     * If you want to setup default data for the addon, override this method, and call
459
-     * parent::initialize_default_data() from within it. This is normally called
460
-     * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
461
-     * and should verify default data is present (but this is also called
462
-     * on reactivations and just after migrations, so please verify you actually want
463
-     * to ADD default data, because it may already be present).
464
-     * However, please call this parent (currently it just fires a hook which other
465
-     * addons may be depending on)
466
-     */
467
-    public function initialize_default_data()
468
-    {
469
-        /**
470
-         * Called when an addon is ensuring its default data is set (possibly called
471
-         * on a reactivation, so first check for the absence of other data before setting
472
-         * default data)
473
-         *
474
-         * @param EE_Addon $addon the addon that called this
475
-         */
476
-        do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
477
-        // override to insert default data. It is safe to use the models here
478
-        // because the site should not be in maintenance mode
479
-    }
480
-
481
-
482
-    /**
483
-     * EE Core detected that this addon has been upgraded. We should check if there
484
-     * are any new migration scripts, and if so put the site into maintenance mode until
485
-     * they're ran
486
-     *
487
-     * @return void
488
-     */
489
-    public function upgrade()
490
-    {
491
-        $classname = get_class($this);
492
-        do_action("AHEE__{$classname}__upgrade");
493
-        do_action('AHEE__EE_Addon__upgrade', $this);
494
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
495
-        // also it's possible there is new default data that needs to be added
496
-        add_action(
497
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
498
-            [$this, 'initialize_db_if_no_migrations_required']
499
-        );
500
-    }
501
-
502
-
503
-    /**
504
-     * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
505
-     */
506
-    public function downgrade()
507
-    {
508
-        $classname = get_class($this);
509
-        do_action("AHEE__{$classname}__downgrade");
510
-        do_action('AHEE__EE_Addon__downgrade', $this);
511
-        // it's possible there's old default data that needs to be double-checked
512
-        add_action(
513
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
514
-            [$this, 'initialize_db_if_no_migrations_required']
515
-        );
516
-    }
517
-
518
-
519
-    /**
520
-     * set_db_update_option_name
521
-     * Until we do something better, we'll just check for migration scripts upon
522
-     * plugin activation only. In the future, we'll want to do it on plugin updates too
523
-     *
524
-     * @return bool
525
-     */
526
-    public function set_db_update_option_name(): bool
527
-    {
528
-        EE_Error::doing_it_wrong(
529
-            __FUNCTION__,
530
-            esc_html__(
531
-                'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
532
-                'event_espresso'
533
-            ),
534
-            '4.3.0.alpha.016'
535
-        );
536
-        // let's just handle this on the next request, ok? right now we're just not really ready
537
-        return $this->set_activation_indicator_option();
538
-    }
539
-
540
-
541
-    /**
542
-     * Returns the name of the activation indicator option
543
-     * (an option which is set temporarily to indicate that this addon was just activated)
544
-     *
545
-     * @return string
546
-     * @deprecated since version 4.3.0.alpha.016
547
-     */
548
-    public function get_db_update_option_name(): string
549
-    {
550
-        EE_Error::doing_it_wrong(
551
-            __FUNCTION__,
552
-            esc_html__(
553
-                'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
554
-                'event_espresso'
555
-            ),
556
-            '4.3.0.alpha.016'
557
-        );
558
-        return $this->get_activation_indicator_option_name();
559
-    }
560
-
561
-
562
-    /**
563
-     * When the addon is activated, this should be called to set a wordpress option that
564
-     * indicates it was activated. This is especially useful for detecting reactivations.
565
-     *
566
-     * @return bool
567
-     */
568
-    public function set_activation_indicator_option(): bool
569
-    {
570
-        // let's just handle this on the next request, ok? right now we're just not really ready
571
-        return update_option($this->get_activation_indicator_option_name(), true);
572
-    }
573
-
574
-
575
-    /**
576
-     * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
577
-     *
578
-     * @return string
579
-     */
580
-    public function get_activation_indicator_option_name(): string
581
-    {
582
-        return 'ee_activation_' . $this->name();
583
-    }
584
-
585
-
586
-    /**
587
-     * Used by EE_System to set the request type of this addon. Should not be used by addon developers
588
-     *
589
-     * @param int $req_type
590
-     */
591
-    public function set_req_type(int $req_type)
592
-    {
593
-        $this->_req_type = $req_type;
594
-    }
595
-
596
-
597
-    /**
598
-     * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
599
-     * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
600
-     * EE_System when it is checking for new install or upgrades of addons
601
-     */
602
-    public function detect_req_type(): int
603
-    {
604
-        if (! $this->_req_type) {
605
-            $this->detect_activation_or_upgrade();
606
-        }
607
-        return $this->_req_type;
608
-    }
609
-
610
-
611
-    /**
612
-     * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
613
-     * Should only be called once per request
614
-     *
615
-     * @return void
616
-     */
617
-    public function detect_activation_or_upgrade()
618
-    {
619
-        $activation_history_for_addon = $this->get_activation_history();
620
-        $request_type                 = EE_System::detect_req_type_given_activation_history(
621
-            $activation_history_for_addon,
622
-            $this->get_activation_indicator_option_name(),
623
-            $this->version()
624
-        );
625
-        $this->set_req_type($request_type);
626
-        $classname = get_class($this);
627
-        switch ($request_type) {
628
-            case EE_System::req_type_new_activation:
629
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
630
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
631
-                $this->new_install();
632
-                $this->update_list_of_installed_versions($activation_history_for_addon);
633
-                break;
634
-            case EE_System::req_type_reactivation:
635
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
636
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
637
-                $this->reactivation();
638
-                $this->update_list_of_installed_versions($activation_history_for_addon);
639
-                break;
640
-            case EE_System::req_type_upgrade:
641
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
642
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
643
-                $this->upgrade();
644
-                $this->update_list_of_installed_versions($activation_history_for_addon);
645
-                break;
646
-            case EE_System::req_type_downgrade:
647
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
648
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
649
-                $this->downgrade();
650
-                $this->update_list_of_installed_versions($activation_history_for_addon);
651
-                break;
652
-            case EE_System::req_type_normal:
653
-            default:
654
-                break;
655
-        }
656
-
657
-        do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
658
-    }
659
-
660
-
661
-    /**
662
-     * Updates the version history for this addon
663
-     *
664
-     * @param array  $version_history
665
-     * @param string $current_version_to_add
666
-     * @return boolean success
667
-     */
668
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
669
-    {
670
-        if (! $version_history) {
671
-            $version_history = $this->get_activation_history();
672
-        }
673
-        if ($current_version_to_add === null) {
674
-            $current_version_to_add = $this->version();
675
-        }
676
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
677
-        return update_option($this->get_activation_history_option_name(), $version_history);
678
-    }
679
-
680
-
681
-    /**
682
-     * Gets the name of the wp option that stores the activation history
683
-     * of this addon
684
-     *
685
-     * @return string
686
-     */
687
-    public function get_activation_history_option_name(): string
688
-    {
689
-        return self::ee_addon_version_history_option_prefix . $this->name();
690
-    }
691
-
692
-
693
-    /**
694
-     * Gets the wp option which stores the activation history for this addon
695
-     *
696
-     * @return array
697
-     */
698
-    public function get_activation_history(): array
699
-    {
700
-        return get_option($this->get_activation_history_option_name(), []);
701
-    }
702
-
703
-
704
-    /**
705
-     * @param string $config_section
706
-     */
707
-    public function set_config_section($config_section = '')
708
-    {
709
-        $this->_config_section = ! empty($config_section) ? $config_section : 'addons';
710
-    }
711
-
712
-
713
-    /**
714
-     * Sets the filepath to the main plugin file
715
-     *
716
-     * @param string $filepath
717
-     */
718
-    public function set_main_plugin_file(string $filepath)
719
-    {
720
-        $this->_main_plugin_file = $filepath;
721
-    }
722
-
723
-
724
-    /**
725
-     * gets the filepath to teh main file
726
-     *
727
-     * @return string
728
-     */
729
-    public function get_main_plugin_file(): string
730
-    {
731
-        return $this->_main_plugin_file;
732
-    }
733
-
734
-
735
-    /**
736
-     * Gets the filename (no path) of the main file (the main file loaded
737
-     * by WP)
738
-     *
739
-     * @return string
740
-     */
741
-    public function get_main_plugin_file_basename(): string
742
-    {
743
-        return plugin_basename($this->get_main_plugin_file());
744
-    }
745
-
746
-
747
-    /**
748
-     * Gets the folder name which contains the main plugin file
749
-     *
750
-     * @return string
751
-     */
752
-    public function get_main_plugin_file_dirname(): string
753
-    {
754
-        return dirname($this->get_main_plugin_file());
755
-    }
756
-
757
-
758
-    /**
759
-     * sets hooks used in the admin
760
-     *
761
-     * @return void
762
-     */
763
-    public function admin_init()
764
-    {
765
-        // is admin and not in M-Mode ?
766
-        if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
767
-            add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
768
-            add_filter('after_plugin_row_' . $this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
769
-        }
770
-    }
771
-
772
-
773
-    /**
774
-     * plugin_actions
775
-     * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
776
-     *
777
-     * @param array  $links
778
-     * @param string $file
779
-     * @return array
780
-     */
781
-    public function plugin_action_links(array $links, string $file): array
782
-    {
783
-        if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
784
-            // before other links
785
-            array_unshift(
786
-                $links,
787
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
788
-                . esc_html__('Settings', 'event_espresso')
789
-                . '</a>'
790
-            );
791
-        }
792
-        return $links;
793
-    }
794
-
795
-
796
-    /**
797
-     * after_plugin_row
798
-     * Add additional content to the plugins page plugin row
799
-     * Inserts another row
800
-     *
801
-     * @param string $plugin_file
802
-     * @param array  $plugin_data
803
-     * @param string $status
804
-     * @return void
805
-     */
806
-    public function after_plugin_row(string $plugin_file, array $plugin_data, string $status)
807
-    {
808
-        $after_plugin_row = '';
809
-        $plugins_page_row = $this->get_plugins_page_row();
810
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
811
-            $class       = $status ? 'active' : 'inactive';
812
-            $link_text   = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
813
-            $link_url    = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
814
-            $description = isset($plugins_page_row['description'])
815
-                ? $plugins_page_row['description']
816
-                : '';
817
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
818
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
819
-                $after_plugin_row .= '<th class="check-column" scope="row"></th>';
820
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
821
-                $after_plugin_row .= '<style>
405
+			EEH_Activation::initialize_db_content();
406
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
407
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
408
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
409
+			);
410
+			$rewrite_rules->flushRewriteRules();
411
+			// in case there are lots of addons being activated at once, let's force garbage collection
412
+			// to help avoid memory limit errors
413
+			// EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
414
+			gc_collect_cycles();
415
+		} else {
416
+			// ask the data migration manager to init this addon's data
417
+			// when migrations are finished because we can't do it now
418
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
419
+		}
420
+	}
421
+
422
+
423
+	/**
424
+	 * Used to setup this addon's database tables, but not necessarily any default
425
+	 * data in them. The default is to actually use the most up-to-date data migration script
426
+	 * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
427
+	 * methods to setup the db.
428
+	 *
429
+	 * @throws EE_Error
430
+	 * @throws ReflectionException
431
+	 */
432
+	public function initialize_db()
433
+	{
434
+		// find the migration script that sets the database to be compatible with the code
435
+		$current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
436
+		if ($current_dms_name) {
437
+			$current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
438
+			$current_data_migration_script->set_migrating(false);
439
+			$current_data_migration_script->schema_changes_before_migration();
440
+			$current_data_migration_script->schema_changes_after_migration();
441
+			if ($current_data_migration_script->get_errors()) {
442
+				foreach ($current_data_migration_script->get_errors() as $error) {
443
+					EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
444
+				}
445
+			}
446
+		}
447
+		// if not DMS was found that should be ok. This addon just doesn't require any database changes
448
+		EE_Data_Migration_Manager::instance()->update_current_database_state_to(
449
+			[
450
+				'slug'    => $this->name(),
451
+				'version' => $this->version(),
452
+			]
453
+		);
454
+	}
455
+
456
+
457
+	/**
458
+	 * If you want to setup default data for the addon, override this method, and call
459
+	 * parent::initialize_default_data() from within it. This is normally called
460
+	 * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
461
+	 * and should verify default data is present (but this is also called
462
+	 * on reactivations and just after migrations, so please verify you actually want
463
+	 * to ADD default data, because it may already be present).
464
+	 * However, please call this parent (currently it just fires a hook which other
465
+	 * addons may be depending on)
466
+	 */
467
+	public function initialize_default_data()
468
+	{
469
+		/**
470
+		 * Called when an addon is ensuring its default data is set (possibly called
471
+		 * on a reactivation, so first check for the absence of other data before setting
472
+		 * default data)
473
+		 *
474
+		 * @param EE_Addon $addon the addon that called this
475
+		 */
476
+		do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
477
+		// override to insert default data. It is safe to use the models here
478
+		// because the site should not be in maintenance mode
479
+	}
480
+
481
+
482
+	/**
483
+	 * EE Core detected that this addon has been upgraded. We should check if there
484
+	 * are any new migration scripts, and if so put the site into maintenance mode until
485
+	 * they're ran
486
+	 *
487
+	 * @return void
488
+	 */
489
+	public function upgrade()
490
+	{
491
+		$classname = get_class($this);
492
+		do_action("AHEE__{$classname}__upgrade");
493
+		do_action('AHEE__EE_Addon__upgrade', $this);
494
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
495
+		// also it's possible there is new default data that needs to be added
496
+		add_action(
497
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
498
+			[$this, 'initialize_db_if_no_migrations_required']
499
+		);
500
+	}
501
+
502
+
503
+	/**
504
+	 * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
505
+	 */
506
+	public function downgrade()
507
+	{
508
+		$classname = get_class($this);
509
+		do_action("AHEE__{$classname}__downgrade");
510
+		do_action('AHEE__EE_Addon__downgrade', $this);
511
+		// it's possible there's old default data that needs to be double-checked
512
+		add_action(
513
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
514
+			[$this, 'initialize_db_if_no_migrations_required']
515
+		);
516
+	}
517
+
518
+
519
+	/**
520
+	 * set_db_update_option_name
521
+	 * Until we do something better, we'll just check for migration scripts upon
522
+	 * plugin activation only. In the future, we'll want to do it on plugin updates too
523
+	 *
524
+	 * @return bool
525
+	 */
526
+	public function set_db_update_option_name(): bool
527
+	{
528
+		EE_Error::doing_it_wrong(
529
+			__FUNCTION__,
530
+			esc_html__(
531
+				'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
532
+				'event_espresso'
533
+			),
534
+			'4.3.0.alpha.016'
535
+		);
536
+		// let's just handle this on the next request, ok? right now we're just not really ready
537
+		return $this->set_activation_indicator_option();
538
+	}
539
+
540
+
541
+	/**
542
+	 * Returns the name of the activation indicator option
543
+	 * (an option which is set temporarily to indicate that this addon was just activated)
544
+	 *
545
+	 * @return string
546
+	 * @deprecated since version 4.3.0.alpha.016
547
+	 */
548
+	public function get_db_update_option_name(): string
549
+	{
550
+		EE_Error::doing_it_wrong(
551
+			__FUNCTION__,
552
+			esc_html__(
553
+				'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
554
+				'event_espresso'
555
+			),
556
+			'4.3.0.alpha.016'
557
+		);
558
+		return $this->get_activation_indicator_option_name();
559
+	}
560
+
561
+
562
+	/**
563
+	 * When the addon is activated, this should be called to set a wordpress option that
564
+	 * indicates it was activated. This is especially useful for detecting reactivations.
565
+	 *
566
+	 * @return bool
567
+	 */
568
+	public function set_activation_indicator_option(): bool
569
+	{
570
+		// let's just handle this on the next request, ok? right now we're just not really ready
571
+		return update_option($this->get_activation_indicator_option_name(), true);
572
+	}
573
+
574
+
575
+	/**
576
+	 * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
577
+	 *
578
+	 * @return string
579
+	 */
580
+	public function get_activation_indicator_option_name(): string
581
+	{
582
+		return 'ee_activation_' . $this->name();
583
+	}
584
+
585
+
586
+	/**
587
+	 * Used by EE_System to set the request type of this addon. Should not be used by addon developers
588
+	 *
589
+	 * @param int $req_type
590
+	 */
591
+	public function set_req_type(int $req_type)
592
+	{
593
+		$this->_req_type = $req_type;
594
+	}
595
+
596
+
597
+	/**
598
+	 * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
599
+	 * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
600
+	 * EE_System when it is checking for new install or upgrades of addons
601
+	 */
602
+	public function detect_req_type(): int
603
+	{
604
+		if (! $this->_req_type) {
605
+			$this->detect_activation_or_upgrade();
606
+		}
607
+		return $this->_req_type;
608
+	}
609
+
610
+
611
+	/**
612
+	 * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
613
+	 * Should only be called once per request
614
+	 *
615
+	 * @return void
616
+	 */
617
+	public function detect_activation_or_upgrade()
618
+	{
619
+		$activation_history_for_addon = $this->get_activation_history();
620
+		$request_type                 = EE_System::detect_req_type_given_activation_history(
621
+			$activation_history_for_addon,
622
+			$this->get_activation_indicator_option_name(),
623
+			$this->version()
624
+		);
625
+		$this->set_req_type($request_type);
626
+		$classname = get_class($this);
627
+		switch ($request_type) {
628
+			case EE_System::req_type_new_activation:
629
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
630
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
631
+				$this->new_install();
632
+				$this->update_list_of_installed_versions($activation_history_for_addon);
633
+				break;
634
+			case EE_System::req_type_reactivation:
635
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
636
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
637
+				$this->reactivation();
638
+				$this->update_list_of_installed_versions($activation_history_for_addon);
639
+				break;
640
+			case EE_System::req_type_upgrade:
641
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
642
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
643
+				$this->upgrade();
644
+				$this->update_list_of_installed_versions($activation_history_for_addon);
645
+				break;
646
+			case EE_System::req_type_downgrade:
647
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
648
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
649
+				$this->downgrade();
650
+				$this->update_list_of_installed_versions($activation_history_for_addon);
651
+				break;
652
+			case EE_System::req_type_normal:
653
+			default:
654
+				break;
655
+		}
656
+
657
+		do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
658
+	}
659
+
660
+
661
+	/**
662
+	 * Updates the version history for this addon
663
+	 *
664
+	 * @param array  $version_history
665
+	 * @param string $current_version_to_add
666
+	 * @return boolean success
667
+	 */
668
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
669
+	{
670
+		if (! $version_history) {
671
+			$version_history = $this->get_activation_history();
672
+		}
673
+		if ($current_version_to_add === null) {
674
+			$current_version_to_add = $this->version();
675
+		}
676
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
677
+		return update_option($this->get_activation_history_option_name(), $version_history);
678
+	}
679
+
680
+
681
+	/**
682
+	 * Gets the name of the wp option that stores the activation history
683
+	 * of this addon
684
+	 *
685
+	 * @return string
686
+	 */
687
+	public function get_activation_history_option_name(): string
688
+	{
689
+		return self::ee_addon_version_history_option_prefix . $this->name();
690
+	}
691
+
692
+
693
+	/**
694
+	 * Gets the wp option which stores the activation history for this addon
695
+	 *
696
+	 * @return array
697
+	 */
698
+	public function get_activation_history(): array
699
+	{
700
+		return get_option($this->get_activation_history_option_name(), []);
701
+	}
702
+
703
+
704
+	/**
705
+	 * @param string $config_section
706
+	 */
707
+	public function set_config_section($config_section = '')
708
+	{
709
+		$this->_config_section = ! empty($config_section) ? $config_section : 'addons';
710
+	}
711
+
712
+
713
+	/**
714
+	 * Sets the filepath to the main plugin file
715
+	 *
716
+	 * @param string $filepath
717
+	 */
718
+	public function set_main_plugin_file(string $filepath)
719
+	{
720
+		$this->_main_plugin_file = $filepath;
721
+	}
722
+
723
+
724
+	/**
725
+	 * gets the filepath to teh main file
726
+	 *
727
+	 * @return string
728
+	 */
729
+	public function get_main_plugin_file(): string
730
+	{
731
+		return $this->_main_plugin_file;
732
+	}
733
+
734
+
735
+	/**
736
+	 * Gets the filename (no path) of the main file (the main file loaded
737
+	 * by WP)
738
+	 *
739
+	 * @return string
740
+	 */
741
+	public function get_main_plugin_file_basename(): string
742
+	{
743
+		return plugin_basename($this->get_main_plugin_file());
744
+	}
745
+
746
+
747
+	/**
748
+	 * Gets the folder name which contains the main plugin file
749
+	 *
750
+	 * @return string
751
+	 */
752
+	public function get_main_plugin_file_dirname(): string
753
+	{
754
+		return dirname($this->get_main_plugin_file());
755
+	}
756
+
757
+
758
+	/**
759
+	 * sets hooks used in the admin
760
+	 *
761
+	 * @return void
762
+	 */
763
+	public function admin_init()
764
+	{
765
+		// is admin and not in M-Mode ?
766
+		if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
767
+			add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
768
+			add_filter('after_plugin_row_' . $this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
769
+		}
770
+	}
771
+
772
+
773
+	/**
774
+	 * plugin_actions
775
+	 * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
776
+	 *
777
+	 * @param array  $links
778
+	 * @param string $file
779
+	 * @return array
780
+	 */
781
+	public function plugin_action_links(array $links, string $file): array
782
+	{
783
+		if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
784
+			// before other links
785
+			array_unshift(
786
+				$links,
787
+				'<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
788
+				. esc_html__('Settings', 'event_espresso')
789
+				. '</a>'
790
+			);
791
+		}
792
+		return $links;
793
+	}
794
+
795
+
796
+	/**
797
+	 * after_plugin_row
798
+	 * Add additional content to the plugins page plugin row
799
+	 * Inserts another row
800
+	 *
801
+	 * @param string $plugin_file
802
+	 * @param array  $plugin_data
803
+	 * @param string $status
804
+	 * @return void
805
+	 */
806
+	public function after_plugin_row(string $plugin_file, array $plugin_data, string $status)
807
+	{
808
+		$after_plugin_row = '';
809
+		$plugins_page_row = $this->get_plugins_page_row();
810
+		if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
811
+			$class       = $status ? 'active' : 'inactive';
812
+			$link_text   = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
813
+			$link_url    = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
814
+			$description = isset($plugins_page_row['description'])
815
+				? $plugins_page_row['description']
816
+				: '';
817
+			if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
818
+				$after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
819
+				$after_plugin_row .= '<th class="check-column" scope="row"></th>';
820
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
821
+				$after_plugin_row .= '<style>
822 822
 .ee-button,
823 823
 .ee-button:active,
824 824
 .ee-button:visited {
@@ -855,67 +855,67 @@  discard block
 block discarded – undo
855 855
 }
856 856
 .ee-button:active { top:0; }
857 857
 </style>';
858
-                $after_plugin_row .= '
858
+				$after_plugin_row .= '
859 859
 <p class="ee-addon-upsell-info-dv">
860 860
 	<a class="ee-button" href="' . $link_url . '">'
861
-                                     . $link_text
862
-                                     . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
863
-                                     . '</a>
861
+									 . $link_text
862
+									 . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
863
+									 . '</a>
864 864
 </p>';
865
-                $after_plugin_row .= '</td>';
866
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
867
-                $after_plugin_row .= $description;
868
-                $after_plugin_row .= '</td>';
869
-                $after_plugin_row .= '</tr>';
870
-            } else {
871
-                $after_plugin_row .= $description;
872
-            }
873
-        }
874
-
875
-        echo $after_plugin_row;
876
-    }
877
-
878
-
879
-    /**
880
-     * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
881
-     * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
882
-     * for back compat reasons.
883
-     *
884
-     * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
885
-     *
886
-     * It is recommended, if client code is `de-registering` an add-on, then do it on the
887
-     * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
888
-     * callback does not get run/set in that request.
889
-     *
890
-     * Also, keep in mind that if a registered add-on happens to be deactivated via
891
-     * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
892
-     * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
893
-     * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
894
-     * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
895
-     * to call `parent::deactivation`.
896
-     *
897
-     * @since 4.9.26
898
-     */
899
-    public function after_registration()
900
-    {
901
-        // cricket chirp... cricket chirp...
902
-    }
903
-
904
-
905
-    /**
906
-     * @return string
907
-     */
908
-    public function getPueSlug(): string
909
-    {
910
-        return $this->pue_slug;
911
-    }
912
-
913
-
914
-    /**
915
-     * @param string $pue_slug
916
-     */
917
-    public function setPueSlug(string $pue_slug)
918
-    {
919
-        $this->pue_slug = $pue_slug;
920
-    }
865
+				$after_plugin_row .= '</td>';
866
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
867
+				$after_plugin_row .= $description;
868
+				$after_plugin_row .= '</td>';
869
+				$after_plugin_row .= '</tr>';
870
+			} else {
871
+				$after_plugin_row .= $description;
872
+			}
873
+		}
874
+
875
+		echo $after_plugin_row;
876
+	}
877
+
878
+
879
+	/**
880
+	 * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
881
+	 * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
882
+	 * for back compat reasons.
883
+	 *
884
+	 * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
885
+	 *
886
+	 * It is recommended, if client code is `de-registering` an add-on, then do it on the
887
+	 * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
888
+	 * callback does not get run/set in that request.
889
+	 *
890
+	 * Also, keep in mind that if a registered add-on happens to be deactivated via
891
+	 * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
892
+	 * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
893
+	 * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
894
+	 * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
895
+	 * to call `parent::deactivation`.
896
+	 *
897
+	 * @since 4.9.26
898
+	 */
899
+	public function after_registration()
900
+	{
901
+		// cricket chirp... cricket chirp...
902
+	}
903
+
904
+
905
+	/**
906
+	 * @return string
907
+	 */
908
+	public function getPueSlug(): string
909
+	{
910
+		return $this->pue_slug;
911
+	}
912
+
913
+
914
+	/**
915
+	 * @param string $pue_slug
916
+	 */
917
+	public function setPueSlug(string $pue_slug)
918
+	{
919
+		$this->pue_slug = $pue_slug;
920
+	}
921 921
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
     public function set_plugins_page_row(array $plugins_page_row = [])
299 299
     {
300 300
         // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (! is_array($plugins_page_row)
301
+        if ( ! is_array($plugins_page_row)
302 302
             && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303 303
         ) {
304 304
             $plugins_page_row = [];
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
      */
580 580
     public function get_activation_indicator_option_name(): string
581 581
     {
582
-        return 'ee_activation_' . $this->name();
582
+        return 'ee_activation_'.$this->name();
583 583
     }
584 584
 
585 585
 
@@ -601,7 +601,7 @@  discard block
 block discarded – undo
601 601
      */
602 602
     public function detect_req_type(): int
603 603
     {
604
-        if (! $this->_req_type) {
604
+        if ( ! $this->_req_type) {
605 605
             $this->detect_activation_or_upgrade();
606 606
         }
607 607
         return $this->_req_type;
@@ -667,13 +667,13 @@  discard block
 block discarded – undo
667 667
      */
668 668
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
669 669
     {
670
-        if (! $version_history) {
670
+        if ( ! $version_history) {
671 671
             $version_history = $this->get_activation_history();
672 672
         }
673 673
         if ($current_version_to_add === null) {
674 674
             $current_version_to_add = $this->version();
675 675
         }
676
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
676
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
677 677
         return update_option($this->get_activation_history_option_name(), $version_history);
678 678
     }
679 679
 
@@ -686,7 +686,7 @@  discard block
 block discarded – undo
686 686
      */
687 687
     public function get_activation_history_option_name(): string
688 688
     {
689
-        return self::ee_addon_version_history_option_prefix . $this->name();
689
+        return self::ee_addon_version_history_option_prefix.$this->name();
690 690
     }
691 691
 
692 692
 
@@ -765,7 +765,7 @@  discard block
 block discarded – undo
765 765
         // is admin and not in M-Mode ?
766 766
         if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
767 767
             add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
768
-            add_filter('after_plugin_row_' . $this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
768
+            add_filter('after_plugin_row_'.$this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
769 769
         }
770 770
     }
771 771
 
@@ -784,7 +784,7 @@  discard block
 block discarded – undo
784 784
             // before other links
785 785
             array_unshift(
786 786
                 $links,
787
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
787
+                '<a href="admin.php?page='.$this->plugin_action_slug().'">'
788 788
                 . esc_html__('Settings', 'event_espresso')
789 789
                 . '</a>'
790 790
             );
@@ -807,15 +807,15 @@  discard block
 block discarded – undo
807 807
     {
808 808
         $after_plugin_row = '';
809 809
         $plugins_page_row = $this->get_plugins_page_row();
810
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
810
+        if ( ! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
811 811
             $class       = $status ? 'active' : 'inactive';
812 812
             $link_text   = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
813 813
             $link_url    = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
814 814
             $description = isset($plugins_page_row['description'])
815 815
                 ? $plugins_page_row['description']
816 816
                 : '';
817
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
818
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
817
+            if ( ! empty($link_text) && ! empty($link_url) && ! empty($description)) {
818
+                $after_plugin_row .= '<tr id="'.sanitize_title($plugin_file).'-ee-addon" class="'.$class.'">';
819 819
                 $after_plugin_row .= '<th class="check-column" scope="row"></th>';
820 820
                 $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
821 821
                 $after_plugin_row .= '<style>
@@ -857,7 +857,7 @@  discard block
 block discarded – undo
857 857
 </style>';
858 858
                 $after_plugin_row .= '
859 859
 <p class="ee-addon-upsell-info-dv">
860
-	<a class="ee-button" href="' . $link_url . '">'
860
+	<a class="ee-button" href="' . $link_url.'">'
861 861
                                      . $link_text
862 862
                                      . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
863 863
                                      . '</a>
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Indentation   +1158 added lines, -1158 removed lines patch added patch discarded remove patch
@@ -25,1162 +25,1162 @@
 block discarded – undo
25 25
 final class EE_System implements ResettableInterface
26 26
 {
27 27
 
28
-    /**
29
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
30
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
31
-     */
32
-    const req_type_normal = 0;
33
-
34
-    /**
35
-     * Indicates this is a brand new installation of EE so we should install
36
-     * tables and default data etc
37
-     */
38
-    const req_type_new_activation = 1;
39
-
40
-    /**
41
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
42
-     * and we just exited maintenance mode). We MUST check the database is setup properly
43
-     * and that default data is setup too
44
-     */
45
-    const req_type_reactivation = 2;
46
-
47
-    /**
48
-     * indicates that EE has been upgraded since its previous request.
49
-     * We may have data migration scripts to call and will want to trigger maintenance mode
50
-     */
51
-    const req_type_upgrade = 3;
52
-
53
-    /**
54
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
55
-     */
56
-    const req_type_downgrade = 4;
57
-
58
-    /**
59
-     * @deprecated since version 4.6.0.dev.006
60
-     * Now whenever a new_activation is detected the request type is still just
61
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
62
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
63
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
64
-     * (Specifically, when the migration manager indicates migrations are finished
65
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
66
-     */
67
-    const req_type_activation_but_not_installed = 5;
68
-
69
-    /**
70
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
71
-     */
72
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
73
-
74
-    /**
75
-     * @var AddonManager $addon_manager
76
-     */
77
-    private $addon_manager;
78
-
79
-    /**
80
-     * @var EE_System $_instance
81
-     */
82
-    private static $_instance;
83
-
84
-    /**
85
-     * @var EE_Registry $registry
86
-     */
87
-    private $registry;
88
-
89
-    /**
90
-     * @var LoaderInterface $loader
91
-     */
92
-    private $loader;
93
-
94
-    /**
95
-     * @var EE_Capabilities $capabilities
96
-     */
97
-    private $capabilities;
98
-
99
-    /**
100
-     * @var EE_Maintenance_Mode $maintenance_mode
101
-     */
102
-    private $maintenance_mode;
103
-
104
-    /**
105
-     * @var RequestInterface $request
106
-     */
107
-    private $request;
108
-
109
-    /**
110
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
111
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
112
-     *
113
-     * @var int $_req_type
114
-     */
115
-    private $_req_type;
116
-
117
-    /**
118
-     * Whether or not there was a non-micro version change in EE core version during this request
119
-     *
120
-     * @var boolean $_major_version_change
121
-     */
122
-    private $_major_version_change = false;
123
-
124
-    /**
125
-     * @var Router $router
126
-     */
127
-    private $router;
128
-
129
-
130
-    /**
131
-     * @singleton method used to instantiate class object
132
-     * @param LoaderInterface|null     $loader
133
-     * @param EE_Maintenance_Mode|null $maintenance_mode
134
-     * @param EE_Registry|null         $registry
135
-     * @param RequestInterface|null    $request
136
-     * @param Router|null              $router
137
-     * @return EE_System
138
-     */
139
-    public static function instance(
140
-        LoaderInterface $loader = null,
141
-        EE_Maintenance_Mode $maintenance_mode = null,
142
-        EE_Registry $registry = null,
143
-        RequestInterface $request = null,
144
-        Router $router = null
145
-    ): EE_System {
146
-        // check if class object is instantiated
147
-        if (! self::$_instance instanceof EE_System) {
148
-            self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
149
-        }
150
-        return self::$_instance;
151
-    }
152
-
153
-
154
-    /**
155
-     * resets the instance and returns it
156
-     *
157
-     * @return EE_System
158
-     */
159
-    public static function reset(): EE_System
160
-    {
161
-        self::$_instance->_req_type = null;
162
-        // make sure none of the old hooks are left hanging around
163
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
164
-        // we need to reset the migration manager in order for it to detect DMSs properly
165
-        EE_Data_Migration_Manager::reset();
166
-        self::instance()->detect_activations_or_upgrades();
167
-        self::instance()->perform_activations_upgrades_and_migrations();
168
-        return self::instance();
169
-    }
170
-
171
-
172
-    /**
173
-     * sets hooks for running rest of system
174
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
175
-     * starting EE Addons from any other point may lead to problems
176
-     *
177
-     * @param LoaderInterface     $loader
178
-     * @param EE_Maintenance_Mode $maintenance_mode
179
-     * @param EE_Registry         $registry
180
-     * @param RequestInterface    $request
181
-     * @param Router              $router
182
-     */
183
-    private function __construct(
184
-        LoaderInterface $loader,
185
-        EE_Maintenance_Mode $maintenance_mode,
186
-        EE_Registry $registry,
187
-        RequestInterface $request,
188
-        Router $router
189
-    ) {
190
-        $this->registry         = $registry;
191
-        $this->loader           = $loader;
192
-        $this->request          = $request;
193
-        $this->router           = $router;
194
-        $this->maintenance_mode = $maintenance_mode;
195
-        do_action('AHEE__EE_System__construct__begin', $this);
196
-        add_action(
197
-            'AHEE__EE_Bootstrap__load_espresso_addons',
198
-            [$this, 'loadCapabilities'],
199
-            5
200
-        );
201
-        add_action(
202
-            'AHEE__EE_Bootstrap__load_espresso_addons',
203
-            [$this, 'loadCommandBus'],
204
-            7
205
-        );
206
-        add_action(
207
-            'AHEE__EE_Bootstrap__load_espresso_addons',
208
-            [$this, 'loadPluginApi'],
209
-            9
210
-        );
211
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
212
-        add_action(
213
-            'AHEE__EE_Bootstrap__load_espresso_addons',
214
-            [$this, 'load_espresso_addons']
215
-        );
216
-        // when an ee addon is activated, we want to call the core hook(s) again
217
-        // because the newly-activated addon didn't get a chance to run at all
218
-        add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
219
-        // detect whether install or upgrade
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
222
-            [$this, 'detect_activations_or_upgrades'],
223
-            3
224
-        );
225
-        // load EE_Config, EE_Textdomain, etc
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_core_configuration',
228
-            [$this, 'load_core_configuration'],
229
-            5
230
-        );
231
-        // load specifications for matching routes to current request
232
-        add_action(
233
-            'AHEE__EE_Bootstrap__load_core_configuration',
234
-            [$this, 'loadRouteMatchSpecifications']
235
-        );
236
-        // load EE_Config, EE_Textdomain, etc
237
-        add_action(
238
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
239
-            [$this, 'register_shortcodes_modules_and_widgets'],
240
-            7
241
-        );
242
-        // you wanna get going? I wanna get going... let's get going!
243
-        add_action(
244
-            'AHEE__EE_Bootstrap__brew_espresso',
245
-            [$this, 'brew_espresso'],
246
-            9
247
-        );
248
-        // other housekeeping
249
-        // exclude EE critical pages from wp_list_pages
250
-        add_filter(
251
-            'wp_list_pages_excludes',
252
-            [$this, 'remove_pages_from_wp_list_pages'],
253
-            10
254
-        );
255
-        // ALL EE Addons should use the following hook point to attach their initial setup too
256
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
257
-        do_action('AHEE__EE_System__construct__complete', $this);
258
-    }
259
-
260
-
261
-    /**
262
-     * load and setup EE_Capabilities
263
-     *
264
-     * @return void
265
-     */
266
-    public function loadCapabilities()
267
-    {
268
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
269
-        add_action(
270
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
271
-            function () {
272
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273
-            }
274
-        );
275
-    }
276
-
277
-
278
-    /**
279
-     * create and cache the CommandBus, and also add middleware
280
-     * The CapChecker middleware requires the use of EE_Capabilities
281
-     * which is why we need to load the CommandBus after Caps are set up
282
-     *
283
-     * @return void
284
-     */
285
-    public function loadCommandBus()
286
-    {
287
-        $this->loader->getShared(
288
-            'CommandBusInterface',
289
-            [
290
-                null,
291
-                apply_filters(
292
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
293
-                    [
294
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
295
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
296
-                    ]
297
-                ),
298
-            ]
299
-        );
300
-    }
301
-
302
-
303
-    /**
304
-     * @return void
305
-     * @throws Exception
306
-     */
307
-    public function loadPluginApi()
308
-    {
309
-        $this->addon_manager = $this->loader->getShared(AddonManager::class);
310
-        $this->addon_manager->initialize();
311
-        $this->loader->getShared('EE_Request_Handler');
312
-    }
313
-
314
-
315
-    /**
316
-     * load_espresso_addons
317
-     * allow addons to load first so that they can set hooks for running DMS's, etc
318
-     * this is hooked into both:
319
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
320
-     *        which runs during the WP 'plugins_loaded' action at priority 5
321
-     *    and the WP 'activate_plugin' hook point
322
-     *
323
-     * @return void
324
-     * @throws Exception
325
-     */
326
-    public function load_espresso_addons()
327
-    {
328
-        // looking for hooks? they've been moved into the AddonManager to maintain compatibility
329
-        $this->addon_manager->loadAddons();
330
-    }
331
-
332
-
333
-    /**
334
-     * detect_activations_or_upgrades
335
-     * Checks for activation or upgrade of core first;
336
-     * then also checks if any registered addons have been activated or upgraded
337
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
338
-     * which runs during the WP 'plugins_loaded' action at priority 3
339
-     *
340
-     * @access public
341
-     * @return void
342
-     */
343
-    public function detect_activations_or_upgrades()
344
-    {
345
-        // first off: let's make sure to handle core
346
-        $this->detect_if_activation_or_upgrade();
347
-        foreach ($this->registry->addons as $addon) {
348
-            if ($addon instanceof EE_Addon) {
349
-                // detect teh request type for that addon
350
-                $addon->detect_activation_or_upgrade();
351
-            }
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * detect_if_activation_or_upgrade
358
-     * Takes care of detecting whether this is a brand new install or code upgrade,
359
-     * and either setting up the DB or setting up maintenance mode etc.
360
-     *
361
-     * @access public
362
-     * @return void
363
-     */
364
-    public function detect_if_activation_or_upgrade()
365
-    {
366
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
367
-        // check if db has been updated, or if its a brand-new installation
368
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
369
-        $request_type       = $this->detect_req_type($espresso_db_update);
370
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
371
-        switch ($request_type) {
372
-            case EE_System::req_type_new_activation:
373
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
374
-                $this->_handle_core_version_change($espresso_db_update);
375
-                break;
376
-            case EE_System::req_type_reactivation:
377
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
378
-                $this->_handle_core_version_change($espresso_db_update);
379
-                break;
380
-            case EE_System::req_type_upgrade:
381
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
382
-                // migrations may be required now that we've upgraded
383
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
384
-                $this->_handle_core_version_change($espresso_db_update);
385
-                break;
386
-            case EE_System::req_type_downgrade:
387
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
388
-                // its possible migrations are no longer required
389
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
390
-                $this->_handle_core_version_change($espresso_db_update);
391
-                break;
392
-            case EE_System::req_type_normal:
393
-            default:
394
-                break;
395
-        }
396
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
397
-    }
398
-
399
-
400
-    /**
401
-     * Updates the list of installed versions and sets hooks for
402
-     * initializing the database later during the request
403
-     *
404
-     * @param array $espresso_db_update
405
-     */
406
-    private function _handle_core_version_change(array $espresso_db_update)
407
-    {
408
-        $this->update_list_of_installed_versions($espresso_db_update);
409
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
410
-        add_action(
411
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
412
-            [$this, 'initialize_db_if_no_migrations_required']
413
-        );
414
-    }
415
-
416
-
417
-    /**
418
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
419
-     * information about what versions of EE have been installed and activated,
420
-     * NOT necessarily the state of the database
421
-     *
422
-     * @param mixed $espresso_db_update           the value of the WordPress option.
423
-     *                                            If not supplied, fetches it from the options table
424
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
425
-     */
426
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
427
-    {
428
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
429
-        if (! $espresso_db_update) {
430
-            $espresso_db_update = get_option('espresso_db_update');
431
-        }
432
-        // check that option is an array
433
-        if (! is_array($espresso_db_update)) {
434
-            // if option is FALSE, then it never existed
435
-            if ($espresso_db_update === false) {
436
-                // make $espresso_db_update an array and save option with autoload OFF
437
-                $espresso_db_update = [];
438
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
439
-            } else {
440
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
441
-                $espresso_db_update = [$espresso_db_update => []];
442
-                update_option('espresso_db_update', $espresso_db_update);
443
-            }
444
-        } else {
445
-            $corrected_db_update = [];
446
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
447
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
448
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
449
-                    // the key is an int, and the value IS NOT an array
450
-                    // so it must be numerically-indexed, where values are versions installed...
451
-                    // fix it!
452
-                    $version_string                         = $should_be_array;
453
-                    $corrected_db_update[ $version_string ] = ['unknown-date'];
454
-                } else {
455
-                    // ok it checks out
456
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
457
-                }
458
-            }
459
-            $espresso_db_update = $corrected_db_update;
460
-            update_option('espresso_db_update', $espresso_db_update);
461
-        }
462
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
463
-        return ! empty($espresso_db_update) ? $espresso_db_update : [];
464
-    }
465
-
466
-
467
-    /**
468
-     * Does the traditional work of setting up the plugin's database and adding default data.
469
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
470
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
471
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
472
-     * so that it will be done when migrations are finished
473
-     *
474
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
475
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
476
-     *                                       This is a resource-intensive job
477
-     *                                       so we prefer to only do it when necessary
478
-     * @return void
479
-     * @throws EE_Error
480
-     */
481
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
482
-    {
483
-        $request_type = $this->detect_req_type();
484
-        // only initialize system if we're not in maintenance mode.
485
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
486
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
487
-            $rewrite_rules = $this->loader->getShared(
488
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
489
-            );
490
-            $rewrite_rules->flush();
491
-            if ($verify_schema) {
492
-                EEH_Activation::initialize_db_and_folders();
493
-            }
494
-            EEH_Activation::initialize_db_content();
495
-            EEH_Activation::system_initialization();
496
-            if ($initialize_addons_too) {
497
-                $this->initialize_addons();
498
-            }
499
-        } else {
500
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
501
-        }
502
-        if ($request_type === EE_System::req_type_new_activation
503
-            || $request_type === EE_System::req_type_reactivation
504
-            || (
505
-                $request_type === EE_System::req_type_upgrade
506
-                && $this->is_major_version_change()
507
-            )
508
-        ) {
509
-            add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
510
-        }
511
-    }
512
-
513
-
514
-    /**
515
-     * Initializes the db for all registered addons
516
-     *
517
-     * @throws EE_Error
518
-     */
519
-    public function initialize_addons()
520
-    {
521
-        // foreach registered addon, make sure its db is up-to-date too
522
-        foreach ($this->registry->addons as $addon) {
523
-            if ($addon instanceof EE_Addon) {
524
-                $addon->initialize_db_if_no_migrations_required();
525
-            }
526
-        }
527
-    }
528
-
529
-
530
-    /**
531
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
532
-     *
533
-     * @param array  $version_history
534
-     * @param string $current_version_to_add version to be added to the version history
535
-     * @return    boolean success as to whether or not this option was changed
536
-     */
537
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
538
-    {
539
-        if (! $version_history) {
540
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
541
-        }
542
-        if ($current_version_to_add === null) {
543
-            $current_version_to_add = espresso_version();
544
-        }
545
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
546
-        // re-save
547
-        return update_option('espresso_db_update', $version_history);
548
-    }
549
-
550
-
551
-    /**
552
-     * Detects if the current version indicated in the has existed in the list of
553
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
554
-     *
555
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
556
-     *                                  If not supplied, fetches it from the options table.
557
-     *                                  Also, caches its result so later parts of the code can also know whether
558
-     *                                  there's been an update or not. This way we can add the current version to
559
-     *                                  espresso_db_update, but still know if this is a new install or not
560
-     * @return int one of the constants on EE_System::req_type_
561
-     */
562
-    public function detect_req_type($espresso_db_update = null): int
563
-    {
564
-        if ($this->_req_type === null) {
565
-            $espresso_db_update          = ! empty($espresso_db_update)
566
-                ? $espresso_db_update
567
-                : $this->fix_espresso_db_upgrade_option();
568
-            $this->_req_type             = EE_System::detect_req_type_given_activation_history(
569
-                $espresso_db_update,
570
-                'ee_espresso_activation',
571
-                espresso_version()
572
-            );
573
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
574
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
575
-        }
576
-        return $this->_req_type;
577
-    }
578
-
579
-
580
-    /**
581
-     * Returns whether or not there was a non-micro version change (ie, change in either
582
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
583
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
584
-     *
585
-     * @param $activation_history
586
-     * @return bool
587
-     */
588
-    private function _detect_major_version_change($activation_history): bool
589
-    {
590
-        $previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
591
-        $previous_version_parts = explode('.', $previous_version);
592
-        $current_version_parts  = explode('.', espresso_version());
593
-        return isset(
594
-            $previous_version_parts[0],
595
-            $previous_version_parts[1],
596
-            $current_version_parts[0],
597
-            $current_version_parts[1]
598
-        ) && (
599
-            $previous_version_parts[0] !== $current_version_parts[0]
600
-            || $previous_version_parts[1] !== $current_version_parts[1]
601
-        );
602
-    }
603
-
604
-
605
-    /**
606
-     * Returns true if either the major or minor version of EE changed during this request.
607
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
608
-     *
609
-     * @return bool
610
-     */
611
-    public function is_major_version_change(): bool
612
-    {
613
-        return $this->_major_version_change;
614
-    }
615
-
616
-
617
-    /**
618
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
619
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
620
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
621
-     * just activated to (for core that will always be espresso_version())
622
-     *
623
-     * @param array|null $activation_history             the option's value which stores the activation history for
624
-     *                                                 this
625
-     *                                                 ee plugin. for core that's 'espresso_db_update'
626
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
627
-     *                                                 indicate that this plugin was just activated
628
-     * @param string $current_version                  the version that was just upgraded to (for core that will be
629
-     *                                                 espresso_version())
630
-     * @return int one of the constants on EE_System::req_type_
631
-     */
632
-    public static function detect_req_type_given_activation_history(
633
-        array $activation_history,
634
-        string $activation_indicator_option_name,
635
-        string $current_version
636
-    ): int {
637
-        $version_change = self::compareVersionWithPrevious($activation_history, $current_version);
638
-        $is_activation  = get_option($activation_indicator_option_name, false);
639
-        $req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
640
-        if ($is_activation) {
641
-            // cleanup in aisle 6
642
-            delete_option($activation_indicator_option_name);
643
-        }
644
-        return $req_type;
645
-    }
646
-
647
-
648
-    /**
649
-     * @param array  $activation_history
650
-     * @param int    $version_change
651
-     * @param bool   $is_activation
652
-     * @return int
653
-     * @since $VID:$
654
-     */
655
-    private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
656
-    {
657
-        // if no previous activation history exists, then this is a brand new install
658
-        if (empty($activation_history)) {
659
-            return EE_System::req_type_new_activation;
660
-        }
661
-        // current version is higher than previous version, so it's an upgrade
662
-        if ($version_change === 1) {
663
-            return EE_System::req_type_upgrade;
664
-        }
665
-        // current version is lower than previous version, so it's a downgrade
666
-        if ($version_change === -1) {
667
-            return EE_System::req_type_downgrade;
668
-        }
669
-        // version hasn't changed since last version so check if the activation indicator is set
670
-        // to determine if it's a reactivation, or just a normal request
671
-        return $is_activation
672
-            ? EE_System::req_type_reactivation
673
-            : EE_System::req_type_normal;
674
-    }
675
-
676
-
677
-    /**
678
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
679
-     * the $activation_history_for_addon
680
-     *
681
-     * @param array  $activation_history    array where keys are versions,
682
-     *                                      values are arrays of times activated (sometimes 'unknown-date')
683
-     * @param string $current_version
684
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
685
-     *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
686
-     *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
687
-     *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
688
-     */
689
-    private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
690
-    {
691
-        // find the most recently-activated version
692
-        $most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
693
-        return version_compare($current_version, $most_recently_active_version);
694
-    }
695
-
696
-
697
-    /**
698
-     * Gets the most recently active version listed in the activation history,
699
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
700
-     *
701
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
702
-     *                                   sometimes containing 'unknown-date'
703
-     * @return string
704
-     */
705
-    private static function getMostRecentlyActiveVersion(array $activation_history): string
706
-    {
707
-        $most_recent_activation_date  = '1970-01-01 00:00:00';
708
-        $most_recently_active_version = '0.0.0.dev.000';
709
-        if (is_array($activation_history)) {
710
-            foreach ($activation_history as $version => $activation_dates) {
711
-                // check there is a record of when this version was activated.
712
-                // Otherwise, mark it as unknown
713
-                if (! $activation_dates) {
714
-                    $activation_dates = ['unknown-date'];
715
-                }
716
-                $activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
717
-                foreach ($activation_dates as $activation_date) {
718
-                    if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
719
-                        $most_recently_active_version = $version;
720
-                        $most_recent_activation_date  = $activation_date;
721
-                    }
722
-                }
723
-            }
724
-        }
725
-        return $most_recently_active_version;
726
-    }
727
-
728
-
729
-    /**
730
-     * This redirects to the about EE page after activation
731
-     *
732
-     * @return void
733
-     */
734
-    public function redirect_to_about_ee()
735
-    {
736
-        $notices = EE_Error::get_notices(false);
737
-        // if current user is an admin and it's not an ajax or rest request
738
-        if (! isset($notices['errors'])
739
-            && $this->request->isAdmin()
740
-            && apply_filters(
741
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
742
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
743
-            )
744
-        ) {
745
-            $query_params = ['page' => 'espresso_about'];
746
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
747
-                $query_params['new_activation'] = true;
748
-            }
749
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
750
-                $query_params['reactivation'] = true;
751
-            }
752
-            $url = add_query_arg($query_params, admin_url('admin.php'));
753
-            EEH_URL::safeRedirectAndExit($url);
754
-        }
755
-    }
756
-
757
-
758
-    /**
759
-     * load_core_configuration
760
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
761
-     * which runs during the WP 'plugins_loaded' action at priority 5
762
-     *
763
-     * @return void
764
-     * @throws ReflectionException
765
-     * @throws Exception
766
-     */
767
-    public function load_core_configuration()
768
-    {
769
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
770
-        $this->loader->getShared('EE_Load_Textdomain');
771
-        // load textdomain
772
-        EE_Load_Textdomain::load_textdomain();
773
-        // load caf stuff a chance to play during the activation process too.
774
-        $this->_maybe_brew_regular();
775
-        // load and setup EE_Config and EE_Network_Config
776
-        $config = $this->loader->getShared('EE_Config');
777
-        $this->loader->getShared('EE_Network_Config');
778
-        // setup autoloaders
779
-        // enable logging?
780
-        if ($config->admin->use_remote_logging) {
781
-            $this->loader->getShared('EE_Log');
782
-        }
783
-        // check for activation errors
784
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
785
-        if ($activation_errors) {
786
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
787
-            update_option('ee_plugin_activation_errors', false);
788
-        }
789
-        // get model names
790
-        $this->_parse_model_names();
791
-        // configure custom post type definitions
792
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
793
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
794
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
795
-    }
796
-
797
-
798
-    /**
799
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
800
-     *
801
-     * @return void
802
-     * @throws ReflectionException
803
-     */
804
-    private function _parse_model_names()
805
-    {
806
-        // get all the files in the EE_MODELS folder that end in .model.php
807
-        $models                 = glob(EE_MODELS . '*.model.php');
808
-        $model_names            = [];
809
-        $non_abstract_db_models = [];
810
-        foreach ($models as $model) {
811
-            // get model classname
812
-            $classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
813
-            $short_name      = str_replace('EEM_', '', $classname);
814
-            $reflectionClass = new ReflectionClass($classname);
815
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
816
-                $non_abstract_db_models[ $short_name ] = $classname;
817
-            }
818
-            $model_names[ $short_name ] = $classname;
819
-        }
820
-        $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
821
-        $this->registry->non_abstract_db_models = apply_filters(
822
-            'FHEE__EE_System__parse_implemented_model_names',
823
-            $non_abstract_db_models
824
-        );
825
-    }
826
-
827
-
828
-    /**
829
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
830
-     * that need to be setup before our EE_System launches.
831
-     *
832
-     * @return void
833
-     * @throws DomainException
834
-     * @throws InvalidArgumentException
835
-     * @throws InvalidDataTypeException
836
-     * @throws InvalidInterfaceException
837
-     * @throws InvalidClassException
838
-     * @throws InvalidFilePathException
839
-     */
840
-    private function _maybe_brew_regular()
841
-    {
842
-        /** @var Domain $domain */
843
-        $domain = DomainFactory::getEventEspressoCoreDomain();
844
-        if ($domain->isCaffeinated()) {
845
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
846
-        }
847
-    }
848
-
849
-
850
-    /**
851
-     * @throws Exception
852
-     * @since 4.9.71.p
853
-     */
854
-    public function loadRouteMatchSpecifications()
855
-    {
856
-        try {
857
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
858
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
859
-            $this->router->loadPrimaryRoutes();
860
-        } catch (Exception $exception) {
861
-            new ExceptionStackTraceDisplay($exception);
862
-        }
863
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
864
-    }
865
-
866
-
867
-    /**
868
-     * register_shortcodes_modules_and_widgets
869
-     * generate lists of shortcodes and modules, then verify paths and classes
870
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
871
-     * which runs during the WP 'plugins_loaded' action at priority 7
872
-     *
873
-     * @access public
874
-     * @return void
875
-     * @throws Exception
876
-     */
877
-    public function register_shortcodes_modules_and_widgets()
878
-    {
879
-        $this->router->registerShortcodesModulesAndWidgets();
880
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
881
-        // check for addons using old hook point
882
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
883
-            $this->_incompatible_addon_error();
884
-        }
885
-    }
886
-
887
-
888
-    /**
889
-     * _incompatible_addon_error
890
-     *
891
-     * @access public
892
-     * @return void
893
-     */
894
-    private function _incompatible_addon_error()
895
-    {
896
-        // get array of classes hooking into here
897
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
898
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
899
-        );
900
-        if (! empty($class_names)) {
901
-            $msg = __(
902
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
903
-                'event_espresso'
904
-            );
905
-            $msg .= '<ul>';
906
-            foreach ($class_names as $class_name) {
907
-                $msg .= '<li><b>Event Espresso - '
908
-                        . str_replace(
909
-                            ['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
910
-                            '',
911
-                            $class_name
912
-                        ) . '</b></li>';
913
-            }
914
-            $msg .= '</ul>';
915
-            $msg .= __(
916
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
917
-                'event_espresso'
918
-            );
919
-            // save list of incompatible addons to wp-options for later use
920
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
921
-            if (is_admin()) {
922
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
923
-            }
924
-        }
925
-    }
926
-
927
-
928
-    /**
929
-     * brew_espresso
930
-     * begins the process of setting hooks for initializing EE in the correct order
931
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
932
-     * which runs during the WP 'plugins_loaded' action at priority 9
933
-     *
934
-     * @return void
935
-     * @throws Exception
936
-     */
937
-    public function brew_espresso()
938
-    {
939
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
940
-        // load some final core systems
941
-        add_action('init', [$this, 'set_hooks_for_core'], 1);
942
-        add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
943
-        add_action('init', [$this, 'load_CPTs_and_session'], 5);
944
-        add_action('init', [$this, 'load_controllers'], 7);
945
-        add_action('init', [$this, 'core_loaded_and_ready'], 9);
946
-        add_action('init', [$this, 'initialize'], 10);
947
-        add_action('init', [$this, 'initialize_last'], 100);
948
-        $this->router->brewEspresso();
949
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
950
-    }
951
-
952
-
953
-    /**
954
-     *    set_hooks_for_core
955
-     *
956
-     * @access public
957
-     * @return    void
958
-     * @throws EE_Error
959
-     */
960
-    public function set_hooks_for_core()
961
-    {
962
-        $this->_deactivate_incompatible_addons();
963
-        do_action('AHEE__EE_System__set_hooks_for_core');
964
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
965
-        // caps need to be initialized on every request so that capability maps are set.
966
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
967
-        $this->registry->CAP->init_caps();
968
-    }
969
-
970
-
971
-    /**
972
-     * Using the information gathered in EE_System::_incompatible_addon_error,
973
-     * deactivates any addons considered incompatible with the current version of EE
974
-     */
975
-    private function _deactivate_incompatible_addons()
976
-    {
977
-        $incompatible_addons = get_option('ee_incompatible_addons', []);
978
-        if (! empty($incompatible_addons)) {
979
-            $active_plugins = get_option('active_plugins', []);
980
-            foreach ($active_plugins as $active_plugin) {
981
-                foreach ($incompatible_addons as $incompatible_addon) {
982
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
983
-                        unset($_GET['activate']);
984
-                        espresso_deactivate_plugin($active_plugin);
985
-                    }
986
-                }
987
-            }
988
-        }
989
-    }
990
-
991
-
992
-    /**
993
-     *    perform_activations_upgrades_and_migrations
994
-     *
995
-     * @access public
996
-     * @return    void
997
-     */
998
-    public function perform_activations_upgrades_and_migrations()
999
-    {
1000
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1001
-    }
1002
-
1003
-
1004
-    /**
1005
-     * @return void
1006
-     * @throws DomainException
1007
-     */
1008
-    public function load_CPTs_and_session()
1009
-    {
1010
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1011
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1012
-        $register_custom_taxonomies = $this->loader->getShared(
1013
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1014
-        );
1015
-        $register_custom_taxonomies->registerCustomTaxonomies();
1016
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1017
-        $register_custom_post_types = $this->loader->getShared(
1018
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1019
-        );
1020
-        $register_custom_post_types->registerCustomPostTypes();
1021
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1022
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1023
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1024
-        );
1025
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1026
-        // load legacy Custom Post Types and Taxonomies
1027
-        $this->loader->getShared('EE_Register_CPTs');
1028
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1029
-    }
1030
-
1031
-
1032
-    /**
1033
-     * load_controllers
1034
-     * this is the best place to load any additional controllers that needs access to EE core.
1035
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1036
-     * time
1037
-     *
1038
-     * @access public
1039
-     * @return void
1040
-     * @throws Exception
1041
-     */
1042
-    public function load_controllers()
1043
-    {
1044
-        do_action('AHEE__EE_System__load_controllers__start');
1045
-        $this->router->loadControllers();
1046
-        do_action('AHEE__EE_System__load_controllers__complete');
1047
-    }
1048
-
1049
-
1050
-    /**
1051
-     * core_loaded_and_ready
1052
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1053
-     *
1054
-     * @access public
1055
-     * @return void
1056
-     * @throws Exception
1057
-     */
1058
-    public function core_loaded_and_ready()
1059
-    {
1060
-        $this->router->coreLoadedAndReady();
1061
-        // integrate WP_Query with the EE models
1062
-        $this->loader->getShared('EE_CPT_Strategy');
1063
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1064
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1065
-        // builders require these even on the front-end
1066
-        require_once EE_PUBLIC . 'template_tags.php';
1067
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1068
-    }
1069
-
1070
-
1071
-    /**
1072
-     * initialize
1073
-     * this is the best place to begin initializing client code
1074
-     *
1075
-     * @access public
1076
-     * @return void
1077
-     */
1078
-    public function initialize()
1079
-    {
1080
-        do_action('AHEE__EE_System__initialize');
1081
-    }
1082
-
1083
-
1084
-    /**
1085
-     * initialize_last
1086
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1087
-     * initialize has done so
1088
-     *
1089
-     * @access public
1090
-     * @return void
1091
-     * @throws Exception
1092
-     */
1093
-    public function initialize_last()
1094
-    {
1095
-        do_action('AHEE__EE_System__initialize_last');
1096
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1097
-        $rewrite_rules = $this->loader->getShared(
1098
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1099
-        );
1100
-        $rewrite_rules->flushRewriteRules();
1101
-        $this->router->initializeLast();
1102
-        add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1103
-    }
1104
-
1105
-
1106
-    /**
1107
-     * @return void
1108
-     */
1109
-    public function addEspressoToolbar()
1110
-    {
1111
-        $this->loader->getShared(
1112
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1113
-            [$this->registry->CAP]
1114
-        );
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * do_not_cache
1120
-     * sets no cache headers and defines no cache constants for WP plugins
1121
-     *
1122
-     * @access public
1123
-     * @return void
1124
-     */
1125
-    public static function do_not_cache()
1126
-    {
1127
-        // set no cache constants
1128
-        if (! defined('DONOTCACHEPAGE')) {
1129
-            define('DONOTCACHEPAGE', true);
1130
-        }
1131
-        if (! defined('DONOTCACHCEOBJECT')) {
1132
-            define('DONOTCACHCEOBJECT', true);
1133
-        }
1134
-        if (! defined('DONOTCACHEDB')) {
1135
-            define('DONOTCACHEDB', true);
1136
-        }
1137
-        // add no cache headers
1138
-        add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1139
-        // plus a little extra for nginx and Google Chrome
1140
-        add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1141
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1142
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1143
-    }
1144
-
1145
-
1146
-    /**
1147
-     *    extra_nocache_headers
1148
-     *
1149
-     * @access    public
1150
-     * @param $headers
1151
-     * @return    array
1152
-     */
1153
-    public static function extra_nocache_headers($headers): array
1154
-    {
1155
-        // for NGINX
1156
-        $headers['X-Accel-Expires'] = 0;
1157
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1158
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1159
-        return $headers;
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     *    nocache_headers
1165
-     *
1166
-     * @access    public
1167
-     * @return    void
1168
-     */
1169
-    public static function nocache_headers()
1170
-    {
1171
-        nocache_headers();
1172
-    }
1173
-
1174
-
1175
-    /**
1176
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1177
-     * never returned with the function.
1178
-     *
1179
-     * @param array $exclude_array any existing pages being excluded are in this array.
1180
-     * @return array
1181
-     */
1182
-    public function remove_pages_from_wp_list_pages(array $exclude_array): array
1183
-    {
1184
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1185
-    }
28
+	/**
29
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
30
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
31
+	 */
32
+	const req_type_normal = 0;
33
+
34
+	/**
35
+	 * Indicates this is a brand new installation of EE so we should install
36
+	 * tables and default data etc
37
+	 */
38
+	const req_type_new_activation = 1;
39
+
40
+	/**
41
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
42
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
43
+	 * and that default data is setup too
44
+	 */
45
+	const req_type_reactivation = 2;
46
+
47
+	/**
48
+	 * indicates that EE has been upgraded since its previous request.
49
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
50
+	 */
51
+	const req_type_upgrade = 3;
52
+
53
+	/**
54
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
55
+	 */
56
+	const req_type_downgrade = 4;
57
+
58
+	/**
59
+	 * @deprecated since version 4.6.0.dev.006
60
+	 * Now whenever a new_activation is detected the request type is still just
61
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
62
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
63
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
64
+	 * (Specifically, when the migration manager indicates migrations are finished
65
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
66
+	 */
67
+	const req_type_activation_but_not_installed = 5;
68
+
69
+	/**
70
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
71
+	 */
72
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
73
+
74
+	/**
75
+	 * @var AddonManager $addon_manager
76
+	 */
77
+	private $addon_manager;
78
+
79
+	/**
80
+	 * @var EE_System $_instance
81
+	 */
82
+	private static $_instance;
83
+
84
+	/**
85
+	 * @var EE_Registry $registry
86
+	 */
87
+	private $registry;
88
+
89
+	/**
90
+	 * @var LoaderInterface $loader
91
+	 */
92
+	private $loader;
93
+
94
+	/**
95
+	 * @var EE_Capabilities $capabilities
96
+	 */
97
+	private $capabilities;
98
+
99
+	/**
100
+	 * @var EE_Maintenance_Mode $maintenance_mode
101
+	 */
102
+	private $maintenance_mode;
103
+
104
+	/**
105
+	 * @var RequestInterface $request
106
+	 */
107
+	private $request;
108
+
109
+	/**
110
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
111
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
112
+	 *
113
+	 * @var int $_req_type
114
+	 */
115
+	private $_req_type;
116
+
117
+	/**
118
+	 * Whether or not there was a non-micro version change in EE core version during this request
119
+	 *
120
+	 * @var boolean $_major_version_change
121
+	 */
122
+	private $_major_version_change = false;
123
+
124
+	/**
125
+	 * @var Router $router
126
+	 */
127
+	private $router;
128
+
129
+
130
+	/**
131
+	 * @singleton method used to instantiate class object
132
+	 * @param LoaderInterface|null     $loader
133
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
134
+	 * @param EE_Registry|null         $registry
135
+	 * @param RequestInterface|null    $request
136
+	 * @param Router|null              $router
137
+	 * @return EE_System
138
+	 */
139
+	public static function instance(
140
+		LoaderInterface $loader = null,
141
+		EE_Maintenance_Mode $maintenance_mode = null,
142
+		EE_Registry $registry = null,
143
+		RequestInterface $request = null,
144
+		Router $router = null
145
+	): EE_System {
146
+		// check if class object is instantiated
147
+		if (! self::$_instance instanceof EE_System) {
148
+			self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
149
+		}
150
+		return self::$_instance;
151
+	}
152
+
153
+
154
+	/**
155
+	 * resets the instance and returns it
156
+	 *
157
+	 * @return EE_System
158
+	 */
159
+	public static function reset(): EE_System
160
+	{
161
+		self::$_instance->_req_type = null;
162
+		// make sure none of the old hooks are left hanging around
163
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
164
+		// we need to reset the migration manager in order for it to detect DMSs properly
165
+		EE_Data_Migration_Manager::reset();
166
+		self::instance()->detect_activations_or_upgrades();
167
+		self::instance()->perform_activations_upgrades_and_migrations();
168
+		return self::instance();
169
+	}
170
+
171
+
172
+	/**
173
+	 * sets hooks for running rest of system
174
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
175
+	 * starting EE Addons from any other point may lead to problems
176
+	 *
177
+	 * @param LoaderInterface     $loader
178
+	 * @param EE_Maintenance_Mode $maintenance_mode
179
+	 * @param EE_Registry         $registry
180
+	 * @param RequestInterface    $request
181
+	 * @param Router              $router
182
+	 */
183
+	private function __construct(
184
+		LoaderInterface $loader,
185
+		EE_Maintenance_Mode $maintenance_mode,
186
+		EE_Registry $registry,
187
+		RequestInterface $request,
188
+		Router $router
189
+	) {
190
+		$this->registry         = $registry;
191
+		$this->loader           = $loader;
192
+		$this->request          = $request;
193
+		$this->router           = $router;
194
+		$this->maintenance_mode = $maintenance_mode;
195
+		do_action('AHEE__EE_System__construct__begin', $this);
196
+		add_action(
197
+			'AHEE__EE_Bootstrap__load_espresso_addons',
198
+			[$this, 'loadCapabilities'],
199
+			5
200
+		);
201
+		add_action(
202
+			'AHEE__EE_Bootstrap__load_espresso_addons',
203
+			[$this, 'loadCommandBus'],
204
+			7
205
+		);
206
+		add_action(
207
+			'AHEE__EE_Bootstrap__load_espresso_addons',
208
+			[$this, 'loadPluginApi'],
209
+			9
210
+		);
211
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
212
+		add_action(
213
+			'AHEE__EE_Bootstrap__load_espresso_addons',
214
+			[$this, 'load_espresso_addons']
215
+		);
216
+		// when an ee addon is activated, we want to call the core hook(s) again
217
+		// because the newly-activated addon didn't get a chance to run at all
218
+		add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
219
+		// detect whether install or upgrade
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
222
+			[$this, 'detect_activations_or_upgrades'],
223
+			3
224
+		);
225
+		// load EE_Config, EE_Textdomain, etc
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_core_configuration',
228
+			[$this, 'load_core_configuration'],
229
+			5
230
+		);
231
+		// load specifications for matching routes to current request
232
+		add_action(
233
+			'AHEE__EE_Bootstrap__load_core_configuration',
234
+			[$this, 'loadRouteMatchSpecifications']
235
+		);
236
+		// load EE_Config, EE_Textdomain, etc
237
+		add_action(
238
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
239
+			[$this, 'register_shortcodes_modules_and_widgets'],
240
+			7
241
+		);
242
+		// you wanna get going? I wanna get going... let's get going!
243
+		add_action(
244
+			'AHEE__EE_Bootstrap__brew_espresso',
245
+			[$this, 'brew_espresso'],
246
+			9
247
+		);
248
+		// other housekeeping
249
+		// exclude EE critical pages from wp_list_pages
250
+		add_filter(
251
+			'wp_list_pages_excludes',
252
+			[$this, 'remove_pages_from_wp_list_pages'],
253
+			10
254
+		);
255
+		// ALL EE Addons should use the following hook point to attach their initial setup too
256
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
257
+		do_action('AHEE__EE_System__construct__complete', $this);
258
+	}
259
+
260
+
261
+	/**
262
+	 * load and setup EE_Capabilities
263
+	 *
264
+	 * @return void
265
+	 */
266
+	public function loadCapabilities()
267
+	{
268
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
269
+		add_action(
270
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
271
+			function () {
272
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273
+			}
274
+		);
275
+	}
276
+
277
+
278
+	/**
279
+	 * create and cache the CommandBus, and also add middleware
280
+	 * The CapChecker middleware requires the use of EE_Capabilities
281
+	 * which is why we need to load the CommandBus after Caps are set up
282
+	 *
283
+	 * @return void
284
+	 */
285
+	public function loadCommandBus()
286
+	{
287
+		$this->loader->getShared(
288
+			'CommandBusInterface',
289
+			[
290
+				null,
291
+				apply_filters(
292
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
293
+					[
294
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
295
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
296
+					]
297
+				),
298
+			]
299
+		);
300
+	}
301
+
302
+
303
+	/**
304
+	 * @return void
305
+	 * @throws Exception
306
+	 */
307
+	public function loadPluginApi()
308
+	{
309
+		$this->addon_manager = $this->loader->getShared(AddonManager::class);
310
+		$this->addon_manager->initialize();
311
+		$this->loader->getShared('EE_Request_Handler');
312
+	}
313
+
314
+
315
+	/**
316
+	 * load_espresso_addons
317
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
318
+	 * this is hooked into both:
319
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
320
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
321
+	 *    and the WP 'activate_plugin' hook point
322
+	 *
323
+	 * @return void
324
+	 * @throws Exception
325
+	 */
326
+	public function load_espresso_addons()
327
+	{
328
+		// looking for hooks? they've been moved into the AddonManager to maintain compatibility
329
+		$this->addon_manager->loadAddons();
330
+	}
331
+
332
+
333
+	/**
334
+	 * detect_activations_or_upgrades
335
+	 * Checks for activation or upgrade of core first;
336
+	 * then also checks if any registered addons have been activated or upgraded
337
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
338
+	 * which runs during the WP 'plugins_loaded' action at priority 3
339
+	 *
340
+	 * @access public
341
+	 * @return void
342
+	 */
343
+	public function detect_activations_or_upgrades()
344
+	{
345
+		// first off: let's make sure to handle core
346
+		$this->detect_if_activation_or_upgrade();
347
+		foreach ($this->registry->addons as $addon) {
348
+			if ($addon instanceof EE_Addon) {
349
+				// detect teh request type for that addon
350
+				$addon->detect_activation_or_upgrade();
351
+			}
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * detect_if_activation_or_upgrade
358
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
359
+	 * and either setting up the DB or setting up maintenance mode etc.
360
+	 *
361
+	 * @access public
362
+	 * @return void
363
+	 */
364
+	public function detect_if_activation_or_upgrade()
365
+	{
366
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
367
+		// check if db has been updated, or if its a brand-new installation
368
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
369
+		$request_type       = $this->detect_req_type($espresso_db_update);
370
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
371
+		switch ($request_type) {
372
+			case EE_System::req_type_new_activation:
373
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
374
+				$this->_handle_core_version_change($espresso_db_update);
375
+				break;
376
+			case EE_System::req_type_reactivation:
377
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
378
+				$this->_handle_core_version_change($espresso_db_update);
379
+				break;
380
+			case EE_System::req_type_upgrade:
381
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
382
+				// migrations may be required now that we've upgraded
383
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
384
+				$this->_handle_core_version_change($espresso_db_update);
385
+				break;
386
+			case EE_System::req_type_downgrade:
387
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
388
+				// its possible migrations are no longer required
389
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
390
+				$this->_handle_core_version_change($espresso_db_update);
391
+				break;
392
+			case EE_System::req_type_normal:
393
+			default:
394
+				break;
395
+		}
396
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
397
+	}
398
+
399
+
400
+	/**
401
+	 * Updates the list of installed versions and sets hooks for
402
+	 * initializing the database later during the request
403
+	 *
404
+	 * @param array $espresso_db_update
405
+	 */
406
+	private function _handle_core_version_change(array $espresso_db_update)
407
+	{
408
+		$this->update_list_of_installed_versions($espresso_db_update);
409
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
410
+		add_action(
411
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
412
+			[$this, 'initialize_db_if_no_migrations_required']
413
+		);
414
+	}
415
+
416
+
417
+	/**
418
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
419
+	 * information about what versions of EE have been installed and activated,
420
+	 * NOT necessarily the state of the database
421
+	 *
422
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
423
+	 *                                            If not supplied, fetches it from the options table
424
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
425
+	 */
426
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
427
+	{
428
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
429
+		if (! $espresso_db_update) {
430
+			$espresso_db_update = get_option('espresso_db_update');
431
+		}
432
+		// check that option is an array
433
+		if (! is_array($espresso_db_update)) {
434
+			// if option is FALSE, then it never existed
435
+			if ($espresso_db_update === false) {
436
+				// make $espresso_db_update an array and save option with autoload OFF
437
+				$espresso_db_update = [];
438
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
439
+			} else {
440
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
441
+				$espresso_db_update = [$espresso_db_update => []];
442
+				update_option('espresso_db_update', $espresso_db_update);
443
+			}
444
+		} else {
445
+			$corrected_db_update = [];
446
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
447
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
448
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
449
+					// the key is an int, and the value IS NOT an array
450
+					// so it must be numerically-indexed, where values are versions installed...
451
+					// fix it!
452
+					$version_string                         = $should_be_array;
453
+					$corrected_db_update[ $version_string ] = ['unknown-date'];
454
+				} else {
455
+					// ok it checks out
456
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
457
+				}
458
+			}
459
+			$espresso_db_update = $corrected_db_update;
460
+			update_option('espresso_db_update', $espresso_db_update);
461
+		}
462
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
463
+		return ! empty($espresso_db_update) ? $espresso_db_update : [];
464
+	}
465
+
466
+
467
+	/**
468
+	 * Does the traditional work of setting up the plugin's database and adding default data.
469
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
470
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
471
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
472
+	 * so that it will be done when migrations are finished
473
+	 *
474
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
475
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
476
+	 *                                       This is a resource-intensive job
477
+	 *                                       so we prefer to only do it when necessary
478
+	 * @return void
479
+	 * @throws EE_Error
480
+	 */
481
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
482
+	{
483
+		$request_type = $this->detect_req_type();
484
+		// only initialize system if we're not in maintenance mode.
485
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
486
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
487
+			$rewrite_rules = $this->loader->getShared(
488
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
489
+			);
490
+			$rewrite_rules->flush();
491
+			if ($verify_schema) {
492
+				EEH_Activation::initialize_db_and_folders();
493
+			}
494
+			EEH_Activation::initialize_db_content();
495
+			EEH_Activation::system_initialization();
496
+			if ($initialize_addons_too) {
497
+				$this->initialize_addons();
498
+			}
499
+		} else {
500
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
501
+		}
502
+		if ($request_type === EE_System::req_type_new_activation
503
+			|| $request_type === EE_System::req_type_reactivation
504
+			|| (
505
+				$request_type === EE_System::req_type_upgrade
506
+				&& $this->is_major_version_change()
507
+			)
508
+		) {
509
+			add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
510
+		}
511
+	}
512
+
513
+
514
+	/**
515
+	 * Initializes the db for all registered addons
516
+	 *
517
+	 * @throws EE_Error
518
+	 */
519
+	public function initialize_addons()
520
+	{
521
+		// foreach registered addon, make sure its db is up-to-date too
522
+		foreach ($this->registry->addons as $addon) {
523
+			if ($addon instanceof EE_Addon) {
524
+				$addon->initialize_db_if_no_migrations_required();
525
+			}
526
+		}
527
+	}
528
+
529
+
530
+	/**
531
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
532
+	 *
533
+	 * @param array  $version_history
534
+	 * @param string $current_version_to_add version to be added to the version history
535
+	 * @return    boolean success as to whether or not this option was changed
536
+	 */
537
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
538
+	{
539
+		if (! $version_history) {
540
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
541
+		}
542
+		if ($current_version_to_add === null) {
543
+			$current_version_to_add = espresso_version();
544
+		}
545
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
546
+		// re-save
547
+		return update_option('espresso_db_update', $version_history);
548
+	}
549
+
550
+
551
+	/**
552
+	 * Detects if the current version indicated in the has existed in the list of
553
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
554
+	 *
555
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
556
+	 *                                  If not supplied, fetches it from the options table.
557
+	 *                                  Also, caches its result so later parts of the code can also know whether
558
+	 *                                  there's been an update or not. This way we can add the current version to
559
+	 *                                  espresso_db_update, but still know if this is a new install or not
560
+	 * @return int one of the constants on EE_System::req_type_
561
+	 */
562
+	public function detect_req_type($espresso_db_update = null): int
563
+	{
564
+		if ($this->_req_type === null) {
565
+			$espresso_db_update          = ! empty($espresso_db_update)
566
+				? $espresso_db_update
567
+				: $this->fix_espresso_db_upgrade_option();
568
+			$this->_req_type             = EE_System::detect_req_type_given_activation_history(
569
+				$espresso_db_update,
570
+				'ee_espresso_activation',
571
+				espresso_version()
572
+			);
573
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
574
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
575
+		}
576
+		return $this->_req_type;
577
+	}
578
+
579
+
580
+	/**
581
+	 * Returns whether or not there was a non-micro version change (ie, change in either
582
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
583
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
584
+	 *
585
+	 * @param $activation_history
586
+	 * @return bool
587
+	 */
588
+	private function _detect_major_version_change($activation_history): bool
589
+	{
590
+		$previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
591
+		$previous_version_parts = explode('.', $previous_version);
592
+		$current_version_parts  = explode('.', espresso_version());
593
+		return isset(
594
+			$previous_version_parts[0],
595
+			$previous_version_parts[1],
596
+			$current_version_parts[0],
597
+			$current_version_parts[1]
598
+		) && (
599
+			$previous_version_parts[0] !== $current_version_parts[0]
600
+			|| $previous_version_parts[1] !== $current_version_parts[1]
601
+		);
602
+	}
603
+
604
+
605
+	/**
606
+	 * Returns true if either the major or minor version of EE changed during this request.
607
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
608
+	 *
609
+	 * @return bool
610
+	 */
611
+	public function is_major_version_change(): bool
612
+	{
613
+		return $this->_major_version_change;
614
+	}
615
+
616
+
617
+	/**
618
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
619
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
620
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
621
+	 * just activated to (for core that will always be espresso_version())
622
+	 *
623
+	 * @param array|null $activation_history             the option's value which stores the activation history for
624
+	 *                                                 this
625
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
626
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
627
+	 *                                                 indicate that this plugin was just activated
628
+	 * @param string $current_version                  the version that was just upgraded to (for core that will be
629
+	 *                                                 espresso_version())
630
+	 * @return int one of the constants on EE_System::req_type_
631
+	 */
632
+	public static function detect_req_type_given_activation_history(
633
+		array $activation_history,
634
+		string $activation_indicator_option_name,
635
+		string $current_version
636
+	): int {
637
+		$version_change = self::compareVersionWithPrevious($activation_history, $current_version);
638
+		$is_activation  = get_option($activation_indicator_option_name, false);
639
+		$req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
640
+		if ($is_activation) {
641
+			// cleanup in aisle 6
642
+			delete_option($activation_indicator_option_name);
643
+		}
644
+		return $req_type;
645
+	}
646
+
647
+
648
+	/**
649
+	 * @param array  $activation_history
650
+	 * @param int    $version_change
651
+	 * @param bool   $is_activation
652
+	 * @return int
653
+	 * @since $VID:$
654
+	 */
655
+	private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
656
+	{
657
+		// if no previous activation history exists, then this is a brand new install
658
+		if (empty($activation_history)) {
659
+			return EE_System::req_type_new_activation;
660
+		}
661
+		// current version is higher than previous version, so it's an upgrade
662
+		if ($version_change === 1) {
663
+			return EE_System::req_type_upgrade;
664
+		}
665
+		// current version is lower than previous version, so it's a downgrade
666
+		if ($version_change === -1) {
667
+			return EE_System::req_type_downgrade;
668
+		}
669
+		// version hasn't changed since last version so check if the activation indicator is set
670
+		// to determine if it's a reactivation, or just a normal request
671
+		return $is_activation
672
+			? EE_System::req_type_reactivation
673
+			: EE_System::req_type_normal;
674
+	}
675
+
676
+
677
+	/**
678
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
679
+	 * the $activation_history_for_addon
680
+	 *
681
+	 * @param array  $activation_history    array where keys are versions,
682
+	 *                                      values are arrays of times activated (sometimes 'unknown-date')
683
+	 * @param string $current_version
684
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
685
+	 *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
686
+	 *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
687
+	 *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
688
+	 */
689
+	private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
690
+	{
691
+		// find the most recently-activated version
692
+		$most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
693
+		return version_compare($current_version, $most_recently_active_version);
694
+	}
695
+
696
+
697
+	/**
698
+	 * Gets the most recently active version listed in the activation history,
699
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
700
+	 *
701
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
702
+	 *                                   sometimes containing 'unknown-date'
703
+	 * @return string
704
+	 */
705
+	private static function getMostRecentlyActiveVersion(array $activation_history): string
706
+	{
707
+		$most_recent_activation_date  = '1970-01-01 00:00:00';
708
+		$most_recently_active_version = '0.0.0.dev.000';
709
+		if (is_array($activation_history)) {
710
+			foreach ($activation_history as $version => $activation_dates) {
711
+				// check there is a record of when this version was activated.
712
+				// Otherwise, mark it as unknown
713
+				if (! $activation_dates) {
714
+					$activation_dates = ['unknown-date'];
715
+				}
716
+				$activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
717
+				foreach ($activation_dates as $activation_date) {
718
+					if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
719
+						$most_recently_active_version = $version;
720
+						$most_recent_activation_date  = $activation_date;
721
+					}
722
+				}
723
+			}
724
+		}
725
+		return $most_recently_active_version;
726
+	}
727
+
728
+
729
+	/**
730
+	 * This redirects to the about EE page after activation
731
+	 *
732
+	 * @return void
733
+	 */
734
+	public function redirect_to_about_ee()
735
+	{
736
+		$notices = EE_Error::get_notices(false);
737
+		// if current user is an admin and it's not an ajax or rest request
738
+		if (! isset($notices['errors'])
739
+			&& $this->request->isAdmin()
740
+			&& apply_filters(
741
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
742
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
743
+			)
744
+		) {
745
+			$query_params = ['page' => 'espresso_about'];
746
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
747
+				$query_params['new_activation'] = true;
748
+			}
749
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
750
+				$query_params['reactivation'] = true;
751
+			}
752
+			$url = add_query_arg($query_params, admin_url('admin.php'));
753
+			EEH_URL::safeRedirectAndExit($url);
754
+		}
755
+	}
756
+
757
+
758
+	/**
759
+	 * load_core_configuration
760
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
761
+	 * which runs during the WP 'plugins_loaded' action at priority 5
762
+	 *
763
+	 * @return void
764
+	 * @throws ReflectionException
765
+	 * @throws Exception
766
+	 */
767
+	public function load_core_configuration()
768
+	{
769
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
770
+		$this->loader->getShared('EE_Load_Textdomain');
771
+		// load textdomain
772
+		EE_Load_Textdomain::load_textdomain();
773
+		// load caf stuff a chance to play during the activation process too.
774
+		$this->_maybe_brew_regular();
775
+		// load and setup EE_Config and EE_Network_Config
776
+		$config = $this->loader->getShared('EE_Config');
777
+		$this->loader->getShared('EE_Network_Config');
778
+		// setup autoloaders
779
+		// enable logging?
780
+		if ($config->admin->use_remote_logging) {
781
+			$this->loader->getShared('EE_Log');
782
+		}
783
+		// check for activation errors
784
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
785
+		if ($activation_errors) {
786
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
787
+			update_option('ee_plugin_activation_errors', false);
788
+		}
789
+		// get model names
790
+		$this->_parse_model_names();
791
+		// configure custom post type definitions
792
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
793
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
794
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
795
+	}
796
+
797
+
798
+	/**
799
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
800
+	 *
801
+	 * @return void
802
+	 * @throws ReflectionException
803
+	 */
804
+	private function _parse_model_names()
805
+	{
806
+		// get all the files in the EE_MODELS folder that end in .model.php
807
+		$models                 = glob(EE_MODELS . '*.model.php');
808
+		$model_names            = [];
809
+		$non_abstract_db_models = [];
810
+		foreach ($models as $model) {
811
+			// get model classname
812
+			$classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
813
+			$short_name      = str_replace('EEM_', '', $classname);
814
+			$reflectionClass = new ReflectionClass($classname);
815
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
816
+				$non_abstract_db_models[ $short_name ] = $classname;
817
+			}
818
+			$model_names[ $short_name ] = $classname;
819
+		}
820
+		$this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
821
+		$this->registry->non_abstract_db_models = apply_filters(
822
+			'FHEE__EE_System__parse_implemented_model_names',
823
+			$non_abstract_db_models
824
+		);
825
+	}
826
+
827
+
828
+	/**
829
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
830
+	 * that need to be setup before our EE_System launches.
831
+	 *
832
+	 * @return void
833
+	 * @throws DomainException
834
+	 * @throws InvalidArgumentException
835
+	 * @throws InvalidDataTypeException
836
+	 * @throws InvalidInterfaceException
837
+	 * @throws InvalidClassException
838
+	 * @throws InvalidFilePathException
839
+	 */
840
+	private function _maybe_brew_regular()
841
+	{
842
+		/** @var Domain $domain */
843
+		$domain = DomainFactory::getEventEspressoCoreDomain();
844
+		if ($domain->isCaffeinated()) {
845
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
846
+		}
847
+	}
848
+
849
+
850
+	/**
851
+	 * @throws Exception
852
+	 * @since 4.9.71.p
853
+	 */
854
+	public function loadRouteMatchSpecifications()
855
+	{
856
+		try {
857
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
858
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
859
+			$this->router->loadPrimaryRoutes();
860
+		} catch (Exception $exception) {
861
+			new ExceptionStackTraceDisplay($exception);
862
+		}
863
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
864
+	}
865
+
866
+
867
+	/**
868
+	 * register_shortcodes_modules_and_widgets
869
+	 * generate lists of shortcodes and modules, then verify paths and classes
870
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
871
+	 * which runs during the WP 'plugins_loaded' action at priority 7
872
+	 *
873
+	 * @access public
874
+	 * @return void
875
+	 * @throws Exception
876
+	 */
877
+	public function register_shortcodes_modules_and_widgets()
878
+	{
879
+		$this->router->registerShortcodesModulesAndWidgets();
880
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
881
+		// check for addons using old hook point
882
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
883
+			$this->_incompatible_addon_error();
884
+		}
885
+	}
886
+
887
+
888
+	/**
889
+	 * _incompatible_addon_error
890
+	 *
891
+	 * @access public
892
+	 * @return void
893
+	 */
894
+	private function _incompatible_addon_error()
895
+	{
896
+		// get array of classes hooking into here
897
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
898
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
899
+		);
900
+		if (! empty($class_names)) {
901
+			$msg = __(
902
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
903
+				'event_espresso'
904
+			);
905
+			$msg .= '<ul>';
906
+			foreach ($class_names as $class_name) {
907
+				$msg .= '<li><b>Event Espresso - '
908
+						. str_replace(
909
+							['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
910
+							'',
911
+							$class_name
912
+						) . '</b></li>';
913
+			}
914
+			$msg .= '</ul>';
915
+			$msg .= __(
916
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
917
+				'event_espresso'
918
+			);
919
+			// save list of incompatible addons to wp-options for later use
920
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
921
+			if (is_admin()) {
922
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
923
+			}
924
+		}
925
+	}
926
+
927
+
928
+	/**
929
+	 * brew_espresso
930
+	 * begins the process of setting hooks for initializing EE in the correct order
931
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
932
+	 * which runs during the WP 'plugins_loaded' action at priority 9
933
+	 *
934
+	 * @return void
935
+	 * @throws Exception
936
+	 */
937
+	public function brew_espresso()
938
+	{
939
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
940
+		// load some final core systems
941
+		add_action('init', [$this, 'set_hooks_for_core'], 1);
942
+		add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
943
+		add_action('init', [$this, 'load_CPTs_and_session'], 5);
944
+		add_action('init', [$this, 'load_controllers'], 7);
945
+		add_action('init', [$this, 'core_loaded_and_ready'], 9);
946
+		add_action('init', [$this, 'initialize'], 10);
947
+		add_action('init', [$this, 'initialize_last'], 100);
948
+		$this->router->brewEspresso();
949
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
950
+	}
951
+
952
+
953
+	/**
954
+	 *    set_hooks_for_core
955
+	 *
956
+	 * @access public
957
+	 * @return    void
958
+	 * @throws EE_Error
959
+	 */
960
+	public function set_hooks_for_core()
961
+	{
962
+		$this->_deactivate_incompatible_addons();
963
+		do_action('AHEE__EE_System__set_hooks_for_core');
964
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
965
+		// caps need to be initialized on every request so that capability maps are set.
966
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
967
+		$this->registry->CAP->init_caps();
968
+	}
969
+
970
+
971
+	/**
972
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
973
+	 * deactivates any addons considered incompatible with the current version of EE
974
+	 */
975
+	private function _deactivate_incompatible_addons()
976
+	{
977
+		$incompatible_addons = get_option('ee_incompatible_addons', []);
978
+		if (! empty($incompatible_addons)) {
979
+			$active_plugins = get_option('active_plugins', []);
980
+			foreach ($active_plugins as $active_plugin) {
981
+				foreach ($incompatible_addons as $incompatible_addon) {
982
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
983
+						unset($_GET['activate']);
984
+						espresso_deactivate_plugin($active_plugin);
985
+					}
986
+				}
987
+			}
988
+		}
989
+	}
990
+
991
+
992
+	/**
993
+	 *    perform_activations_upgrades_and_migrations
994
+	 *
995
+	 * @access public
996
+	 * @return    void
997
+	 */
998
+	public function perform_activations_upgrades_and_migrations()
999
+	{
1000
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1001
+	}
1002
+
1003
+
1004
+	/**
1005
+	 * @return void
1006
+	 * @throws DomainException
1007
+	 */
1008
+	public function load_CPTs_and_session()
1009
+	{
1010
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1011
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1012
+		$register_custom_taxonomies = $this->loader->getShared(
1013
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1014
+		);
1015
+		$register_custom_taxonomies->registerCustomTaxonomies();
1016
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1017
+		$register_custom_post_types = $this->loader->getShared(
1018
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1019
+		);
1020
+		$register_custom_post_types->registerCustomPostTypes();
1021
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1022
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1023
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1024
+		);
1025
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1026
+		// load legacy Custom Post Types and Taxonomies
1027
+		$this->loader->getShared('EE_Register_CPTs');
1028
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1029
+	}
1030
+
1031
+
1032
+	/**
1033
+	 * load_controllers
1034
+	 * this is the best place to load any additional controllers that needs access to EE core.
1035
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1036
+	 * time
1037
+	 *
1038
+	 * @access public
1039
+	 * @return void
1040
+	 * @throws Exception
1041
+	 */
1042
+	public function load_controllers()
1043
+	{
1044
+		do_action('AHEE__EE_System__load_controllers__start');
1045
+		$this->router->loadControllers();
1046
+		do_action('AHEE__EE_System__load_controllers__complete');
1047
+	}
1048
+
1049
+
1050
+	/**
1051
+	 * core_loaded_and_ready
1052
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1053
+	 *
1054
+	 * @access public
1055
+	 * @return void
1056
+	 * @throws Exception
1057
+	 */
1058
+	public function core_loaded_and_ready()
1059
+	{
1060
+		$this->router->coreLoadedAndReady();
1061
+		// integrate WP_Query with the EE models
1062
+		$this->loader->getShared('EE_CPT_Strategy');
1063
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1064
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1065
+		// builders require these even on the front-end
1066
+		require_once EE_PUBLIC . 'template_tags.php';
1067
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1068
+	}
1069
+
1070
+
1071
+	/**
1072
+	 * initialize
1073
+	 * this is the best place to begin initializing client code
1074
+	 *
1075
+	 * @access public
1076
+	 * @return void
1077
+	 */
1078
+	public function initialize()
1079
+	{
1080
+		do_action('AHEE__EE_System__initialize');
1081
+	}
1082
+
1083
+
1084
+	/**
1085
+	 * initialize_last
1086
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1087
+	 * initialize has done so
1088
+	 *
1089
+	 * @access public
1090
+	 * @return void
1091
+	 * @throws Exception
1092
+	 */
1093
+	public function initialize_last()
1094
+	{
1095
+		do_action('AHEE__EE_System__initialize_last');
1096
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1097
+		$rewrite_rules = $this->loader->getShared(
1098
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1099
+		);
1100
+		$rewrite_rules->flushRewriteRules();
1101
+		$this->router->initializeLast();
1102
+		add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1103
+	}
1104
+
1105
+
1106
+	/**
1107
+	 * @return void
1108
+	 */
1109
+	public function addEspressoToolbar()
1110
+	{
1111
+		$this->loader->getShared(
1112
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1113
+			[$this->registry->CAP]
1114
+		);
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * do_not_cache
1120
+	 * sets no cache headers and defines no cache constants for WP plugins
1121
+	 *
1122
+	 * @access public
1123
+	 * @return void
1124
+	 */
1125
+	public static function do_not_cache()
1126
+	{
1127
+		// set no cache constants
1128
+		if (! defined('DONOTCACHEPAGE')) {
1129
+			define('DONOTCACHEPAGE', true);
1130
+		}
1131
+		if (! defined('DONOTCACHCEOBJECT')) {
1132
+			define('DONOTCACHCEOBJECT', true);
1133
+		}
1134
+		if (! defined('DONOTCACHEDB')) {
1135
+			define('DONOTCACHEDB', true);
1136
+		}
1137
+		// add no cache headers
1138
+		add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1139
+		// plus a little extra for nginx and Google Chrome
1140
+		add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1141
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1142
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1143
+	}
1144
+
1145
+
1146
+	/**
1147
+	 *    extra_nocache_headers
1148
+	 *
1149
+	 * @access    public
1150
+	 * @param $headers
1151
+	 * @return    array
1152
+	 */
1153
+	public static function extra_nocache_headers($headers): array
1154
+	{
1155
+		// for NGINX
1156
+		$headers['X-Accel-Expires'] = 0;
1157
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1158
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1159
+		return $headers;
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 *    nocache_headers
1165
+	 *
1166
+	 * @access    public
1167
+	 * @return    void
1168
+	 */
1169
+	public static function nocache_headers()
1170
+	{
1171
+		nocache_headers();
1172
+	}
1173
+
1174
+
1175
+	/**
1176
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1177
+	 * never returned with the function.
1178
+	 *
1179
+	 * @param array $exclude_array any existing pages being excluded are in this array.
1180
+	 * @return array
1181
+	 */
1182
+	public function remove_pages_from_wp_list_pages(array $exclude_array): array
1183
+	{
1184
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1185
+	}
1186 1186
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
         Router $router = null
145 145
     ): EE_System {
146 146
         // check if class object is instantiated
147
-        if (! self::$_instance instanceof EE_System) {
147
+        if ( ! self::$_instance instanceof EE_System) {
148 148
             self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
149 149
         }
150 150
         return self::$_instance;
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
         $this->capabilities = $this->loader->getShared('EE_Capabilities');
269 269
         add_action(
270 270
             'AHEE__EE_Capabilities__init_caps__before_initialization',
271
-            function () {
271
+            function() {
272 272
                 LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273 273
             }
274 274
         );
@@ -426,11 +426,11 @@  discard block
 block discarded – undo
426 426
     private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
427 427
     {
428 428
         do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
429
-        if (! $espresso_db_update) {
429
+        if ( ! $espresso_db_update) {
430 430
             $espresso_db_update = get_option('espresso_db_update');
431 431
         }
432 432
         // check that option is an array
433
-        if (! is_array($espresso_db_update)) {
433
+        if ( ! is_array($espresso_db_update)) {
434 434
             // if option is FALSE, then it never existed
435 435
             if ($espresso_db_update === false) {
436 436
                 // make $espresso_db_update an array and save option with autoload OFF
@@ -450,10 +450,10 @@  discard block
 block discarded – undo
450 450
                     // so it must be numerically-indexed, where values are versions installed...
451 451
                     // fix it!
452 452
                     $version_string                         = $should_be_array;
453
-                    $corrected_db_update[ $version_string ] = ['unknown-date'];
453
+                    $corrected_db_update[$version_string] = ['unknown-date'];
454 454
                 } else {
455 455
                     // ok it checks out
456
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
456
+                    $corrected_db_update[$should_be_version_string] = $should_be_array;
457 457
                 }
458 458
             }
459 459
             $espresso_db_update = $corrected_db_update;
@@ -536,13 +536,13 @@  discard block
 block discarded – undo
536 536
      */
537 537
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
538 538
     {
539
-        if (! $version_history) {
539
+        if ( ! $version_history) {
540 540
             $version_history = $this->fix_espresso_db_upgrade_option($version_history);
541 541
         }
542 542
         if ($current_version_to_add === null) {
543 543
             $current_version_to_add = espresso_version();
544 544
         }
545
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
545
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
546 546
         // re-save
547 547
         return update_option('espresso_db_update', $version_history);
548 548
     }
@@ -710,7 +710,7 @@  discard block
 block discarded – undo
710 710
             foreach ($activation_history as $version => $activation_dates) {
711 711
                 // check there is a record of when this version was activated.
712 712
                 // Otherwise, mark it as unknown
713
-                if (! $activation_dates) {
713
+                if ( ! $activation_dates) {
714 714
                     $activation_dates = ['unknown-date'];
715 715
                 }
716 716
                 $activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
@@ -735,7 +735,7 @@  discard block
 block discarded – undo
735 735
     {
736 736
         $notices = EE_Error::get_notices(false);
737 737
         // if current user is an admin and it's not an ajax or rest request
738
-        if (! isset($notices['errors'])
738
+        if ( ! isset($notices['errors'])
739 739
             && $this->request->isAdmin()
740 740
             && apply_filters(
741 741
                 'FHEE__EE_System__redirect_to_about_ee__do_redirect',
@@ -804,7 +804,7 @@  discard block
 block discarded – undo
804 804
     private function _parse_model_names()
805 805
     {
806 806
         // get all the files in the EE_MODELS folder that end in .model.php
807
-        $models                 = glob(EE_MODELS . '*.model.php');
807
+        $models                 = glob(EE_MODELS.'*.model.php');
808 808
         $model_names            = [];
809 809
         $non_abstract_db_models = [];
810 810
         foreach ($models as $model) {
@@ -813,9 +813,9 @@  discard block
 block discarded – undo
813 813
             $short_name      = str_replace('EEM_', '', $classname);
814 814
             $reflectionClass = new ReflectionClass($classname);
815 815
             if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
816
-                $non_abstract_db_models[ $short_name ] = $classname;
816
+                $non_abstract_db_models[$short_name] = $classname;
817 817
             }
818
-            $model_names[ $short_name ] = $classname;
818
+            $model_names[$short_name] = $classname;
819 819
         }
820 820
         $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
821 821
         $this->registry->non_abstract_db_models = apply_filters(
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
         /** @var Domain $domain */
843 843
         $domain = DomainFactory::getEventEspressoCoreDomain();
844 844
         if ($domain->isCaffeinated()) {
845
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
845
+            require_once EE_CAFF_PATH.'brewing_regular.php';
846 846
         }
847 847
     }
848 848
 
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
         $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
898 898
             'AHEE__EE_System__register_shortcodes_modules_and_addons'
899 899
         );
900
-        if (! empty($class_names)) {
900
+        if ( ! empty($class_names)) {
901 901
             $msg = __(
902 902
                 'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
903 903
                 'event_espresso'
@@ -909,7 +909,7 @@  discard block
 block discarded – undo
909 909
                             ['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
910 910
                             '',
911 911
                             $class_name
912
-                        ) . '</b></li>';
912
+                        ).'</b></li>';
913 913
             }
914 914
             $msg .= '</ul>';
915 915
             $msg .= __(
@@ -975,7 +975,7 @@  discard block
 block discarded – undo
975 975
     private function _deactivate_incompatible_addons()
976 976
     {
977 977
         $incompatible_addons = get_option('ee_incompatible_addons', []);
978
-        if (! empty($incompatible_addons)) {
978
+        if ( ! empty($incompatible_addons)) {
979 979
             $active_plugins = get_option('active_plugins', []);
980 980
             foreach ($active_plugins as $active_plugin) {
981 981
                 foreach ($incompatible_addons as $incompatible_addon) {
@@ -1063,7 +1063,7 @@  discard block
 block discarded – undo
1063 1063
         do_action('AHEE__EE_System__core_loaded_and_ready');
1064 1064
         // always load template tags, because it's faster than checking if it's a front-end request, and many page
1065 1065
         // builders require these even on the front-end
1066
-        require_once EE_PUBLIC . 'template_tags.php';
1066
+        require_once EE_PUBLIC.'template_tags.php';
1067 1067
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1068 1068
     }
1069 1069
 
@@ -1125,13 +1125,13 @@  discard block
 block discarded – undo
1125 1125
     public static function do_not_cache()
1126 1126
     {
1127 1127
         // set no cache constants
1128
-        if (! defined('DONOTCACHEPAGE')) {
1128
+        if ( ! defined('DONOTCACHEPAGE')) {
1129 1129
             define('DONOTCACHEPAGE', true);
1130 1130
         }
1131
-        if (! defined('DONOTCACHCEOBJECT')) {
1131
+        if ( ! defined('DONOTCACHCEOBJECT')) {
1132 1132
             define('DONOTCACHCEOBJECT', true);
1133 1133
         }
1134
-        if (! defined('DONOTCACHEDB')) {
1134
+        if ( ! defined('DONOTCACHEDB')) {
1135 1135
             define('DONOTCACHEDB', true);
1136 1136
         }
1137 1137
         // add no cache headers
Please login to merge, or discard this patch.
core/interfaces/EEHI_File.interface.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -6,27 +6,27 @@
 block discarded – undo
6 6
 interface EEHI_File
7 7
 {
8 8
 
9
-    /**
10
-     * ensure_file_exists_and_is_writable
11
-     * ensures that a file exists and is writable, will attempt to create file if it does not exist
12
-     *
13
-     * @param string $full_file_path
14
-     * @throws EE_Error
15
-     * @return bool
16
-     */
17
-    public static function ensure_file_exists_and_is_writable(string $full_file_path = ''): bool;
9
+	/**
10
+	 * ensure_file_exists_and_is_writable
11
+	 * ensures that a file exists and is writable, will attempt to create file if it does not exist
12
+	 *
13
+	 * @param string $full_file_path
14
+	 * @throws EE_Error
15
+	 * @return bool
16
+	 */
17
+	public static function ensure_file_exists_and_is_writable(string $full_file_path = ''): bool;
18 18
 
19 19
 
20 20
 
21
-    /**
22
-     * ensure_folder_exists_and_is_writable
23
-     * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
24
-     *
25
-     * @param string $folder
26
-     * @throws EE_Error
27
-     * @return bool
28
-     */
29
-    public static function ensure_folder_exists_and_is_writable(string $folder = ''): bool;
21
+	/**
22
+	 * ensure_folder_exists_and_is_writable
23
+	 * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
24
+	 *
25
+	 * @param string $folder
26
+	 * @throws EE_Error
27
+	 * @return bool
28
+	 */
29
+	public static function ensure_folder_exists_and_is_writable(string $folder = ''): bool;
30 30
 }
31 31
 // End of file EEHI_File.interface.php
32 32
 // Location: core/interfaces/EEHI_File.interface.php
Please login to merge, or discard this patch.
core/EE_Psr4AutoloaderInit.core.php 1 patch
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -17,39 +17,39 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * @type Psr4Autoloader
22
-     */
23
-    protected static $psr4_loader;
24
-
25
-
26
-    /**
27
-     * @return void
28
-     * @throws EE_Error
29
-     */
30
-    public function initializeAutoloader()
31
-    {
32
-        static $initialized = false;
33
-        if (! $initialized) {
34
-            // instantiate PSR4 autoloader
35
-            espresso_load_required('Psr4Autoloader', EE_CORE . 'Psr4Autoloader.php');
36
-            EE_Psr4AutoloaderInit::$psr4_loader = new Psr4Autoloader();
37
-            // register the autoloader
38
-            EE_Psr4AutoloaderInit::$psr4_loader->register();
39
-            // register the base directories for the namespace prefix
40
-            EE_Psr4AutoloaderInit::$psr4_loader->addNamespace('EventEspresso', EE_PLUGIN_DIR_PATH);
41
-            EE_Psr4AutoloaderInit::$psr4_loader->addNamespace('EventEspressoBatchRequest', EE_LIBRARIES . 'batch');
42
-            EE_Psr4AutoloaderInit::$psr4_loader->addNamespace('EventEspressoVendor', EE_THIRD_PARTY);
43
-            $initialized = true;
44
-        }
45
-    }
46
-
47
-
48
-    /**
49
-     * @return Psr4Autoloader
50
-     */
51
-    public static function psr4_loader(): Psr4Autoloader
52
-    {
53
-        return self::$psr4_loader;
54
-    }
20
+	/**
21
+	 * @type Psr4Autoloader
22
+	 */
23
+	protected static $psr4_loader;
24
+
25
+
26
+	/**
27
+	 * @return void
28
+	 * @throws EE_Error
29
+	 */
30
+	public function initializeAutoloader()
31
+	{
32
+		static $initialized = false;
33
+		if (! $initialized) {
34
+			// instantiate PSR4 autoloader
35
+			espresso_load_required('Psr4Autoloader', EE_CORE . 'Psr4Autoloader.php');
36
+			EE_Psr4AutoloaderInit::$psr4_loader = new Psr4Autoloader();
37
+			// register the autoloader
38
+			EE_Psr4AutoloaderInit::$psr4_loader->register();
39
+			// register the base directories for the namespace prefix
40
+			EE_Psr4AutoloaderInit::$psr4_loader->addNamespace('EventEspresso', EE_PLUGIN_DIR_PATH);
41
+			EE_Psr4AutoloaderInit::$psr4_loader->addNamespace('EventEspressoBatchRequest', EE_LIBRARIES . 'batch');
42
+			EE_Psr4AutoloaderInit::$psr4_loader->addNamespace('EventEspressoVendor', EE_THIRD_PARTY);
43
+			$initialized = true;
44
+		}
45
+	}
46
+
47
+
48
+	/**
49
+	 * @return Psr4Autoloader
50
+	 */
51
+	public static function psr4_loader(): Psr4Autoloader
52
+	{
53
+		return self::$psr4_loader;
54
+	}
55 55
 }
Please login to merge, or discard this patch.