@@ -241,7 +241,7 @@ |
||
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 | */ |
@@ -12,278 +12,278 @@ |
||
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 | } |
@@ -27,12 +27,12 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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; |
@@ -31,7 +31,7 @@ |
||
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( |
@@ -13,256 +13,256 @@ |
||
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 | } |
@@ -73,7 +73,7 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 | } |
@@ -152,7 +152,7 @@ |
||
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) |
@@ -47,147 +47,147 @@ |
||
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 | } |
@@ -69,9 +69,9 @@ discard block |
||
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 |
||
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 |
@@ -15,275 +15,275 @@ |
||
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 | } |
@@ -57,7 +57,7 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 | } |
@@ -25,915 +25,915 @@ |
||
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 | } |
@@ -61,13 +61,13 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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'), |
@@ -19,806 +19,806 @@ discard block |
||
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 |
||
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 | - . ' <span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>' |
|
863 | - . '</a> |
|
861 | + . $link_text |
|
862 | + . ' <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 | } |
@@ -298,7 +298,7 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 | . ' <span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>' |
863 | 863 | . '</a> |
@@ -25,1162 +25,1162 @@ |
||
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 | } |
@@ -144,7 +144,7 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
@@ -6,27 +6,27 @@ |
||
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 |
@@ -17,39 +17,39 @@ |
||
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 | } |