@@ -23,1256 +23,1256 @@ |
||
23 | 23 | class EED_Core_Rest_Api extends \EED_Module |
24 | 24 | { |
25 | 25 | |
26 | - const ee_api_namespace = 'ee/v'; |
|
26 | + const ee_api_namespace = 'ee/v'; |
|
27 | 27 | |
28 | - const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
29 | - |
|
30 | - const saved_routes_option_names = 'ee_core_routes'; |
|
31 | - |
|
32 | - /** |
|
33 | - * string used in _links response bodies to make them globally unique. |
|
34 | - * |
|
35 | - * @see http://v2.wp-api.org/extending/linking/ |
|
36 | - */ |
|
37 | - const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
38 | - |
|
39 | - /** |
|
40 | - * @var CalculatedModelFields |
|
41 | - */ |
|
42 | - protected static $_field_calculator; |
|
43 | - |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * @return EED_Core_Rest_Api|EED_Module |
|
48 | - */ |
|
49 | - public static function instance() |
|
50 | - { |
|
51 | - self::$_field_calculator = new CalculatedModelFields(); |
|
52 | - return parent::get_instance(__CLASS__); |
|
53 | - } |
|
54 | - |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
59 | - * |
|
60 | - * @access public |
|
61 | - * @return void |
|
62 | - */ |
|
63 | - public static function set_hooks() |
|
64 | - { |
|
65 | - self::set_hooks_both(); |
|
66 | - } |
|
67 | - |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
72 | - * |
|
73 | - * @access public |
|
74 | - * @return void |
|
75 | - */ |
|
76 | - public static function set_hooks_admin() |
|
77 | - { |
|
78 | - self::set_hooks_both(); |
|
79 | - } |
|
80 | - |
|
81 | - |
|
82 | - |
|
83 | - public static function set_hooks_both() |
|
84 | - { |
|
85 | - add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10); |
|
86 | - add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5); |
|
87 | - add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2); |
|
88 | - add_filter('rest_index', |
|
89 | - array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex')); |
|
90 | - EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
91 | - } |
|
92 | - |
|
93 | - |
|
94 | - |
|
95 | - /** |
|
96 | - * sets up hooks which only need to be included as part of REST API requests; |
|
97 | - * other requests like to the frontend or admin etc don't need them |
|
98 | - * |
|
99 | - * @throws \EE_Error |
|
100 | - */ |
|
101 | - public static function set_hooks_rest_api() |
|
102 | - { |
|
103 | - //set hooks which account for changes made to the API |
|
104 | - EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
105 | - } |
|
106 | - |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * public wrapper of _set_hooks_for_changes. |
|
111 | - * Loads all the hooks which make requests to old versions of the API |
|
112 | - * appear the same as they always did |
|
113 | - * |
|
114 | - * @throws EE_Error |
|
115 | - */ |
|
116 | - public static function set_hooks_for_changes() |
|
117 | - { |
|
118 | - self::_set_hooks_for_changes(); |
|
119 | - } |
|
120 | - |
|
121 | - |
|
122 | - |
|
123 | - /** |
|
124 | - * Loads all the hooks which make requests to old versions of the API |
|
125 | - * appear the same as they always did |
|
126 | - * |
|
127 | - * @throws EE_Error |
|
128 | - */ |
|
129 | - protected static function _set_hooks_for_changes() |
|
130 | - { |
|
131 | - $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false); |
|
132 | - foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
133 | - //ignore the base parent class |
|
134 | - //and legacy named classes |
|
135 | - if ($classname_in_namespace === 'ChangesInBase' |
|
136 | - || strpos($classname_in_namespace, 'Changes_In_') === 0 |
|
137 | - ) { |
|
138 | - continue; |
|
139 | - } |
|
140 | - $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
141 | - if (class_exists($full_classname)) { |
|
142 | - $instance_of_class = new $full_classname; |
|
143 | - if ($instance_of_class instanceof ChangesInBase) { |
|
144 | - $instance_of_class->setHooks(); |
|
145 | - } |
|
146 | - } |
|
147 | - } |
|
148 | - } |
|
149 | - |
|
150 | - |
|
151 | - |
|
152 | - /** |
|
153 | - * Filters the WP routes to add our EE-related ones. This takes a bit of time |
|
154 | - * so we actually prefer to only do it when an EE plugin is activated or upgraded |
|
155 | - * |
|
156 | - * @throws \EE_Error |
|
157 | - */ |
|
158 | - public static function register_routes() |
|
159 | - { |
|
160 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) { |
|
161 | - foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) { |
|
162 | - /** |
|
163 | - * @var array $data_for_multiple_endpoints numerically indexed array |
|
164 | - * but can also contain route options like { |
|
165 | - * @type array $schema { |
|
166 | - * @type callable $schema_callback |
|
167 | - * @type array $callback_args arguments that will be passed to the callback, after the |
|
168 | - * WP_REST_Request of course |
|
169 | - * } |
|
170 | - * } |
|
171 | - */ |
|
172 | - //when registering routes, register all the endpoints' data at the same time |
|
173 | - $multiple_endpoint_args = array(); |
|
174 | - foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) { |
|
175 | - /** |
|
176 | - * @var array $data_for_single_endpoint { |
|
177 | - * @type callable $callback |
|
178 | - * @type string methods |
|
179 | - * @type array args |
|
180 | - * @type array _links |
|
181 | - * @type array $callback_args arguments that will be passed to the callback, after the |
|
182 | - * WP_REST_Request of course |
|
183 | - * } |
|
184 | - */ |
|
185 | - //skip route options |
|
186 | - if (! is_numeric($endpoint_key)) { |
|
187 | - continue; |
|
188 | - } |
|
189 | - if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
190 | - throw new EE_Error( |
|
191 | - esc_html__( |
|
192 | - // @codingStandardsIgnoreStart |
|
193 | - 'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).', |
|
194 | - // @codingStandardsIgnoreEnd |
|
195 | - 'event_espresso') |
|
196 | - ); |
|
197 | - } |
|
198 | - $callback = $data_for_single_endpoint['callback']; |
|
199 | - $single_endpoint_args = array( |
|
200 | - 'methods' => $data_for_single_endpoint['methods'], |
|
201 | - 'args' => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args'] |
|
202 | - : array(), |
|
203 | - ); |
|
204 | - if (isset($data_for_single_endpoint['_links'])) { |
|
205 | - $single_endpoint_args['_links'] = $data_for_single_endpoint['_links']; |
|
206 | - } |
|
207 | - if (isset($data_for_single_endpoint['callback_args'])) { |
|
208 | - $callback_args = $data_for_single_endpoint['callback_args']; |
|
209 | - $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use ( |
|
210 | - $callback, |
|
211 | - $callback_args |
|
212 | - ) { |
|
213 | - array_unshift($callback_args, $request); |
|
214 | - return call_user_func_array( |
|
215 | - $callback, |
|
216 | - $callback_args |
|
217 | - ); |
|
218 | - }; |
|
219 | - } else { |
|
220 | - $single_endpoint_args['callback'] = $data_for_single_endpoint['callback']; |
|
221 | - } |
|
222 | - $multiple_endpoint_args[] = $single_endpoint_args; |
|
223 | - } |
|
224 | - if (isset($data_for_multiple_endpoints['schema'])) { |
|
225 | - $schema_route_data = $data_for_multiple_endpoints['schema']; |
|
226 | - $schema_callback = $schema_route_data['schema_callback']; |
|
227 | - $callback_args = $schema_route_data['callback_args']; |
|
228 | - $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) { |
|
229 | - return call_user_func_array( |
|
230 | - $schema_callback, |
|
231 | - $callback_args |
|
232 | - ); |
|
233 | - }; |
|
234 | - } |
|
235 | - register_rest_route( |
|
236 | - $namespace, |
|
237 | - $relative_route, |
|
238 | - $multiple_endpoint_args |
|
239 | - ); |
|
240 | - } |
|
241 | - } |
|
242 | - } |
|
243 | - |
|
244 | - |
|
245 | - |
|
246 | - /** |
|
247 | - * Checks if there was a version change or something that merits invalidating the cached |
|
248 | - * route data. If so, invalidates the cached route data so that it gets refreshed |
|
249 | - * next time the WP API is used |
|
250 | - */ |
|
251 | - public static function invalidate_cached_route_data_on_version_change() |
|
252 | - { |
|
253 | - if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) { |
|
254 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
255 | - } |
|
256 | - foreach (EE_Registry::instance()->addons as $addon) { |
|
257 | - if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) { |
|
258 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
259 | - } |
|
260 | - } |
|
261 | - } |
|
262 | - |
|
263 | - |
|
264 | - |
|
265 | - /** |
|
266 | - * Removes the cached route data so it will get refreshed next time the WP API is used |
|
267 | - */ |
|
268 | - public static function invalidate_cached_route_data() |
|
269 | - { |
|
270 | - //delete the saved EE REST API routes |
|
271 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
|
272 | - delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
273 | - } |
|
274 | - } |
|
275 | - |
|
276 | - |
|
277 | - |
|
278 | - /** |
|
279 | - * Gets the EE route data |
|
280 | - * |
|
281 | - * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
282 | - * @throws \EE_Error |
|
283 | - * @type string|array $callback |
|
284 | - * @type string $methods |
|
285 | - * @type boolean $hidden_endpoint |
|
286 | - * } |
|
287 | - */ |
|
288 | - public static function get_ee_route_data() |
|
289 | - { |
|
290 | - $ee_routes = array(); |
|
291 | - foreach (self::versions_served() as $version => $hidden_endpoints) { |
|
292 | - $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version( |
|
293 | - $version, |
|
294 | - $hidden_endpoints |
|
295 | - ); |
|
296 | - } |
|
297 | - return $ee_routes; |
|
298 | - } |
|
299 | - |
|
300 | - |
|
301 | - |
|
302 | - /** |
|
303 | - * Gets the EE route data from the wp options if it exists already, |
|
304 | - * otherwise re-generates it and saves it to the option |
|
305 | - * |
|
306 | - * @param string $version |
|
307 | - * @param boolean $hidden_endpoints |
|
308 | - * @return array |
|
309 | - * @throws \EE_Error |
|
310 | - */ |
|
311 | - protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
312 | - { |
|
313 | - $ee_routes = get_option(self::saved_routes_option_names . $version, null); |
|
314 | - if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) { |
|
315 | - $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
316 | - } |
|
317 | - return $ee_routes; |
|
318 | - } |
|
319 | - |
|
320 | - |
|
321 | - |
|
322 | - /** |
|
323 | - * Saves the EE REST API route data to a wp option and returns it |
|
324 | - * |
|
325 | - * @param string $version |
|
326 | - * @param boolean $hidden_endpoints |
|
327 | - * @return mixed|null |
|
328 | - * @throws \EE_Error |
|
329 | - */ |
|
330 | - protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
331 | - { |
|
332 | - $instance = self::instance(); |
|
333 | - $routes = apply_filters( |
|
334 | - 'EED_Core_Rest_Api__save_ee_route_data_for_version__routes', |
|
335 | - array_replace_recursive( |
|
336 | - $instance->_get_config_route_data_for_version($version, $hidden_endpoints), |
|
337 | - $instance->_get_meta_route_data_for_version($version, $hidden_endpoints), |
|
338 | - $instance->_get_model_route_data_for_version($version, $hidden_endpoints), |
|
339 | - $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
|
340 | - ) |
|
341 | - ); |
|
342 | - $option_name = self::saved_routes_option_names . $version; |
|
343 | - if (get_option($option_name)) { |
|
344 | - update_option($option_name, $routes, true); |
|
345 | - } else { |
|
346 | - add_option($option_name, $routes, null, 'no'); |
|
347 | - } |
|
348 | - return $routes; |
|
349 | - } |
|
350 | - |
|
351 | - |
|
352 | - |
|
353 | - /** |
|
354 | - * Calculates all the EE routes and saves it to a WordPress option so we don't |
|
355 | - * need to calculate it on every request |
|
356 | - * |
|
357 | - * @deprecated since version 4.9.1 |
|
358 | - * @return void |
|
359 | - */ |
|
360 | - public static function save_ee_routes() |
|
361 | - { |
|
362 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
363 | - $instance = self::instance(); |
|
364 | - $routes = apply_filters( |
|
365 | - 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
366 | - array_replace_recursive( |
|
367 | - $instance->_register_config_routes(), |
|
368 | - $instance->_register_meta_routes(), |
|
369 | - $instance->_register_model_routes(), |
|
370 | - $instance->_register_rpc_routes() |
|
371 | - ) |
|
372 | - ); |
|
373 | - update_option(self::saved_routes_option_names, $routes, true); |
|
374 | - } |
|
375 | - } |
|
376 | - |
|
377 | - |
|
378 | - |
|
379 | - /** |
|
380 | - * Gets all the route information relating to EE models |
|
381 | - * |
|
382 | - * @return array @see get_ee_route_data |
|
383 | - * @deprecated since version 4.9.1 |
|
384 | - */ |
|
385 | - protected function _register_model_routes() |
|
386 | - { |
|
387 | - $model_routes = array(); |
|
388 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
389 | - $model_routes[EED_Core_Rest_Api::ee_api_namespace |
|
390 | - . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
391 | - } |
|
392 | - return $model_routes; |
|
393 | - } |
|
394 | - |
|
395 | - |
|
396 | - |
|
397 | - /** |
|
398 | - * Decides whether or not to add write endpoints for this model. |
|
399 | - * |
|
400 | - * Currently, this defaults to exclude all global tables and models |
|
401 | - * which would allow inserting WP core data (we don't want to duplicate |
|
402 | - * what WP API does, as it's unnecessary, extra work, and potentially extra bugs) |
|
403 | - * @param EEM_Base $model |
|
404 | - * @return bool |
|
405 | - */ |
|
406 | - public static function should_have_write_endpoints(EEM_Base $model) |
|
407 | - { |
|
408 | - if ($model->is_wp_core_model()){ |
|
409 | - return false; |
|
410 | - } |
|
411 | - foreach($model->get_tables() as $table){ |
|
412 | - if( $table->is_global()){ |
|
413 | - return false; |
|
414 | - } |
|
415 | - } |
|
416 | - return true; |
|
417 | - } |
|
418 | - |
|
419 | - |
|
420 | - |
|
421 | - /** |
|
422 | - * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`) |
|
423 | - * in this versioned namespace of EE4 |
|
424 | - * @param $version |
|
425 | - * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event') |
|
426 | - */ |
|
427 | - public static function model_names_with_plural_routes($version){ |
|
428 | - $model_version_info = new ModelVersionInfo($version); |
|
429 | - $models_to_register = $model_version_info->modelsForRequestedVersion(); |
|
430 | - //let's not bother having endpoints for extra metas |
|
431 | - unset( |
|
432 | - $models_to_register['Extra_Meta'], |
|
433 | - $models_to_register['Extra_Join'], |
|
434 | - $models_to_register['Post_Meta'] |
|
435 | - ); |
|
436 | - return apply_filters( |
|
437 | - 'FHEE__EED_Core_REST_API___register_model_routes', |
|
438 | - $models_to_register |
|
439 | - ); |
|
440 | - } |
|
441 | - |
|
442 | - |
|
443 | - |
|
444 | - /** |
|
445 | - * Gets the route data for EE models in the specified version |
|
446 | - * |
|
447 | - * @param string $version |
|
448 | - * @param boolean $hidden_endpoint |
|
449 | - * @return array |
|
450 | - * @throws EE_Error |
|
451 | - */ |
|
452 | - protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
453 | - { |
|
454 | - $model_routes = array(); |
|
455 | - $model_version_info = new ModelVersionInfo($version); |
|
456 | - foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
|
457 | - $model = \EE_Registry::instance()->load_model($model_name); |
|
458 | - //if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
459 | - if (! $model instanceof EEM_Base) { |
|
460 | - continue; |
|
461 | - } |
|
462 | - //yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
463 | - $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
|
464 | - $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
|
465 | - $model_routes[$plural_model_route] = array( |
|
466 | - array( |
|
467 | - 'callback' => array( |
|
468 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
469 | - 'handleRequestGetAll', |
|
470 | - ), |
|
471 | - 'callback_args' => array($version, $model_name), |
|
472 | - 'methods' => WP_REST_Server::READABLE, |
|
473 | - 'hidden_endpoint' => $hidden_endpoint, |
|
474 | - 'args' => $this->_get_read_query_params($model, $version), |
|
475 | - '_links' => array( |
|
476 | - 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
477 | - ), |
|
478 | - ), |
|
479 | - 'schema' => array( |
|
480 | - 'schema_callback' => array( |
|
481 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
482 | - 'handleSchemaRequest', |
|
483 | - ), |
|
484 | - 'callback_args' => array($version, $model_name), |
|
485 | - ), |
|
486 | - ); |
|
487 | - $model_routes[$singular_model_route] = array( |
|
488 | - array( |
|
489 | - 'callback' => array( |
|
490 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
491 | - 'handleRequestGetOne', |
|
492 | - ), |
|
493 | - 'callback_args' => array($version, $model_name), |
|
494 | - 'methods' => WP_REST_Server::READABLE, |
|
495 | - 'hidden_endpoint' => $hidden_endpoint, |
|
496 | - 'args' => $this->_get_response_selection_query_params($model, $version), |
|
497 | - ), |
|
498 | - ); |
|
499 | - if( apply_filters( |
|
500 | - 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints', |
|
501 | - EED_Core_Rest_Api::should_have_write_endpoints($model), |
|
502 | - $model |
|
503 | - )){ |
|
504 | - $model_routes[$plural_model_route][] = array( |
|
505 | - 'callback' => array( |
|
506 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
507 | - 'handleRequestInsert', |
|
508 | - ), |
|
509 | - 'callback_args' => array($version, $model_name), |
|
510 | - 'methods' => WP_REST_Server::CREATABLE, |
|
511 | - 'hidden_endpoint' => $hidden_endpoint, |
|
512 | - 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
|
513 | - ); |
|
514 | - $model_routes[$singular_model_route] = array_merge( |
|
515 | - $model_routes[$singular_model_route], |
|
516 | - array( |
|
517 | - array( |
|
518 | - 'callback' => array( |
|
519 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
520 | - 'handleRequestUpdate', |
|
521 | - ), |
|
522 | - 'callback_args' => array($version, $model_name), |
|
523 | - 'methods' => WP_REST_Server::EDITABLE, |
|
524 | - 'hidden_endpoint' => $hidden_endpoint, |
|
525 | - 'args' => $this->_get_write_params($model_name, $model_version_info), |
|
526 | - ), |
|
527 | - array( |
|
528 | - 'callback' => array( |
|
529 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
530 | - 'handleRequestDelete', |
|
531 | - ), |
|
532 | - 'callback_args' => array($version, $model_name), |
|
533 | - 'methods' => WP_REST_Server::DELETABLE, |
|
534 | - 'hidden_endpoint' => $hidden_endpoint, |
|
535 | - 'args' => $this->_get_delete_query_params($model, $version), |
|
536 | - ) |
|
537 | - ) |
|
538 | - ); |
|
539 | - } |
|
540 | - foreach ($model->relation_settings() as $relation_name => $relation_obj) { |
|
541 | - |
|
542 | - $related_route = EED_Core_Rest_Api::get_relation_route_via( |
|
543 | - $model, |
|
544 | - '(?P<id>[^\/]+)', |
|
545 | - $relation_obj |
|
546 | - ); |
|
547 | - $endpoints = array( |
|
548 | - array( |
|
549 | - 'callback' => array( |
|
550 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
551 | - 'handleRequestGetRelated', |
|
552 | - ), |
|
553 | - 'callback_args' => array($version, $model_name, $relation_name), |
|
554 | - 'methods' => WP_REST_Server::READABLE, |
|
555 | - 'hidden_endpoint' => $hidden_endpoint, |
|
556 | - 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
557 | - ), |
|
558 | - ); |
|
559 | - $model_routes[$related_route] = $endpoints; |
|
560 | - } |
|
561 | - } |
|
562 | - return $model_routes; |
|
563 | - } |
|
564 | - |
|
565 | - |
|
566 | - |
|
567 | - /** |
|
568 | - * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace, |
|
569 | - * excluding the preceding slash. |
|
570 | - * Eg you pass get_plural_route_to('Event') = 'events' |
|
571 | - * |
|
572 | - * @param EEM_Base $model |
|
573 | - * @return string |
|
574 | - */ |
|
575 | - public static function get_collection_route(EEM_Base $model) |
|
576 | - { |
|
577 | - return EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
578 | - } |
|
579 | - |
|
580 | - |
|
581 | - |
|
582 | - /** |
|
583 | - * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
584 | - * excluding the preceding slash. |
|
585 | - * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
586 | - * |
|
587 | - * @param EEM_Base $model eg Event or Venue |
|
588 | - * @param string $id |
|
589 | - * @return string |
|
590 | - */ |
|
591 | - public static function get_entity_route($model, $id) |
|
592 | - { |
|
593 | - return EED_Core_Rest_Api::get_collection_route($model). '/' . $id; |
|
594 | - } |
|
595 | - |
|
596 | - |
|
597 | - /** |
|
598 | - * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
599 | - * excluding the preceding slash. |
|
600 | - * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
601 | - * |
|
602 | - * @param EEM_Base $model eg Event or Venue |
|
603 | - * @param string $id |
|
604 | - * @param EE_Model_Relation_Base $relation_obj |
|
605 | - * @return string |
|
606 | - */ |
|
607 | - public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj) |
|
608 | - { |
|
609 | - $related_model_name_endpoint_part = ModelRead::getRelatedEntityName( |
|
610 | - $relation_obj->get_other_model()->get_this_model_name(), |
|
611 | - $relation_obj |
|
612 | - ); |
|
613 | - return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
614 | - } |
|
615 | - |
|
616 | - |
|
617 | - |
|
618 | - /** |
|
619 | - * Adds onto the $relative_route the EE4 REST API versioned namespace. |
|
620 | - * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events' |
|
621 | - * @param string $relative_route |
|
622 | - * @param string $version |
|
623 | - * @return string |
|
624 | - */ |
|
625 | - public static function get_versioned_route_to($relative_route, $version = '4.8.36'){ |
|
626 | - return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
627 | - } |
|
628 | - |
|
629 | - |
|
630 | - |
|
631 | - /** |
|
632 | - * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
633 | - * routes that don't conform to the traditional REST CRUD-style). |
|
634 | - * |
|
635 | - * @deprecated since 4.9.1 |
|
636 | - */ |
|
637 | - protected function _register_rpc_routes() |
|
638 | - { |
|
639 | - $routes = array(); |
|
640 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
641 | - $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version( |
|
642 | - $version, |
|
643 | - $hidden_endpoint |
|
644 | - ); |
|
645 | - } |
|
646 | - return $routes; |
|
647 | - } |
|
648 | - |
|
649 | - |
|
650 | - |
|
651 | - /** |
|
652 | - * @param string $version |
|
653 | - * @param boolean $hidden_endpoint |
|
654 | - * @return array |
|
655 | - */ |
|
656 | - protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
657 | - { |
|
658 | - $this_versions_routes = array(); |
|
659 | - //checkin endpoint |
|
660 | - $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array( |
|
661 | - array( |
|
662 | - 'callback' => array( |
|
663 | - 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
664 | - 'handleRequestToggleCheckin', |
|
665 | - ), |
|
666 | - 'methods' => WP_REST_Server::CREATABLE, |
|
667 | - 'hidden_endpoint' => $hidden_endpoint, |
|
668 | - 'args' => array( |
|
669 | - 'force' => array( |
|
670 | - 'required' => false, |
|
671 | - 'default' => false, |
|
672 | - 'description' => __( |
|
673 | - // @codingStandardsIgnoreStart |
|
674 | - 'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
675 | - // @codingStandardsIgnoreEnd |
|
676 | - 'event_espresso' |
|
677 | - ), |
|
678 | - ), |
|
679 | - ), |
|
680 | - 'callback_args' => array($version), |
|
681 | - ), |
|
682 | - ); |
|
683 | - return apply_filters( |
|
684 | - 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
685 | - $this_versions_routes, |
|
686 | - $version, |
|
687 | - $hidden_endpoint |
|
688 | - ); |
|
689 | - } |
|
690 | - |
|
691 | - |
|
692 | - |
|
693 | - /** |
|
694 | - * Gets the query params that can be used when request one or many |
|
695 | - * |
|
696 | - * @param EEM_Base $model |
|
697 | - * @param string $version |
|
698 | - * @return array |
|
699 | - */ |
|
700 | - protected function _get_response_selection_query_params(\EEM_Base $model, $version) |
|
701 | - { |
|
702 | - return apply_filters( |
|
703 | - 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
704 | - array( |
|
705 | - 'include' => array( |
|
706 | - 'required' => false, |
|
707 | - 'default' => '*', |
|
708 | - 'type' => 'string', |
|
709 | - ), |
|
710 | - 'calculate' => array( |
|
711 | - 'required' => false, |
|
712 | - 'default' => '', |
|
713 | - 'enum' => self::$_field_calculator->retrieveCalculatedFieldsForModel($model), |
|
714 | - 'type' => 'string', |
|
715 | - //because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization |
|
716 | - //freaks out. We'll just validate this argument while handling the request |
|
717 | - 'validate_callback' => null, |
|
718 | - 'sanitize_callback' => null, |
|
719 | - ), |
|
720 | - ), |
|
721 | - $model, |
|
722 | - $version |
|
723 | - ); |
|
724 | - } |
|
725 | - |
|
726 | - |
|
727 | - |
|
728 | - /** |
|
729 | - * Gets the parameters acceptable for delete requests |
|
730 | - * |
|
731 | - * @param \EEM_Base $model |
|
732 | - * @param string $version |
|
733 | - * @return array |
|
734 | - */ |
|
735 | - protected function _get_delete_query_params(\EEM_Base $model, $version) |
|
736 | - { |
|
737 | - $params_for_delete = array( |
|
738 | - 'allow_blocking' => array( |
|
739 | - 'required' => false, |
|
740 | - 'default' => true, |
|
741 | - 'type' => 'boolean', |
|
742 | - ), |
|
743 | - ); |
|
744 | - $params_for_delete['force'] = array( |
|
745 | - 'required' => false, |
|
746 | - 'default' => false, |
|
747 | - 'type' => 'boolean', |
|
748 | - ); |
|
749 | - return apply_filters( |
|
750 | - 'FHEE__EED_Core_Rest_Api___get_delete_query_params', |
|
751 | - $params_for_delete, |
|
752 | - $model, |
|
753 | - $version |
|
754 | - ); |
|
755 | - } |
|
756 | - |
|
757 | - |
|
758 | - |
|
759 | - /** |
|
760 | - * Gets info about reading query params that are acceptable |
|
761 | - * |
|
762 | - * @param \EEM_Base $model eg 'Event' or 'Venue' |
|
763 | - * @param string $version |
|
764 | - * @return array describing the args acceptable when querying this model |
|
765 | - * @throws EE_Error |
|
766 | - */ |
|
767 | - protected function _get_read_query_params(\EEM_Base $model, $version) |
|
768 | - { |
|
769 | - $default_orderby = array(); |
|
770 | - foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
771 | - $default_orderby[$key_field->get_name()] = 'ASC'; |
|
772 | - } |
|
773 | - return array_merge( |
|
774 | - $this->_get_response_selection_query_params($model, $version), |
|
775 | - array( |
|
776 | - 'where' => array( |
|
777 | - 'required' => false, |
|
778 | - 'default' => array(), |
|
779 | - 'type' => 'object', |
|
780 | - //because we accept an almost infinite list of possible where conditions, WP |
|
781 | - // core validation and sanitization freaks out. We'll just validate this argument |
|
782 | - // while handling the request |
|
783 | - 'validate_callback' => null, |
|
784 | - 'sanitize_callback' => null, |
|
785 | - ), |
|
786 | - 'limit' => array( |
|
787 | - 'required' => false, |
|
788 | - 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
789 | - 'type' => array( |
|
790 | - 'array', |
|
791 | - 'string', |
|
792 | - 'integer', |
|
793 | - ), |
|
794 | - //because we accept a variety of types, WP core validation and sanitization |
|
795 | - //freaks out. We'll just validate this argument while handling the request |
|
796 | - 'validate_callback' => null, |
|
797 | - 'sanitize_callback' => null, |
|
798 | - ), |
|
799 | - 'order_by' => array( |
|
800 | - 'required' => false, |
|
801 | - 'default' => $default_orderby, |
|
802 | - 'type' => array( |
|
803 | - 'object', |
|
804 | - 'string', |
|
805 | - ),//because we accept a variety of types, WP core validation and sanitization |
|
806 | - //freaks out. We'll just validate this argument while handling the request |
|
807 | - 'validate_callback' => null, |
|
808 | - 'sanitize_callback' => null, |
|
809 | - ), |
|
810 | - 'group_by' => array( |
|
811 | - 'required' => false, |
|
812 | - 'default' => null, |
|
813 | - 'type' => array( |
|
814 | - 'object', |
|
815 | - 'string', |
|
816 | - ), |
|
817 | - //because we accept an almost infinite list of possible groupings, |
|
818 | - // WP core validation and sanitization |
|
819 | - //freaks out. We'll just validate this argument while handling the request |
|
820 | - 'validate_callback' => null, |
|
821 | - 'sanitize_callback' => null, |
|
822 | - ), |
|
823 | - 'having' => array( |
|
824 | - 'required' => false, |
|
825 | - 'default' => null, |
|
826 | - 'type' => 'object', |
|
827 | - //because we accept an almost infinite list of possible where conditions, WP |
|
828 | - // core validation and sanitization freaks out. We'll just validate this argument |
|
829 | - // while handling the request |
|
830 | - 'validate_callback' => null, |
|
831 | - 'sanitize_callback' => null, |
|
832 | - ), |
|
833 | - 'caps' => array( |
|
834 | - 'required' => false, |
|
835 | - 'default' => EEM_Base::caps_read, |
|
836 | - 'type' => 'string', |
|
837 | - 'enum' => array( |
|
838 | - EEM_Base::caps_read, |
|
839 | - EEM_Base::caps_read_admin, |
|
840 | - EEM_Base::caps_edit, |
|
841 | - EEM_Base::caps_delete |
|
842 | - ) |
|
843 | - ), |
|
844 | - ) |
|
845 | - ); |
|
846 | - } |
|
847 | - |
|
848 | - |
|
849 | - |
|
850 | - /** |
|
851 | - * Gets parameter information for a model regarding writing data |
|
852 | - * |
|
853 | - * @param string $model_name |
|
854 | - * @param ModelVersionInfo $model_version_info |
|
855 | - * @param boolean $create whether this is for request to create (in which case we need |
|
856 | - * all required params) or just to update (in which case we don't need those on every request) |
|
857 | - * @return array |
|
858 | - */ |
|
859 | - protected function _get_write_params( |
|
860 | - $model_name, |
|
861 | - ModelVersionInfo $model_version_info, |
|
862 | - $create = false |
|
863 | - ) { |
|
864 | - $model = EE_Registry::instance()->load_model($model_name); |
|
865 | - $fields = $model_version_info->fieldsOnModelInThisVersion($model); |
|
866 | - $args_info = array(); |
|
867 | - foreach ($fields as $field_name => $field_obj) { |
|
868 | - if ($field_obj->is_auto_increment()) { |
|
869 | - //totally ignore auto increment IDs |
|
870 | - continue; |
|
871 | - } |
|
872 | - $arg_info = $field_obj->getSchema(); |
|
873 | - $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null; |
|
874 | - $arg_info['required'] = $required; |
|
875 | - //remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right? |
|
876 | - unset($arg_info['readonly']); |
|
877 | - $schema_properties = $field_obj->getSchemaProperties(); |
|
878 | - if ( |
|
879 | - isset($schema_properties['raw']) |
|
880 | - && $field_obj->getSchemaType() === 'object' |
|
881 | - ) { |
|
882 | - //if there's a "raw" form of this argument, use those properties instead |
|
883 | - $arg_info = array_replace( |
|
884 | - $arg_info, |
|
885 | - $schema_properties['raw'] |
|
886 | - ); |
|
887 | - } |
|
888 | - $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson( |
|
889 | - $field_obj, |
|
890 | - $field_obj->get_default_value(), |
|
891 | - $model_version_info->requestedVersion() |
|
892 | - ); |
|
893 | - //we do our own validation and sanitization within the controller |
|
894 | - $arg_info['sanitize_callback'] = |
|
895 | - array( |
|
896 | - 'EED_Core_Rest_Api', |
|
897 | - 'default_sanitize_callback', |
|
898 | - ); |
|
899 | - $args_info[$field_name] = $arg_info; |
|
900 | - if ($field_obj instanceof EE_Datetime_Field) { |
|
901 | - $gmt_arg_info = $arg_info; |
|
902 | - $gmt_arg_info['description'] = sprintf( |
|
903 | - esc_html__( |
|
904 | - '%1$s - the value for this field in UTC. Ignored if %2$s is provided.', |
|
905 | - 'event_espresso' |
|
906 | - ), |
|
907 | - $field_obj->get_nicename(), |
|
908 | - $field_name |
|
909 | - ); |
|
910 | - $args_info[$field_name . '_gmt'] = $gmt_arg_info; |
|
911 | - } |
|
912 | - } |
|
913 | - return $args_info; |
|
914 | - } |
|
915 | - |
|
916 | - |
|
917 | - |
|
918 | - /** |
|
919 | - * Replacement for WP API's 'rest_parse_request_arg'. |
|
920 | - * If the value is blank but not required, don't bother validating it. |
|
921 | - * Also, it uses our email validation instead of WP API's default. |
|
922 | - * |
|
923 | - * @param $value |
|
924 | - * @param WP_REST_Request $request |
|
925 | - * @param $param |
|
926 | - * @return bool|true|WP_Error |
|
927 | - * @throws InvalidArgumentException |
|
928 | - * @throws InvalidInterfaceException |
|
929 | - * @throws InvalidDataTypeException |
|
930 | - */ |
|
931 | - public static function default_sanitize_callback( $value, WP_REST_Request $request, $param) |
|
932 | - { |
|
933 | - $attributes = $request->get_attributes(); |
|
934 | - if (! isset($attributes['args'][$param]) |
|
935 | - || ! is_array($attributes['args'][$param])) { |
|
936 | - $validation_result = true; |
|
937 | - } else { |
|
938 | - $args = $attributes['args'][$param]; |
|
939 | - if (( |
|
940 | - $value === '' |
|
941 | - || $value === null |
|
942 | - ) |
|
943 | - && (! isset($args['required']) |
|
944 | - || $args['required'] === false |
|
945 | - ) |
|
946 | - ) { |
|
947 | - //not required and not provided? that's cool |
|
948 | - $validation_result = true; |
|
949 | - } elseif (isset($args['format']) |
|
950 | - && $args['format'] === 'email' |
|
951 | - ) { |
|
952 | - $validation_result = true; |
|
953 | - if (! self::_validate_email($value)) { |
|
954 | - $validation_result = new WP_Error( |
|
955 | - 'rest_invalid_param', |
|
956 | - esc_html__( |
|
957 | - 'The email address is not valid or does not exist.', |
|
958 | - 'event_espresso' |
|
959 | - ) |
|
960 | - ); |
|
961 | - } |
|
962 | - } else { |
|
963 | - $validation_result = rest_validate_value_from_schema($value, $args, $param); |
|
964 | - } |
|
965 | - } |
|
966 | - if (is_wp_error($validation_result)) { |
|
967 | - return $validation_result; |
|
968 | - } |
|
969 | - return rest_sanitize_request_arg($value, $request, $param); |
|
970 | - } |
|
971 | - |
|
972 | - |
|
973 | - |
|
974 | - /** |
|
975 | - * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email() |
|
976 | - * |
|
977 | - * @param $email |
|
978 | - * @return bool |
|
979 | - * @throws InvalidArgumentException |
|
980 | - * @throws InvalidInterfaceException |
|
981 | - * @throws InvalidDataTypeException |
|
982 | - */ |
|
983 | - protected static function _validate_email($email){ |
|
984 | - try { |
|
985 | - EmailAddressFactory::create($email); |
|
986 | - return true; |
|
987 | - } catch (EmailValidationException $e) { |
|
988 | - return false; |
|
989 | - } |
|
990 | - } |
|
991 | - |
|
992 | - |
|
993 | - |
|
994 | - /** |
|
995 | - * Gets routes for the config |
|
996 | - * |
|
997 | - * @return array @see _register_model_routes |
|
998 | - * @deprecated since version 4.9.1 |
|
999 | - */ |
|
1000 | - protected function _register_config_routes() |
|
1001 | - { |
|
1002 | - $config_routes = array(); |
|
1003 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
1004 | - $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version( |
|
1005 | - $version, |
|
1006 | - $hidden_endpoint |
|
1007 | - ); |
|
1008 | - } |
|
1009 | - return $config_routes; |
|
1010 | - } |
|
1011 | - |
|
1012 | - |
|
1013 | - |
|
1014 | - /** |
|
1015 | - * Gets routes for the config for the specified version |
|
1016 | - * |
|
1017 | - * @param string $version |
|
1018 | - * @param boolean $hidden_endpoint |
|
1019 | - * @return array |
|
1020 | - */ |
|
1021 | - protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
1022 | - { |
|
1023 | - return array( |
|
1024 | - 'config' => array( |
|
1025 | - array( |
|
1026 | - 'callback' => array( |
|
1027 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1028 | - 'handleRequest', |
|
1029 | - ), |
|
1030 | - 'methods' => WP_REST_Server::READABLE, |
|
1031 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1032 | - 'callback_args' => array($version), |
|
1033 | - ), |
|
1034 | - ), |
|
1035 | - 'site_info' => array( |
|
1036 | - array( |
|
1037 | - 'callback' => array( |
|
1038 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1039 | - 'handleRequestSiteInfo', |
|
1040 | - ), |
|
1041 | - 'methods' => WP_REST_Server::READABLE, |
|
1042 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1043 | - 'callback_args' => array($version), |
|
1044 | - ), |
|
1045 | - ), |
|
1046 | - ); |
|
1047 | - } |
|
1048 | - |
|
1049 | - |
|
1050 | - |
|
1051 | - /** |
|
1052 | - * Gets the meta info routes |
|
1053 | - * |
|
1054 | - * @return array @see _register_model_routes |
|
1055 | - * @deprecated since version 4.9.1 |
|
1056 | - */ |
|
1057 | - protected function _register_meta_routes() |
|
1058 | - { |
|
1059 | - $meta_routes = array(); |
|
1060 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
1061 | - $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version( |
|
1062 | - $version, |
|
1063 | - $hidden_endpoint |
|
1064 | - ); |
|
1065 | - } |
|
1066 | - return $meta_routes; |
|
1067 | - } |
|
1068 | - |
|
1069 | - |
|
1070 | - |
|
1071 | - /** |
|
1072 | - * @param string $version |
|
1073 | - * @param boolean $hidden_endpoint |
|
1074 | - * @return array |
|
1075 | - */ |
|
1076 | - protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
1077 | - { |
|
1078 | - return array( |
|
1079 | - 'resources' => array( |
|
1080 | - array( |
|
1081 | - 'callback' => array( |
|
1082 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
1083 | - 'handleRequestModelsMeta', |
|
1084 | - ), |
|
1085 | - 'methods' => WP_REST_Server::READABLE, |
|
1086 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1087 | - 'callback_args' => array($version), |
|
1088 | - ), |
|
1089 | - ), |
|
1090 | - ); |
|
1091 | - } |
|
1092 | - |
|
1093 | - |
|
1094 | - |
|
1095 | - /** |
|
1096 | - * Tries to hide old 4.6 endpoints from the |
|
1097 | - * |
|
1098 | - * @param array $route_data |
|
1099 | - * @return array |
|
1100 | - * @throws \EE_Error |
|
1101 | - */ |
|
1102 | - public static function hide_old_endpoints($route_data) |
|
1103 | - { |
|
1104 | - //allow API clients to override which endpoints get hidden, in case |
|
1105 | - //they want to discover particular endpoints |
|
1106 | - //also, we don't have access to the request so we have to just grab it from the superglobal |
|
1107 | - $force_show_ee_namespace = ltrim( |
|
1108 | - EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''), |
|
1109 | - '/' |
|
1110 | - ); |
|
1111 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
1112 | - foreach ($relative_urls as $resource_name => $endpoints) { |
|
1113 | - foreach ($endpoints as $key => $endpoint) { |
|
1114 | - //skip schema and other route options |
|
1115 | - if (! is_numeric($key)) { |
|
1116 | - continue; |
|
1117 | - } |
|
1118 | - //by default, hide "hidden_endpoint"s, unless the request indicates |
|
1119 | - //to $force_show_ee_namespace, in which case only show that one |
|
1120 | - //namespace's endpoints (and hide all others) |
|
1121 | - if ( |
|
1122 | - ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
1123 | - || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
1124 | - ) { |
|
1125 | - $full_route = '/' . ltrim($namespace, '/'); |
|
1126 | - $full_route .= '/' . ltrim($resource_name, '/'); |
|
1127 | - unset($route_data[$full_route]); |
|
1128 | - } |
|
1129 | - } |
|
1130 | - } |
|
1131 | - } |
|
1132 | - return $route_data; |
|
1133 | - } |
|
1134 | - |
|
1135 | - |
|
1136 | - |
|
1137 | - /** |
|
1138 | - * Returns an array describing which versions of core support serving requests for. |
|
1139 | - * Keys are core versions' major and minor version, and values are the |
|
1140 | - * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
1141 | - * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
1142 | - * the answers table entirely, in which case it would be very difficult for |
|
1143 | - * it to serve 4.6-style responses. |
|
1144 | - * Versions of core that are missing from this array are unknowns. |
|
1145 | - * previous ver |
|
1146 | - * |
|
1147 | - * @return array |
|
1148 | - */ |
|
1149 | - public static function version_compatibilities() |
|
1150 | - { |
|
1151 | - return apply_filters( |
|
1152 | - 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
1153 | - array( |
|
1154 | - '4.8.29' => '4.8.29', |
|
1155 | - '4.8.33' => '4.8.29', |
|
1156 | - '4.8.34' => '4.8.29', |
|
1157 | - '4.8.36' => '4.8.29', |
|
1158 | - ) |
|
1159 | - ); |
|
1160 | - } |
|
1161 | - |
|
1162 | - |
|
1163 | - |
|
1164 | - /** |
|
1165 | - * Gets the latest API version served. Eg if there |
|
1166 | - * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
1167 | - * we are on core version 4.8.34, it will return the string "4.8.32" |
|
1168 | - * |
|
1169 | - * @return string |
|
1170 | - */ |
|
1171 | - public static function latest_rest_api_version() |
|
1172 | - { |
|
1173 | - $versions_served = \EED_Core_Rest_Api::versions_served(); |
|
1174 | - $versions_served_keys = array_keys($versions_served); |
|
1175 | - return end($versions_served_keys); |
|
1176 | - } |
|
1177 | - |
|
1178 | - |
|
1179 | - |
|
1180 | - /** |
|
1181 | - * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
1182 | - * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
1183 | - * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
1184 | - * We also indicate whether or not this version should be put in the index or not |
|
1185 | - * |
|
1186 | - * @return array keys are API version numbers (just major and minor numbers), and values |
|
1187 | - * are whether or not they should be hidden |
|
1188 | - */ |
|
1189 | - public static function versions_served() |
|
1190 | - { |
|
1191 | - $versions_served = array(); |
|
1192 | - $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
1193 | - $lowest_compatible_version = end($possibly_served_versions); |
|
1194 | - reset($possibly_served_versions); |
|
1195 | - $versions_served_historically = array_keys($possibly_served_versions); |
|
1196 | - $latest_version = end($versions_served_historically); |
|
1197 | - reset($versions_served_historically); |
|
1198 | - //for each version of core we have ever served: |
|
1199 | - foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
1200 | - //if it's not above the current core version, and it's compatible with the current version of core |
|
1201 | - if ($key_versioned_endpoint === $latest_version) { |
|
1202 | - //don't hide the latest version in the index |
|
1203 | - $versions_served[$key_versioned_endpoint] = false; |
|
1204 | - } elseif ( |
|
1205 | - $key_versioned_endpoint >= $lowest_compatible_version |
|
1206 | - && $key_versioned_endpoint < EED_Core_Rest_Api::core_version() |
|
1207 | - ) { |
|
1208 | - //include, but hide, previous versions which are still supported |
|
1209 | - $versions_served[$key_versioned_endpoint] = true; |
|
1210 | - } elseif (apply_filters( |
|
1211 | - 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
1212 | - false, |
|
1213 | - $possibly_served_versions |
|
1214 | - )) { |
|
1215 | - //if a version is no longer supported, don't include it in index or list of versions served |
|
1216 | - $versions_served[$key_versioned_endpoint] = true; |
|
1217 | - } |
|
1218 | - } |
|
1219 | - return $versions_served; |
|
1220 | - } |
|
1221 | - |
|
1222 | - |
|
1223 | - |
|
1224 | - /** |
|
1225 | - * Gets the major and minor version of EE core's version string |
|
1226 | - * |
|
1227 | - * @return string |
|
1228 | - */ |
|
1229 | - public static function core_version() |
|
1230 | - { |
|
1231 | - return apply_filters( |
|
1232 | - 'FHEE__EED_Core_REST_API__core_version', |
|
1233 | - implode( |
|
1234 | - '.', |
|
1235 | - array_slice( |
|
1236 | - explode( |
|
1237 | - '.', |
|
1238 | - espresso_version() |
|
1239 | - ), |
|
1240 | - 0, |
|
1241 | - 3 |
|
1242 | - ) |
|
1243 | - ) |
|
1244 | - ); |
|
1245 | - } |
|
1246 | - |
|
1247 | - |
|
1248 | - |
|
1249 | - /** |
|
1250 | - * Gets the default limit that should be used when querying for resources |
|
1251 | - * |
|
1252 | - * @return int |
|
1253 | - */ |
|
1254 | - public static function get_default_query_limit() |
|
1255 | - { |
|
1256 | - //we actually don't use a const because we want folks to always use |
|
1257 | - //this method, not the const directly |
|
1258 | - return apply_filters( |
|
1259 | - 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
1260 | - 50 |
|
1261 | - ); |
|
1262 | - } |
|
1263 | - |
|
1264 | - |
|
1265 | - |
|
1266 | - /** |
|
1267 | - * run - initial module setup |
|
1268 | - * |
|
1269 | - * @access public |
|
1270 | - * @param WP $WP |
|
1271 | - * @return void |
|
1272 | - */ |
|
1273 | - public function run($WP) |
|
1274 | - { |
|
1275 | - } |
|
28 | + const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
29 | + |
|
30 | + const saved_routes_option_names = 'ee_core_routes'; |
|
31 | + |
|
32 | + /** |
|
33 | + * string used in _links response bodies to make them globally unique. |
|
34 | + * |
|
35 | + * @see http://v2.wp-api.org/extending/linking/ |
|
36 | + */ |
|
37 | + const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
38 | + |
|
39 | + /** |
|
40 | + * @var CalculatedModelFields |
|
41 | + */ |
|
42 | + protected static $_field_calculator; |
|
43 | + |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * @return EED_Core_Rest_Api|EED_Module |
|
48 | + */ |
|
49 | + public static function instance() |
|
50 | + { |
|
51 | + self::$_field_calculator = new CalculatedModelFields(); |
|
52 | + return parent::get_instance(__CLASS__); |
|
53 | + } |
|
54 | + |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
59 | + * |
|
60 | + * @access public |
|
61 | + * @return void |
|
62 | + */ |
|
63 | + public static function set_hooks() |
|
64 | + { |
|
65 | + self::set_hooks_both(); |
|
66 | + } |
|
67 | + |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
72 | + * |
|
73 | + * @access public |
|
74 | + * @return void |
|
75 | + */ |
|
76 | + public static function set_hooks_admin() |
|
77 | + { |
|
78 | + self::set_hooks_both(); |
|
79 | + } |
|
80 | + |
|
81 | + |
|
82 | + |
|
83 | + public static function set_hooks_both() |
|
84 | + { |
|
85 | + add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10); |
|
86 | + add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5); |
|
87 | + add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2); |
|
88 | + add_filter('rest_index', |
|
89 | + array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex')); |
|
90 | + EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
91 | + } |
|
92 | + |
|
93 | + |
|
94 | + |
|
95 | + /** |
|
96 | + * sets up hooks which only need to be included as part of REST API requests; |
|
97 | + * other requests like to the frontend or admin etc don't need them |
|
98 | + * |
|
99 | + * @throws \EE_Error |
|
100 | + */ |
|
101 | + public static function set_hooks_rest_api() |
|
102 | + { |
|
103 | + //set hooks which account for changes made to the API |
|
104 | + EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
105 | + } |
|
106 | + |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * public wrapper of _set_hooks_for_changes. |
|
111 | + * Loads all the hooks which make requests to old versions of the API |
|
112 | + * appear the same as they always did |
|
113 | + * |
|
114 | + * @throws EE_Error |
|
115 | + */ |
|
116 | + public static function set_hooks_for_changes() |
|
117 | + { |
|
118 | + self::_set_hooks_for_changes(); |
|
119 | + } |
|
120 | + |
|
121 | + |
|
122 | + |
|
123 | + /** |
|
124 | + * Loads all the hooks which make requests to old versions of the API |
|
125 | + * appear the same as they always did |
|
126 | + * |
|
127 | + * @throws EE_Error |
|
128 | + */ |
|
129 | + protected static function _set_hooks_for_changes() |
|
130 | + { |
|
131 | + $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false); |
|
132 | + foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
133 | + //ignore the base parent class |
|
134 | + //and legacy named classes |
|
135 | + if ($classname_in_namespace === 'ChangesInBase' |
|
136 | + || strpos($classname_in_namespace, 'Changes_In_') === 0 |
|
137 | + ) { |
|
138 | + continue; |
|
139 | + } |
|
140 | + $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
141 | + if (class_exists($full_classname)) { |
|
142 | + $instance_of_class = new $full_classname; |
|
143 | + if ($instance_of_class instanceof ChangesInBase) { |
|
144 | + $instance_of_class->setHooks(); |
|
145 | + } |
|
146 | + } |
|
147 | + } |
|
148 | + } |
|
149 | + |
|
150 | + |
|
151 | + |
|
152 | + /** |
|
153 | + * Filters the WP routes to add our EE-related ones. This takes a bit of time |
|
154 | + * so we actually prefer to only do it when an EE plugin is activated or upgraded |
|
155 | + * |
|
156 | + * @throws \EE_Error |
|
157 | + */ |
|
158 | + public static function register_routes() |
|
159 | + { |
|
160 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) { |
|
161 | + foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) { |
|
162 | + /** |
|
163 | + * @var array $data_for_multiple_endpoints numerically indexed array |
|
164 | + * but can also contain route options like { |
|
165 | + * @type array $schema { |
|
166 | + * @type callable $schema_callback |
|
167 | + * @type array $callback_args arguments that will be passed to the callback, after the |
|
168 | + * WP_REST_Request of course |
|
169 | + * } |
|
170 | + * } |
|
171 | + */ |
|
172 | + //when registering routes, register all the endpoints' data at the same time |
|
173 | + $multiple_endpoint_args = array(); |
|
174 | + foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) { |
|
175 | + /** |
|
176 | + * @var array $data_for_single_endpoint { |
|
177 | + * @type callable $callback |
|
178 | + * @type string methods |
|
179 | + * @type array args |
|
180 | + * @type array _links |
|
181 | + * @type array $callback_args arguments that will be passed to the callback, after the |
|
182 | + * WP_REST_Request of course |
|
183 | + * } |
|
184 | + */ |
|
185 | + //skip route options |
|
186 | + if (! is_numeric($endpoint_key)) { |
|
187 | + continue; |
|
188 | + } |
|
189 | + if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
190 | + throw new EE_Error( |
|
191 | + esc_html__( |
|
192 | + // @codingStandardsIgnoreStart |
|
193 | + 'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).', |
|
194 | + // @codingStandardsIgnoreEnd |
|
195 | + 'event_espresso') |
|
196 | + ); |
|
197 | + } |
|
198 | + $callback = $data_for_single_endpoint['callback']; |
|
199 | + $single_endpoint_args = array( |
|
200 | + 'methods' => $data_for_single_endpoint['methods'], |
|
201 | + 'args' => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args'] |
|
202 | + : array(), |
|
203 | + ); |
|
204 | + if (isset($data_for_single_endpoint['_links'])) { |
|
205 | + $single_endpoint_args['_links'] = $data_for_single_endpoint['_links']; |
|
206 | + } |
|
207 | + if (isset($data_for_single_endpoint['callback_args'])) { |
|
208 | + $callback_args = $data_for_single_endpoint['callback_args']; |
|
209 | + $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use ( |
|
210 | + $callback, |
|
211 | + $callback_args |
|
212 | + ) { |
|
213 | + array_unshift($callback_args, $request); |
|
214 | + return call_user_func_array( |
|
215 | + $callback, |
|
216 | + $callback_args |
|
217 | + ); |
|
218 | + }; |
|
219 | + } else { |
|
220 | + $single_endpoint_args['callback'] = $data_for_single_endpoint['callback']; |
|
221 | + } |
|
222 | + $multiple_endpoint_args[] = $single_endpoint_args; |
|
223 | + } |
|
224 | + if (isset($data_for_multiple_endpoints['schema'])) { |
|
225 | + $schema_route_data = $data_for_multiple_endpoints['schema']; |
|
226 | + $schema_callback = $schema_route_data['schema_callback']; |
|
227 | + $callback_args = $schema_route_data['callback_args']; |
|
228 | + $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) { |
|
229 | + return call_user_func_array( |
|
230 | + $schema_callback, |
|
231 | + $callback_args |
|
232 | + ); |
|
233 | + }; |
|
234 | + } |
|
235 | + register_rest_route( |
|
236 | + $namespace, |
|
237 | + $relative_route, |
|
238 | + $multiple_endpoint_args |
|
239 | + ); |
|
240 | + } |
|
241 | + } |
|
242 | + } |
|
243 | + |
|
244 | + |
|
245 | + |
|
246 | + /** |
|
247 | + * Checks if there was a version change or something that merits invalidating the cached |
|
248 | + * route data. If so, invalidates the cached route data so that it gets refreshed |
|
249 | + * next time the WP API is used |
|
250 | + */ |
|
251 | + public static function invalidate_cached_route_data_on_version_change() |
|
252 | + { |
|
253 | + if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) { |
|
254 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
255 | + } |
|
256 | + foreach (EE_Registry::instance()->addons as $addon) { |
|
257 | + if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) { |
|
258 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
259 | + } |
|
260 | + } |
|
261 | + } |
|
262 | + |
|
263 | + |
|
264 | + |
|
265 | + /** |
|
266 | + * Removes the cached route data so it will get refreshed next time the WP API is used |
|
267 | + */ |
|
268 | + public static function invalidate_cached_route_data() |
|
269 | + { |
|
270 | + //delete the saved EE REST API routes |
|
271 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
|
272 | + delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
273 | + } |
|
274 | + } |
|
275 | + |
|
276 | + |
|
277 | + |
|
278 | + /** |
|
279 | + * Gets the EE route data |
|
280 | + * |
|
281 | + * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
282 | + * @throws \EE_Error |
|
283 | + * @type string|array $callback |
|
284 | + * @type string $methods |
|
285 | + * @type boolean $hidden_endpoint |
|
286 | + * } |
|
287 | + */ |
|
288 | + public static function get_ee_route_data() |
|
289 | + { |
|
290 | + $ee_routes = array(); |
|
291 | + foreach (self::versions_served() as $version => $hidden_endpoints) { |
|
292 | + $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version( |
|
293 | + $version, |
|
294 | + $hidden_endpoints |
|
295 | + ); |
|
296 | + } |
|
297 | + return $ee_routes; |
|
298 | + } |
|
299 | + |
|
300 | + |
|
301 | + |
|
302 | + /** |
|
303 | + * Gets the EE route data from the wp options if it exists already, |
|
304 | + * otherwise re-generates it and saves it to the option |
|
305 | + * |
|
306 | + * @param string $version |
|
307 | + * @param boolean $hidden_endpoints |
|
308 | + * @return array |
|
309 | + * @throws \EE_Error |
|
310 | + */ |
|
311 | + protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
312 | + { |
|
313 | + $ee_routes = get_option(self::saved_routes_option_names . $version, null); |
|
314 | + if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) { |
|
315 | + $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
316 | + } |
|
317 | + return $ee_routes; |
|
318 | + } |
|
319 | + |
|
320 | + |
|
321 | + |
|
322 | + /** |
|
323 | + * Saves the EE REST API route data to a wp option and returns it |
|
324 | + * |
|
325 | + * @param string $version |
|
326 | + * @param boolean $hidden_endpoints |
|
327 | + * @return mixed|null |
|
328 | + * @throws \EE_Error |
|
329 | + */ |
|
330 | + protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
331 | + { |
|
332 | + $instance = self::instance(); |
|
333 | + $routes = apply_filters( |
|
334 | + 'EED_Core_Rest_Api__save_ee_route_data_for_version__routes', |
|
335 | + array_replace_recursive( |
|
336 | + $instance->_get_config_route_data_for_version($version, $hidden_endpoints), |
|
337 | + $instance->_get_meta_route_data_for_version($version, $hidden_endpoints), |
|
338 | + $instance->_get_model_route_data_for_version($version, $hidden_endpoints), |
|
339 | + $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
|
340 | + ) |
|
341 | + ); |
|
342 | + $option_name = self::saved_routes_option_names . $version; |
|
343 | + if (get_option($option_name)) { |
|
344 | + update_option($option_name, $routes, true); |
|
345 | + } else { |
|
346 | + add_option($option_name, $routes, null, 'no'); |
|
347 | + } |
|
348 | + return $routes; |
|
349 | + } |
|
350 | + |
|
351 | + |
|
352 | + |
|
353 | + /** |
|
354 | + * Calculates all the EE routes and saves it to a WordPress option so we don't |
|
355 | + * need to calculate it on every request |
|
356 | + * |
|
357 | + * @deprecated since version 4.9.1 |
|
358 | + * @return void |
|
359 | + */ |
|
360 | + public static function save_ee_routes() |
|
361 | + { |
|
362 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
363 | + $instance = self::instance(); |
|
364 | + $routes = apply_filters( |
|
365 | + 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
366 | + array_replace_recursive( |
|
367 | + $instance->_register_config_routes(), |
|
368 | + $instance->_register_meta_routes(), |
|
369 | + $instance->_register_model_routes(), |
|
370 | + $instance->_register_rpc_routes() |
|
371 | + ) |
|
372 | + ); |
|
373 | + update_option(self::saved_routes_option_names, $routes, true); |
|
374 | + } |
|
375 | + } |
|
376 | + |
|
377 | + |
|
378 | + |
|
379 | + /** |
|
380 | + * Gets all the route information relating to EE models |
|
381 | + * |
|
382 | + * @return array @see get_ee_route_data |
|
383 | + * @deprecated since version 4.9.1 |
|
384 | + */ |
|
385 | + protected function _register_model_routes() |
|
386 | + { |
|
387 | + $model_routes = array(); |
|
388 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
389 | + $model_routes[EED_Core_Rest_Api::ee_api_namespace |
|
390 | + . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
391 | + } |
|
392 | + return $model_routes; |
|
393 | + } |
|
394 | + |
|
395 | + |
|
396 | + |
|
397 | + /** |
|
398 | + * Decides whether or not to add write endpoints for this model. |
|
399 | + * |
|
400 | + * Currently, this defaults to exclude all global tables and models |
|
401 | + * which would allow inserting WP core data (we don't want to duplicate |
|
402 | + * what WP API does, as it's unnecessary, extra work, and potentially extra bugs) |
|
403 | + * @param EEM_Base $model |
|
404 | + * @return bool |
|
405 | + */ |
|
406 | + public static function should_have_write_endpoints(EEM_Base $model) |
|
407 | + { |
|
408 | + if ($model->is_wp_core_model()){ |
|
409 | + return false; |
|
410 | + } |
|
411 | + foreach($model->get_tables() as $table){ |
|
412 | + if( $table->is_global()){ |
|
413 | + return false; |
|
414 | + } |
|
415 | + } |
|
416 | + return true; |
|
417 | + } |
|
418 | + |
|
419 | + |
|
420 | + |
|
421 | + /** |
|
422 | + * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`) |
|
423 | + * in this versioned namespace of EE4 |
|
424 | + * @param $version |
|
425 | + * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event') |
|
426 | + */ |
|
427 | + public static function model_names_with_plural_routes($version){ |
|
428 | + $model_version_info = new ModelVersionInfo($version); |
|
429 | + $models_to_register = $model_version_info->modelsForRequestedVersion(); |
|
430 | + //let's not bother having endpoints for extra metas |
|
431 | + unset( |
|
432 | + $models_to_register['Extra_Meta'], |
|
433 | + $models_to_register['Extra_Join'], |
|
434 | + $models_to_register['Post_Meta'] |
|
435 | + ); |
|
436 | + return apply_filters( |
|
437 | + 'FHEE__EED_Core_REST_API___register_model_routes', |
|
438 | + $models_to_register |
|
439 | + ); |
|
440 | + } |
|
441 | + |
|
442 | + |
|
443 | + |
|
444 | + /** |
|
445 | + * Gets the route data for EE models in the specified version |
|
446 | + * |
|
447 | + * @param string $version |
|
448 | + * @param boolean $hidden_endpoint |
|
449 | + * @return array |
|
450 | + * @throws EE_Error |
|
451 | + */ |
|
452 | + protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
453 | + { |
|
454 | + $model_routes = array(); |
|
455 | + $model_version_info = new ModelVersionInfo($version); |
|
456 | + foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
|
457 | + $model = \EE_Registry::instance()->load_model($model_name); |
|
458 | + //if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
459 | + if (! $model instanceof EEM_Base) { |
|
460 | + continue; |
|
461 | + } |
|
462 | + //yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
463 | + $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
|
464 | + $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
|
465 | + $model_routes[$plural_model_route] = array( |
|
466 | + array( |
|
467 | + 'callback' => array( |
|
468 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
469 | + 'handleRequestGetAll', |
|
470 | + ), |
|
471 | + 'callback_args' => array($version, $model_name), |
|
472 | + 'methods' => WP_REST_Server::READABLE, |
|
473 | + 'hidden_endpoint' => $hidden_endpoint, |
|
474 | + 'args' => $this->_get_read_query_params($model, $version), |
|
475 | + '_links' => array( |
|
476 | + 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
477 | + ), |
|
478 | + ), |
|
479 | + 'schema' => array( |
|
480 | + 'schema_callback' => array( |
|
481 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
482 | + 'handleSchemaRequest', |
|
483 | + ), |
|
484 | + 'callback_args' => array($version, $model_name), |
|
485 | + ), |
|
486 | + ); |
|
487 | + $model_routes[$singular_model_route] = array( |
|
488 | + array( |
|
489 | + 'callback' => array( |
|
490 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
491 | + 'handleRequestGetOne', |
|
492 | + ), |
|
493 | + 'callback_args' => array($version, $model_name), |
|
494 | + 'methods' => WP_REST_Server::READABLE, |
|
495 | + 'hidden_endpoint' => $hidden_endpoint, |
|
496 | + 'args' => $this->_get_response_selection_query_params($model, $version), |
|
497 | + ), |
|
498 | + ); |
|
499 | + if( apply_filters( |
|
500 | + 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints', |
|
501 | + EED_Core_Rest_Api::should_have_write_endpoints($model), |
|
502 | + $model |
|
503 | + )){ |
|
504 | + $model_routes[$plural_model_route][] = array( |
|
505 | + 'callback' => array( |
|
506 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
507 | + 'handleRequestInsert', |
|
508 | + ), |
|
509 | + 'callback_args' => array($version, $model_name), |
|
510 | + 'methods' => WP_REST_Server::CREATABLE, |
|
511 | + 'hidden_endpoint' => $hidden_endpoint, |
|
512 | + 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
|
513 | + ); |
|
514 | + $model_routes[$singular_model_route] = array_merge( |
|
515 | + $model_routes[$singular_model_route], |
|
516 | + array( |
|
517 | + array( |
|
518 | + 'callback' => array( |
|
519 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
520 | + 'handleRequestUpdate', |
|
521 | + ), |
|
522 | + 'callback_args' => array($version, $model_name), |
|
523 | + 'methods' => WP_REST_Server::EDITABLE, |
|
524 | + 'hidden_endpoint' => $hidden_endpoint, |
|
525 | + 'args' => $this->_get_write_params($model_name, $model_version_info), |
|
526 | + ), |
|
527 | + array( |
|
528 | + 'callback' => array( |
|
529 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
530 | + 'handleRequestDelete', |
|
531 | + ), |
|
532 | + 'callback_args' => array($version, $model_name), |
|
533 | + 'methods' => WP_REST_Server::DELETABLE, |
|
534 | + 'hidden_endpoint' => $hidden_endpoint, |
|
535 | + 'args' => $this->_get_delete_query_params($model, $version), |
|
536 | + ) |
|
537 | + ) |
|
538 | + ); |
|
539 | + } |
|
540 | + foreach ($model->relation_settings() as $relation_name => $relation_obj) { |
|
541 | + |
|
542 | + $related_route = EED_Core_Rest_Api::get_relation_route_via( |
|
543 | + $model, |
|
544 | + '(?P<id>[^\/]+)', |
|
545 | + $relation_obj |
|
546 | + ); |
|
547 | + $endpoints = array( |
|
548 | + array( |
|
549 | + 'callback' => array( |
|
550 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
551 | + 'handleRequestGetRelated', |
|
552 | + ), |
|
553 | + 'callback_args' => array($version, $model_name, $relation_name), |
|
554 | + 'methods' => WP_REST_Server::READABLE, |
|
555 | + 'hidden_endpoint' => $hidden_endpoint, |
|
556 | + 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
557 | + ), |
|
558 | + ); |
|
559 | + $model_routes[$related_route] = $endpoints; |
|
560 | + } |
|
561 | + } |
|
562 | + return $model_routes; |
|
563 | + } |
|
564 | + |
|
565 | + |
|
566 | + |
|
567 | + /** |
|
568 | + * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace, |
|
569 | + * excluding the preceding slash. |
|
570 | + * Eg you pass get_plural_route_to('Event') = 'events' |
|
571 | + * |
|
572 | + * @param EEM_Base $model |
|
573 | + * @return string |
|
574 | + */ |
|
575 | + public static function get_collection_route(EEM_Base $model) |
|
576 | + { |
|
577 | + return EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
578 | + } |
|
579 | + |
|
580 | + |
|
581 | + |
|
582 | + /** |
|
583 | + * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
584 | + * excluding the preceding slash. |
|
585 | + * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
586 | + * |
|
587 | + * @param EEM_Base $model eg Event or Venue |
|
588 | + * @param string $id |
|
589 | + * @return string |
|
590 | + */ |
|
591 | + public static function get_entity_route($model, $id) |
|
592 | + { |
|
593 | + return EED_Core_Rest_Api::get_collection_route($model). '/' . $id; |
|
594 | + } |
|
595 | + |
|
596 | + |
|
597 | + /** |
|
598 | + * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
599 | + * excluding the preceding slash. |
|
600 | + * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
601 | + * |
|
602 | + * @param EEM_Base $model eg Event or Venue |
|
603 | + * @param string $id |
|
604 | + * @param EE_Model_Relation_Base $relation_obj |
|
605 | + * @return string |
|
606 | + */ |
|
607 | + public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj) |
|
608 | + { |
|
609 | + $related_model_name_endpoint_part = ModelRead::getRelatedEntityName( |
|
610 | + $relation_obj->get_other_model()->get_this_model_name(), |
|
611 | + $relation_obj |
|
612 | + ); |
|
613 | + return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
614 | + } |
|
615 | + |
|
616 | + |
|
617 | + |
|
618 | + /** |
|
619 | + * Adds onto the $relative_route the EE4 REST API versioned namespace. |
|
620 | + * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events' |
|
621 | + * @param string $relative_route |
|
622 | + * @param string $version |
|
623 | + * @return string |
|
624 | + */ |
|
625 | + public static function get_versioned_route_to($relative_route, $version = '4.8.36'){ |
|
626 | + return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
627 | + } |
|
628 | + |
|
629 | + |
|
630 | + |
|
631 | + /** |
|
632 | + * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
633 | + * routes that don't conform to the traditional REST CRUD-style). |
|
634 | + * |
|
635 | + * @deprecated since 4.9.1 |
|
636 | + */ |
|
637 | + protected function _register_rpc_routes() |
|
638 | + { |
|
639 | + $routes = array(); |
|
640 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
641 | + $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version( |
|
642 | + $version, |
|
643 | + $hidden_endpoint |
|
644 | + ); |
|
645 | + } |
|
646 | + return $routes; |
|
647 | + } |
|
648 | + |
|
649 | + |
|
650 | + |
|
651 | + /** |
|
652 | + * @param string $version |
|
653 | + * @param boolean $hidden_endpoint |
|
654 | + * @return array |
|
655 | + */ |
|
656 | + protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
657 | + { |
|
658 | + $this_versions_routes = array(); |
|
659 | + //checkin endpoint |
|
660 | + $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array( |
|
661 | + array( |
|
662 | + 'callback' => array( |
|
663 | + 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
664 | + 'handleRequestToggleCheckin', |
|
665 | + ), |
|
666 | + 'methods' => WP_REST_Server::CREATABLE, |
|
667 | + 'hidden_endpoint' => $hidden_endpoint, |
|
668 | + 'args' => array( |
|
669 | + 'force' => array( |
|
670 | + 'required' => false, |
|
671 | + 'default' => false, |
|
672 | + 'description' => __( |
|
673 | + // @codingStandardsIgnoreStart |
|
674 | + 'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
675 | + // @codingStandardsIgnoreEnd |
|
676 | + 'event_espresso' |
|
677 | + ), |
|
678 | + ), |
|
679 | + ), |
|
680 | + 'callback_args' => array($version), |
|
681 | + ), |
|
682 | + ); |
|
683 | + return apply_filters( |
|
684 | + 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
685 | + $this_versions_routes, |
|
686 | + $version, |
|
687 | + $hidden_endpoint |
|
688 | + ); |
|
689 | + } |
|
690 | + |
|
691 | + |
|
692 | + |
|
693 | + /** |
|
694 | + * Gets the query params that can be used when request one or many |
|
695 | + * |
|
696 | + * @param EEM_Base $model |
|
697 | + * @param string $version |
|
698 | + * @return array |
|
699 | + */ |
|
700 | + protected function _get_response_selection_query_params(\EEM_Base $model, $version) |
|
701 | + { |
|
702 | + return apply_filters( |
|
703 | + 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
704 | + array( |
|
705 | + 'include' => array( |
|
706 | + 'required' => false, |
|
707 | + 'default' => '*', |
|
708 | + 'type' => 'string', |
|
709 | + ), |
|
710 | + 'calculate' => array( |
|
711 | + 'required' => false, |
|
712 | + 'default' => '', |
|
713 | + 'enum' => self::$_field_calculator->retrieveCalculatedFieldsForModel($model), |
|
714 | + 'type' => 'string', |
|
715 | + //because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization |
|
716 | + //freaks out. We'll just validate this argument while handling the request |
|
717 | + 'validate_callback' => null, |
|
718 | + 'sanitize_callback' => null, |
|
719 | + ), |
|
720 | + ), |
|
721 | + $model, |
|
722 | + $version |
|
723 | + ); |
|
724 | + } |
|
725 | + |
|
726 | + |
|
727 | + |
|
728 | + /** |
|
729 | + * Gets the parameters acceptable for delete requests |
|
730 | + * |
|
731 | + * @param \EEM_Base $model |
|
732 | + * @param string $version |
|
733 | + * @return array |
|
734 | + */ |
|
735 | + protected function _get_delete_query_params(\EEM_Base $model, $version) |
|
736 | + { |
|
737 | + $params_for_delete = array( |
|
738 | + 'allow_blocking' => array( |
|
739 | + 'required' => false, |
|
740 | + 'default' => true, |
|
741 | + 'type' => 'boolean', |
|
742 | + ), |
|
743 | + ); |
|
744 | + $params_for_delete['force'] = array( |
|
745 | + 'required' => false, |
|
746 | + 'default' => false, |
|
747 | + 'type' => 'boolean', |
|
748 | + ); |
|
749 | + return apply_filters( |
|
750 | + 'FHEE__EED_Core_Rest_Api___get_delete_query_params', |
|
751 | + $params_for_delete, |
|
752 | + $model, |
|
753 | + $version |
|
754 | + ); |
|
755 | + } |
|
756 | + |
|
757 | + |
|
758 | + |
|
759 | + /** |
|
760 | + * Gets info about reading query params that are acceptable |
|
761 | + * |
|
762 | + * @param \EEM_Base $model eg 'Event' or 'Venue' |
|
763 | + * @param string $version |
|
764 | + * @return array describing the args acceptable when querying this model |
|
765 | + * @throws EE_Error |
|
766 | + */ |
|
767 | + protected function _get_read_query_params(\EEM_Base $model, $version) |
|
768 | + { |
|
769 | + $default_orderby = array(); |
|
770 | + foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
771 | + $default_orderby[$key_field->get_name()] = 'ASC'; |
|
772 | + } |
|
773 | + return array_merge( |
|
774 | + $this->_get_response_selection_query_params($model, $version), |
|
775 | + array( |
|
776 | + 'where' => array( |
|
777 | + 'required' => false, |
|
778 | + 'default' => array(), |
|
779 | + 'type' => 'object', |
|
780 | + //because we accept an almost infinite list of possible where conditions, WP |
|
781 | + // core validation and sanitization freaks out. We'll just validate this argument |
|
782 | + // while handling the request |
|
783 | + 'validate_callback' => null, |
|
784 | + 'sanitize_callback' => null, |
|
785 | + ), |
|
786 | + 'limit' => array( |
|
787 | + 'required' => false, |
|
788 | + 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
789 | + 'type' => array( |
|
790 | + 'array', |
|
791 | + 'string', |
|
792 | + 'integer', |
|
793 | + ), |
|
794 | + //because we accept a variety of types, WP core validation and sanitization |
|
795 | + //freaks out. We'll just validate this argument while handling the request |
|
796 | + 'validate_callback' => null, |
|
797 | + 'sanitize_callback' => null, |
|
798 | + ), |
|
799 | + 'order_by' => array( |
|
800 | + 'required' => false, |
|
801 | + 'default' => $default_orderby, |
|
802 | + 'type' => array( |
|
803 | + 'object', |
|
804 | + 'string', |
|
805 | + ),//because we accept a variety of types, WP core validation and sanitization |
|
806 | + //freaks out. We'll just validate this argument while handling the request |
|
807 | + 'validate_callback' => null, |
|
808 | + 'sanitize_callback' => null, |
|
809 | + ), |
|
810 | + 'group_by' => array( |
|
811 | + 'required' => false, |
|
812 | + 'default' => null, |
|
813 | + 'type' => array( |
|
814 | + 'object', |
|
815 | + 'string', |
|
816 | + ), |
|
817 | + //because we accept an almost infinite list of possible groupings, |
|
818 | + // WP core validation and sanitization |
|
819 | + //freaks out. We'll just validate this argument while handling the request |
|
820 | + 'validate_callback' => null, |
|
821 | + 'sanitize_callback' => null, |
|
822 | + ), |
|
823 | + 'having' => array( |
|
824 | + 'required' => false, |
|
825 | + 'default' => null, |
|
826 | + 'type' => 'object', |
|
827 | + //because we accept an almost infinite list of possible where conditions, WP |
|
828 | + // core validation and sanitization freaks out. We'll just validate this argument |
|
829 | + // while handling the request |
|
830 | + 'validate_callback' => null, |
|
831 | + 'sanitize_callback' => null, |
|
832 | + ), |
|
833 | + 'caps' => array( |
|
834 | + 'required' => false, |
|
835 | + 'default' => EEM_Base::caps_read, |
|
836 | + 'type' => 'string', |
|
837 | + 'enum' => array( |
|
838 | + EEM_Base::caps_read, |
|
839 | + EEM_Base::caps_read_admin, |
|
840 | + EEM_Base::caps_edit, |
|
841 | + EEM_Base::caps_delete |
|
842 | + ) |
|
843 | + ), |
|
844 | + ) |
|
845 | + ); |
|
846 | + } |
|
847 | + |
|
848 | + |
|
849 | + |
|
850 | + /** |
|
851 | + * Gets parameter information for a model regarding writing data |
|
852 | + * |
|
853 | + * @param string $model_name |
|
854 | + * @param ModelVersionInfo $model_version_info |
|
855 | + * @param boolean $create whether this is for request to create (in which case we need |
|
856 | + * all required params) or just to update (in which case we don't need those on every request) |
|
857 | + * @return array |
|
858 | + */ |
|
859 | + protected function _get_write_params( |
|
860 | + $model_name, |
|
861 | + ModelVersionInfo $model_version_info, |
|
862 | + $create = false |
|
863 | + ) { |
|
864 | + $model = EE_Registry::instance()->load_model($model_name); |
|
865 | + $fields = $model_version_info->fieldsOnModelInThisVersion($model); |
|
866 | + $args_info = array(); |
|
867 | + foreach ($fields as $field_name => $field_obj) { |
|
868 | + if ($field_obj->is_auto_increment()) { |
|
869 | + //totally ignore auto increment IDs |
|
870 | + continue; |
|
871 | + } |
|
872 | + $arg_info = $field_obj->getSchema(); |
|
873 | + $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null; |
|
874 | + $arg_info['required'] = $required; |
|
875 | + //remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right? |
|
876 | + unset($arg_info['readonly']); |
|
877 | + $schema_properties = $field_obj->getSchemaProperties(); |
|
878 | + if ( |
|
879 | + isset($schema_properties['raw']) |
|
880 | + && $field_obj->getSchemaType() === 'object' |
|
881 | + ) { |
|
882 | + //if there's a "raw" form of this argument, use those properties instead |
|
883 | + $arg_info = array_replace( |
|
884 | + $arg_info, |
|
885 | + $schema_properties['raw'] |
|
886 | + ); |
|
887 | + } |
|
888 | + $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson( |
|
889 | + $field_obj, |
|
890 | + $field_obj->get_default_value(), |
|
891 | + $model_version_info->requestedVersion() |
|
892 | + ); |
|
893 | + //we do our own validation and sanitization within the controller |
|
894 | + $arg_info['sanitize_callback'] = |
|
895 | + array( |
|
896 | + 'EED_Core_Rest_Api', |
|
897 | + 'default_sanitize_callback', |
|
898 | + ); |
|
899 | + $args_info[$field_name] = $arg_info; |
|
900 | + if ($field_obj instanceof EE_Datetime_Field) { |
|
901 | + $gmt_arg_info = $arg_info; |
|
902 | + $gmt_arg_info['description'] = sprintf( |
|
903 | + esc_html__( |
|
904 | + '%1$s - the value for this field in UTC. Ignored if %2$s is provided.', |
|
905 | + 'event_espresso' |
|
906 | + ), |
|
907 | + $field_obj->get_nicename(), |
|
908 | + $field_name |
|
909 | + ); |
|
910 | + $args_info[$field_name . '_gmt'] = $gmt_arg_info; |
|
911 | + } |
|
912 | + } |
|
913 | + return $args_info; |
|
914 | + } |
|
915 | + |
|
916 | + |
|
917 | + |
|
918 | + /** |
|
919 | + * Replacement for WP API's 'rest_parse_request_arg'. |
|
920 | + * If the value is blank but not required, don't bother validating it. |
|
921 | + * Also, it uses our email validation instead of WP API's default. |
|
922 | + * |
|
923 | + * @param $value |
|
924 | + * @param WP_REST_Request $request |
|
925 | + * @param $param |
|
926 | + * @return bool|true|WP_Error |
|
927 | + * @throws InvalidArgumentException |
|
928 | + * @throws InvalidInterfaceException |
|
929 | + * @throws InvalidDataTypeException |
|
930 | + */ |
|
931 | + public static function default_sanitize_callback( $value, WP_REST_Request $request, $param) |
|
932 | + { |
|
933 | + $attributes = $request->get_attributes(); |
|
934 | + if (! isset($attributes['args'][$param]) |
|
935 | + || ! is_array($attributes['args'][$param])) { |
|
936 | + $validation_result = true; |
|
937 | + } else { |
|
938 | + $args = $attributes['args'][$param]; |
|
939 | + if (( |
|
940 | + $value === '' |
|
941 | + || $value === null |
|
942 | + ) |
|
943 | + && (! isset($args['required']) |
|
944 | + || $args['required'] === false |
|
945 | + ) |
|
946 | + ) { |
|
947 | + //not required and not provided? that's cool |
|
948 | + $validation_result = true; |
|
949 | + } elseif (isset($args['format']) |
|
950 | + && $args['format'] === 'email' |
|
951 | + ) { |
|
952 | + $validation_result = true; |
|
953 | + if (! self::_validate_email($value)) { |
|
954 | + $validation_result = new WP_Error( |
|
955 | + 'rest_invalid_param', |
|
956 | + esc_html__( |
|
957 | + 'The email address is not valid or does not exist.', |
|
958 | + 'event_espresso' |
|
959 | + ) |
|
960 | + ); |
|
961 | + } |
|
962 | + } else { |
|
963 | + $validation_result = rest_validate_value_from_schema($value, $args, $param); |
|
964 | + } |
|
965 | + } |
|
966 | + if (is_wp_error($validation_result)) { |
|
967 | + return $validation_result; |
|
968 | + } |
|
969 | + return rest_sanitize_request_arg($value, $request, $param); |
|
970 | + } |
|
971 | + |
|
972 | + |
|
973 | + |
|
974 | + /** |
|
975 | + * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email() |
|
976 | + * |
|
977 | + * @param $email |
|
978 | + * @return bool |
|
979 | + * @throws InvalidArgumentException |
|
980 | + * @throws InvalidInterfaceException |
|
981 | + * @throws InvalidDataTypeException |
|
982 | + */ |
|
983 | + protected static function _validate_email($email){ |
|
984 | + try { |
|
985 | + EmailAddressFactory::create($email); |
|
986 | + return true; |
|
987 | + } catch (EmailValidationException $e) { |
|
988 | + return false; |
|
989 | + } |
|
990 | + } |
|
991 | + |
|
992 | + |
|
993 | + |
|
994 | + /** |
|
995 | + * Gets routes for the config |
|
996 | + * |
|
997 | + * @return array @see _register_model_routes |
|
998 | + * @deprecated since version 4.9.1 |
|
999 | + */ |
|
1000 | + protected function _register_config_routes() |
|
1001 | + { |
|
1002 | + $config_routes = array(); |
|
1003 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
1004 | + $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version( |
|
1005 | + $version, |
|
1006 | + $hidden_endpoint |
|
1007 | + ); |
|
1008 | + } |
|
1009 | + return $config_routes; |
|
1010 | + } |
|
1011 | + |
|
1012 | + |
|
1013 | + |
|
1014 | + /** |
|
1015 | + * Gets routes for the config for the specified version |
|
1016 | + * |
|
1017 | + * @param string $version |
|
1018 | + * @param boolean $hidden_endpoint |
|
1019 | + * @return array |
|
1020 | + */ |
|
1021 | + protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
1022 | + { |
|
1023 | + return array( |
|
1024 | + 'config' => array( |
|
1025 | + array( |
|
1026 | + 'callback' => array( |
|
1027 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1028 | + 'handleRequest', |
|
1029 | + ), |
|
1030 | + 'methods' => WP_REST_Server::READABLE, |
|
1031 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1032 | + 'callback_args' => array($version), |
|
1033 | + ), |
|
1034 | + ), |
|
1035 | + 'site_info' => array( |
|
1036 | + array( |
|
1037 | + 'callback' => array( |
|
1038 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1039 | + 'handleRequestSiteInfo', |
|
1040 | + ), |
|
1041 | + 'methods' => WP_REST_Server::READABLE, |
|
1042 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1043 | + 'callback_args' => array($version), |
|
1044 | + ), |
|
1045 | + ), |
|
1046 | + ); |
|
1047 | + } |
|
1048 | + |
|
1049 | + |
|
1050 | + |
|
1051 | + /** |
|
1052 | + * Gets the meta info routes |
|
1053 | + * |
|
1054 | + * @return array @see _register_model_routes |
|
1055 | + * @deprecated since version 4.9.1 |
|
1056 | + */ |
|
1057 | + protected function _register_meta_routes() |
|
1058 | + { |
|
1059 | + $meta_routes = array(); |
|
1060 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
1061 | + $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version( |
|
1062 | + $version, |
|
1063 | + $hidden_endpoint |
|
1064 | + ); |
|
1065 | + } |
|
1066 | + return $meta_routes; |
|
1067 | + } |
|
1068 | + |
|
1069 | + |
|
1070 | + |
|
1071 | + /** |
|
1072 | + * @param string $version |
|
1073 | + * @param boolean $hidden_endpoint |
|
1074 | + * @return array |
|
1075 | + */ |
|
1076 | + protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
1077 | + { |
|
1078 | + return array( |
|
1079 | + 'resources' => array( |
|
1080 | + array( |
|
1081 | + 'callback' => array( |
|
1082 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
1083 | + 'handleRequestModelsMeta', |
|
1084 | + ), |
|
1085 | + 'methods' => WP_REST_Server::READABLE, |
|
1086 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1087 | + 'callback_args' => array($version), |
|
1088 | + ), |
|
1089 | + ), |
|
1090 | + ); |
|
1091 | + } |
|
1092 | + |
|
1093 | + |
|
1094 | + |
|
1095 | + /** |
|
1096 | + * Tries to hide old 4.6 endpoints from the |
|
1097 | + * |
|
1098 | + * @param array $route_data |
|
1099 | + * @return array |
|
1100 | + * @throws \EE_Error |
|
1101 | + */ |
|
1102 | + public static function hide_old_endpoints($route_data) |
|
1103 | + { |
|
1104 | + //allow API clients to override which endpoints get hidden, in case |
|
1105 | + //they want to discover particular endpoints |
|
1106 | + //also, we don't have access to the request so we have to just grab it from the superglobal |
|
1107 | + $force_show_ee_namespace = ltrim( |
|
1108 | + EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''), |
|
1109 | + '/' |
|
1110 | + ); |
|
1111 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
1112 | + foreach ($relative_urls as $resource_name => $endpoints) { |
|
1113 | + foreach ($endpoints as $key => $endpoint) { |
|
1114 | + //skip schema and other route options |
|
1115 | + if (! is_numeric($key)) { |
|
1116 | + continue; |
|
1117 | + } |
|
1118 | + //by default, hide "hidden_endpoint"s, unless the request indicates |
|
1119 | + //to $force_show_ee_namespace, in which case only show that one |
|
1120 | + //namespace's endpoints (and hide all others) |
|
1121 | + if ( |
|
1122 | + ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
1123 | + || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
1124 | + ) { |
|
1125 | + $full_route = '/' . ltrim($namespace, '/'); |
|
1126 | + $full_route .= '/' . ltrim($resource_name, '/'); |
|
1127 | + unset($route_data[$full_route]); |
|
1128 | + } |
|
1129 | + } |
|
1130 | + } |
|
1131 | + } |
|
1132 | + return $route_data; |
|
1133 | + } |
|
1134 | + |
|
1135 | + |
|
1136 | + |
|
1137 | + /** |
|
1138 | + * Returns an array describing which versions of core support serving requests for. |
|
1139 | + * Keys are core versions' major and minor version, and values are the |
|
1140 | + * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
1141 | + * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
1142 | + * the answers table entirely, in which case it would be very difficult for |
|
1143 | + * it to serve 4.6-style responses. |
|
1144 | + * Versions of core that are missing from this array are unknowns. |
|
1145 | + * previous ver |
|
1146 | + * |
|
1147 | + * @return array |
|
1148 | + */ |
|
1149 | + public static function version_compatibilities() |
|
1150 | + { |
|
1151 | + return apply_filters( |
|
1152 | + 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
1153 | + array( |
|
1154 | + '4.8.29' => '4.8.29', |
|
1155 | + '4.8.33' => '4.8.29', |
|
1156 | + '4.8.34' => '4.8.29', |
|
1157 | + '4.8.36' => '4.8.29', |
|
1158 | + ) |
|
1159 | + ); |
|
1160 | + } |
|
1161 | + |
|
1162 | + |
|
1163 | + |
|
1164 | + /** |
|
1165 | + * Gets the latest API version served. Eg if there |
|
1166 | + * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
1167 | + * we are on core version 4.8.34, it will return the string "4.8.32" |
|
1168 | + * |
|
1169 | + * @return string |
|
1170 | + */ |
|
1171 | + public static function latest_rest_api_version() |
|
1172 | + { |
|
1173 | + $versions_served = \EED_Core_Rest_Api::versions_served(); |
|
1174 | + $versions_served_keys = array_keys($versions_served); |
|
1175 | + return end($versions_served_keys); |
|
1176 | + } |
|
1177 | + |
|
1178 | + |
|
1179 | + |
|
1180 | + /** |
|
1181 | + * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
1182 | + * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
1183 | + * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
1184 | + * We also indicate whether or not this version should be put in the index or not |
|
1185 | + * |
|
1186 | + * @return array keys are API version numbers (just major and minor numbers), and values |
|
1187 | + * are whether or not they should be hidden |
|
1188 | + */ |
|
1189 | + public static function versions_served() |
|
1190 | + { |
|
1191 | + $versions_served = array(); |
|
1192 | + $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
1193 | + $lowest_compatible_version = end($possibly_served_versions); |
|
1194 | + reset($possibly_served_versions); |
|
1195 | + $versions_served_historically = array_keys($possibly_served_versions); |
|
1196 | + $latest_version = end($versions_served_historically); |
|
1197 | + reset($versions_served_historically); |
|
1198 | + //for each version of core we have ever served: |
|
1199 | + foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
1200 | + //if it's not above the current core version, and it's compatible with the current version of core |
|
1201 | + if ($key_versioned_endpoint === $latest_version) { |
|
1202 | + //don't hide the latest version in the index |
|
1203 | + $versions_served[$key_versioned_endpoint] = false; |
|
1204 | + } elseif ( |
|
1205 | + $key_versioned_endpoint >= $lowest_compatible_version |
|
1206 | + && $key_versioned_endpoint < EED_Core_Rest_Api::core_version() |
|
1207 | + ) { |
|
1208 | + //include, but hide, previous versions which are still supported |
|
1209 | + $versions_served[$key_versioned_endpoint] = true; |
|
1210 | + } elseif (apply_filters( |
|
1211 | + 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
1212 | + false, |
|
1213 | + $possibly_served_versions |
|
1214 | + )) { |
|
1215 | + //if a version is no longer supported, don't include it in index or list of versions served |
|
1216 | + $versions_served[$key_versioned_endpoint] = true; |
|
1217 | + } |
|
1218 | + } |
|
1219 | + return $versions_served; |
|
1220 | + } |
|
1221 | + |
|
1222 | + |
|
1223 | + |
|
1224 | + /** |
|
1225 | + * Gets the major and minor version of EE core's version string |
|
1226 | + * |
|
1227 | + * @return string |
|
1228 | + */ |
|
1229 | + public static function core_version() |
|
1230 | + { |
|
1231 | + return apply_filters( |
|
1232 | + 'FHEE__EED_Core_REST_API__core_version', |
|
1233 | + implode( |
|
1234 | + '.', |
|
1235 | + array_slice( |
|
1236 | + explode( |
|
1237 | + '.', |
|
1238 | + espresso_version() |
|
1239 | + ), |
|
1240 | + 0, |
|
1241 | + 3 |
|
1242 | + ) |
|
1243 | + ) |
|
1244 | + ); |
|
1245 | + } |
|
1246 | + |
|
1247 | + |
|
1248 | + |
|
1249 | + /** |
|
1250 | + * Gets the default limit that should be used when querying for resources |
|
1251 | + * |
|
1252 | + * @return int |
|
1253 | + */ |
|
1254 | + public static function get_default_query_limit() |
|
1255 | + { |
|
1256 | + //we actually don't use a const because we want folks to always use |
|
1257 | + //this method, not the const directly |
|
1258 | + return apply_filters( |
|
1259 | + 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
1260 | + 50 |
|
1261 | + ); |
|
1262 | + } |
|
1263 | + |
|
1264 | + |
|
1265 | + |
|
1266 | + /** |
|
1267 | + * run - initial module setup |
|
1268 | + * |
|
1269 | + * @access public |
|
1270 | + * @param WP $WP |
|
1271 | + * @return void |
|
1272 | + */ |
|
1273 | + public function run($WP) |
|
1274 | + { |
|
1275 | + } |
|
1276 | 1276 | } |
1277 | 1277 | |
1278 | 1278 | // End of file EED_Core_Rest_Api.module.php |
@@ -1,5 +1,4 @@ |
||
1 | 1 | <?php |
2 | -use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice; |
|
3 | 2 | use EventEspresso\core\domain\services\factories\EmailAddressFactory; |
4 | 3 | use EventEspresso\core\domain\services\validation\email\EmailValidationException; |
5 | 4 | use EventEspresso\core\exceptions\InvalidDataTypeException; |
@@ -29,843 +29,843 @@ |
||
29 | 29 | { |
30 | 30 | |
31 | 31 | |
32 | - /** |
|
33 | - * @var EE_Datetime_Offset_Fix_Form |
|
34 | - */ |
|
35 | - protected $datetime_fix_offset_form; |
|
36 | - |
|
37 | - |
|
38 | - |
|
39 | - protected function _init_page_props() |
|
40 | - { |
|
41 | - $this->page_slug = EE_MAINTENANCE_PG_SLUG; |
|
42 | - $this->page_label = EE_MAINTENANCE_LABEL; |
|
43 | - $this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL; |
|
44 | - $this->_admin_base_path = EE_MAINTENANCE_ADMIN; |
|
45 | - } |
|
46 | - |
|
47 | - |
|
48 | - |
|
49 | - protected function _ajax_hooks() |
|
50 | - { |
|
51 | - add_action('wp_ajax_migration_step', array($this, 'migration_step')); |
|
52 | - add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran')); |
|
53 | - } |
|
54 | - |
|
55 | - |
|
56 | - |
|
57 | - protected function _define_page_props() |
|
58 | - { |
|
59 | - $this->_admin_page_title = EE_MAINTENANCE_LABEL; |
|
60 | - $this->_labels = array( |
|
61 | - 'buttons' => array( |
|
62 | - 'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'), |
|
63 | - 'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'), |
|
64 | - ), |
|
65 | - ); |
|
66 | - } |
|
67 | - |
|
68 | - |
|
69 | - |
|
70 | - protected function _set_page_routes() |
|
71 | - { |
|
72 | - $this->_page_routes = array( |
|
73 | - 'default' => array( |
|
74 | - 'func' => '_maintenance', |
|
75 | - 'capability' => 'manage_options', |
|
76 | - ), |
|
77 | - 'change_maintenance_level' => array( |
|
78 | - 'func' => '_change_maintenance_level', |
|
79 | - 'capability' => 'manage_options', |
|
80 | - 'noheader' => true, |
|
81 | - ), |
|
82 | - 'system_status' => array( |
|
83 | - 'func' => '_system_status', |
|
84 | - 'capability' => 'manage_options', |
|
85 | - ), |
|
86 | - 'download_system_status' => array( |
|
87 | - 'func' => '_download_system_status', |
|
88 | - 'capability' => 'manage_options', |
|
89 | - 'noheader' => true, |
|
90 | - ), |
|
91 | - 'send_migration_crash_report' => array( |
|
92 | - 'func' => '_send_migration_crash_report', |
|
93 | - 'capability' => 'manage_options', |
|
94 | - 'noheader' => true, |
|
95 | - ), |
|
96 | - 'confirm_migration_crash_report_sent' => array( |
|
97 | - 'func' => '_confirm_migration_crash_report_sent', |
|
98 | - 'capability' => 'manage_options', |
|
99 | - ), |
|
100 | - 'data_reset' => array( |
|
101 | - 'func' => '_data_reset_and_delete', |
|
102 | - 'capability' => 'manage_options', |
|
103 | - ), |
|
104 | - 'reset_db' => array( |
|
105 | - 'func' => '_reset_db', |
|
106 | - 'capability' => 'manage_options', |
|
107 | - 'noheader' => true, |
|
108 | - 'args' => array('nuke_old_ee4_data' => true), |
|
109 | - ), |
|
110 | - 'start_with_fresh_ee4_db' => array( |
|
111 | - 'func' => '_reset_db', |
|
112 | - 'capability' => 'manage_options', |
|
113 | - 'noheader' => true, |
|
114 | - 'args' => array('nuke_old_ee4_data' => false), |
|
115 | - ), |
|
116 | - 'delete_db' => array( |
|
117 | - 'func' => '_delete_db', |
|
118 | - 'capability' => 'manage_options', |
|
119 | - 'noheader' => true, |
|
120 | - ), |
|
121 | - 'rerun_migration_from_ee3' => array( |
|
122 | - 'func' => '_rerun_migration_from_ee3', |
|
123 | - 'capability' => 'manage_options', |
|
124 | - 'noheader' => true, |
|
125 | - ), |
|
126 | - 'reset_reservations' => array( |
|
127 | - 'func' => '_reset_reservations', |
|
128 | - 'capability' => 'manage_options', |
|
129 | - 'noheader' => true, |
|
130 | - ), |
|
131 | - 'reset_capabilities' => array( |
|
132 | - 'func' => '_reset_capabilities', |
|
133 | - 'capability' => 'manage_options', |
|
134 | - 'noheader' => true, |
|
135 | - ), |
|
136 | - 'reattempt_migration' => array( |
|
137 | - 'func' => '_reattempt_migration', |
|
138 | - 'capability' => 'manage_options', |
|
139 | - 'noheader' => true, |
|
140 | - ), |
|
141 | - 'datetime_tools' => array( |
|
142 | - 'func' => '_datetime_tools', |
|
143 | - 'capability' => 'manage_options' |
|
144 | - ), |
|
145 | - 'run_datetime_offset_fix' => array( |
|
146 | - 'func' => '_apply_datetime_offset', |
|
147 | - 'noheader' => true, |
|
148 | - 'headers_sent_route' => 'datetime_tools', |
|
149 | - 'capability' => 'manage_options' |
|
150 | - ) |
|
151 | - ); |
|
152 | - } |
|
153 | - |
|
154 | - |
|
155 | - |
|
156 | - protected function _set_page_config() |
|
157 | - { |
|
158 | - $this->_page_config = array( |
|
159 | - 'default' => array( |
|
160 | - 'nav' => array( |
|
161 | - 'label' => esc_html__('Maintenance', 'event_espresso'), |
|
162 | - 'order' => 10, |
|
163 | - ), |
|
164 | - 'require_nonce' => false, |
|
165 | - ), |
|
166 | - 'data_reset' => array( |
|
167 | - 'nav' => array( |
|
168 | - 'label' => esc_html__('Reset/Delete Data', 'event_espresso'), |
|
169 | - 'order' => 20, |
|
170 | - ), |
|
171 | - 'require_nonce' => false, |
|
172 | - ), |
|
173 | - 'datetime_tools' => array( |
|
174 | - 'nav' => array( |
|
175 | - 'label' => esc_html__('Datetime Utilities', 'event_espresso'), |
|
176 | - 'order' => 25 |
|
177 | - ), |
|
178 | - 'require_nonce' => false, |
|
179 | - ), |
|
180 | - 'system_status' => array( |
|
181 | - 'nav' => array( |
|
182 | - 'label' => esc_html__("System Information", "event_espresso"), |
|
183 | - 'order' => 30, |
|
184 | - ), |
|
185 | - 'require_nonce' => false, |
|
186 | - ), |
|
187 | - ); |
|
188 | - } |
|
189 | - |
|
190 | - |
|
191 | - |
|
192 | - /** |
|
193 | - * default maintenance page. If we're in maintenance mode level 2, then we need to show |
|
194 | - * the migration scripts and all that UI. |
|
195 | - */ |
|
196 | - public function _maintenance() |
|
197 | - { |
|
198 | - //it all depends if we're in maintenance model level 1 (frontend-only) or |
|
199 | - //level 2 (everything except maintenance page) |
|
200 | - try { |
|
201 | - //get the current maintenance level and check if |
|
202 | - //we are removed |
|
203 | - $mm = EE_Maintenance_Mode::instance()->level(); |
|
204 | - $placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
205 | - if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) { |
|
206 | - //we just took the site out of maintenance mode, so notify the user. |
|
207 | - //unfortunately this message appears to be echoed on the NEXT page load... |
|
208 | - //oh well, we should really be checking for this on addon deactivation anyways |
|
209 | - EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required', |
|
210 | - 'event_espresso')); |
|
211 | - $this->_process_notices(array('page' => 'espresso_maintenance_settings'), false); |
|
212 | - } |
|
213 | - //in case an exception is thrown while trying to handle migrations |
|
214 | - switch (EE_Maintenance_Mode::instance()->level()) { |
|
215 | - case EE_Maintenance_Mode::level_0_not_in_maintenance: |
|
216 | - case EE_Maintenance_Mode::level_1_frontend_only_maintenance: |
|
217 | - $show_maintenance_switch = true; |
|
218 | - $show_backup_db_text = false; |
|
219 | - $show_migration_progress = false; |
|
220 | - $script_names = array(); |
|
221 | - $addons_should_be_upgraded_first = false; |
|
222 | - break; |
|
223 | - case EE_Maintenance_Mode::level_2_complete_maintenance: |
|
224 | - $show_maintenance_switch = false; |
|
225 | - $show_migration_progress = true; |
|
226 | - if (isset($this->_req_data['continue_migration'])) { |
|
227 | - $show_backup_db_text = false; |
|
228 | - } else { |
|
229 | - $show_backup_db_text = true; |
|
230 | - } |
|
231 | - $scripts_needing_to_run = EE_Data_Migration_Manager::instance() |
|
232 | - ->check_for_applicable_data_migration_scripts(); |
|
233 | - $addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating(); |
|
234 | - $script_names = array(); |
|
235 | - $current_script = null; |
|
236 | - foreach ($scripts_needing_to_run as $script) { |
|
237 | - if ($script instanceof EE_Data_Migration_Script_Base) { |
|
238 | - if ( ! $current_script) { |
|
239 | - $current_script = $script; |
|
240 | - $current_script->migration_page_hooks(); |
|
241 | - } |
|
242 | - $script_names[] = $script->pretty_name(); |
|
243 | - } |
|
244 | - } |
|
245 | - break; |
|
246 | - } |
|
247 | - $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true); |
|
248 | - $exception_thrown = false; |
|
249 | - } catch (EE_Error $e) { |
|
250 | - EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage()); |
|
251 | - //now, just so we can display the page correctly, make a error migration script stage object |
|
252 | - //and also put the error on it. It only persists for the duration of this request |
|
253 | - $most_recent_migration = new EE_DMS_Unknown_1_0_0(); |
|
254 | - $most_recent_migration->add_error($e->getMessage()); |
|
255 | - $exception_thrown = true; |
|
256 | - } |
|
257 | - $current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set(); |
|
258 | - $current_db_state = str_replace('.decaf', '', $current_db_state); |
|
259 | - if ($exception_thrown |
|
260 | - || ($most_recent_migration |
|
261 | - && $most_recent_migration instanceof EE_Data_Migration_Script_Base |
|
262 | - && $most_recent_migration->is_broken() |
|
263 | - ) |
|
264 | - ) { |
|
265 | - $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php'; |
|
266 | - $this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/'; |
|
267 | - $this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action' => 'confirm_migration_crash_report_sent', |
|
268 | - 'success' => '0', |
|
269 | - ), EE_MAINTENANCE_ADMIN_URL); |
|
270 | - } elseif ($addons_should_be_upgraded_first) { |
|
271 | - $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php'; |
|
272 | - } else { |
|
273 | - if ($most_recent_migration |
|
274 | - && $most_recent_migration instanceof EE_Data_Migration_Script_Base |
|
275 | - && $most_recent_migration->can_continue() |
|
276 | - ) { |
|
277 | - $show_backup_db_text = false; |
|
278 | - $show_continue_current_migration_script = true; |
|
279 | - $show_most_recent_migration = true; |
|
280 | - } elseif (isset($this->_req_data['continue_migration'])) { |
|
281 | - $show_most_recent_migration = true; |
|
282 | - $show_continue_current_migration_script = false; |
|
283 | - } else { |
|
284 | - $show_most_recent_migration = false; |
|
285 | - $show_continue_current_migration_script = false; |
|
286 | - } |
|
287 | - if (isset($current_script)) { |
|
288 | - $migrates_to = $current_script->migrates_to_version(); |
|
289 | - $plugin_slug = $migrates_to['slug']; |
|
290 | - $new_version = $migrates_to['version']; |
|
291 | - $this->_template_args = array_merge($this->_template_args, array( |
|
292 | - 'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"), |
|
293 | - isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug), |
|
294 | - 'next_db_state' => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'), |
|
295 | - $new_version, $plugin_slug) : null, |
|
296 | - )); |
|
297 | - } else { |
|
298 | - $this->_template_args['current_db_state'] = null; |
|
299 | - $this->_template_args['next_db_state'] = null; |
|
300 | - } |
|
301 | - $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php'; |
|
302 | - $this->_template_args = array_merge( |
|
303 | - $this->_template_args, |
|
304 | - array( |
|
305 | - 'show_most_recent_migration' => $show_most_recent_migration, |
|
306 | - //flag for showing the most recent migration's status and/or errors |
|
307 | - 'show_migration_progress' => $show_migration_progress, |
|
308 | - //flag for showing the option to run migrations and see their progress |
|
309 | - 'show_backup_db_text' => $show_backup_db_text, |
|
310 | - //flag for showing text telling the user to backup their DB |
|
311 | - 'show_maintenance_switch' => $show_maintenance_switch, |
|
312 | - //flag for showing the option to change maintenance mode between levels 0 and 1 |
|
313 | - 'script_names' => $script_names, |
|
314 | - //array of names of scripts that have run |
|
315 | - 'show_continue_current_migration_script' => $show_continue_current_migration_script, |
|
316 | - //flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0 |
|
317 | - 'reset_db_page_link' => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'), |
|
318 | - EE_MAINTENANCE_ADMIN_URL), |
|
319 | - 'data_reset_page' => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'), |
|
320 | - EE_MAINTENANCE_ADMIN_URL), |
|
321 | - 'update_migration_script_page_link' => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'), |
|
322 | - EE_MAINTENANCE_ADMIN_URL), |
|
323 | - 'ultimate_db_state' => sprintf(__("EE%s", 'event_espresso'), |
|
324 | - espresso_version()), |
|
325 | - ) |
|
326 | - ); |
|
327 | - //make sure we have the form fields helper available. It usually is, but sometimes it isn't |
|
328 | - } |
|
329 | - $this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration |
|
330 | - //now render the migration options part, and put it in a variable |
|
331 | - $migration_options_template_file = apply_filters( |
|
332 | - 'FHEE__ee_migration_page__migration_options_template', |
|
333 | - EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php' |
|
334 | - ); |
|
335 | - $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true); |
|
336 | - $this->_template_args['migration_options_html'] = $migration_options_html; |
|
337 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path, |
|
338 | - $this->_template_args, true); |
|
339 | - $this->display_admin_page_with_sidebar(); |
|
340 | - } |
|
341 | - |
|
342 | - |
|
343 | - |
|
344 | - /** |
|
345 | - * returns JSON and executes another step of the currently-executing data migration (called via ajax) |
|
346 | - */ |
|
347 | - public function migration_step() |
|
348 | - { |
|
349 | - $this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request(); |
|
350 | - $this->_return_json(); |
|
351 | - } |
|
352 | - |
|
353 | - |
|
354 | - |
|
355 | - /** |
|
356 | - * Can be used by js when it notices a response with HTML in it in order |
|
357 | - * to log the malformed response |
|
358 | - */ |
|
359 | - public function add_error_to_migrations_ran() |
|
360 | - { |
|
361 | - EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']); |
|
362 | - $this->_template_args['data'] = array('ok' => true); |
|
363 | - $this->_return_json(); |
|
364 | - } |
|
365 | - |
|
366 | - |
|
367 | - |
|
368 | - /** |
|
369 | - * changes the maintenance level, provided there are still no migration scripts that should run |
|
370 | - */ |
|
371 | - public function _change_maintenance_level() |
|
372 | - { |
|
373 | - $new_level = absint($this->_req_data['maintenance_mode_level']); |
|
374 | - if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) { |
|
375 | - EE_Maintenance_Mode::instance()->set_maintenance_level($new_level); |
|
376 | - $success = true; |
|
377 | - } else { |
|
378 | - EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
379 | - $success = false; |
|
380 | - } |
|
381 | - $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso")); |
|
382 | - } |
|
383 | - |
|
384 | - |
|
385 | - |
|
386 | - /** |
|
387 | - * a tab with options for resetting and/or deleting EE data |
|
388 | - * |
|
389 | - * @throws \EE_Error |
|
390 | - * @throws \DomainException |
|
391 | - */ |
|
392 | - public function _data_reset_and_delete() |
|
393 | - { |
|
394 | - $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php'; |
|
395 | - $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button( |
|
396 | - 'reset_reservations', |
|
397 | - 'reset_reservations', |
|
398 | - array(), |
|
399 | - 'button button-primary ee-confirm', |
|
400 | - '', |
|
401 | - false |
|
402 | - ); |
|
403 | - $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button( |
|
404 | - 'reset_capabilities', |
|
405 | - 'reset_capabilities', |
|
406 | - array(), |
|
407 | - 'button button-primary ee-confirm', |
|
408 | - '', |
|
409 | - false |
|
410 | - ); |
|
411 | - $this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
412 | - array('action' => 'delete_db'), |
|
413 | - EE_MAINTENANCE_ADMIN_URL |
|
414 | - ); |
|
415 | - $this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
416 | - array('action' => 'reset_db'), |
|
417 | - EE_MAINTENANCE_ADMIN_URL |
|
418 | - ); |
|
419 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
420 | - $this->_template_path, |
|
421 | - $this->_template_args, |
|
422 | - true |
|
423 | - ); |
|
424 | - $this->display_admin_page_with_sidebar(); |
|
425 | - } |
|
426 | - |
|
427 | - |
|
428 | - |
|
429 | - protected function _reset_reservations() |
|
430 | - { |
|
431 | - if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) { |
|
432 | - EE_Error::add_success( |
|
433 | - __( |
|
434 | - 'Ticket and datetime reserved counts have been successfully reset.', |
|
435 | - 'event_espresso' |
|
436 | - ) |
|
437 | - ); |
|
438 | - } else { |
|
439 | - EE_Error::add_success( |
|
440 | - __( |
|
441 | - 'Ticket and datetime reserved counts were correct and did not need resetting.', |
|
442 | - 'event_espresso' |
|
443 | - ) |
|
444 | - ); |
|
445 | - } |
|
446 | - $this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true); |
|
447 | - } |
|
448 | - |
|
449 | - |
|
450 | - |
|
451 | - protected function _reset_capabilities() |
|
452 | - { |
|
453 | - EE_Registry::instance()->CAP->init_caps(true); |
|
454 | - EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.', |
|
455 | - 'event_espresso')); |
|
456 | - $this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true); |
|
457 | - } |
|
458 | - |
|
459 | - |
|
460 | - |
|
461 | - /** |
|
462 | - * resets the DMSs so we can attempt to continue migrating after a fatal error |
|
463 | - * (only a good idea when someone has somehow tried ot fix whatever caused |
|
464 | - * the fatal error in teh first place) |
|
465 | - */ |
|
466 | - protected function _reattempt_migration() |
|
467 | - { |
|
468 | - EE_Data_Migration_Manager::instance()->reattempt(); |
|
469 | - $this->_redirect_after_action(false, '', '', array('action' => 'default'), true); |
|
470 | - } |
|
471 | - |
|
472 | - |
|
473 | - |
|
474 | - /** |
|
475 | - * shows the big ol' System Information page |
|
476 | - */ |
|
477 | - public function _system_status() |
|
478 | - { |
|
479 | - $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php'; |
|
480 | - $this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati(); |
|
481 | - $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
482 | - array( |
|
483 | - 'action' => 'download_system_status', |
|
484 | - ), |
|
485 | - EE_MAINTENANCE_ADMIN_URL |
|
486 | - ); |
|
487 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path, |
|
488 | - $this->_template_args, true); |
|
489 | - $this->display_admin_page_with_sidebar(); |
|
490 | - } |
|
491 | - |
|
492 | - /** |
|
493 | - * Downloads an HTML file of the system status that can be easily stored or emailed |
|
494 | - */ |
|
495 | - public function _download_system_status() |
|
496 | - { |
|
497 | - $status_info = EEM_System_Status::instance()->get_system_stati(); |
|
498 | - header( 'Content-Disposition: attachment' ); |
|
499 | - header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" ); |
|
500 | - echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>"; |
|
501 | - echo "<h1>System Information for " . site_url() . "</h1>"; |
|
502 | - echo EEH_Template::layout_array_as_table( $status_info ); |
|
503 | - die; |
|
504 | - } |
|
505 | - |
|
506 | - |
|
507 | - |
|
508 | - public function _send_migration_crash_report() |
|
509 | - { |
|
510 | - $from = $this->_req_data['from']; |
|
511 | - $from_name = $this->_req_data['from_name']; |
|
512 | - $body = $this->_req_data['body']; |
|
513 | - try { |
|
514 | - $success = wp_mail(EE_SUPPORT_EMAIL, |
|
515 | - 'Migration Crash Report', |
|
516 | - $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true), |
|
517 | - array( |
|
518 | - "from:$from_name<$from>", |
|
519 | - // 'content-type:text/html charset=UTF-8' |
|
520 | - )); |
|
521 | - } catch (Exception $e) { |
|
522 | - $success = false; |
|
523 | - } |
|
524 | - $this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"), |
|
525 | - esc_html__("sent", "event_espresso"), |
|
526 | - array('success' => $success, 'action' => 'confirm_migration_crash_report_sent')); |
|
527 | - } |
|
528 | - |
|
529 | - |
|
530 | - |
|
531 | - public function _confirm_migration_crash_report_sent() |
|
532 | - { |
|
533 | - try { |
|
534 | - $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true); |
|
535 | - } catch (EE_Error $e) { |
|
536 | - EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage()); |
|
537 | - //now, just so we can display the page correctly, make a error migration script stage object |
|
538 | - //and also put the error on it. It only persists for the duration of this request |
|
539 | - $most_recent_migration = new EE_DMS_Unknown_1_0_0(); |
|
540 | - $most_recent_migration->add_error($e->getMessage()); |
|
541 | - } |
|
542 | - $success = $this->_req_data['success'] == '1' ? true : false; |
|
543 | - $this->_template_args['success'] = $success; |
|
544 | - $this->_template_args['most_recent_migration'] = $most_recent_migration; |
|
545 | - $this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'), |
|
546 | - EE_MAINTENANCE_ADMIN_URL); |
|
547 | - $this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'), |
|
548 | - EE_MAINTENANCE_ADMIN_URL); |
|
549 | - $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'), |
|
550 | - EE_MAINTENANCE_ADMIN_URL); |
|
551 | - $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php'; |
|
552 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path, |
|
553 | - $this->_template_args, true); |
|
554 | - $this->display_admin_page_with_sidebar(); |
|
555 | - } |
|
556 | - |
|
557 | - |
|
558 | - |
|
559 | - /** |
|
560 | - * Resets the entire EE4 database. |
|
561 | - * Currently basically only sets up ee4 database for a fresh install- doesn't |
|
562 | - * actually clean out the old wp options, or cpts (although does erase old ee table data) |
|
563 | - * |
|
564 | - * @param boolean $nuke_old_ee4_data controls whether or not we |
|
565 | - * destroy the old ee4 data, or just try initializing ee4 default data |
|
566 | - */ |
|
567 | - public function _reset_db($nuke_old_ee4_data = true) |
|
568 | - { |
|
569 | - EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance); |
|
570 | - if ($nuke_old_ee4_data) { |
|
571 | - EEH_Activation::delete_all_espresso_cpt_data(); |
|
572 | - EEH_Activation::delete_all_espresso_tables_and_data(false); |
|
573 | - EEH_Activation::remove_cron_tasks(); |
|
574 | - } |
|
575 | - //make sure when we reset the registry's config that it |
|
576 | - //switches to using the new singleton |
|
577 | - EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true); |
|
578 | - EE_System::instance()->initialize_db_if_no_migrations_required(true); |
|
579 | - EE_System::instance()->redirect_to_about_ee(); |
|
580 | - } |
|
581 | - |
|
582 | - |
|
583 | - |
|
584 | - /** |
|
585 | - * Deletes ALL EE tables, Records, and Options from the database. |
|
586 | - */ |
|
587 | - public function _delete_db() |
|
588 | - { |
|
589 | - EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance); |
|
590 | - EEH_Activation::delete_all_espresso_cpt_data(); |
|
591 | - EEH_Activation::delete_all_espresso_tables_and_data(); |
|
592 | - EEH_Activation::remove_cron_tasks(); |
|
593 | - EEH_Activation::deactivate_event_espresso(); |
|
594 | - wp_safe_redirect(admin_url('plugins.php')); |
|
595 | - exit; |
|
596 | - } |
|
597 | - |
|
598 | - |
|
599 | - |
|
600 | - /** |
|
601 | - * sets up EE4 to rerun the migrations from ee3 to ee4 |
|
602 | - */ |
|
603 | - public function _rerun_migration_from_ee3() |
|
604 | - { |
|
605 | - EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance); |
|
606 | - EEH_Activation::delete_all_espresso_cpt_data(); |
|
607 | - EEH_Activation::delete_all_espresso_tables_and_data(false); |
|
608 | - //set the db state to something that will require migrations |
|
609 | - update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0'); |
|
610 | - EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance); |
|
611 | - $this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso')); |
|
612 | - } |
|
613 | - |
|
614 | - |
|
615 | - |
|
616 | - //none of the below group are currently used for Gateway Settings |
|
617 | - protected function _add_screen_options() |
|
618 | - { |
|
619 | - } |
|
620 | - |
|
621 | - |
|
622 | - |
|
623 | - protected function _add_feature_pointers() |
|
624 | - { |
|
625 | - } |
|
626 | - |
|
32 | + /** |
|
33 | + * @var EE_Datetime_Offset_Fix_Form |
|
34 | + */ |
|
35 | + protected $datetime_fix_offset_form; |
|
36 | + |
|
37 | + |
|
38 | + |
|
39 | + protected function _init_page_props() |
|
40 | + { |
|
41 | + $this->page_slug = EE_MAINTENANCE_PG_SLUG; |
|
42 | + $this->page_label = EE_MAINTENANCE_LABEL; |
|
43 | + $this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL; |
|
44 | + $this->_admin_base_path = EE_MAINTENANCE_ADMIN; |
|
45 | + } |
|
46 | + |
|
47 | + |
|
48 | + |
|
49 | + protected function _ajax_hooks() |
|
50 | + { |
|
51 | + add_action('wp_ajax_migration_step', array($this, 'migration_step')); |
|
52 | + add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran')); |
|
53 | + } |
|
54 | + |
|
55 | + |
|
56 | + |
|
57 | + protected function _define_page_props() |
|
58 | + { |
|
59 | + $this->_admin_page_title = EE_MAINTENANCE_LABEL; |
|
60 | + $this->_labels = array( |
|
61 | + 'buttons' => array( |
|
62 | + 'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'), |
|
63 | + 'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'), |
|
64 | + ), |
|
65 | + ); |
|
66 | + } |
|
67 | + |
|
68 | + |
|
69 | + |
|
70 | + protected function _set_page_routes() |
|
71 | + { |
|
72 | + $this->_page_routes = array( |
|
73 | + 'default' => array( |
|
74 | + 'func' => '_maintenance', |
|
75 | + 'capability' => 'manage_options', |
|
76 | + ), |
|
77 | + 'change_maintenance_level' => array( |
|
78 | + 'func' => '_change_maintenance_level', |
|
79 | + 'capability' => 'manage_options', |
|
80 | + 'noheader' => true, |
|
81 | + ), |
|
82 | + 'system_status' => array( |
|
83 | + 'func' => '_system_status', |
|
84 | + 'capability' => 'manage_options', |
|
85 | + ), |
|
86 | + 'download_system_status' => array( |
|
87 | + 'func' => '_download_system_status', |
|
88 | + 'capability' => 'manage_options', |
|
89 | + 'noheader' => true, |
|
90 | + ), |
|
91 | + 'send_migration_crash_report' => array( |
|
92 | + 'func' => '_send_migration_crash_report', |
|
93 | + 'capability' => 'manage_options', |
|
94 | + 'noheader' => true, |
|
95 | + ), |
|
96 | + 'confirm_migration_crash_report_sent' => array( |
|
97 | + 'func' => '_confirm_migration_crash_report_sent', |
|
98 | + 'capability' => 'manage_options', |
|
99 | + ), |
|
100 | + 'data_reset' => array( |
|
101 | + 'func' => '_data_reset_and_delete', |
|
102 | + 'capability' => 'manage_options', |
|
103 | + ), |
|
104 | + 'reset_db' => array( |
|
105 | + 'func' => '_reset_db', |
|
106 | + 'capability' => 'manage_options', |
|
107 | + 'noheader' => true, |
|
108 | + 'args' => array('nuke_old_ee4_data' => true), |
|
109 | + ), |
|
110 | + 'start_with_fresh_ee4_db' => array( |
|
111 | + 'func' => '_reset_db', |
|
112 | + 'capability' => 'manage_options', |
|
113 | + 'noheader' => true, |
|
114 | + 'args' => array('nuke_old_ee4_data' => false), |
|
115 | + ), |
|
116 | + 'delete_db' => array( |
|
117 | + 'func' => '_delete_db', |
|
118 | + 'capability' => 'manage_options', |
|
119 | + 'noheader' => true, |
|
120 | + ), |
|
121 | + 'rerun_migration_from_ee3' => array( |
|
122 | + 'func' => '_rerun_migration_from_ee3', |
|
123 | + 'capability' => 'manage_options', |
|
124 | + 'noheader' => true, |
|
125 | + ), |
|
126 | + 'reset_reservations' => array( |
|
127 | + 'func' => '_reset_reservations', |
|
128 | + 'capability' => 'manage_options', |
|
129 | + 'noheader' => true, |
|
130 | + ), |
|
131 | + 'reset_capabilities' => array( |
|
132 | + 'func' => '_reset_capabilities', |
|
133 | + 'capability' => 'manage_options', |
|
134 | + 'noheader' => true, |
|
135 | + ), |
|
136 | + 'reattempt_migration' => array( |
|
137 | + 'func' => '_reattempt_migration', |
|
138 | + 'capability' => 'manage_options', |
|
139 | + 'noheader' => true, |
|
140 | + ), |
|
141 | + 'datetime_tools' => array( |
|
142 | + 'func' => '_datetime_tools', |
|
143 | + 'capability' => 'manage_options' |
|
144 | + ), |
|
145 | + 'run_datetime_offset_fix' => array( |
|
146 | + 'func' => '_apply_datetime_offset', |
|
147 | + 'noheader' => true, |
|
148 | + 'headers_sent_route' => 'datetime_tools', |
|
149 | + 'capability' => 'manage_options' |
|
150 | + ) |
|
151 | + ); |
|
152 | + } |
|
153 | + |
|
154 | + |
|
155 | + |
|
156 | + protected function _set_page_config() |
|
157 | + { |
|
158 | + $this->_page_config = array( |
|
159 | + 'default' => array( |
|
160 | + 'nav' => array( |
|
161 | + 'label' => esc_html__('Maintenance', 'event_espresso'), |
|
162 | + 'order' => 10, |
|
163 | + ), |
|
164 | + 'require_nonce' => false, |
|
165 | + ), |
|
166 | + 'data_reset' => array( |
|
167 | + 'nav' => array( |
|
168 | + 'label' => esc_html__('Reset/Delete Data', 'event_espresso'), |
|
169 | + 'order' => 20, |
|
170 | + ), |
|
171 | + 'require_nonce' => false, |
|
172 | + ), |
|
173 | + 'datetime_tools' => array( |
|
174 | + 'nav' => array( |
|
175 | + 'label' => esc_html__('Datetime Utilities', 'event_espresso'), |
|
176 | + 'order' => 25 |
|
177 | + ), |
|
178 | + 'require_nonce' => false, |
|
179 | + ), |
|
180 | + 'system_status' => array( |
|
181 | + 'nav' => array( |
|
182 | + 'label' => esc_html__("System Information", "event_espresso"), |
|
183 | + 'order' => 30, |
|
184 | + ), |
|
185 | + 'require_nonce' => false, |
|
186 | + ), |
|
187 | + ); |
|
188 | + } |
|
189 | + |
|
190 | + |
|
191 | + |
|
192 | + /** |
|
193 | + * default maintenance page. If we're in maintenance mode level 2, then we need to show |
|
194 | + * the migration scripts and all that UI. |
|
195 | + */ |
|
196 | + public function _maintenance() |
|
197 | + { |
|
198 | + //it all depends if we're in maintenance model level 1 (frontend-only) or |
|
199 | + //level 2 (everything except maintenance page) |
|
200 | + try { |
|
201 | + //get the current maintenance level and check if |
|
202 | + //we are removed |
|
203 | + $mm = EE_Maintenance_Mode::instance()->level(); |
|
204 | + $placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
205 | + if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) { |
|
206 | + //we just took the site out of maintenance mode, so notify the user. |
|
207 | + //unfortunately this message appears to be echoed on the NEXT page load... |
|
208 | + //oh well, we should really be checking for this on addon deactivation anyways |
|
209 | + EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required', |
|
210 | + 'event_espresso')); |
|
211 | + $this->_process_notices(array('page' => 'espresso_maintenance_settings'), false); |
|
212 | + } |
|
213 | + //in case an exception is thrown while trying to handle migrations |
|
214 | + switch (EE_Maintenance_Mode::instance()->level()) { |
|
215 | + case EE_Maintenance_Mode::level_0_not_in_maintenance: |
|
216 | + case EE_Maintenance_Mode::level_1_frontend_only_maintenance: |
|
217 | + $show_maintenance_switch = true; |
|
218 | + $show_backup_db_text = false; |
|
219 | + $show_migration_progress = false; |
|
220 | + $script_names = array(); |
|
221 | + $addons_should_be_upgraded_first = false; |
|
222 | + break; |
|
223 | + case EE_Maintenance_Mode::level_2_complete_maintenance: |
|
224 | + $show_maintenance_switch = false; |
|
225 | + $show_migration_progress = true; |
|
226 | + if (isset($this->_req_data['continue_migration'])) { |
|
227 | + $show_backup_db_text = false; |
|
228 | + } else { |
|
229 | + $show_backup_db_text = true; |
|
230 | + } |
|
231 | + $scripts_needing_to_run = EE_Data_Migration_Manager::instance() |
|
232 | + ->check_for_applicable_data_migration_scripts(); |
|
233 | + $addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating(); |
|
234 | + $script_names = array(); |
|
235 | + $current_script = null; |
|
236 | + foreach ($scripts_needing_to_run as $script) { |
|
237 | + if ($script instanceof EE_Data_Migration_Script_Base) { |
|
238 | + if ( ! $current_script) { |
|
239 | + $current_script = $script; |
|
240 | + $current_script->migration_page_hooks(); |
|
241 | + } |
|
242 | + $script_names[] = $script->pretty_name(); |
|
243 | + } |
|
244 | + } |
|
245 | + break; |
|
246 | + } |
|
247 | + $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true); |
|
248 | + $exception_thrown = false; |
|
249 | + } catch (EE_Error $e) { |
|
250 | + EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage()); |
|
251 | + //now, just so we can display the page correctly, make a error migration script stage object |
|
252 | + //and also put the error on it. It only persists for the duration of this request |
|
253 | + $most_recent_migration = new EE_DMS_Unknown_1_0_0(); |
|
254 | + $most_recent_migration->add_error($e->getMessage()); |
|
255 | + $exception_thrown = true; |
|
256 | + } |
|
257 | + $current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set(); |
|
258 | + $current_db_state = str_replace('.decaf', '', $current_db_state); |
|
259 | + if ($exception_thrown |
|
260 | + || ($most_recent_migration |
|
261 | + && $most_recent_migration instanceof EE_Data_Migration_Script_Base |
|
262 | + && $most_recent_migration->is_broken() |
|
263 | + ) |
|
264 | + ) { |
|
265 | + $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php'; |
|
266 | + $this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/'; |
|
267 | + $this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action' => 'confirm_migration_crash_report_sent', |
|
268 | + 'success' => '0', |
|
269 | + ), EE_MAINTENANCE_ADMIN_URL); |
|
270 | + } elseif ($addons_should_be_upgraded_first) { |
|
271 | + $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php'; |
|
272 | + } else { |
|
273 | + if ($most_recent_migration |
|
274 | + && $most_recent_migration instanceof EE_Data_Migration_Script_Base |
|
275 | + && $most_recent_migration->can_continue() |
|
276 | + ) { |
|
277 | + $show_backup_db_text = false; |
|
278 | + $show_continue_current_migration_script = true; |
|
279 | + $show_most_recent_migration = true; |
|
280 | + } elseif (isset($this->_req_data['continue_migration'])) { |
|
281 | + $show_most_recent_migration = true; |
|
282 | + $show_continue_current_migration_script = false; |
|
283 | + } else { |
|
284 | + $show_most_recent_migration = false; |
|
285 | + $show_continue_current_migration_script = false; |
|
286 | + } |
|
287 | + if (isset($current_script)) { |
|
288 | + $migrates_to = $current_script->migrates_to_version(); |
|
289 | + $plugin_slug = $migrates_to['slug']; |
|
290 | + $new_version = $migrates_to['version']; |
|
291 | + $this->_template_args = array_merge($this->_template_args, array( |
|
292 | + 'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"), |
|
293 | + isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug), |
|
294 | + 'next_db_state' => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'), |
|
295 | + $new_version, $plugin_slug) : null, |
|
296 | + )); |
|
297 | + } else { |
|
298 | + $this->_template_args['current_db_state'] = null; |
|
299 | + $this->_template_args['next_db_state'] = null; |
|
300 | + } |
|
301 | + $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php'; |
|
302 | + $this->_template_args = array_merge( |
|
303 | + $this->_template_args, |
|
304 | + array( |
|
305 | + 'show_most_recent_migration' => $show_most_recent_migration, |
|
306 | + //flag for showing the most recent migration's status and/or errors |
|
307 | + 'show_migration_progress' => $show_migration_progress, |
|
308 | + //flag for showing the option to run migrations and see their progress |
|
309 | + 'show_backup_db_text' => $show_backup_db_text, |
|
310 | + //flag for showing text telling the user to backup their DB |
|
311 | + 'show_maintenance_switch' => $show_maintenance_switch, |
|
312 | + //flag for showing the option to change maintenance mode between levels 0 and 1 |
|
313 | + 'script_names' => $script_names, |
|
314 | + //array of names of scripts that have run |
|
315 | + 'show_continue_current_migration_script' => $show_continue_current_migration_script, |
|
316 | + //flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0 |
|
317 | + 'reset_db_page_link' => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'), |
|
318 | + EE_MAINTENANCE_ADMIN_URL), |
|
319 | + 'data_reset_page' => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'), |
|
320 | + EE_MAINTENANCE_ADMIN_URL), |
|
321 | + 'update_migration_script_page_link' => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'), |
|
322 | + EE_MAINTENANCE_ADMIN_URL), |
|
323 | + 'ultimate_db_state' => sprintf(__("EE%s", 'event_espresso'), |
|
324 | + espresso_version()), |
|
325 | + ) |
|
326 | + ); |
|
327 | + //make sure we have the form fields helper available. It usually is, but sometimes it isn't |
|
328 | + } |
|
329 | + $this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration |
|
330 | + //now render the migration options part, and put it in a variable |
|
331 | + $migration_options_template_file = apply_filters( |
|
332 | + 'FHEE__ee_migration_page__migration_options_template', |
|
333 | + EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php' |
|
334 | + ); |
|
335 | + $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true); |
|
336 | + $this->_template_args['migration_options_html'] = $migration_options_html; |
|
337 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path, |
|
338 | + $this->_template_args, true); |
|
339 | + $this->display_admin_page_with_sidebar(); |
|
340 | + } |
|
341 | + |
|
342 | + |
|
343 | + |
|
344 | + /** |
|
345 | + * returns JSON and executes another step of the currently-executing data migration (called via ajax) |
|
346 | + */ |
|
347 | + public function migration_step() |
|
348 | + { |
|
349 | + $this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request(); |
|
350 | + $this->_return_json(); |
|
351 | + } |
|
352 | + |
|
353 | + |
|
354 | + |
|
355 | + /** |
|
356 | + * Can be used by js when it notices a response with HTML in it in order |
|
357 | + * to log the malformed response |
|
358 | + */ |
|
359 | + public function add_error_to_migrations_ran() |
|
360 | + { |
|
361 | + EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']); |
|
362 | + $this->_template_args['data'] = array('ok' => true); |
|
363 | + $this->_return_json(); |
|
364 | + } |
|
365 | + |
|
366 | + |
|
367 | + |
|
368 | + /** |
|
369 | + * changes the maintenance level, provided there are still no migration scripts that should run |
|
370 | + */ |
|
371 | + public function _change_maintenance_level() |
|
372 | + { |
|
373 | + $new_level = absint($this->_req_data['maintenance_mode_level']); |
|
374 | + if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) { |
|
375 | + EE_Maintenance_Mode::instance()->set_maintenance_level($new_level); |
|
376 | + $success = true; |
|
377 | + } else { |
|
378 | + EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
379 | + $success = false; |
|
380 | + } |
|
381 | + $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso")); |
|
382 | + } |
|
383 | + |
|
384 | + |
|
385 | + |
|
386 | + /** |
|
387 | + * a tab with options for resetting and/or deleting EE data |
|
388 | + * |
|
389 | + * @throws \EE_Error |
|
390 | + * @throws \DomainException |
|
391 | + */ |
|
392 | + public function _data_reset_and_delete() |
|
393 | + { |
|
394 | + $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php'; |
|
395 | + $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button( |
|
396 | + 'reset_reservations', |
|
397 | + 'reset_reservations', |
|
398 | + array(), |
|
399 | + 'button button-primary ee-confirm', |
|
400 | + '', |
|
401 | + false |
|
402 | + ); |
|
403 | + $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button( |
|
404 | + 'reset_capabilities', |
|
405 | + 'reset_capabilities', |
|
406 | + array(), |
|
407 | + 'button button-primary ee-confirm', |
|
408 | + '', |
|
409 | + false |
|
410 | + ); |
|
411 | + $this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
412 | + array('action' => 'delete_db'), |
|
413 | + EE_MAINTENANCE_ADMIN_URL |
|
414 | + ); |
|
415 | + $this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
416 | + array('action' => 'reset_db'), |
|
417 | + EE_MAINTENANCE_ADMIN_URL |
|
418 | + ); |
|
419 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
420 | + $this->_template_path, |
|
421 | + $this->_template_args, |
|
422 | + true |
|
423 | + ); |
|
424 | + $this->display_admin_page_with_sidebar(); |
|
425 | + } |
|
426 | + |
|
427 | + |
|
428 | + |
|
429 | + protected function _reset_reservations() |
|
430 | + { |
|
431 | + if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) { |
|
432 | + EE_Error::add_success( |
|
433 | + __( |
|
434 | + 'Ticket and datetime reserved counts have been successfully reset.', |
|
435 | + 'event_espresso' |
|
436 | + ) |
|
437 | + ); |
|
438 | + } else { |
|
439 | + EE_Error::add_success( |
|
440 | + __( |
|
441 | + 'Ticket and datetime reserved counts were correct and did not need resetting.', |
|
442 | + 'event_espresso' |
|
443 | + ) |
|
444 | + ); |
|
445 | + } |
|
446 | + $this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true); |
|
447 | + } |
|
448 | + |
|
449 | + |
|
450 | + |
|
451 | + protected function _reset_capabilities() |
|
452 | + { |
|
453 | + EE_Registry::instance()->CAP->init_caps(true); |
|
454 | + EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.', |
|
455 | + 'event_espresso')); |
|
456 | + $this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true); |
|
457 | + } |
|
458 | + |
|
459 | + |
|
460 | + |
|
461 | + /** |
|
462 | + * resets the DMSs so we can attempt to continue migrating after a fatal error |
|
463 | + * (only a good idea when someone has somehow tried ot fix whatever caused |
|
464 | + * the fatal error in teh first place) |
|
465 | + */ |
|
466 | + protected function _reattempt_migration() |
|
467 | + { |
|
468 | + EE_Data_Migration_Manager::instance()->reattempt(); |
|
469 | + $this->_redirect_after_action(false, '', '', array('action' => 'default'), true); |
|
470 | + } |
|
471 | + |
|
472 | + |
|
473 | + |
|
474 | + /** |
|
475 | + * shows the big ol' System Information page |
|
476 | + */ |
|
477 | + public function _system_status() |
|
478 | + { |
|
479 | + $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php'; |
|
480 | + $this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati(); |
|
481 | + $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
482 | + array( |
|
483 | + 'action' => 'download_system_status', |
|
484 | + ), |
|
485 | + EE_MAINTENANCE_ADMIN_URL |
|
486 | + ); |
|
487 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path, |
|
488 | + $this->_template_args, true); |
|
489 | + $this->display_admin_page_with_sidebar(); |
|
490 | + } |
|
491 | + |
|
492 | + /** |
|
493 | + * Downloads an HTML file of the system status that can be easily stored or emailed |
|
494 | + */ |
|
495 | + public function _download_system_status() |
|
496 | + { |
|
497 | + $status_info = EEM_System_Status::instance()->get_system_stati(); |
|
498 | + header( 'Content-Disposition: attachment' ); |
|
499 | + header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" ); |
|
500 | + echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>"; |
|
501 | + echo "<h1>System Information for " . site_url() . "</h1>"; |
|
502 | + echo EEH_Template::layout_array_as_table( $status_info ); |
|
503 | + die; |
|
504 | + } |
|
505 | + |
|
506 | + |
|
507 | + |
|
508 | + public function _send_migration_crash_report() |
|
509 | + { |
|
510 | + $from = $this->_req_data['from']; |
|
511 | + $from_name = $this->_req_data['from_name']; |
|
512 | + $body = $this->_req_data['body']; |
|
513 | + try { |
|
514 | + $success = wp_mail(EE_SUPPORT_EMAIL, |
|
515 | + 'Migration Crash Report', |
|
516 | + $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true), |
|
517 | + array( |
|
518 | + "from:$from_name<$from>", |
|
519 | + // 'content-type:text/html charset=UTF-8' |
|
520 | + )); |
|
521 | + } catch (Exception $e) { |
|
522 | + $success = false; |
|
523 | + } |
|
524 | + $this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"), |
|
525 | + esc_html__("sent", "event_espresso"), |
|
526 | + array('success' => $success, 'action' => 'confirm_migration_crash_report_sent')); |
|
527 | + } |
|
528 | + |
|
529 | + |
|
530 | + |
|
531 | + public function _confirm_migration_crash_report_sent() |
|
532 | + { |
|
533 | + try { |
|
534 | + $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true); |
|
535 | + } catch (EE_Error $e) { |
|
536 | + EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage()); |
|
537 | + //now, just so we can display the page correctly, make a error migration script stage object |
|
538 | + //and also put the error on it. It only persists for the duration of this request |
|
539 | + $most_recent_migration = new EE_DMS_Unknown_1_0_0(); |
|
540 | + $most_recent_migration->add_error($e->getMessage()); |
|
541 | + } |
|
542 | + $success = $this->_req_data['success'] == '1' ? true : false; |
|
543 | + $this->_template_args['success'] = $success; |
|
544 | + $this->_template_args['most_recent_migration'] = $most_recent_migration; |
|
545 | + $this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'), |
|
546 | + EE_MAINTENANCE_ADMIN_URL); |
|
547 | + $this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'), |
|
548 | + EE_MAINTENANCE_ADMIN_URL); |
|
549 | + $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'), |
|
550 | + EE_MAINTENANCE_ADMIN_URL); |
|
551 | + $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php'; |
|
552 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path, |
|
553 | + $this->_template_args, true); |
|
554 | + $this->display_admin_page_with_sidebar(); |
|
555 | + } |
|
556 | + |
|
557 | + |
|
558 | + |
|
559 | + /** |
|
560 | + * Resets the entire EE4 database. |
|
561 | + * Currently basically only sets up ee4 database for a fresh install- doesn't |
|
562 | + * actually clean out the old wp options, or cpts (although does erase old ee table data) |
|
563 | + * |
|
564 | + * @param boolean $nuke_old_ee4_data controls whether or not we |
|
565 | + * destroy the old ee4 data, or just try initializing ee4 default data |
|
566 | + */ |
|
567 | + public function _reset_db($nuke_old_ee4_data = true) |
|
568 | + { |
|
569 | + EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance); |
|
570 | + if ($nuke_old_ee4_data) { |
|
571 | + EEH_Activation::delete_all_espresso_cpt_data(); |
|
572 | + EEH_Activation::delete_all_espresso_tables_and_data(false); |
|
573 | + EEH_Activation::remove_cron_tasks(); |
|
574 | + } |
|
575 | + //make sure when we reset the registry's config that it |
|
576 | + //switches to using the new singleton |
|
577 | + EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true); |
|
578 | + EE_System::instance()->initialize_db_if_no_migrations_required(true); |
|
579 | + EE_System::instance()->redirect_to_about_ee(); |
|
580 | + } |
|
581 | + |
|
582 | + |
|
583 | + |
|
584 | + /** |
|
585 | + * Deletes ALL EE tables, Records, and Options from the database. |
|
586 | + */ |
|
587 | + public function _delete_db() |
|
588 | + { |
|
589 | + EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance); |
|
590 | + EEH_Activation::delete_all_espresso_cpt_data(); |
|
591 | + EEH_Activation::delete_all_espresso_tables_and_data(); |
|
592 | + EEH_Activation::remove_cron_tasks(); |
|
593 | + EEH_Activation::deactivate_event_espresso(); |
|
594 | + wp_safe_redirect(admin_url('plugins.php')); |
|
595 | + exit; |
|
596 | + } |
|
597 | + |
|
598 | + |
|
599 | + |
|
600 | + /** |
|
601 | + * sets up EE4 to rerun the migrations from ee3 to ee4 |
|
602 | + */ |
|
603 | + public function _rerun_migration_from_ee3() |
|
604 | + { |
|
605 | + EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance); |
|
606 | + EEH_Activation::delete_all_espresso_cpt_data(); |
|
607 | + EEH_Activation::delete_all_espresso_tables_and_data(false); |
|
608 | + //set the db state to something that will require migrations |
|
609 | + update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0'); |
|
610 | + EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance); |
|
611 | + $this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso')); |
|
612 | + } |
|
613 | + |
|
614 | + |
|
615 | + |
|
616 | + //none of the below group are currently used for Gateway Settings |
|
617 | + protected function _add_screen_options() |
|
618 | + { |
|
619 | + } |
|
620 | + |
|
621 | + |
|
622 | + |
|
623 | + protected function _add_feature_pointers() |
|
624 | + { |
|
625 | + } |
|
626 | + |
|
627 | 627 | |
628 | 628 | |
629 | - public function admin_init() |
|
630 | - { |
|
631 | - } |
|
632 | - |
|
633 | - |
|
634 | - |
|
635 | - public function admin_notices() |
|
636 | - { |
|
637 | - } |
|
638 | - |
|
629 | + public function admin_init() |
|
630 | + { |
|
631 | + } |
|
632 | + |
|
633 | + |
|
634 | + |
|
635 | + public function admin_notices() |
|
636 | + { |
|
637 | + } |
|
638 | + |
|
639 | 639 | |
640 | 640 | |
641 | - public function admin_footer_scripts() |
|
642 | - { |
|
643 | - } |
|
641 | + public function admin_footer_scripts() |
|
642 | + { |
|
643 | + } |
|
644 | 644 | |
645 | 645 | |
646 | 646 | |
647 | - public function load_scripts_styles() |
|
648 | - { |
|
649 | - wp_enqueue_script('ee_admin_js'); |
|
647 | + public function load_scripts_styles() |
|
648 | + { |
|
649 | + wp_enqueue_script('ee_admin_js'); |
|
650 | 650 | // wp_enqueue_media(); |
651 | 651 | // wp_enqueue_script('media-upload'); |
652 | - wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'), |
|
653 | - EVENT_ESPRESSO_VERSION, true); |
|
654 | - wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(), |
|
655 | - EVENT_ESPRESSO_VERSION); |
|
656 | - wp_enqueue_style('espresso_maintenance'); |
|
657 | - //localize script stuff |
|
658 | - wp_localize_script('ee-maintenance', 'ee_maintenance', array( |
|
659 | - 'migrating' => esc_html__("Updating Database...", "event_espresso"), |
|
660 | - 'next' => esc_html__("Next", "event_espresso"), |
|
661 | - 'fatal_error' => esc_html__("A Fatal Error Has Occurred", "event_espresso"), |
|
662 | - 'click_next_when_ready' => esc_html__( |
|
663 | - "The current Database Update has ended. Click 'next' when ready to proceed", |
|
664 | - "event_espresso" |
|
665 | - ), |
|
666 | - 'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts, |
|
667 | - 'status_fatal_error' => EE_Data_Migration_Manager::status_fatal_error, |
|
668 | - 'status_completed' => EE_Data_Migration_Manager::status_completed, |
|
669 | - 'confirm' => esc_html__( |
|
670 | - 'Are you sure you want to do this? It CANNOT be undone!', |
|
671 | - 'event_espresso' |
|
672 | - ), |
|
673 | - 'confirm_skip_migration' => esc_html__( |
|
674 | - 'You have chosen to NOT migrate your existing data. Are you sure you want to continue?', |
|
675 | - 'event_espresso' |
|
676 | - ) |
|
677 | - )); |
|
678 | - } |
|
679 | - |
|
680 | - |
|
681 | - |
|
682 | - public function load_scripts_styles_default() |
|
683 | - { |
|
684 | - //styles |
|
652 | + wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'), |
|
653 | + EVENT_ESPRESSO_VERSION, true); |
|
654 | + wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(), |
|
655 | + EVENT_ESPRESSO_VERSION); |
|
656 | + wp_enqueue_style('espresso_maintenance'); |
|
657 | + //localize script stuff |
|
658 | + wp_localize_script('ee-maintenance', 'ee_maintenance', array( |
|
659 | + 'migrating' => esc_html__("Updating Database...", "event_espresso"), |
|
660 | + 'next' => esc_html__("Next", "event_espresso"), |
|
661 | + 'fatal_error' => esc_html__("A Fatal Error Has Occurred", "event_espresso"), |
|
662 | + 'click_next_when_ready' => esc_html__( |
|
663 | + "The current Database Update has ended. Click 'next' when ready to proceed", |
|
664 | + "event_espresso" |
|
665 | + ), |
|
666 | + 'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts, |
|
667 | + 'status_fatal_error' => EE_Data_Migration_Manager::status_fatal_error, |
|
668 | + 'status_completed' => EE_Data_Migration_Manager::status_completed, |
|
669 | + 'confirm' => esc_html__( |
|
670 | + 'Are you sure you want to do this? It CANNOT be undone!', |
|
671 | + 'event_espresso' |
|
672 | + ), |
|
673 | + 'confirm_skip_migration' => esc_html__( |
|
674 | + 'You have chosen to NOT migrate your existing data. Are you sure you want to continue?', |
|
675 | + 'event_espresso' |
|
676 | + ) |
|
677 | + )); |
|
678 | + } |
|
679 | + |
|
680 | + |
|
681 | + |
|
682 | + public function load_scripts_styles_default() |
|
683 | + { |
|
684 | + //styles |
|
685 | 685 | // wp_enqueue_style('ee-text-links'); |
686 | 686 | // //scripts |
687 | 687 | // wp_enqueue_script('ee-text-links'); |
688 | - } |
|
689 | - |
|
690 | - |
|
691 | - /** |
|
692 | - * Enqueue scripts and styles for the datetime tools page. |
|
693 | - */ |
|
694 | - public function load_scripts_styles_datetime_tools() |
|
695 | - { |
|
696 | - EE_Datepicker_Input::enqueue_styles_and_scripts(); |
|
697 | - } |
|
698 | - |
|
699 | - |
|
700 | - protected function _datetime_tools() |
|
701 | - { |
|
702 | - $form_action = EE_Admin_Page::add_query_args_and_nonce( |
|
703 | - array( |
|
704 | - 'action' => 'run_datetime_offset_fix', |
|
705 | - 'return_action' => $this->_req_action |
|
706 | - ), |
|
707 | - EE_MAINTENANCE_ADMIN_URL |
|
708 | - ); |
|
709 | - $form = $this->_get_datetime_offset_fix_form(); |
|
710 | - $this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso'); |
|
711 | - $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post') |
|
712 | - . $form->get_html_and_js() |
|
713 | - . $form->form_close(); |
|
714 | - $this->display_admin_page_with_no_sidebar(); |
|
715 | - } |
|
716 | - |
|
717 | - |
|
718 | - |
|
719 | - protected function _get_datetime_offset_fix_form() |
|
720 | - { |
|
721 | - if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) { |
|
722 | - $this->datetime_fix_offset_form = new EE_Form_Section_Proper( |
|
723 | - array( |
|
724 | - 'name' => 'datetime_offset_fix_option', |
|
725 | - 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
726 | - 'subsections' => array( |
|
727 | - 'title' => new EE_Form_Section_HTML( |
|
728 | - EEH_HTML::h2( |
|
729 | - esc_html__('Datetime Offset Tool', 'event_espresso') |
|
730 | - ) |
|
731 | - ), |
|
732 | - 'explanation' => new EE_Form_Section_HTML( |
|
733 | - EEH_HTML::p( |
|
734 | - esc_html__( |
|
735 | - 'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.', |
|
736 | - 'event_espresso' |
|
737 | - ) |
|
738 | - ) |
|
739 | - . EEH_HTML::p( |
|
740 | - esc_html__( |
|
741 | - 'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied. Decimals represent the fraction of hours, not minutes.', |
|
742 | - 'event_espresso' |
|
743 | - ) |
|
744 | - ) |
|
745 | - ), |
|
746 | - 'offset_input' => new EE_Float_Input( |
|
747 | - array( |
|
748 | - 'html_name' => 'offset_for_datetimes', |
|
749 | - 'html_label_text' => esc_html__( |
|
750 | - 'Offset to apply (in hours):', |
|
751 | - 'event_espresso' |
|
752 | - ), |
|
753 | - 'min_value' => '-12', |
|
754 | - 'max_value' => '14', |
|
755 | - 'step_value' => '.25', |
|
756 | - 'default' => DatetimeOffsetFix::getOffset() |
|
757 | - ) |
|
758 | - ), |
|
759 | - 'date_range_explanation' => new EE_Form_Section_HTML( |
|
760 | - EEH_HTML::p( |
|
761 | - esc_html__( |
|
762 | - 'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.', |
|
763 | - 'event_espresso' |
|
764 | - ) |
|
765 | - ) |
|
766 | - . EEH_HTML::p( |
|
767 | - EEH_HTML::strong( |
|
768 | - sprintf( |
|
769 | - esc_html__( |
|
770 | - 'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).', |
|
771 | - 'event_espresso' |
|
772 | - ), |
|
773 | - '<a href="https://www.timeanddate.com/worldclock/converter.html">', |
|
774 | - '</a>' |
|
775 | - ) |
|
776 | - ) |
|
777 | - ) |
|
778 | - ), |
|
779 | - 'date_range_start_date' => new EE_Datepicker_Input( |
|
780 | - array( |
|
781 | - 'html_name' => 'offset_date_start_range', |
|
782 | - 'html_label_text' => esc_html__( |
|
783 | - 'Start Date for dates the offset applied to:', |
|
784 | - 'event_espresso' |
|
785 | - ) |
|
786 | - ) |
|
787 | - ), |
|
788 | - 'date_range_end_date' => new EE_Datepicker_Input( |
|
789 | - array( |
|
790 | - 'html_name' => 'offset_date_end_range', |
|
791 | - 'html_label_text' => esc_html( |
|
792 | - 'End Date for dates the offset is applied to:', |
|
793 | - 'event_espresso' |
|
794 | - ) |
|
795 | - ) |
|
796 | - ), |
|
797 | - 'submit' => new EE_Submit_Input( |
|
798 | - array( |
|
799 | - 'html_label_text' => '', |
|
800 | - 'default' => esc_html__('Apply Offset', 'event_espresso') |
|
801 | - ) |
|
802 | - ), |
|
803 | - ) |
|
804 | - ) |
|
805 | - ); |
|
806 | - } |
|
807 | - return $this->datetime_fix_offset_form; |
|
808 | - } |
|
809 | - |
|
810 | - |
|
811 | - /** |
|
812 | - * Callback for the run_datetime_offset_fix route. |
|
813 | - * @throws EE_Error |
|
814 | - */ |
|
815 | - protected function _apply_datetime_offset() |
|
816 | - { |
|
817 | - if ($_SERVER['REQUEST_METHOD'] === 'POST') { |
|
818 | - $form = $this->_get_datetime_offset_fix_form(); |
|
819 | - $form->receive_form_submission($this->_req_data); |
|
820 | - if ($form->is_valid()) { |
|
821 | - //save offset data so batch processor can get it. |
|
822 | - DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input')); |
|
823 | - $utc_timezone = new DateTimeZone('UTC'); |
|
824 | - $date_range_start_date = DateTime::createFromFormat( |
|
825 | - 'm/d/Y H:i:s', |
|
826 | - $form->get_input_value('date_range_start_date') . ' 00:00:00', |
|
827 | - $utc_timezone |
|
828 | - ); |
|
829 | - $date_range_end_date = DateTime::createFromFormat( |
|
830 | - 'm/d/Y H:i:s', |
|
831 | - $form->get_input_value('date_range_end_date') . ' 23:59:59', |
|
832 | - $utc_timezone |
|
833 | - ); |
|
834 | - if ($date_range_start_date instanceof DateTime) { |
|
835 | - DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date)); |
|
836 | - } |
|
837 | - if ($date_range_end_date instanceof DateTime) { |
|
838 | - DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date)); |
|
839 | - } |
|
840 | - //redirect to batch tool |
|
841 | - wp_redirect( |
|
842 | - EE_Admin_Page::add_query_args_and_nonce( |
|
843 | - array( |
|
844 | - 'page' => 'espresso_batch', |
|
845 | - 'batch' => 'job', |
|
846 | - 'label' => esc_html__('Applying Offset', 'event_espresso'), |
|
847 | - 'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'), |
|
848 | - 'return_url' => urlencode( |
|
849 | - add_query_arg( |
|
850 | - array( |
|
851 | - 'action' => 'datetime_tools', |
|
852 | - ), |
|
853 | - EEH_URL::current_url_without_query_paramaters( |
|
854 | - array( |
|
855 | - 'return_action', |
|
856 | - 'run_datetime_offset_fix_nonce', |
|
857 | - 'return', |
|
858 | - 'datetime_tools_nonce' |
|
859 | - ) |
|
860 | - ) |
|
861 | - ) |
|
862 | - ) |
|
863 | - ), |
|
864 | - admin_url() |
|
865 | - ) |
|
866 | - ); |
|
867 | - exit; |
|
868 | - } |
|
869 | - } |
|
870 | - } |
|
688 | + } |
|
689 | + |
|
690 | + |
|
691 | + /** |
|
692 | + * Enqueue scripts and styles for the datetime tools page. |
|
693 | + */ |
|
694 | + public function load_scripts_styles_datetime_tools() |
|
695 | + { |
|
696 | + EE_Datepicker_Input::enqueue_styles_and_scripts(); |
|
697 | + } |
|
698 | + |
|
699 | + |
|
700 | + protected function _datetime_tools() |
|
701 | + { |
|
702 | + $form_action = EE_Admin_Page::add_query_args_and_nonce( |
|
703 | + array( |
|
704 | + 'action' => 'run_datetime_offset_fix', |
|
705 | + 'return_action' => $this->_req_action |
|
706 | + ), |
|
707 | + EE_MAINTENANCE_ADMIN_URL |
|
708 | + ); |
|
709 | + $form = $this->_get_datetime_offset_fix_form(); |
|
710 | + $this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso'); |
|
711 | + $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post') |
|
712 | + . $form->get_html_and_js() |
|
713 | + . $form->form_close(); |
|
714 | + $this->display_admin_page_with_no_sidebar(); |
|
715 | + } |
|
716 | + |
|
717 | + |
|
718 | + |
|
719 | + protected function _get_datetime_offset_fix_form() |
|
720 | + { |
|
721 | + if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) { |
|
722 | + $this->datetime_fix_offset_form = new EE_Form_Section_Proper( |
|
723 | + array( |
|
724 | + 'name' => 'datetime_offset_fix_option', |
|
725 | + 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
726 | + 'subsections' => array( |
|
727 | + 'title' => new EE_Form_Section_HTML( |
|
728 | + EEH_HTML::h2( |
|
729 | + esc_html__('Datetime Offset Tool', 'event_espresso') |
|
730 | + ) |
|
731 | + ), |
|
732 | + 'explanation' => new EE_Form_Section_HTML( |
|
733 | + EEH_HTML::p( |
|
734 | + esc_html__( |
|
735 | + 'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.', |
|
736 | + 'event_espresso' |
|
737 | + ) |
|
738 | + ) |
|
739 | + . EEH_HTML::p( |
|
740 | + esc_html__( |
|
741 | + 'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied. Decimals represent the fraction of hours, not minutes.', |
|
742 | + 'event_espresso' |
|
743 | + ) |
|
744 | + ) |
|
745 | + ), |
|
746 | + 'offset_input' => new EE_Float_Input( |
|
747 | + array( |
|
748 | + 'html_name' => 'offset_for_datetimes', |
|
749 | + 'html_label_text' => esc_html__( |
|
750 | + 'Offset to apply (in hours):', |
|
751 | + 'event_espresso' |
|
752 | + ), |
|
753 | + 'min_value' => '-12', |
|
754 | + 'max_value' => '14', |
|
755 | + 'step_value' => '.25', |
|
756 | + 'default' => DatetimeOffsetFix::getOffset() |
|
757 | + ) |
|
758 | + ), |
|
759 | + 'date_range_explanation' => new EE_Form_Section_HTML( |
|
760 | + EEH_HTML::p( |
|
761 | + esc_html__( |
|
762 | + 'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.', |
|
763 | + 'event_espresso' |
|
764 | + ) |
|
765 | + ) |
|
766 | + . EEH_HTML::p( |
|
767 | + EEH_HTML::strong( |
|
768 | + sprintf( |
|
769 | + esc_html__( |
|
770 | + 'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).', |
|
771 | + 'event_espresso' |
|
772 | + ), |
|
773 | + '<a href="https://www.timeanddate.com/worldclock/converter.html">', |
|
774 | + '</a>' |
|
775 | + ) |
|
776 | + ) |
|
777 | + ) |
|
778 | + ), |
|
779 | + 'date_range_start_date' => new EE_Datepicker_Input( |
|
780 | + array( |
|
781 | + 'html_name' => 'offset_date_start_range', |
|
782 | + 'html_label_text' => esc_html__( |
|
783 | + 'Start Date for dates the offset applied to:', |
|
784 | + 'event_espresso' |
|
785 | + ) |
|
786 | + ) |
|
787 | + ), |
|
788 | + 'date_range_end_date' => new EE_Datepicker_Input( |
|
789 | + array( |
|
790 | + 'html_name' => 'offset_date_end_range', |
|
791 | + 'html_label_text' => esc_html( |
|
792 | + 'End Date for dates the offset is applied to:', |
|
793 | + 'event_espresso' |
|
794 | + ) |
|
795 | + ) |
|
796 | + ), |
|
797 | + 'submit' => new EE_Submit_Input( |
|
798 | + array( |
|
799 | + 'html_label_text' => '', |
|
800 | + 'default' => esc_html__('Apply Offset', 'event_espresso') |
|
801 | + ) |
|
802 | + ), |
|
803 | + ) |
|
804 | + ) |
|
805 | + ); |
|
806 | + } |
|
807 | + return $this->datetime_fix_offset_form; |
|
808 | + } |
|
809 | + |
|
810 | + |
|
811 | + /** |
|
812 | + * Callback for the run_datetime_offset_fix route. |
|
813 | + * @throws EE_Error |
|
814 | + */ |
|
815 | + protected function _apply_datetime_offset() |
|
816 | + { |
|
817 | + if ($_SERVER['REQUEST_METHOD'] === 'POST') { |
|
818 | + $form = $this->_get_datetime_offset_fix_form(); |
|
819 | + $form->receive_form_submission($this->_req_data); |
|
820 | + if ($form->is_valid()) { |
|
821 | + //save offset data so batch processor can get it. |
|
822 | + DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input')); |
|
823 | + $utc_timezone = new DateTimeZone('UTC'); |
|
824 | + $date_range_start_date = DateTime::createFromFormat( |
|
825 | + 'm/d/Y H:i:s', |
|
826 | + $form->get_input_value('date_range_start_date') . ' 00:00:00', |
|
827 | + $utc_timezone |
|
828 | + ); |
|
829 | + $date_range_end_date = DateTime::createFromFormat( |
|
830 | + 'm/d/Y H:i:s', |
|
831 | + $form->get_input_value('date_range_end_date') . ' 23:59:59', |
|
832 | + $utc_timezone |
|
833 | + ); |
|
834 | + if ($date_range_start_date instanceof DateTime) { |
|
835 | + DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date)); |
|
836 | + } |
|
837 | + if ($date_range_end_date instanceof DateTime) { |
|
838 | + DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date)); |
|
839 | + } |
|
840 | + //redirect to batch tool |
|
841 | + wp_redirect( |
|
842 | + EE_Admin_Page::add_query_args_and_nonce( |
|
843 | + array( |
|
844 | + 'page' => 'espresso_batch', |
|
845 | + 'batch' => 'job', |
|
846 | + 'label' => esc_html__('Applying Offset', 'event_espresso'), |
|
847 | + 'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'), |
|
848 | + 'return_url' => urlencode( |
|
849 | + add_query_arg( |
|
850 | + array( |
|
851 | + 'action' => 'datetime_tools', |
|
852 | + ), |
|
853 | + EEH_URL::current_url_without_query_paramaters( |
|
854 | + array( |
|
855 | + 'return_action', |
|
856 | + 'run_datetime_offset_fix_nonce', |
|
857 | + 'return', |
|
858 | + 'datetime_tools_nonce' |
|
859 | + ) |
|
860 | + ) |
|
861 | + ) |
|
862 | + ) |
|
863 | + ), |
|
864 | + admin_url() |
|
865 | + ) |
|
866 | + ); |
|
867 | + exit; |
|
868 | + } |
|
869 | + } |
|
870 | + } |
|
871 | 871 | } //end Maintenance_Admin_Page class |
@@ -22,454 +22,454 @@ discard block |
||
22 | 22 | final class EE_Admin implements InterminableInterface |
23 | 23 | { |
24 | 24 | |
25 | - /** |
|
26 | - * @var EE_Admin $_instance |
|
27 | - */ |
|
28 | - private static $_instance; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var PersistentAdminNoticeManager $persistent_admin_notice_manager |
|
32 | - */ |
|
33 | - private $persistent_admin_notice_manager; |
|
34 | - |
|
35 | - /** |
|
36 | - * @singleton method used to instantiate class object |
|
37 | - * @return EE_Admin |
|
38 | - * @throws EE_Error |
|
39 | - */ |
|
40 | - public static function instance() |
|
41 | - { |
|
42 | - // check if class object is instantiated |
|
43 | - if (! self::$_instance instanceof EE_Admin) { |
|
44 | - self::$_instance = new self(); |
|
45 | - } |
|
46 | - return self::$_instance; |
|
47 | - } |
|
48 | - |
|
49 | - |
|
50 | - /** |
|
51 | - * @return EE_Admin |
|
52 | - * @throws EE_Error |
|
53 | - */ |
|
54 | - public static function reset() |
|
55 | - { |
|
56 | - self::$_instance = null; |
|
57 | - return self::instance(); |
|
58 | - } |
|
59 | - |
|
60 | - |
|
61 | - /** |
|
62 | - * class constructor |
|
63 | - * |
|
64 | - * @throws EE_Error |
|
65 | - * @throws InvalidDataTypeException |
|
66 | - * @throws InvalidInterfaceException |
|
67 | - * @throws InvalidArgumentException |
|
68 | - */ |
|
69 | - protected function __construct() |
|
70 | - { |
|
71 | - // define global EE_Admin constants |
|
72 | - $this->_define_all_constants(); |
|
73 | - // set autoloaders for our admin page classes based on included path information |
|
74 | - EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_ADMIN); |
|
75 | - // admin hooks |
|
76 | - add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2); |
|
77 | - // load EE_Request_Handler early |
|
78 | - add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'get_request')); |
|
79 | - add_action('AHEE__EE_System__initialize_last', array($this, 'init')); |
|
80 | - add_action('AHEE__EE_Admin_Page__route_admin_request', array($this, 'route_admin_request'), 100, 2); |
|
81 | - add_action('wp_loaded', array($this, 'wp_loaded'), 100); |
|
82 | - add_action('admin_init', array($this, 'admin_init'), 100); |
|
83 | - add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20); |
|
84 | - add_action('admin_notices', array($this, 'display_admin_notices'), 10); |
|
85 | - add_action('network_admin_notices', array($this, 'display_admin_notices'), 10); |
|
86 | - add_filter('pre_update_option', array($this, 'check_for_invalid_datetime_formats'), 100, 2); |
|
87 | - add_filter('admin_footer_text', array($this, 'espresso_admin_footer')); |
|
88 | - //reset Environment config (we only do this on admin page loads); |
|
89 | - EE_Registry::instance()->CFG->environment->recheck_values(); |
|
90 | - do_action('AHEE__EE_Admin__loaded'); |
|
91 | - } |
|
92 | - |
|
93 | - |
|
94 | - |
|
95 | - /** |
|
96 | - * _define_all_constants |
|
97 | - * define constants that are set globally for all admin pages |
|
98 | - * |
|
99 | - * @return void |
|
100 | - */ |
|
101 | - private function _define_all_constants() |
|
102 | - { |
|
103 | - if (! defined('EE_ADMIN_URL')) { |
|
104 | - define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/'); |
|
105 | - define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/'); |
|
106 | - define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS); |
|
107 | - define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/'); |
|
108 | - define('WP_AJAX_URL', admin_url('admin-ajax.php')); |
|
109 | - } |
|
110 | - } |
|
111 | - |
|
112 | - |
|
113 | - /** |
|
114 | - * filter_plugin_actions - adds links to the Plugins page listing |
|
115 | - * |
|
116 | - * @param array $links |
|
117 | - * @param string $plugin |
|
118 | - * @return array |
|
119 | - */ |
|
120 | - public function filter_plugin_actions($links, $plugin) |
|
121 | - { |
|
122 | - // set $main_file in stone |
|
123 | - static $main_file; |
|
124 | - // if $main_file is not set yet |
|
125 | - if (! $main_file) { |
|
126 | - $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE); |
|
127 | - } |
|
128 | - if ($plugin === $main_file) { |
|
129 | - // compare current plugin to this one |
|
130 | - if (EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
131 | - $maintenance_link = '<a href="admin.php?page=espresso_maintenance_settings"' |
|
132 | - . ' title="Event Espresso is in maintenance mode. Click this link to learn why.">' |
|
133 | - . esc_html__('Maintenance Mode Active', 'event_espresso') |
|
134 | - . '</a>'; |
|
135 | - array_unshift($links, $maintenance_link); |
|
136 | - } else { |
|
137 | - $org_settings_link = '<a href="admin.php?page=espresso_general_settings">' |
|
138 | - . esc_html__('Settings', 'event_espresso') |
|
139 | - . '</a>'; |
|
140 | - $events_link = '<a href="admin.php?page=espresso_events">' |
|
141 | - . esc_html__('Events', 'event_espresso') |
|
142 | - . '</a>'; |
|
143 | - // add before other links |
|
144 | - array_unshift($links, $org_settings_link, $events_link); |
|
145 | - } |
|
146 | - } |
|
147 | - return $links; |
|
148 | - } |
|
149 | - |
|
150 | - |
|
151 | - /** |
|
152 | - * _get_request |
|
153 | - * |
|
154 | - * @return void |
|
155 | - * @throws EE_Error |
|
156 | - * @throws InvalidArgumentException |
|
157 | - * @throws InvalidDataTypeException |
|
158 | - * @throws InvalidInterfaceException |
|
159 | - * @throws ReflectionException |
|
160 | - */ |
|
161 | - public function get_request() |
|
162 | - { |
|
163 | - EE_Registry::instance()->load_core('Request_Handler'); |
|
164 | - EE_Registry::instance()->load_core('CPT_Strategy'); |
|
165 | - } |
|
166 | - |
|
167 | - |
|
168 | - |
|
169 | - /** |
|
170 | - * hide_admin_pages_except_maintenance_mode |
|
171 | - * |
|
172 | - * @param array $admin_page_folder_names |
|
173 | - * @return array |
|
174 | - */ |
|
175 | - public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array()) |
|
176 | - { |
|
177 | - return array( |
|
178 | - 'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS, |
|
179 | - 'about' => EE_ADMIN_PAGES . 'about' . DS, |
|
180 | - 'support' => EE_ADMIN_PAGES . 'support' . DS, |
|
181 | - ); |
|
182 | - } |
|
183 | - |
|
184 | - |
|
185 | - |
|
186 | - /** |
|
187 | - * init- should fire after shortcode, module, addon, other plugin (default priority), and even |
|
188 | - * EE_Front_Controller's init phases have run |
|
189 | - * |
|
190 | - * @return void |
|
191 | - * @throws EE_Error |
|
192 | - * @throws InvalidArgumentException |
|
193 | - * @throws InvalidDataTypeException |
|
194 | - * @throws InvalidInterfaceException |
|
195 | - * @throws ReflectionException |
|
196 | - * @throws ServiceNotFoundException |
|
197 | - */ |
|
198 | - public function init() |
|
199 | - { |
|
200 | - //only enable most of the EE_Admin IF we're not in full maintenance mode |
|
201 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
202 | - //ok so we want to enable the entire admin |
|
203 | - $this->persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared( |
|
204 | - 'EventEspresso\core\services\notifications\PersistentAdminNoticeManager', |
|
205 | - array( |
|
206 | - EE_Admin_Page::add_query_args_and_nonce( |
|
207 | - array( |
|
208 | - 'page' => EE_Registry::instance()->REQ->get('page', ''), |
|
209 | - 'action' => EE_Registry::instance()->REQ->get('action', ''), |
|
210 | - ), |
|
211 | - EE_ADMIN_URL |
|
212 | - ), |
|
213 | - ) |
|
214 | - ); |
|
215 | - $this->maybeSetDatetimeWarningNotice(); |
|
216 | - //at a glance dashboard widget |
|
217 | - add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10); |
|
218 | - //filter for get_edit_post_link used on comments for custom post types |
|
219 | - add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2); |
|
220 | - } |
|
221 | - // run the admin page factory but ONLY if we are doing an ee admin ajax request |
|
222 | - if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
223 | - try { |
|
224 | - //this loads the controller for the admin pages which will setup routing etc |
|
225 | - EE_Registry::instance()->load_core('Admin_Page_Loader'); |
|
226 | - } catch (EE_Error $e) { |
|
227 | - $e->get_error(); |
|
228 | - } |
|
229 | - } |
|
230 | - add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1); |
|
231 | - //make sure our CPTs and custom taxonomy metaboxes get shown for first time users |
|
232 | - add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10); |
|
233 | - add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10); |
|
234 | - //exclude EE critical pages from all nav menus and wp_list_pages |
|
235 | - add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10); |
|
236 | - } |
|
237 | - |
|
238 | - |
|
239 | - /** |
|
240 | - * get_persistent_admin_notices |
|
241 | - * |
|
242 | - * @access public |
|
243 | - * @return void |
|
244 | - * @throws EE_Error |
|
245 | - * @throws InvalidArgumentException |
|
246 | - * @throws InvalidDataTypeException |
|
247 | - * @throws InvalidInterfaceException |
|
248 | - */ |
|
249 | - public function maybeSetDatetimeWarningNotice() |
|
250 | - { |
|
251 | - //add dismissable notice for datetime changes. Only valid if site does not have a timezone_string set. |
|
252 | - //@todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version |
|
253 | - //with this. But after enough time (indeterminate at this point) we can just remove this notice. |
|
254 | - //this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626 |
|
255 | - if (! get_option('timezone_string') && EEM_Event::instance()->count() > 0) { |
|
256 | - new PersistentAdminNotice( |
|
257 | - 'datetime_fix_notice', |
|
258 | - sprintf( |
|
259 | - esc_html__( |
|
260 | - '%1$sImportant announcement related to your install of Event Espresso%2$s: There are some changes made to your site that could affect how dates display for your events and other related items with dates and times. Read more about it %3$shere%4$s. If your dates and times are displaying incorrectly (incorrect offset), you can fix it using the tool on %5$sthis page%4$s.', |
|
261 | - 'event_espresso' |
|
262 | - ), |
|
263 | - '<strong>', |
|
264 | - '</strong>', |
|
265 | - '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">', |
|
266 | - '</a>', |
|
267 | - '<a href="' . EE_Admin_Page::add_query_args_and_nonce( |
|
268 | - array( |
|
269 | - 'page' => 'espresso_maintenance_settings', |
|
270 | - 'action' => 'datetime_tools' |
|
271 | - ), |
|
272 | - admin_url('admin.php') |
|
273 | - ) . '">' |
|
274 | - ), |
|
275 | - false, |
|
276 | - 'manage_options', |
|
277 | - 'datetime_fix_persistent_notice' |
|
278 | - ); |
|
279 | - } |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - |
|
284 | - /** |
|
285 | - * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from |
|
286 | - * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in |
|
287 | - * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that |
|
288 | - * to override any queries found in the existing query for the given post type. Note that _default_query is not a |
|
289 | - * normal property on the post_type object. It's found ONLY in this particular context. |
|
290 | - * |
|
291 | - * @param WP_Post $post_type WP post type object |
|
292 | - * @return WP_Post |
|
293 | - * @throws InvalidArgumentException |
|
294 | - * @throws InvalidDataTypeException |
|
295 | - * @throws InvalidInterfaceException |
|
296 | - */ |
|
297 | - public function remove_pages_from_nav_menu($post_type) |
|
298 | - { |
|
299 | - //if this isn't the "pages" post type let's get out |
|
300 | - if ($post_type->name !== 'page') { |
|
301 | - return $post_type; |
|
302 | - } |
|
303 | - $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
304 | - $post_type->_default_query = array( |
|
305 | - 'post__not_in' => $critical_pages, |
|
306 | - ); |
|
307 | - return $post_type; |
|
308 | - } |
|
309 | - |
|
310 | - |
|
311 | - |
|
312 | - /** |
|
313 | - * WP by default only shows three metaboxes in "nav-menus.php" for first times users. We want to make sure our |
|
314 | - * metaboxes get shown as well |
|
315 | - * |
|
316 | - * @return void |
|
317 | - */ |
|
318 | - public function enable_hidden_ee_nav_menu_metaboxes() |
|
319 | - { |
|
320 | - global $wp_meta_boxes, $pagenow; |
|
321 | - if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
322 | - return; |
|
323 | - } |
|
324 | - $user = wp_get_current_user(); |
|
325 | - //has this been done yet? |
|
326 | - if (get_user_option('ee_nav_menu_initialized', $user->ID)) { |
|
327 | - return; |
|
328 | - } |
|
329 | - |
|
330 | - $hidden_meta_boxes = get_user_option('metaboxhidden_nav-menus', $user->ID); |
|
331 | - $initial_meta_boxes = apply_filters( |
|
332 | - 'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes', |
|
333 | - array( |
|
334 | - 'nav-menu-theme-locations', |
|
335 | - 'add-page', |
|
336 | - 'add-custom-links', |
|
337 | - 'add-category', |
|
338 | - 'add-espresso_events', |
|
339 | - 'add-espresso_venues', |
|
340 | - 'add-espresso_event_categories', |
|
341 | - 'add-espresso_venue_categories', |
|
342 | - 'add-post-type-post', |
|
343 | - 'add-post-type-page', |
|
344 | - ) |
|
345 | - ); |
|
346 | - |
|
347 | - if (is_array($hidden_meta_boxes)) { |
|
348 | - foreach ($hidden_meta_boxes as $key => $meta_box_id) { |
|
349 | - if (in_array($meta_box_id, $initial_meta_boxes, true)) { |
|
350 | - unset($hidden_meta_boxes[$key]); |
|
351 | - } |
|
352 | - } |
|
353 | - } |
|
354 | - update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true); |
|
355 | - update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true); |
|
356 | - } |
|
357 | - |
|
358 | - |
|
359 | - |
|
360 | - /** |
|
361 | - * This method simply registers custom nav menu boxes for "nav_menus.php route" |
|
362 | - * Currently EE is using this to make sure there are menu options for our CPT archive page routes. |
|
363 | - * |
|
364 | - * @todo modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by |
|
365 | - * addons etc. |
|
366 | - * @return void |
|
367 | - */ |
|
368 | - public function register_custom_nav_menu_boxes() |
|
369 | - { |
|
370 | - add_meta_box( |
|
371 | - 'add-extra-nav-menu-pages', |
|
372 | - esc_html__('Event Espresso Pages', 'event_espresso'), |
|
373 | - array($this, 'ee_cpt_archive_pages'), |
|
374 | - 'nav-menus', |
|
375 | - 'side', |
|
376 | - 'core' |
|
377 | - ); |
|
378 | - } |
|
379 | - |
|
380 | - |
|
381 | - |
|
382 | - /** |
|
383 | - * Use this to edit the post link for our cpts so that the edit link points to the correct page. |
|
384 | - * |
|
385 | - * @since 4.3.0 |
|
386 | - * @param string $link the original link generated by wp |
|
387 | - * @param int $id post id |
|
388 | - * @return string the (maybe) modified link |
|
389 | - */ |
|
390 | - public function modify_edit_post_link($link, $id) |
|
391 | - { |
|
392 | - if (! $post = get_post($id)) { |
|
393 | - return $link; |
|
394 | - } |
|
395 | - if ($post->post_type === 'espresso_attendees') { |
|
396 | - $query_args = array( |
|
397 | - 'action' => 'edit_attendee', |
|
398 | - 'post' => $id, |
|
399 | - ); |
|
400 | - return EEH_URL::add_query_args_and_nonce( |
|
401 | - $query_args, |
|
402 | - admin_url('admin.php?page=espresso_registrations') |
|
403 | - ); |
|
404 | - } |
|
405 | - return $link; |
|
406 | - } |
|
407 | - |
|
408 | - |
|
409 | - |
|
410 | - public function ee_cpt_archive_pages() |
|
411 | - { |
|
412 | - global $nav_menu_selected_id; |
|
413 | - $db_fields = false; |
|
414 | - $walker = new Walker_Nav_Menu_Checklist($db_fields); |
|
415 | - $current_tab = 'event-archives'; |
|
416 | - $removed_args = array( |
|
417 | - 'action', |
|
418 | - 'customlink-tab', |
|
419 | - 'edit-menu-item', |
|
420 | - 'menu-item', |
|
421 | - 'page-tab', |
|
422 | - '_wpnonce', |
|
423 | - ); |
|
424 | - ?> |
|
25 | + /** |
|
26 | + * @var EE_Admin $_instance |
|
27 | + */ |
|
28 | + private static $_instance; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var PersistentAdminNoticeManager $persistent_admin_notice_manager |
|
32 | + */ |
|
33 | + private $persistent_admin_notice_manager; |
|
34 | + |
|
35 | + /** |
|
36 | + * @singleton method used to instantiate class object |
|
37 | + * @return EE_Admin |
|
38 | + * @throws EE_Error |
|
39 | + */ |
|
40 | + public static function instance() |
|
41 | + { |
|
42 | + // check if class object is instantiated |
|
43 | + if (! self::$_instance instanceof EE_Admin) { |
|
44 | + self::$_instance = new self(); |
|
45 | + } |
|
46 | + return self::$_instance; |
|
47 | + } |
|
48 | + |
|
49 | + |
|
50 | + /** |
|
51 | + * @return EE_Admin |
|
52 | + * @throws EE_Error |
|
53 | + */ |
|
54 | + public static function reset() |
|
55 | + { |
|
56 | + self::$_instance = null; |
|
57 | + return self::instance(); |
|
58 | + } |
|
59 | + |
|
60 | + |
|
61 | + /** |
|
62 | + * class constructor |
|
63 | + * |
|
64 | + * @throws EE_Error |
|
65 | + * @throws InvalidDataTypeException |
|
66 | + * @throws InvalidInterfaceException |
|
67 | + * @throws InvalidArgumentException |
|
68 | + */ |
|
69 | + protected function __construct() |
|
70 | + { |
|
71 | + // define global EE_Admin constants |
|
72 | + $this->_define_all_constants(); |
|
73 | + // set autoloaders for our admin page classes based on included path information |
|
74 | + EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_ADMIN); |
|
75 | + // admin hooks |
|
76 | + add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2); |
|
77 | + // load EE_Request_Handler early |
|
78 | + add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'get_request')); |
|
79 | + add_action('AHEE__EE_System__initialize_last', array($this, 'init')); |
|
80 | + add_action('AHEE__EE_Admin_Page__route_admin_request', array($this, 'route_admin_request'), 100, 2); |
|
81 | + add_action('wp_loaded', array($this, 'wp_loaded'), 100); |
|
82 | + add_action('admin_init', array($this, 'admin_init'), 100); |
|
83 | + add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20); |
|
84 | + add_action('admin_notices', array($this, 'display_admin_notices'), 10); |
|
85 | + add_action('network_admin_notices', array($this, 'display_admin_notices'), 10); |
|
86 | + add_filter('pre_update_option', array($this, 'check_for_invalid_datetime_formats'), 100, 2); |
|
87 | + add_filter('admin_footer_text', array($this, 'espresso_admin_footer')); |
|
88 | + //reset Environment config (we only do this on admin page loads); |
|
89 | + EE_Registry::instance()->CFG->environment->recheck_values(); |
|
90 | + do_action('AHEE__EE_Admin__loaded'); |
|
91 | + } |
|
92 | + |
|
93 | + |
|
94 | + |
|
95 | + /** |
|
96 | + * _define_all_constants |
|
97 | + * define constants that are set globally for all admin pages |
|
98 | + * |
|
99 | + * @return void |
|
100 | + */ |
|
101 | + private function _define_all_constants() |
|
102 | + { |
|
103 | + if (! defined('EE_ADMIN_URL')) { |
|
104 | + define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/'); |
|
105 | + define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/'); |
|
106 | + define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS); |
|
107 | + define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/'); |
|
108 | + define('WP_AJAX_URL', admin_url('admin-ajax.php')); |
|
109 | + } |
|
110 | + } |
|
111 | + |
|
112 | + |
|
113 | + /** |
|
114 | + * filter_plugin_actions - adds links to the Plugins page listing |
|
115 | + * |
|
116 | + * @param array $links |
|
117 | + * @param string $plugin |
|
118 | + * @return array |
|
119 | + */ |
|
120 | + public function filter_plugin_actions($links, $plugin) |
|
121 | + { |
|
122 | + // set $main_file in stone |
|
123 | + static $main_file; |
|
124 | + // if $main_file is not set yet |
|
125 | + if (! $main_file) { |
|
126 | + $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE); |
|
127 | + } |
|
128 | + if ($plugin === $main_file) { |
|
129 | + // compare current plugin to this one |
|
130 | + if (EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
131 | + $maintenance_link = '<a href="admin.php?page=espresso_maintenance_settings"' |
|
132 | + . ' title="Event Espresso is in maintenance mode. Click this link to learn why.">' |
|
133 | + . esc_html__('Maintenance Mode Active', 'event_espresso') |
|
134 | + . '</a>'; |
|
135 | + array_unshift($links, $maintenance_link); |
|
136 | + } else { |
|
137 | + $org_settings_link = '<a href="admin.php?page=espresso_general_settings">' |
|
138 | + . esc_html__('Settings', 'event_espresso') |
|
139 | + . '</a>'; |
|
140 | + $events_link = '<a href="admin.php?page=espresso_events">' |
|
141 | + . esc_html__('Events', 'event_espresso') |
|
142 | + . '</a>'; |
|
143 | + // add before other links |
|
144 | + array_unshift($links, $org_settings_link, $events_link); |
|
145 | + } |
|
146 | + } |
|
147 | + return $links; |
|
148 | + } |
|
149 | + |
|
150 | + |
|
151 | + /** |
|
152 | + * _get_request |
|
153 | + * |
|
154 | + * @return void |
|
155 | + * @throws EE_Error |
|
156 | + * @throws InvalidArgumentException |
|
157 | + * @throws InvalidDataTypeException |
|
158 | + * @throws InvalidInterfaceException |
|
159 | + * @throws ReflectionException |
|
160 | + */ |
|
161 | + public function get_request() |
|
162 | + { |
|
163 | + EE_Registry::instance()->load_core('Request_Handler'); |
|
164 | + EE_Registry::instance()->load_core('CPT_Strategy'); |
|
165 | + } |
|
166 | + |
|
167 | + |
|
168 | + |
|
169 | + /** |
|
170 | + * hide_admin_pages_except_maintenance_mode |
|
171 | + * |
|
172 | + * @param array $admin_page_folder_names |
|
173 | + * @return array |
|
174 | + */ |
|
175 | + public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array()) |
|
176 | + { |
|
177 | + return array( |
|
178 | + 'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS, |
|
179 | + 'about' => EE_ADMIN_PAGES . 'about' . DS, |
|
180 | + 'support' => EE_ADMIN_PAGES . 'support' . DS, |
|
181 | + ); |
|
182 | + } |
|
183 | + |
|
184 | + |
|
185 | + |
|
186 | + /** |
|
187 | + * init- should fire after shortcode, module, addon, other plugin (default priority), and even |
|
188 | + * EE_Front_Controller's init phases have run |
|
189 | + * |
|
190 | + * @return void |
|
191 | + * @throws EE_Error |
|
192 | + * @throws InvalidArgumentException |
|
193 | + * @throws InvalidDataTypeException |
|
194 | + * @throws InvalidInterfaceException |
|
195 | + * @throws ReflectionException |
|
196 | + * @throws ServiceNotFoundException |
|
197 | + */ |
|
198 | + public function init() |
|
199 | + { |
|
200 | + //only enable most of the EE_Admin IF we're not in full maintenance mode |
|
201 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
202 | + //ok so we want to enable the entire admin |
|
203 | + $this->persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared( |
|
204 | + 'EventEspresso\core\services\notifications\PersistentAdminNoticeManager', |
|
205 | + array( |
|
206 | + EE_Admin_Page::add_query_args_and_nonce( |
|
207 | + array( |
|
208 | + 'page' => EE_Registry::instance()->REQ->get('page', ''), |
|
209 | + 'action' => EE_Registry::instance()->REQ->get('action', ''), |
|
210 | + ), |
|
211 | + EE_ADMIN_URL |
|
212 | + ), |
|
213 | + ) |
|
214 | + ); |
|
215 | + $this->maybeSetDatetimeWarningNotice(); |
|
216 | + //at a glance dashboard widget |
|
217 | + add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10); |
|
218 | + //filter for get_edit_post_link used on comments for custom post types |
|
219 | + add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2); |
|
220 | + } |
|
221 | + // run the admin page factory but ONLY if we are doing an ee admin ajax request |
|
222 | + if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
223 | + try { |
|
224 | + //this loads the controller for the admin pages which will setup routing etc |
|
225 | + EE_Registry::instance()->load_core('Admin_Page_Loader'); |
|
226 | + } catch (EE_Error $e) { |
|
227 | + $e->get_error(); |
|
228 | + } |
|
229 | + } |
|
230 | + add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1); |
|
231 | + //make sure our CPTs and custom taxonomy metaboxes get shown for first time users |
|
232 | + add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10); |
|
233 | + add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10); |
|
234 | + //exclude EE critical pages from all nav menus and wp_list_pages |
|
235 | + add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10); |
|
236 | + } |
|
237 | + |
|
238 | + |
|
239 | + /** |
|
240 | + * get_persistent_admin_notices |
|
241 | + * |
|
242 | + * @access public |
|
243 | + * @return void |
|
244 | + * @throws EE_Error |
|
245 | + * @throws InvalidArgumentException |
|
246 | + * @throws InvalidDataTypeException |
|
247 | + * @throws InvalidInterfaceException |
|
248 | + */ |
|
249 | + public function maybeSetDatetimeWarningNotice() |
|
250 | + { |
|
251 | + //add dismissable notice for datetime changes. Only valid if site does not have a timezone_string set. |
|
252 | + //@todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version |
|
253 | + //with this. But after enough time (indeterminate at this point) we can just remove this notice. |
|
254 | + //this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626 |
|
255 | + if (! get_option('timezone_string') && EEM_Event::instance()->count() > 0) { |
|
256 | + new PersistentAdminNotice( |
|
257 | + 'datetime_fix_notice', |
|
258 | + sprintf( |
|
259 | + esc_html__( |
|
260 | + '%1$sImportant announcement related to your install of Event Espresso%2$s: There are some changes made to your site that could affect how dates display for your events and other related items with dates and times. Read more about it %3$shere%4$s. If your dates and times are displaying incorrectly (incorrect offset), you can fix it using the tool on %5$sthis page%4$s.', |
|
261 | + 'event_espresso' |
|
262 | + ), |
|
263 | + '<strong>', |
|
264 | + '</strong>', |
|
265 | + '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">', |
|
266 | + '</a>', |
|
267 | + '<a href="' . EE_Admin_Page::add_query_args_and_nonce( |
|
268 | + array( |
|
269 | + 'page' => 'espresso_maintenance_settings', |
|
270 | + 'action' => 'datetime_tools' |
|
271 | + ), |
|
272 | + admin_url('admin.php') |
|
273 | + ) . '">' |
|
274 | + ), |
|
275 | + false, |
|
276 | + 'manage_options', |
|
277 | + 'datetime_fix_persistent_notice' |
|
278 | + ); |
|
279 | + } |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + |
|
284 | + /** |
|
285 | + * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from |
|
286 | + * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in |
|
287 | + * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that |
|
288 | + * to override any queries found in the existing query for the given post type. Note that _default_query is not a |
|
289 | + * normal property on the post_type object. It's found ONLY in this particular context. |
|
290 | + * |
|
291 | + * @param WP_Post $post_type WP post type object |
|
292 | + * @return WP_Post |
|
293 | + * @throws InvalidArgumentException |
|
294 | + * @throws InvalidDataTypeException |
|
295 | + * @throws InvalidInterfaceException |
|
296 | + */ |
|
297 | + public function remove_pages_from_nav_menu($post_type) |
|
298 | + { |
|
299 | + //if this isn't the "pages" post type let's get out |
|
300 | + if ($post_type->name !== 'page') { |
|
301 | + return $post_type; |
|
302 | + } |
|
303 | + $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
304 | + $post_type->_default_query = array( |
|
305 | + 'post__not_in' => $critical_pages, |
|
306 | + ); |
|
307 | + return $post_type; |
|
308 | + } |
|
309 | + |
|
310 | + |
|
311 | + |
|
312 | + /** |
|
313 | + * WP by default only shows three metaboxes in "nav-menus.php" for first times users. We want to make sure our |
|
314 | + * metaboxes get shown as well |
|
315 | + * |
|
316 | + * @return void |
|
317 | + */ |
|
318 | + public function enable_hidden_ee_nav_menu_metaboxes() |
|
319 | + { |
|
320 | + global $wp_meta_boxes, $pagenow; |
|
321 | + if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
322 | + return; |
|
323 | + } |
|
324 | + $user = wp_get_current_user(); |
|
325 | + //has this been done yet? |
|
326 | + if (get_user_option('ee_nav_menu_initialized', $user->ID)) { |
|
327 | + return; |
|
328 | + } |
|
329 | + |
|
330 | + $hidden_meta_boxes = get_user_option('metaboxhidden_nav-menus', $user->ID); |
|
331 | + $initial_meta_boxes = apply_filters( |
|
332 | + 'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes', |
|
333 | + array( |
|
334 | + 'nav-menu-theme-locations', |
|
335 | + 'add-page', |
|
336 | + 'add-custom-links', |
|
337 | + 'add-category', |
|
338 | + 'add-espresso_events', |
|
339 | + 'add-espresso_venues', |
|
340 | + 'add-espresso_event_categories', |
|
341 | + 'add-espresso_venue_categories', |
|
342 | + 'add-post-type-post', |
|
343 | + 'add-post-type-page', |
|
344 | + ) |
|
345 | + ); |
|
346 | + |
|
347 | + if (is_array($hidden_meta_boxes)) { |
|
348 | + foreach ($hidden_meta_boxes as $key => $meta_box_id) { |
|
349 | + if (in_array($meta_box_id, $initial_meta_boxes, true)) { |
|
350 | + unset($hidden_meta_boxes[$key]); |
|
351 | + } |
|
352 | + } |
|
353 | + } |
|
354 | + update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true); |
|
355 | + update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true); |
|
356 | + } |
|
357 | + |
|
358 | + |
|
359 | + |
|
360 | + /** |
|
361 | + * This method simply registers custom nav menu boxes for "nav_menus.php route" |
|
362 | + * Currently EE is using this to make sure there are menu options for our CPT archive page routes. |
|
363 | + * |
|
364 | + * @todo modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by |
|
365 | + * addons etc. |
|
366 | + * @return void |
|
367 | + */ |
|
368 | + public function register_custom_nav_menu_boxes() |
|
369 | + { |
|
370 | + add_meta_box( |
|
371 | + 'add-extra-nav-menu-pages', |
|
372 | + esc_html__('Event Espresso Pages', 'event_espresso'), |
|
373 | + array($this, 'ee_cpt_archive_pages'), |
|
374 | + 'nav-menus', |
|
375 | + 'side', |
|
376 | + 'core' |
|
377 | + ); |
|
378 | + } |
|
379 | + |
|
380 | + |
|
381 | + |
|
382 | + /** |
|
383 | + * Use this to edit the post link for our cpts so that the edit link points to the correct page. |
|
384 | + * |
|
385 | + * @since 4.3.0 |
|
386 | + * @param string $link the original link generated by wp |
|
387 | + * @param int $id post id |
|
388 | + * @return string the (maybe) modified link |
|
389 | + */ |
|
390 | + public function modify_edit_post_link($link, $id) |
|
391 | + { |
|
392 | + if (! $post = get_post($id)) { |
|
393 | + return $link; |
|
394 | + } |
|
395 | + if ($post->post_type === 'espresso_attendees') { |
|
396 | + $query_args = array( |
|
397 | + 'action' => 'edit_attendee', |
|
398 | + 'post' => $id, |
|
399 | + ); |
|
400 | + return EEH_URL::add_query_args_and_nonce( |
|
401 | + $query_args, |
|
402 | + admin_url('admin.php?page=espresso_registrations') |
|
403 | + ); |
|
404 | + } |
|
405 | + return $link; |
|
406 | + } |
|
407 | + |
|
408 | + |
|
409 | + |
|
410 | + public function ee_cpt_archive_pages() |
|
411 | + { |
|
412 | + global $nav_menu_selected_id; |
|
413 | + $db_fields = false; |
|
414 | + $walker = new Walker_Nav_Menu_Checklist($db_fields); |
|
415 | + $current_tab = 'event-archives'; |
|
416 | + $removed_args = array( |
|
417 | + 'action', |
|
418 | + 'customlink-tab', |
|
419 | + 'edit-menu-item', |
|
420 | + 'menu-item', |
|
421 | + 'page-tab', |
|
422 | + '_wpnonce', |
|
423 | + ); |
|
424 | + ?> |
|
425 | 425 | <div id="posttype-extra-nav-menu-pages" class="posttypediv"> |
426 | 426 | <ul id="posttype-extra-nav-menu-pages-tabs" class="posttype-tabs add-menu-item-tabs"> |
427 | 427 | <li <?php echo('event-archives' === $current_tab ? ' class="tabs"' : ''); ?>> |
428 | 428 | <a class="nav-tab-link" data-type="tabs-panel-posttype-extra-nav-menu-pages-event-archives" |
429 | 429 | href="<?php if ($nav_menu_selected_id) { |
430 | - echo esc_url( |
|
431 | - add_query_arg( |
|
432 | - 'extra-nav-menu-pages-tab', |
|
433 | - 'event-archives', |
|
434 | - remove_query_arg($removed_args) |
|
435 | - ) |
|
436 | - ); |
|
437 | - } ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives"> |
|
430 | + echo esc_url( |
|
431 | + add_query_arg( |
|
432 | + 'extra-nav-menu-pages-tab', |
|
433 | + 'event-archives', |
|
434 | + remove_query_arg($removed_args) |
|
435 | + ) |
|
436 | + ); |
|
437 | + } ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives"> |
|
438 | 438 | <?php _e('Event Archive Pages', 'event_espresso'); ?> |
439 | 439 | </a> |
440 | 440 | </li> |
441 | 441 | </ul><!-- .posttype-tabs --> |
442 | 442 | |
443 | 443 | <div id="tabs-panel-posttype-extra-nav-menu-pages-event-archives" class="tabs-panel <?php |
444 | - echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive'); |
|
445 | - ?>"> |
|
444 | + echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive'); |
|
445 | + ?>"> |
|
446 | 446 | <ul id="extra-nav-menu-pageschecklist-event-archives" class="categorychecklist form-no-clear"> |
447 | 447 | <?php |
448 | - $pages = $this->_get_extra_nav_menu_pages_items(); |
|
449 | - $args['walker'] = $walker; |
|
450 | - echo walk_nav_menu_tree( |
|
451 | - array_map( |
|
452 | - array($this, '_setup_extra_nav_menu_pages_items'), |
|
453 | - $pages |
|
454 | - ), |
|
455 | - 0, |
|
456 | - (object) $args |
|
457 | - ); |
|
458 | - ?> |
|
448 | + $pages = $this->_get_extra_nav_menu_pages_items(); |
|
449 | + $args['walker'] = $walker; |
|
450 | + echo walk_nav_menu_tree( |
|
451 | + array_map( |
|
452 | + array($this, '_setup_extra_nav_menu_pages_items'), |
|
453 | + $pages |
|
454 | + ), |
|
455 | + 0, |
|
456 | + (object) $args |
|
457 | + ); |
|
458 | + ?> |
|
459 | 459 | </ul> |
460 | 460 | </div><!-- /.tabs-panel --> |
461 | 461 | |
462 | 462 | <p class="button-controls"> |
463 | 463 | <span class="list-controls"> |
464 | 464 | <a href="<?php |
465 | - echo esc_url(add_query_arg( |
|
466 | - array( |
|
467 | - 'extra-nav-menu-pages-tab' => 'event-archives', |
|
468 | - 'selectall' => 1, |
|
469 | - ), |
|
470 | - remove_query_arg($removed_args) |
|
471 | - )); |
|
472 | - ?>#posttype-extra-nav-menu-pages>" class="select-all"><?php _e('Select All'); ?></a> |
|
465 | + echo esc_url(add_query_arg( |
|
466 | + array( |
|
467 | + 'extra-nav-menu-pages-tab' => 'event-archives', |
|
468 | + 'selectall' => 1, |
|
469 | + ), |
|
470 | + remove_query_arg($removed_args) |
|
471 | + )); |
|
472 | + ?>#posttype-extra-nav-menu-pages>" class="select-all"><?php _e('Select All'); ?></a> |
|
473 | 473 | </span> |
474 | 474 | <span class="add-to-menu"> |
475 | 475 | <input type="submit"<?php wp_nav_menu_disabled_check($nav_menu_selected_id); ?> |
@@ -482,471 +482,471 @@ discard block |
||
482 | 482 | |
483 | 483 | </div><!-- /.posttypediv --> |
484 | 484 | <?php |
485 | - } |
|
486 | - |
|
487 | - |
|
488 | - /** |
|
489 | - * Returns an array of event archive nav items. |
|
490 | - * |
|
491 | - * @todo for now this method is just in place so when it gets abstracted further we can substitute in whatever |
|
492 | - * method we use for getting the extra nav menu items |
|
493 | - * @return array |
|
494 | - */ |
|
495 | - private function _get_extra_nav_menu_pages_items() |
|
496 | - { |
|
497 | - $menuitems[] = array( |
|
498 | - 'title' => esc_html__('Event List', 'event_espresso'), |
|
499 | - 'url' => get_post_type_archive_link('espresso_events'), |
|
500 | - 'description' => esc_html__('Archive page for all events.', 'event_espresso'), |
|
501 | - ); |
|
502 | - return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems); |
|
503 | - } |
|
504 | - |
|
505 | - |
|
506 | - /** |
|
507 | - * Setup nav menu walker item for usage in the event archive nav menu metabox. It receives a menu_item array with |
|
508 | - * the properties and converts it to the menu item object. |
|
509 | - * |
|
510 | - * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php |
|
511 | - * @param $menu_item_values |
|
512 | - * @return stdClass |
|
513 | - */ |
|
514 | - private function _setup_extra_nav_menu_pages_items($menu_item_values) |
|
515 | - { |
|
516 | - $menu_item = new stdClass(); |
|
517 | - $keys = array( |
|
518 | - 'ID' => 0, |
|
519 | - 'db_id' => 0, |
|
520 | - 'menu_item_parent' => 0, |
|
521 | - 'object_id' => -1, |
|
522 | - 'post_parent' => 0, |
|
523 | - 'type' => 'custom', |
|
524 | - 'object' => '', |
|
525 | - 'type_label' => esc_html__('Extra Nav Menu Item', 'event_espresso'), |
|
526 | - 'title' => '', |
|
527 | - 'url' => '', |
|
528 | - 'target' => '', |
|
529 | - 'attr_title' => '', |
|
530 | - 'description' => '', |
|
531 | - 'classes' => array(), |
|
532 | - 'xfn' => '', |
|
533 | - ); |
|
534 | - |
|
535 | - foreach ($keys as $key => $value) { |
|
536 | - $menu_item->{$key} = isset($menu_item_values[$key]) ? $menu_item_values[$key] : $value; |
|
537 | - } |
|
538 | - return $menu_item; |
|
539 | - } |
|
540 | - |
|
541 | - |
|
542 | - /** |
|
543 | - * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an |
|
544 | - * EE_Admin_Page route is called. |
|
545 | - * |
|
546 | - * @return void |
|
547 | - */ |
|
548 | - public function route_admin_request() |
|
549 | - { |
|
550 | - } |
|
551 | - |
|
552 | - |
|
553 | - /** |
|
554 | - * wp_loaded should fire on the WordPress wp_loaded hook. This fires on a VERY late priority. |
|
555 | - * |
|
556 | - * @return void |
|
557 | - */ |
|
558 | - public function wp_loaded() |
|
559 | - { |
|
560 | - } |
|
561 | - |
|
562 | - |
|
563 | - /** |
|
564 | - * admin_init |
|
565 | - * |
|
566 | - * @return void |
|
567 | - * @throws EE_Error |
|
568 | - * @throws InvalidArgumentException |
|
569 | - * @throws InvalidDataTypeException |
|
570 | - * @throws InvalidInterfaceException |
|
571 | - * @throws ReflectionException |
|
572 | - */ |
|
573 | - public function admin_init() |
|
574 | - { |
|
575 | - |
|
576 | - /** |
|
577 | - * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php), |
|
578 | - * so any hooking into core WP routes is taken care of. So in this next few lines of code: |
|
579 | - * - check if doing post processing. |
|
580 | - * - check if doing post processing of one of EE CPTs |
|
581 | - * - instantiate the corresponding EE CPT model for the post_type being processed. |
|
582 | - */ |
|
583 | - if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') { |
|
584 | - EE_Registry::instance()->load_core('Register_CPTs'); |
|
585 | - EE_Register_CPTs::instantiate_cpt_models($_POST['post_type']); |
|
586 | - } |
|
587 | - |
|
588 | - |
|
589 | - /** |
|
590 | - * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting |
|
591 | - * critical pages. The only place critical pages need included in a generated dropdown is on the "Critical |
|
592 | - * Pages" tab in the EE General Settings Admin page. |
|
593 | - * This is for user-proofing. |
|
594 | - */ |
|
595 | - add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages')); |
|
596 | - } |
|
597 | - |
|
598 | - |
|
599 | - /** |
|
600 | - * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection. |
|
601 | - * |
|
602 | - * @param string $output Current output. |
|
603 | - * @return string |
|
604 | - * @throws InvalidArgumentException |
|
605 | - * @throws InvalidDataTypeException |
|
606 | - * @throws InvalidInterfaceException |
|
607 | - */ |
|
608 | - public function modify_dropdown_pages($output) |
|
609 | - { |
|
610 | - //get critical pages |
|
611 | - $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
612 | - |
|
613 | - //split current output by line break for easier parsing. |
|
614 | - $split_output = explode("\n", $output); |
|
615 | - |
|
616 | - //loop through to remove any critical pages from the array. |
|
617 | - foreach ($critical_pages as $page_id) { |
|
618 | - $needle = 'value="' . $page_id . '"'; |
|
619 | - foreach ($split_output as $key => $haystack) { |
|
620 | - if (strpos($haystack, $needle) !== false) { |
|
621 | - unset($split_output[$key]); |
|
622 | - } |
|
623 | - } |
|
624 | - } |
|
625 | - //replace output with the new contents |
|
626 | - return implode("\n", $split_output); |
|
627 | - } |
|
628 | - |
|
629 | - |
|
630 | - /** |
|
631 | - * enqueue all admin scripts that need loaded for admin pages |
|
632 | - * |
|
633 | - * @return void |
|
634 | - */ |
|
635 | - public function enqueue_admin_scripts() |
|
636 | - { |
|
637 | - // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js. |
|
638 | - // Note: the intention of this script is to only do TARGETED injections. I.E, only injecting on certain script |
|
639 | - // calls. |
|
640 | - wp_enqueue_script( |
|
641 | - 'ee-inject-wp', |
|
642 | - EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
643 | - array('jquery'), |
|
644 | - EVENT_ESPRESSO_VERSION, |
|
645 | - true |
|
646 | - ); |
|
647 | - // register cookie script for future dependencies |
|
648 | - wp_register_script( |
|
649 | - 'jquery-cookie', |
|
650 | - EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
651 | - array('jquery'), |
|
652 | - '2.1', |
|
653 | - true |
|
654 | - ); |
|
655 | - //joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again |
|
656 | - // via: add_filter('FHEE_load_joyride', '__return_true' ); |
|
657 | - if (apply_filters('FHEE_load_joyride', false)) { |
|
658 | - //joyride style |
|
659 | - wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1'); |
|
660 | - wp_register_style( |
|
661 | - 'ee-joyride-css', |
|
662 | - EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
663 | - array('joyride-css'), |
|
664 | - EVENT_ESPRESSO_VERSION |
|
665 | - ); |
|
666 | - wp_register_script( |
|
667 | - 'joyride-modernizr', |
|
668 | - EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
669 | - array(), |
|
670 | - '2.1', |
|
671 | - true |
|
672 | - ); |
|
673 | - //joyride JS |
|
674 | - wp_register_script( |
|
675 | - 'jquery-joyride', |
|
676 | - EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
677 | - array('jquery-cookie', 'joyride-modernizr'), |
|
678 | - '2.1', |
|
679 | - true |
|
680 | - ); |
|
681 | - // wanna go for a joyride? |
|
682 | - wp_enqueue_style('ee-joyride-css'); |
|
683 | - wp_enqueue_script('jquery-joyride'); |
|
684 | - } |
|
685 | - } |
|
686 | - |
|
687 | - |
|
688 | - /** |
|
689 | - * display_admin_notices |
|
690 | - * |
|
691 | - * @return void |
|
692 | - */ |
|
693 | - public function display_admin_notices() |
|
694 | - { |
|
695 | - echo EE_Error::get_notices(); |
|
696 | - } |
|
697 | - |
|
698 | - |
|
699 | - |
|
700 | - /** |
|
701 | - * @param array $elements |
|
702 | - * @return array |
|
703 | - * @throws EE_Error |
|
704 | - * @throws InvalidArgumentException |
|
705 | - * @throws InvalidDataTypeException |
|
706 | - * @throws InvalidInterfaceException |
|
707 | - */ |
|
708 | - public function dashboard_glance_items($elements) |
|
709 | - { |
|
710 | - $elements = is_array($elements) ? $elements : array($elements); |
|
711 | - $events = EEM_Event::instance()->count(); |
|
712 | - $items['events']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
713 | - array('page' => 'espresso_events'), |
|
714 | - admin_url('admin.php') |
|
715 | - ); |
|
716 | - $items['events']['text'] = sprintf(_n('%s Event', '%s Events', $events), number_format_i18n($events)); |
|
717 | - $items['events']['title'] = esc_html__('Click to view all Events', 'event_espresso'); |
|
718 | - $registrations = EEM_Registration::instance()->count( |
|
719 | - array( |
|
720 | - array( |
|
721 | - 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
722 | - ), |
|
723 | - ) |
|
724 | - ); |
|
725 | - $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
726 | - array('page' => 'espresso_registrations'), |
|
727 | - admin_url('admin.php') |
|
728 | - ); |
|
729 | - $items['registrations']['text'] = sprintf( |
|
730 | - _n('%s Registration', '%s Registrations', $registrations), |
|
731 | - number_format_i18n($registrations) |
|
732 | - ); |
|
733 | - $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso'); |
|
734 | - |
|
735 | - $items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items); |
|
736 | - |
|
737 | - foreach ($items as $type => $item_properties) { |
|
738 | - $elements[] = sprintf( |
|
739 | - '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>', |
|
740 | - $item_properties['url'], |
|
741 | - $item_properties['title'], |
|
742 | - $item_properties['text'] |
|
743 | - ); |
|
744 | - } |
|
745 | - return $elements; |
|
746 | - } |
|
747 | - |
|
748 | - |
|
749 | - /** |
|
750 | - * check_for_invalid_datetime_formats |
|
751 | - * if an admin changes their date or time format settings on the WP General Settings admin page, verify that |
|
752 | - * their selected format can be parsed by PHP |
|
753 | - * |
|
754 | - * @param $value |
|
755 | - * @param $option |
|
756 | - * @throws EE_Error |
|
757 | - * @return string |
|
758 | - */ |
|
759 | - public function check_for_invalid_datetime_formats($value, $option) |
|
760 | - { |
|
761 | - // check for date_format or time_format |
|
762 | - switch ($option) { |
|
763 | - case 'date_format': |
|
764 | - $date_time_format = $value . ' ' . get_option('time_format'); |
|
765 | - break; |
|
766 | - case 'time_format': |
|
767 | - $date_time_format = get_option('date_format') . ' ' . $value; |
|
768 | - break; |
|
769 | - default: |
|
770 | - $date_time_format = false; |
|
771 | - } |
|
772 | - // do we have a date_time format to check ? |
|
773 | - if ($date_time_format) { |
|
774 | - $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format); |
|
775 | - |
|
776 | - if (is_array($error_msg)) { |
|
777 | - $msg = '<p>' |
|
778 | - . sprintf( |
|
779 | - esc_html__( |
|
780 | - 'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:', |
|
781 | - 'event_espresso' |
|
782 | - ), |
|
783 | - date($date_time_format), |
|
784 | - $date_time_format |
|
785 | - ) |
|
786 | - . '</p><p><ul>'; |
|
787 | - |
|
788 | - |
|
789 | - foreach ($error_msg as $error) { |
|
790 | - $msg .= '<li>' . $error . '</li>'; |
|
791 | - } |
|
792 | - |
|
793 | - $msg .= '</ul></p><p>' |
|
794 | - . sprintf( |
|
795 | - esc_html__( |
|
796 | - '%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s', |
|
797 | - 'event_espresso' |
|
798 | - ), |
|
799 | - '<span style="color:#D54E21;">', |
|
800 | - '</span>' |
|
801 | - ) |
|
802 | - . '</p>'; |
|
803 | - |
|
804 | - // trigger WP settings error |
|
805 | - add_settings_error( |
|
806 | - 'date_format', |
|
807 | - 'date_format', |
|
808 | - $msg |
|
809 | - ); |
|
810 | - |
|
811 | - // set format to something valid |
|
812 | - switch ($option) { |
|
813 | - case 'date_format': |
|
814 | - $value = 'F j, Y'; |
|
815 | - break; |
|
816 | - case 'time_format': |
|
817 | - $value = 'g:i a'; |
|
818 | - break; |
|
819 | - } |
|
820 | - } |
|
821 | - } |
|
822 | - return $value; |
|
823 | - } |
|
824 | - |
|
825 | - |
|
826 | - /** |
|
827 | - * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso" |
|
828 | - * |
|
829 | - * @param $content |
|
830 | - * @return string |
|
831 | - */ |
|
832 | - public function its_eSpresso($content) |
|
833 | - { |
|
834 | - return str_replace('[EXPRESSO_', '[ESPRESSO_', $content); |
|
835 | - } |
|
836 | - |
|
837 | - |
|
838 | - /** |
|
839 | - * espresso_admin_footer |
|
840 | - * |
|
841 | - * @return string |
|
842 | - */ |
|
843 | - public function espresso_admin_footer() |
|
844 | - { |
|
845 | - return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer')); |
|
846 | - } |
|
847 | - |
|
848 | - |
|
849 | - /** |
|
850 | - * static method for registering ee admin page. |
|
851 | - * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register. |
|
852 | - * |
|
853 | - * @since 4.3.0 |
|
854 | - * @deprecated 4.3.0 Use EE_Register_Admin_Page::register() instead |
|
855 | - * @see EE_Register_Admin_Page::register() |
|
856 | - * @param $page_basename |
|
857 | - * @param $page_path |
|
858 | - * @param array $config |
|
859 | - * @return void |
|
860 | - * @throws EE_Error |
|
861 | - */ |
|
862 | - public static function register_ee_admin_page($page_basename, $page_path, $config = array()) |
|
863 | - { |
|
864 | - EE_Error::doing_it_wrong( |
|
865 | - __METHOD__, |
|
866 | - sprintf( |
|
867 | - esc_html__( |
|
868 | - 'Usage is deprecated. Use EE_Register_Admin_Page::register() for registering the %s admin page.', |
|
869 | - 'event_espresso' |
|
870 | - ), |
|
871 | - $page_basename |
|
872 | - ), |
|
873 | - '4.3' |
|
874 | - ); |
|
875 | - if (class_exists('EE_Register_Admin_Page')) { |
|
876 | - $config['page_path'] = $page_path; |
|
877 | - } |
|
878 | - EE_Register_Admin_Page::register($page_basename, $config); |
|
879 | - } |
|
880 | - |
|
881 | - |
|
882 | - /** |
|
883 | - * @deprecated 4.8.41 |
|
884 | - * @param int $post_ID |
|
885 | - * @param \WP_Post $post |
|
886 | - * @return void |
|
887 | - */ |
|
888 | - public static function parse_post_content_on_save($post_ID, $post) |
|
889 | - { |
|
890 | - EE_Error::doing_it_wrong( |
|
891 | - __METHOD__, |
|
892 | - esc_html__('Usage is deprecated', 'event_espresso'), |
|
893 | - '4.8.41' |
|
894 | - ); |
|
895 | - } |
|
896 | - |
|
897 | - |
|
898 | - /** |
|
899 | - * @deprecated 4.8.41 |
|
900 | - * @param $option |
|
901 | - * @param $old_value |
|
902 | - * @param $value |
|
903 | - * @return void |
|
904 | - */ |
|
905 | - public function reset_page_for_posts_on_change($option, $old_value, $value) |
|
906 | - { |
|
907 | - EE_Error::doing_it_wrong( |
|
908 | - __METHOD__, |
|
909 | - esc_html__('Usage is deprecated', 'event_espresso'), |
|
910 | - '4.8.41' |
|
911 | - ); |
|
912 | - } |
|
913 | - |
|
914 | - |
|
915 | - |
|
916 | - /** |
|
917 | - * @deprecated 4.9.27 |
|
918 | - * @return void |
|
919 | - */ |
|
920 | - public function get_persistent_admin_notices() |
|
921 | - { |
|
922 | - EE_Error::doing_it_wrong( |
|
923 | - __METHOD__, |
|
924 | - sprintf( |
|
925 | - __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
926 | - '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
927 | - ), |
|
928 | - '4.9.27' |
|
929 | - ); |
|
930 | - } |
|
931 | - |
|
932 | - |
|
933 | - |
|
934 | - /** |
|
935 | - * @deprecated 4.9.27 |
|
936 | - * @throws InvalidInterfaceException |
|
937 | - * @throws InvalidDataTypeException |
|
938 | - * @throws DomainException |
|
939 | - */ |
|
940 | - public function dismiss_ee_nag_notice_callback() |
|
941 | - { |
|
942 | - EE_Error::doing_it_wrong( |
|
943 | - __METHOD__, |
|
944 | - sprintf( |
|
945 | - __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
946 | - '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
947 | - ), |
|
948 | - '4.9.27' |
|
949 | - ); |
|
950 | - $this->persistent_admin_notice_manager->dismissNotice(); |
|
951 | - } |
|
485 | + } |
|
486 | + |
|
487 | + |
|
488 | + /** |
|
489 | + * Returns an array of event archive nav items. |
|
490 | + * |
|
491 | + * @todo for now this method is just in place so when it gets abstracted further we can substitute in whatever |
|
492 | + * method we use for getting the extra nav menu items |
|
493 | + * @return array |
|
494 | + */ |
|
495 | + private function _get_extra_nav_menu_pages_items() |
|
496 | + { |
|
497 | + $menuitems[] = array( |
|
498 | + 'title' => esc_html__('Event List', 'event_espresso'), |
|
499 | + 'url' => get_post_type_archive_link('espresso_events'), |
|
500 | + 'description' => esc_html__('Archive page for all events.', 'event_espresso'), |
|
501 | + ); |
|
502 | + return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems); |
|
503 | + } |
|
504 | + |
|
505 | + |
|
506 | + /** |
|
507 | + * Setup nav menu walker item for usage in the event archive nav menu metabox. It receives a menu_item array with |
|
508 | + * the properties and converts it to the menu item object. |
|
509 | + * |
|
510 | + * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php |
|
511 | + * @param $menu_item_values |
|
512 | + * @return stdClass |
|
513 | + */ |
|
514 | + private function _setup_extra_nav_menu_pages_items($menu_item_values) |
|
515 | + { |
|
516 | + $menu_item = new stdClass(); |
|
517 | + $keys = array( |
|
518 | + 'ID' => 0, |
|
519 | + 'db_id' => 0, |
|
520 | + 'menu_item_parent' => 0, |
|
521 | + 'object_id' => -1, |
|
522 | + 'post_parent' => 0, |
|
523 | + 'type' => 'custom', |
|
524 | + 'object' => '', |
|
525 | + 'type_label' => esc_html__('Extra Nav Menu Item', 'event_espresso'), |
|
526 | + 'title' => '', |
|
527 | + 'url' => '', |
|
528 | + 'target' => '', |
|
529 | + 'attr_title' => '', |
|
530 | + 'description' => '', |
|
531 | + 'classes' => array(), |
|
532 | + 'xfn' => '', |
|
533 | + ); |
|
534 | + |
|
535 | + foreach ($keys as $key => $value) { |
|
536 | + $menu_item->{$key} = isset($menu_item_values[$key]) ? $menu_item_values[$key] : $value; |
|
537 | + } |
|
538 | + return $menu_item; |
|
539 | + } |
|
540 | + |
|
541 | + |
|
542 | + /** |
|
543 | + * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an |
|
544 | + * EE_Admin_Page route is called. |
|
545 | + * |
|
546 | + * @return void |
|
547 | + */ |
|
548 | + public function route_admin_request() |
|
549 | + { |
|
550 | + } |
|
551 | + |
|
552 | + |
|
553 | + /** |
|
554 | + * wp_loaded should fire on the WordPress wp_loaded hook. This fires on a VERY late priority. |
|
555 | + * |
|
556 | + * @return void |
|
557 | + */ |
|
558 | + public function wp_loaded() |
|
559 | + { |
|
560 | + } |
|
561 | + |
|
562 | + |
|
563 | + /** |
|
564 | + * admin_init |
|
565 | + * |
|
566 | + * @return void |
|
567 | + * @throws EE_Error |
|
568 | + * @throws InvalidArgumentException |
|
569 | + * @throws InvalidDataTypeException |
|
570 | + * @throws InvalidInterfaceException |
|
571 | + * @throws ReflectionException |
|
572 | + */ |
|
573 | + public function admin_init() |
|
574 | + { |
|
575 | + |
|
576 | + /** |
|
577 | + * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php), |
|
578 | + * so any hooking into core WP routes is taken care of. So in this next few lines of code: |
|
579 | + * - check if doing post processing. |
|
580 | + * - check if doing post processing of one of EE CPTs |
|
581 | + * - instantiate the corresponding EE CPT model for the post_type being processed. |
|
582 | + */ |
|
583 | + if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') { |
|
584 | + EE_Registry::instance()->load_core('Register_CPTs'); |
|
585 | + EE_Register_CPTs::instantiate_cpt_models($_POST['post_type']); |
|
586 | + } |
|
587 | + |
|
588 | + |
|
589 | + /** |
|
590 | + * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting |
|
591 | + * critical pages. The only place critical pages need included in a generated dropdown is on the "Critical |
|
592 | + * Pages" tab in the EE General Settings Admin page. |
|
593 | + * This is for user-proofing. |
|
594 | + */ |
|
595 | + add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages')); |
|
596 | + } |
|
597 | + |
|
598 | + |
|
599 | + /** |
|
600 | + * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection. |
|
601 | + * |
|
602 | + * @param string $output Current output. |
|
603 | + * @return string |
|
604 | + * @throws InvalidArgumentException |
|
605 | + * @throws InvalidDataTypeException |
|
606 | + * @throws InvalidInterfaceException |
|
607 | + */ |
|
608 | + public function modify_dropdown_pages($output) |
|
609 | + { |
|
610 | + //get critical pages |
|
611 | + $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array(); |
|
612 | + |
|
613 | + //split current output by line break for easier parsing. |
|
614 | + $split_output = explode("\n", $output); |
|
615 | + |
|
616 | + //loop through to remove any critical pages from the array. |
|
617 | + foreach ($critical_pages as $page_id) { |
|
618 | + $needle = 'value="' . $page_id . '"'; |
|
619 | + foreach ($split_output as $key => $haystack) { |
|
620 | + if (strpos($haystack, $needle) !== false) { |
|
621 | + unset($split_output[$key]); |
|
622 | + } |
|
623 | + } |
|
624 | + } |
|
625 | + //replace output with the new contents |
|
626 | + return implode("\n", $split_output); |
|
627 | + } |
|
628 | + |
|
629 | + |
|
630 | + /** |
|
631 | + * enqueue all admin scripts that need loaded for admin pages |
|
632 | + * |
|
633 | + * @return void |
|
634 | + */ |
|
635 | + public function enqueue_admin_scripts() |
|
636 | + { |
|
637 | + // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js. |
|
638 | + // Note: the intention of this script is to only do TARGETED injections. I.E, only injecting on certain script |
|
639 | + // calls. |
|
640 | + wp_enqueue_script( |
|
641 | + 'ee-inject-wp', |
|
642 | + EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
643 | + array('jquery'), |
|
644 | + EVENT_ESPRESSO_VERSION, |
|
645 | + true |
|
646 | + ); |
|
647 | + // register cookie script for future dependencies |
|
648 | + wp_register_script( |
|
649 | + 'jquery-cookie', |
|
650 | + EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
651 | + array('jquery'), |
|
652 | + '2.1', |
|
653 | + true |
|
654 | + ); |
|
655 | + //joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again |
|
656 | + // via: add_filter('FHEE_load_joyride', '__return_true' ); |
|
657 | + if (apply_filters('FHEE_load_joyride', false)) { |
|
658 | + //joyride style |
|
659 | + wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1'); |
|
660 | + wp_register_style( |
|
661 | + 'ee-joyride-css', |
|
662 | + EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
663 | + array('joyride-css'), |
|
664 | + EVENT_ESPRESSO_VERSION |
|
665 | + ); |
|
666 | + wp_register_script( |
|
667 | + 'joyride-modernizr', |
|
668 | + EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
669 | + array(), |
|
670 | + '2.1', |
|
671 | + true |
|
672 | + ); |
|
673 | + //joyride JS |
|
674 | + wp_register_script( |
|
675 | + 'jquery-joyride', |
|
676 | + EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
677 | + array('jquery-cookie', 'joyride-modernizr'), |
|
678 | + '2.1', |
|
679 | + true |
|
680 | + ); |
|
681 | + // wanna go for a joyride? |
|
682 | + wp_enqueue_style('ee-joyride-css'); |
|
683 | + wp_enqueue_script('jquery-joyride'); |
|
684 | + } |
|
685 | + } |
|
686 | + |
|
687 | + |
|
688 | + /** |
|
689 | + * display_admin_notices |
|
690 | + * |
|
691 | + * @return void |
|
692 | + */ |
|
693 | + public function display_admin_notices() |
|
694 | + { |
|
695 | + echo EE_Error::get_notices(); |
|
696 | + } |
|
697 | + |
|
698 | + |
|
699 | + |
|
700 | + /** |
|
701 | + * @param array $elements |
|
702 | + * @return array |
|
703 | + * @throws EE_Error |
|
704 | + * @throws InvalidArgumentException |
|
705 | + * @throws InvalidDataTypeException |
|
706 | + * @throws InvalidInterfaceException |
|
707 | + */ |
|
708 | + public function dashboard_glance_items($elements) |
|
709 | + { |
|
710 | + $elements = is_array($elements) ? $elements : array($elements); |
|
711 | + $events = EEM_Event::instance()->count(); |
|
712 | + $items['events']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
713 | + array('page' => 'espresso_events'), |
|
714 | + admin_url('admin.php') |
|
715 | + ); |
|
716 | + $items['events']['text'] = sprintf(_n('%s Event', '%s Events', $events), number_format_i18n($events)); |
|
717 | + $items['events']['title'] = esc_html__('Click to view all Events', 'event_espresso'); |
|
718 | + $registrations = EEM_Registration::instance()->count( |
|
719 | + array( |
|
720 | + array( |
|
721 | + 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
722 | + ), |
|
723 | + ) |
|
724 | + ); |
|
725 | + $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
726 | + array('page' => 'espresso_registrations'), |
|
727 | + admin_url('admin.php') |
|
728 | + ); |
|
729 | + $items['registrations']['text'] = sprintf( |
|
730 | + _n('%s Registration', '%s Registrations', $registrations), |
|
731 | + number_format_i18n($registrations) |
|
732 | + ); |
|
733 | + $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso'); |
|
734 | + |
|
735 | + $items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items); |
|
736 | + |
|
737 | + foreach ($items as $type => $item_properties) { |
|
738 | + $elements[] = sprintf( |
|
739 | + '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>', |
|
740 | + $item_properties['url'], |
|
741 | + $item_properties['title'], |
|
742 | + $item_properties['text'] |
|
743 | + ); |
|
744 | + } |
|
745 | + return $elements; |
|
746 | + } |
|
747 | + |
|
748 | + |
|
749 | + /** |
|
750 | + * check_for_invalid_datetime_formats |
|
751 | + * if an admin changes their date or time format settings on the WP General Settings admin page, verify that |
|
752 | + * their selected format can be parsed by PHP |
|
753 | + * |
|
754 | + * @param $value |
|
755 | + * @param $option |
|
756 | + * @throws EE_Error |
|
757 | + * @return string |
|
758 | + */ |
|
759 | + public function check_for_invalid_datetime_formats($value, $option) |
|
760 | + { |
|
761 | + // check for date_format or time_format |
|
762 | + switch ($option) { |
|
763 | + case 'date_format': |
|
764 | + $date_time_format = $value . ' ' . get_option('time_format'); |
|
765 | + break; |
|
766 | + case 'time_format': |
|
767 | + $date_time_format = get_option('date_format') . ' ' . $value; |
|
768 | + break; |
|
769 | + default: |
|
770 | + $date_time_format = false; |
|
771 | + } |
|
772 | + // do we have a date_time format to check ? |
|
773 | + if ($date_time_format) { |
|
774 | + $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format); |
|
775 | + |
|
776 | + if (is_array($error_msg)) { |
|
777 | + $msg = '<p>' |
|
778 | + . sprintf( |
|
779 | + esc_html__( |
|
780 | + 'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:', |
|
781 | + 'event_espresso' |
|
782 | + ), |
|
783 | + date($date_time_format), |
|
784 | + $date_time_format |
|
785 | + ) |
|
786 | + . '</p><p><ul>'; |
|
787 | + |
|
788 | + |
|
789 | + foreach ($error_msg as $error) { |
|
790 | + $msg .= '<li>' . $error . '</li>'; |
|
791 | + } |
|
792 | + |
|
793 | + $msg .= '</ul></p><p>' |
|
794 | + . sprintf( |
|
795 | + esc_html__( |
|
796 | + '%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s', |
|
797 | + 'event_espresso' |
|
798 | + ), |
|
799 | + '<span style="color:#D54E21;">', |
|
800 | + '</span>' |
|
801 | + ) |
|
802 | + . '</p>'; |
|
803 | + |
|
804 | + // trigger WP settings error |
|
805 | + add_settings_error( |
|
806 | + 'date_format', |
|
807 | + 'date_format', |
|
808 | + $msg |
|
809 | + ); |
|
810 | + |
|
811 | + // set format to something valid |
|
812 | + switch ($option) { |
|
813 | + case 'date_format': |
|
814 | + $value = 'F j, Y'; |
|
815 | + break; |
|
816 | + case 'time_format': |
|
817 | + $value = 'g:i a'; |
|
818 | + break; |
|
819 | + } |
|
820 | + } |
|
821 | + } |
|
822 | + return $value; |
|
823 | + } |
|
824 | + |
|
825 | + |
|
826 | + /** |
|
827 | + * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso" |
|
828 | + * |
|
829 | + * @param $content |
|
830 | + * @return string |
|
831 | + */ |
|
832 | + public function its_eSpresso($content) |
|
833 | + { |
|
834 | + return str_replace('[EXPRESSO_', '[ESPRESSO_', $content); |
|
835 | + } |
|
836 | + |
|
837 | + |
|
838 | + /** |
|
839 | + * espresso_admin_footer |
|
840 | + * |
|
841 | + * @return string |
|
842 | + */ |
|
843 | + public function espresso_admin_footer() |
|
844 | + { |
|
845 | + return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer')); |
|
846 | + } |
|
847 | + |
|
848 | + |
|
849 | + /** |
|
850 | + * static method for registering ee admin page. |
|
851 | + * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register. |
|
852 | + * |
|
853 | + * @since 4.3.0 |
|
854 | + * @deprecated 4.3.0 Use EE_Register_Admin_Page::register() instead |
|
855 | + * @see EE_Register_Admin_Page::register() |
|
856 | + * @param $page_basename |
|
857 | + * @param $page_path |
|
858 | + * @param array $config |
|
859 | + * @return void |
|
860 | + * @throws EE_Error |
|
861 | + */ |
|
862 | + public static function register_ee_admin_page($page_basename, $page_path, $config = array()) |
|
863 | + { |
|
864 | + EE_Error::doing_it_wrong( |
|
865 | + __METHOD__, |
|
866 | + sprintf( |
|
867 | + esc_html__( |
|
868 | + 'Usage is deprecated. Use EE_Register_Admin_Page::register() for registering the %s admin page.', |
|
869 | + 'event_espresso' |
|
870 | + ), |
|
871 | + $page_basename |
|
872 | + ), |
|
873 | + '4.3' |
|
874 | + ); |
|
875 | + if (class_exists('EE_Register_Admin_Page')) { |
|
876 | + $config['page_path'] = $page_path; |
|
877 | + } |
|
878 | + EE_Register_Admin_Page::register($page_basename, $config); |
|
879 | + } |
|
880 | + |
|
881 | + |
|
882 | + /** |
|
883 | + * @deprecated 4.8.41 |
|
884 | + * @param int $post_ID |
|
885 | + * @param \WP_Post $post |
|
886 | + * @return void |
|
887 | + */ |
|
888 | + public static function parse_post_content_on_save($post_ID, $post) |
|
889 | + { |
|
890 | + EE_Error::doing_it_wrong( |
|
891 | + __METHOD__, |
|
892 | + esc_html__('Usage is deprecated', 'event_espresso'), |
|
893 | + '4.8.41' |
|
894 | + ); |
|
895 | + } |
|
896 | + |
|
897 | + |
|
898 | + /** |
|
899 | + * @deprecated 4.8.41 |
|
900 | + * @param $option |
|
901 | + * @param $old_value |
|
902 | + * @param $value |
|
903 | + * @return void |
|
904 | + */ |
|
905 | + public function reset_page_for_posts_on_change($option, $old_value, $value) |
|
906 | + { |
|
907 | + EE_Error::doing_it_wrong( |
|
908 | + __METHOD__, |
|
909 | + esc_html__('Usage is deprecated', 'event_espresso'), |
|
910 | + '4.8.41' |
|
911 | + ); |
|
912 | + } |
|
913 | + |
|
914 | + |
|
915 | + |
|
916 | + /** |
|
917 | + * @deprecated 4.9.27 |
|
918 | + * @return void |
|
919 | + */ |
|
920 | + public function get_persistent_admin_notices() |
|
921 | + { |
|
922 | + EE_Error::doing_it_wrong( |
|
923 | + __METHOD__, |
|
924 | + sprintf( |
|
925 | + __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
926 | + '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
927 | + ), |
|
928 | + '4.9.27' |
|
929 | + ); |
|
930 | + } |
|
931 | + |
|
932 | + |
|
933 | + |
|
934 | + /** |
|
935 | + * @deprecated 4.9.27 |
|
936 | + * @throws InvalidInterfaceException |
|
937 | + * @throws InvalidDataTypeException |
|
938 | + * @throws DomainException |
|
939 | + */ |
|
940 | + public function dismiss_ee_nag_notice_callback() |
|
941 | + { |
|
942 | + EE_Error::doing_it_wrong( |
|
943 | + __METHOD__, |
|
944 | + sprintf( |
|
945 | + __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'), |
|
946 | + '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
947 | + ), |
|
948 | + '4.9.27' |
|
949 | + ); |
|
950 | + $this->persistent_admin_notice_manager->dismissNotice(); |
|
951 | + } |
|
952 | 952 | } |
@@ -40,7 +40,7 @@ discard block |
||
40 | 40 | public static function instance() |
41 | 41 | { |
42 | 42 | // check if class object is instantiated |
43 | - if (! self::$_instance instanceof EE_Admin) { |
|
43 | + if ( ! self::$_instance instanceof EE_Admin) { |
|
44 | 44 | self::$_instance = new self(); |
45 | 45 | } |
46 | 46 | return self::$_instance; |
@@ -100,11 +100,11 @@ discard block |
||
100 | 100 | */ |
101 | 101 | private function _define_all_constants() |
102 | 102 | { |
103 | - if (! defined('EE_ADMIN_URL')) { |
|
104 | - define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/'); |
|
105 | - define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/'); |
|
106 | - define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS); |
|
107 | - define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/'); |
|
103 | + if ( ! defined('EE_ADMIN_URL')) { |
|
104 | + define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL.'core/admin/'); |
|
105 | + define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL.'admin_pages/'); |
|
106 | + define('EE_ADMIN_TEMPLATE', EE_ADMIN.'templates'.DS); |
|
107 | + define('WP_ADMIN_PATH', ABSPATH.'wp-admin/'); |
|
108 | 108 | define('WP_AJAX_URL', admin_url('admin-ajax.php')); |
109 | 109 | } |
110 | 110 | } |
@@ -122,7 +122,7 @@ discard block |
||
122 | 122 | // set $main_file in stone |
123 | 123 | static $main_file; |
124 | 124 | // if $main_file is not set yet |
125 | - if (! $main_file) { |
|
125 | + if ( ! $main_file) { |
|
126 | 126 | $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE); |
127 | 127 | } |
128 | 128 | if ($plugin === $main_file) { |
@@ -175,9 +175,9 @@ discard block |
||
175 | 175 | public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array()) |
176 | 176 | { |
177 | 177 | return array( |
178 | - 'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS, |
|
179 | - 'about' => EE_ADMIN_PAGES . 'about' . DS, |
|
180 | - 'support' => EE_ADMIN_PAGES . 'support' . DS, |
|
178 | + 'maintenance' => EE_ADMIN_PAGES.'maintenance'.DS, |
|
179 | + 'about' => EE_ADMIN_PAGES.'about'.DS, |
|
180 | + 'support' => EE_ADMIN_PAGES.'support'.DS, |
|
181 | 181 | ); |
182 | 182 | } |
183 | 183 | |
@@ -219,7 +219,7 @@ discard block |
||
219 | 219 | add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2); |
220 | 220 | } |
221 | 221 | // run the admin page factory but ONLY if we are doing an ee admin ajax request |
222 | - if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
222 | + if ( ! defined('DOING_AJAX') || EE_ADMIN_AJAX) { |
|
223 | 223 | try { |
224 | 224 | //this loads the controller for the admin pages which will setup routing etc |
225 | 225 | EE_Registry::instance()->load_core('Admin_Page_Loader'); |
@@ -252,7 +252,7 @@ discard block |
||
252 | 252 | //@todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version |
253 | 253 | //with this. But after enough time (indeterminate at this point) we can just remove this notice. |
254 | 254 | //this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626 |
255 | - if (! get_option('timezone_string') && EEM_Event::instance()->count() > 0) { |
|
255 | + if ( ! get_option('timezone_string') && EEM_Event::instance()->count() > 0) { |
|
256 | 256 | new PersistentAdminNotice( |
257 | 257 | 'datetime_fix_notice', |
258 | 258 | sprintf( |
@@ -264,13 +264,13 @@ discard block |
||
264 | 264 | '</strong>', |
265 | 265 | '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">', |
266 | 266 | '</a>', |
267 | - '<a href="' . EE_Admin_Page::add_query_args_and_nonce( |
|
267 | + '<a href="'.EE_Admin_Page::add_query_args_and_nonce( |
|
268 | 268 | array( |
269 | 269 | 'page' => 'espresso_maintenance_settings', |
270 | 270 | 'action' => 'datetime_tools' |
271 | 271 | ), |
272 | 272 | admin_url('admin.php') |
273 | - ) . '">' |
|
273 | + ).'">' |
|
274 | 274 | ), |
275 | 275 | false, |
276 | 276 | 'manage_options', |
@@ -318,7 +318,7 @@ discard block |
||
318 | 318 | public function enable_hidden_ee_nav_menu_metaboxes() |
319 | 319 | { |
320 | 320 | global $wp_meta_boxes, $pagenow; |
321 | - if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
321 | + if ( ! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') { |
|
322 | 322 | return; |
323 | 323 | } |
324 | 324 | $user = wp_get_current_user(); |
@@ -389,7 +389,7 @@ discard block |
||
389 | 389 | */ |
390 | 390 | public function modify_edit_post_link($link, $id) |
391 | 391 | { |
392 | - if (! $post = get_post($id)) { |
|
392 | + if ( ! $post = get_post($id)) { |
|
393 | 393 | return $link; |
394 | 394 | } |
395 | 395 | if ($post->post_type === 'espresso_attendees') { |
@@ -615,7 +615,7 @@ discard block |
||
615 | 615 | |
616 | 616 | //loop through to remove any critical pages from the array. |
617 | 617 | foreach ($critical_pages as $page_id) { |
618 | - $needle = 'value="' . $page_id . '"'; |
|
618 | + $needle = 'value="'.$page_id.'"'; |
|
619 | 619 | foreach ($split_output as $key => $haystack) { |
620 | 620 | if (strpos($haystack, $needle) !== false) { |
621 | 621 | unset($split_output[$key]); |
@@ -639,7 +639,7 @@ discard block |
||
639 | 639 | // calls. |
640 | 640 | wp_enqueue_script( |
641 | 641 | 'ee-inject-wp', |
642 | - EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
642 | + EE_ADMIN_URL.'assets/ee-cpt-wp-injects.js', |
|
643 | 643 | array('jquery'), |
644 | 644 | EVENT_ESPRESSO_VERSION, |
645 | 645 | true |
@@ -647,7 +647,7 @@ discard block |
||
647 | 647 | // register cookie script for future dependencies |
648 | 648 | wp_register_script( |
649 | 649 | 'jquery-cookie', |
650 | - EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
650 | + EE_THIRD_PARTY_URL.'joyride/jquery.cookie.js', |
|
651 | 651 | array('jquery'), |
652 | 652 | '2.1', |
653 | 653 | true |
@@ -656,16 +656,16 @@ discard block |
||
656 | 656 | // via: add_filter('FHEE_load_joyride', '__return_true' ); |
657 | 657 | if (apply_filters('FHEE_load_joyride', false)) { |
658 | 658 | //joyride style |
659 | - wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1'); |
|
659 | + wp_register_style('joyride-css', EE_THIRD_PARTY_URL.'joyride/joyride-2.1.css', array(), '2.1'); |
|
660 | 660 | wp_register_style( |
661 | 661 | 'ee-joyride-css', |
662 | - EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
662 | + EE_GLOBAL_ASSETS_URL.'css/ee-joyride-styles.css', |
|
663 | 663 | array('joyride-css'), |
664 | 664 | EVENT_ESPRESSO_VERSION |
665 | 665 | ); |
666 | 666 | wp_register_script( |
667 | 667 | 'joyride-modernizr', |
668 | - EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
668 | + EE_THIRD_PARTY_URL.'joyride/modernizr.mq.js', |
|
669 | 669 | array(), |
670 | 670 | '2.1', |
671 | 671 | true |
@@ -673,7 +673,7 @@ discard block |
||
673 | 673 | //joyride JS |
674 | 674 | wp_register_script( |
675 | 675 | 'jquery-joyride', |
676 | - EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
676 | + EE_THIRD_PARTY_URL.'joyride/jquery.joyride-2.1.js', |
|
677 | 677 | array('jquery-cookie', 'joyride-modernizr'), |
678 | 678 | '2.1', |
679 | 679 | true |
@@ -722,21 +722,21 @@ discard block |
||
722 | 722 | ), |
723 | 723 | ) |
724 | 724 | ); |
725 | - $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
725 | + $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce( |
|
726 | 726 | array('page' => 'espresso_registrations'), |
727 | 727 | admin_url('admin.php') |
728 | 728 | ); |
729 | - $items['registrations']['text'] = sprintf( |
|
729 | + $items['registrations']['text'] = sprintf( |
|
730 | 730 | _n('%s Registration', '%s Registrations', $registrations), |
731 | 731 | number_format_i18n($registrations) |
732 | 732 | ); |
733 | 733 | $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso'); |
734 | 734 | |
735 | - $items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items); |
|
735 | + $items = (array) apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items); |
|
736 | 736 | |
737 | 737 | foreach ($items as $type => $item_properties) { |
738 | 738 | $elements[] = sprintf( |
739 | - '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>', |
|
739 | + '<a class="ee-dashboard-link-'.$type.'" href="%s" title="%s">%s</a>', |
|
740 | 740 | $item_properties['url'], |
741 | 741 | $item_properties['title'], |
742 | 742 | $item_properties['text'] |
@@ -761,10 +761,10 @@ discard block |
||
761 | 761 | // check for date_format or time_format |
762 | 762 | switch ($option) { |
763 | 763 | case 'date_format': |
764 | - $date_time_format = $value . ' ' . get_option('time_format'); |
|
764 | + $date_time_format = $value.' '.get_option('time_format'); |
|
765 | 765 | break; |
766 | 766 | case 'time_format': |
767 | - $date_time_format = get_option('date_format') . ' ' . $value; |
|
767 | + $date_time_format = get_option('date_format').' '.$value; |
|
768 | 768 | break; |
769 | 769 | default: |
770 | 770 | $date_time_format = false; |
@@ -787,7 +787,7 @@ discard block |
||
787 | 787 | |
788 | 788 | |
789 | 789 | foreach ($error_msg as $error) { |
790 | - $msg .= '<li>' . $error . '</li>'; |
|
790 | + $msg .= '<li>'.$error.'</li>'; |
|
791 | 791 | } |
792 | 792 | |
793 | 793 | $msg .= '</ul></p><p>' |
@@ -1,6 +1,6 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | if (! defined('EVENT_ESPRESSO_VERSION')) { |
3 | - exit('NO direct script access allowed'); |
|
3 | + exit('NO direct script access allowed'); |
|
4 | 4 | } |
5 | 5 | |
6 | 6 | /** |
@@ -28,596 +28,596 @@ discard block |
||
28 | 28 | class Registration_Form_Admin_Page extends EE_Admin_Page |
29 | 29 | { |
30 | 30 | |
31 | - /** |
|
32 | - * _question |
|
33 | - * holds the specific question object for the question details screen |
|
34 | - * |
|
35 | - * @var EE_Question $_question |
|
36 | - */ |
|
37 | - protected $_question; |
|
38 | - |
|
39 | - /** |
|
40 | - * _question_group |
|
41 | - * holds the specific question group object for the question group details screen |
|
42 | - * |
|
43 | - * @var EE_Question_Group $_question_group |
|
44 | - */ |
|
45 | - protected $_question_group; |
|
46 | - |
|
47 | - /** |
|
48 | - *_question_model EEM_Question model instance (for queries) |
|
49 | - * |
|
50 | - * @var EEM_Question $_question_model ; |
|
51 | - */ |
|
52 | - protected $_question_model; |
|
53 | - |
|
54 | - /** |
|
55 | - * _question_group_model EEM_Question_group instance (for queries) |
|
56 | - * |
|
57 | - * @var EEM_Question_Group $_question_group_model |
|
58 | - */ |
|
59 | - protected $_question_group_model; |
|
60 | - |
|
61 | - |
|
62 | - /** |
|
63 | - * @Constructor |
|
64 | - * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object. |
|
65 | - * @access public |
|
66 | - */ |
|
67 | - public function __construct($routing = true) |
|
68 | - { |
|
69 | - require_once(EE_MODELS . 'EEM_Question.model.php'); |
|
70 | - require_once(EE_MODELS . 'EEM_Question_Group.model.php'); |
|
71 | - $this->_question_model = EEM_Question::instance(); |
|
72 | - $this->_question_group_model = EEM_Question_Group::instance(); |
|
73 | - parent::__construct($routing); |
|
74 | - } |
|
75 | - |
|
76 | - |
|
77 | - protected function _init_page_props() |
|
78 | - { |
|
79 | - $this->page_slug = REGISTRATION_FORM_PG_SLUG; |
|
80 | - $this->page_label = esc_html__('Registration Form', 'event_espresso'); |
|
81 | - $this->_admin_base_url = REGISTRATION_FORM_ADMIN_URL; |
|
82 | - $this->_admin_base_path = REGISTRATION_FORM_ADMIN; |
|
83 | - } |
|
84 | - |
|
85 | - |
|
86 | - protected function _ajax_hooks() |
|
87 | - { |
|
88 | - } |
|
89 | - |
|
90 | - |
|
91 | - protected function _define_page_props() |
|
92 | - { |
|
93 | - $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso'); |
|
94 | - $this->_labels = array( |
|
95 | - 'buttons' => array( |
|
96 | - 'edit_question' => esc_html__('Edit Question', 'event_espresso'), |
|
97 | - ), |
|
98 | - ); |
|
99 | - } |
|
100 | - |
|
101 | - |
|
102 | - /** |
|
103 | - *_set_page_routes |
|
104 | - */ |
|
105 | - protected function _set_page_routes() |
|
106 | - { |
|
107 | - $qst_id = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0; |
|
108 | - $this->_page_routes = array( |
|
109 | - 'default' => array( |
|
110 | - 'func' => '_questions_overview_list_table', |
|
111 | - 'capability' => 'ee_read_questions', |
|
112 | - ), |
|
113 | - |
|
114 | - 'edit_question' => array( |
|
115 | - 'func' => '_edit_question', |
|
116 | - 'capability' => 'ee_edit_question', |
|
117 | - 'obj_id' => $qst_id, |
|
118 | - 'args' => array('edit'), |
|
119 | - ), |
|
120 | - |
|
121 | - 'question_groups' => array( |
|
122 | - 'func' => '_questions_groups_preview', |
|
123 | - 'capability' => 'ee_read_question_groups', |
|
124 | - ), |
|
125 | - |
|
126 | - 'update_question' => array( |
|
127 | - 'func' => '_insert_or_update_question', |
|
128 | - 'args' => array('new_question' => false), |
|
129 | - 'capability' => 'ee_edit_question', |
|
130 | - 'obj_id' => $qst_id, |
|
131 | - 'noheader' => true, |
|
132 | - ), |
|
133 | - ); |
|
134 | - } |
|
135 | - |
|
136 | - |
|
137 | - protected function _set_page_config() |
|
138 | - { |
|
139 | - $this->_page_config = array( |
|
140 | - 'default' => array( |
|
141 | - 'nav' => array( |
|
142 | - 'label' => esc_html__('Questions', 'event_espresso'), |
|
143 | - 'order' => 10, |
|
144 | - ), |
|
145 | - 'list_table' => 'Registration_Form_Questions_Admin_List_Table', |
|
146 | - 'metaboxes' => $this->_default_espresso_metaboxes, |
|
147 | - 'help_tabs' => array( |
|
148 | - 'registration_form_questions_overview_help_tab' => array( |
|
149 | - 'title' => esc_html__('Questions Overview', 'event_espresso'), |
|
150 | - 'filename' => 'registration_form_questions_overview', |
|
151 | - ), |
|
152 | - 'registration_form_questions_overview_table_column_headings_help_tab' => array( |
|
153 | - 'title' => esc_html__('Questions Overview Table Column Headings', 'event_espresso'), |
|
154 | - 'filename' => 'registration_form_questions_overview_table_column_headings', |
|
155 | - ), |
|
156 | - 'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array( |
|
157 | - 'title' => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'), |
|
158 | - 'filename' => 'registration_form_questions_overview_views_bulk_actions_search', |
|
159 | - ), |
|
160 | - ), |
|
161 | - 'help_tour' => array('Registration_Form_Questions_Overview_Help_Tour'), |
|
162 | - 'require_nonce' => false, |
|
163 | - 'qtips' => array( |
|
164 | - 'EE_Registration_Form_Tips', |
|
165 | - )/**/ |
|
166 | - ), |
|
167 | - |
|
168 | - 'question_groups' => array( |
|
169 | - 'nav' => array( |
|
170 | - 'label' => esc_html__('Question Groups', 'event_espresso'), |
|
171 | - 'order' => 20, |
|
172 | - ), |
|
173 | - 'metaboxes' => $this->_default_espresso_metaboxes, |
|
174 | - 'help_tabs' => array( |
|
175 | - 'registration_form_question_groups_help_tab' => array( |
|
176 | - 'title' => esc_html__('Question Groups', 'event_espresso'), |
|
177 | - 'filename' => 'registration_form_question_groups', |
|
178 | - ), |
|
179 | - ), |
|
180 | - 'help_tour' => array('Registration_Form_Question_Groups_Help_Tour'), |
|
181 | - 'require_nonce' => false, |
|
182 | - ), |
|
183 | - |
|
184 | - 'edit_question' => array( |
|
185 | - 'nav' => array( |
|
186 | - 'label' => esc_html__('Edit Question', 'event_espresso'), |
|
187 | - 'order' => 15, |
|
188 | - 'persistent' => false, |
|
189 | - 'url' => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']), |
|
190 | - $this->_current_page_view_url) : $this->_admin_base_url, |
|
191 | - ), |
|
192 | - 'metaboxes' => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')), |
|
193 | - 'help_tabs' => array( |
|
194 | - 'registration_form_edit_question_group_help_tab' => array( |
|
195 | - 'title' => esc_html__('Edit Question', 'event_espresso'), |
|
196 | - 'filename' => 'registration_form_edit_question', |
|
197 | - ), |
|
198 | - ), |
|
199 | - 'help_tour' => array('Registration_Form_Edit_Question_Help_Tour'), |
|
200 | - 'require_nonce' => false, |
|
201 | - ), |
|
202 | - ); |
|
203 | - } |
|
204 | - |
|
205 | - |
|
206 | - protected function _add_screen_options() |
|
207 | - { |
|
208 | - //todo |
|
209 | - } |
|
210 | - |
|
211 | - protected function _add_screen_options_default() |
|
212 | - { |
|
213 | - $page_title = $this->_admin_page_title; |
|
214 | - $this->_admin_page_title = esc_html__('Questions', 'event_espresso'); |
|
215 | - $this->_per_page_screen_option(); |
|
216 | - $this->_admin_page_title = $page_title; |
|
217 | - } |
|
218 | - |
|
219 | - protected function _add_screen_options_question_groups() |
|
220 | - { |
|
221 | - $page_title = $this->_admin_page_title; |
|
222 | - $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso'); |
|
223 | - $this->_per_page_screen_option(); |
|
224 | - $this->_admin_page_title = $page_title; |
|
225 | - } |
|
226 | - |
|
227 | - //none of the below group are currently used for Event Categories |
|
228 | - protected function _add_feature_pointers() |
|
229 | - { |
|
230 | - } |
|
231 | - |
|
232 | - public function load_scripts_styles() |
|
233 | - { |
|
234 | - wp_register_style('espresso_registration', |
|
235 | - REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
236 | - wp_enqueue_style('espresso_registration'); |
|
237 | - } |
|
238 | - |
|
239 | - public function admin_init() |
|
240 | - { |
|
241 | - } |
|
242 | - |
|
243 | - public function admin_notices() |
|
244 | - { |
|
245 | - } |
|
246 | - |
|
247 | - public function admin_footer_scripts() |
|
248 | - { |
|
249 | - } |
|
250 | - |
|
251 | - |
|
252 | - public function load_scripts_styles_default() |
|
253 | - { |
|
254 | - } |
|
255 | - |
|
256 | - |
|
257 | - public function load_scripts_styles_add_question() |
|
258 | - { |
|
259 | - $this->load_scripts_styles_forms(); |
|
260 | - wp_register_script('espresso_registration_form_single', |
|
261 | - REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
262 | - EVENT_ESPRESSO_VERSION, true); |
|
263 | - wp_enqueue_script('espresso_registration_form_single'); |
|
264 | - } |
|
265 | - |
|
266 | - public function load_scripts_styles_edit_question() |
|
267 | - { |
|
268 | - $this->load_scripts_styles_forms(); |
|
269 | - wp_register_script('espresso_registration_form_single', |
|
270 | - REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
271 | - EVENT_ESPRESSO_VERSION, true); |
|
272 | - wp_enqueue_script('espresso_registration_form_single'); |
|
273 | - } |
|
274 | - |
|
275 | - |
|
276 | - public function recaptcha_info_help_tab() |
|
277 | - { |
|
278 | - $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php'; |
|
279 | - EEH_Template::display_template($template, array()); |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - public function load_scripts_styles_forms() |
|
284 | - { |
|
285 | - //styles |
|
286 | - wp_enqueue_style('espresso-ui-theme'); |
|
287 | - //scripts |
|
288 | - wp_enqueue_script('ee_admin_js'); |
|
289 | - } |
|
290 | - |
|
291 | - |
|
292 | - protected function _set_list_table_views_default() |
|
293 | - { |
|
294 | - $this->_views = array( |
|
295 | - 'all' => array( |
|
296 | - 'slug' => 'all', |
|
297 | - 'label' => esc_html__('View All Questions', 'event_espresso'), |
|
298 | - 'count' => 0, |
|
31 | + /** |
|
32 | + * _question |
|
33 | + * holds the specific question object for the question details screen |
|
34 | + * |
|
35 | + * @var EE_Question $_question |
|
36 | + */ |
|
37 | + protected $_question; |
|
38 | + |
|
39 | + /** |
|
40 | + * _question_group |
|
41 | + * holds the specific question group object for the question group details screen |
|
42 | + * |
|
43 | + * @var EE_Question_Group $_question_group |
|
44 | + */ |
|
45 | + protected $_question_group; |
|
46 | + |
|
47 | + /** |
|
48 | + *_question_model EEM_Question model instance (for queries) |
|
49 | + * |
|
50 | + * @var EEM_Question $_question_model ; |
|
51 | + */ |
|
52 | + protected $_question_model; |
|
53 | + |
|
54 | + /** |
|
55 | + * _question_group_model EEM_Question_group instance (for queries) |
|
56 | + * |
|
57 | + * @var EEM_Question_Group $_question_group_model |
|
58 | + */ |
|
59 | + protected $_question_group_model; |
|
60 | + |
|
61 | + |
|
62 | + /** |
|
63 | + * @Constructor |
|
64 | + * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object. |
|
65 | + * @access public |
|
66 | + */ |
|
67 | + public function __construct($routing = true) |
|
68 | + { |
|
69 | + require_once(EE_MODELS . 'EEM_Question.model.php'); |
|
70 | + require_once(EE_MODELS . 'EEM_Question_Group.model.php'); |
|
71 | + $this->_question_model = EEM_Question::instance(); |
|
72 | + $this->_question_group_model = EEM_Question_Group::instance(); |
|
73 | + parent::__construct($routing); |
|
74 | + } |
|
75 | + |
|
76 | + |
|
77 | + protected function _init_page_props() |
|
78 | + { |
|
79 | + $this->page_slug = REGISTRATION_FORM_PG_SLUG; |
|
80 | + $this->page_label = esc_html__('Registration Form', 'event_espresso'); |
|
81 | + $this->_admin_base_url = REGISTRATION_FORM_ADMIN_URL; |
|
82 | + $this->_admin_base_path = REGISTRATION_FORM_ADMIN; |
|
83 | + } |
|
84 | + |
|
85 | + |
|
86 | + protected function _ajax_hooks() |
|
87 | + { |
|
88 | + } |
|
89 | + |
|
90 | + |
|
91 | + protected function _define_page_props() |
|
92 | + { |
|
93 | + $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso'); |
|
94 | + $this->_labels = array( |
|
95 | + 'buttons' => array( |
|
96 | + 'edit_question' => esc_html__('Edit Question', 'event_espresso'), |
|
97 | + ), |
|
98 | + ); |
|
99 | + } |
|
100 | + |
|
101 | + |
|
102 | + /** |
|
103 | + *_set_page_routes |
|
104 | + */ |
|
105 | + protected function _set_page_routes() |
|
106 | + { |
|
107 | + $qst_id = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0; |
|
108 | + $this->_page_routes = array( |
|
109 | + 'default' => array( |
|
110 | + 'func' => '_questions_overview_list_table', |
|
111 | + 'capability' => 'ee_read_questions', |
|
112 | + ), |
|
113 | + |
|
114 | + 'edit_question' => array( |
|
115 | + 'func' => '_edit_question', |
|
116 | + 'capability' => 'ee_edit_question', |
|
117 | + 'obj_id' => $qst_id, |
|
118 | + 'args' => array('edit'), |
|
119 | + ), |
|
120 | + |
|
121 | + 'question_groups' => array( |
|
122 | + 'func' => '_questions_groups_preview', |
|
123 | + 'capability' => 'ee_read_question_groups', |
|
124 | + ), |
|
125 | + |
|
126 | + 'update_question' => array( |
|
127 | + 'func' => '_insert_or_update_question', |
|
128 | + 'args' => array('new_question' => false), |
|
129 | + 'capability' => 'ee_edit_question', |
|
130 | + 'obj_id' => $qst_id, |
|
131 | + 'noheader' => true, |
|
132 | + ), |
|
133 | + ); |
|
134 | + } |
|
135 | + |
|
136 | + |
|
137 | + protected function _set_page_config() |
|
138 | + { |
|
139 | + $this->_page_config = array( |
|
140 | + 'default' => array( |
|
141 | + 'nav' => array( |
|
142 | + 'label' => esc_html__('Questions', 'event_espresso'), |
|
143 | + 'order' => 10, |
|
144 | + ), |
|
145 | + 'list_table' => 'Registration_Form_Questions_Admin_List_Table', |
|
146 | + 'metaboxes' => $this->_default_espresso_metaboxes, |
|
147 | + 'help_tabs' => array( |
|
148 | + 'registration_form_questions_overview_help_tab' => array( |
|
149 | + 'title' => esc_html__('Questions Overview', 'event_espresso'), |
|
150 | + 'filename' => 'registration_form_questions_overview', |
|
151 | + ), |
|
152 | + 'registration_form_questions_overview_table_column_headings_help_tab' => array( |
|
153 | + 'title' => esc_html__('Questions Overview Table Column Headings', 'event_espresso'), |
|
154 | + 'filename' => 'registration_form_questions_overview_table_column_headings', |
|
155 | + ), |
|
156 | + 'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array( |
|
157 | + 'title' => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'), |
|
158 | + 'filename' => 'registration_form_questions_overview_views_bulk_actions_search', |
|
159 | + ), |
|
160 | + ), |
|
161 | + 'help_tour' => array('Registration_Form_Questions_Overview_Help_Tour'), |
|
162 | + 'require_nonce' => false, |
|
163 | + 'qtips' => array( |
|
164 | + 'EE_Registration_Form_Tips', |
|
165 | + )/**/ |
|
166 | + ), |
|
167 | + |
|
168 | + 'question_groups' => array( |
|
169 | + 'nav' => array( |
|
170 | + 'label' => esc_html__('Question Groups', 'event_espresso'), |
|
171 | + 'order' => 20, |
|
172 | + ), |
|
173 | + 'metaboxes' => $this->_default_espresso_metaboxes, |
|
174 | + 'help_tabs' => array( |
|
175 | + 'registration_form_question_groups_help_tab' => array( |
|
176 | + 'title' => esc_html__('Question Groups', 'event_espresso'), |
|
177 | + 'filename' => 'registration_form_question_groups', |
|
178 | + ), |
|
179 | + ), |
|
180 | + 'help_tour' => array('Registration_Form_Question_Groups_Help_Tour'), |
|
181 | + 'require_nonce' => false, |
|
182 | + ), |
|
183 | + |
|
184 | + 'edit_question' => array( |
|
185 | + 'nav' => array( |
|
186 | + 'label' => esc_html__('Edit Question', 'event_espresso'), |
|
187 | + 'order' => 15, |
|
188 | + 'persistent' => false, |
|
189 | + 'url' => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']), |
|
190 | + $this->_current_page_view_url) : $this->_admin_base_url, |
|
191 | + ), |
|
192 | + 'metaboxes' => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')), |
|
193 | + 'help_tabs' => array( |
|
194 | + 'registration_form_edit_question_group_help_tab' => array( |
|
195 | + 'title' => esc_html__('Edit Question', 'event_espresso'), |
|
196 | + 'filename' => 'registration_form_edit_question', |
|
197 | + ), |
|
198 | + ), |
|
199 | + 'help_tour' => array('Registration_Form_Edit_Question_Help_Tour'), |
|
200 | + 'require_nonce' => false, |
|
201 | + ), |
|
202 | + ); |
|
203 | + } |
|
204 | + |
|
205 | + |
|
206 | + protected function _add_screen_options() |
|
207 | + { |
|
208 | + //todo |
|
209 | + } |
|
210 | + |
|
211 | + protected function _add_screen_options_default() |
|
212 | + { |
|
213 | + $page_title = $this->_admin_page_title; |
|
214 | + $this->_admin_page_title = esc_html__('Questions', 'event_espresso'); |
|
215 | + $this->_per_page_screen_option(); |
|
216 | + $this->_admin_page_title = $page_title; |
|
217 | + } |
|
218 | + |
|
219 | + protected function _add_screen_options_question_groups() |
|
220 | + { |
|
221 | + $page_title = $this->_admin_page_title; |
|
222 | + $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso'); |
|
223 | + $this->_per_page_screen_option(); |
|
224 | + $this->_admin_page_title = $page_title; |
|
225 | + } |
|
226 | + |
|
227 | + //none of the below group are currently used for Event Categories |
|
228 | + protected function _add_feature_pointers() |
|
229 | + { |
|
230 | + } |
|
231 | + |
|
232 | + public function load_scripts_styles() |
|
233 | + { |
|
234 | + wp_register_style('espresso_registration', |
|
235 | + REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
236 | + wp_enqueue_style('espresso_registration'); |
|
237 | + } |
|
238 | + |
|
239 | + public function admin_init() |
|
240 | + { |
|
241 | + } |
|
242 | + |
|
243 | + public function admin_notices() |
|
244 | + { |
|
245 | + } |
|
246 | + |
|
247 | + public function admin_footer_scripts() |
|
248 | + { |
|
249 | + } |
|
250 | + |
|
251 | + |
|
252 | + public function load_scripts_styles_default() |
|
253 | + { |
|
254 | + } |
|
255 | + |
|
256 | + |
|
257 | + public function load_scripts_styles_add_question() |
|
258 | + { |
|
259 | + $this->load_scripts_styles_forms(); |
|
260 | + wp_register_script('espresso_registration_form_single', |
|
261 | + REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
262 | + EVENT_ESPRESSO_VERSION, true); |
|
263 | + wp_enqueue_script('espresso_registration_form_single'); |
|
264 | + } |
|
265 | + |
|
266 | + public function load_scripts_styles_edit_question() |
|
267 | + { |
|
268 | + $this->load_scripts_styles_forms(); |
|
269 | + wp_register_script('espresso_registration_form_single', |
|
270 | + REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
271 | + EVENT_ESPRESSO_VERSION, true); |
|
272 | + wp_enqueue_script('espresso_registration_form_single'); |
|
273 | + } |
|
274 | + |
|
275 | + |
|
276 | + public function recaptcha_info_help_tab() |
|
277 | + { |
|
278 | + $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php'; |
|
279 | + EEH_Template::display_template($template, array()); |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + public function load_scripts_styles_forms() |
|
284 | + { |
|
285 | + //styles |
|
286 | + wp_enqueue_style('espresso-ui-theme'); |
|
287 | + //scripts |
|
288 | + wp_enqueue_script('ee_admin_js'); |
|
289 | + } |
|
290 | + |
|
291 | + |
|
292 | + protected function _set_list_table_views_default() |
|
293 | + { |
|
294 | + $this->_views = array( |
|
295 | + 'all' => array( |
|
296 | + 'slug' => 'all', |
|
297 | + 'label' => esc_html__('View All Questions', 'event_espresso'), |
|
298 | + 'count' => 0, |
|
299 | 299 | // 'bulk_action' => array( |
300 | 300 | // 'trash_questions' => esc_html__('Trash', 'event_espresso'), |
301 | 301 | // ) |
302 | - ), |
|
303 | - ); |
|
304 | - |
|
305 | - if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions', |
|
306 | - 'espresso_registration_form_trash_questions') |
|
307 | - ) { |
|
308 | - $this->_views['trash'] = array( |
|
309 | - 'slug' => 'trash', |
|
310 | - 'label' => esc_html__('Trash', 'event_espresso'), |
|
311 | - 'count' => 0, |
|
302 | + ), |
|
303 | + ); |
|
304 | + |
|
305 | + if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions', |
|
306 | + 'espresso_registration_form_trash_questions') |
|
307 | + ) { |
|
308 | + $this->_views['trash'] = array( |
|
309 | + 'slug' => 'trash', |
|
310 | + 'label' => esc_html__('Trash', 'event_espresso'), |
|
311 | + 'count' => 0, |
|
312 | 312 | // 'bulk_action' => array( |
313 | 313 | // 'delete_questions' => esc_html__('Delete Permanently', 'event_espresso'), |
314 | 314 | // 'restore_questions' => esc_html__('Restore', 'event_espresso'), |
315 | - ); |
|
316 | - } |
|
317 | - } |
|
318 | - |
|
319 | - /** |
|
320 | - * This just previews the question groups tab that comes in caffeinated. |
|
321 | - * |
|
322 | - * @return string html |
|
323 | - */ |
|
324 | - protected function _questions_groups_preview() |
|
325 | - { |
|
326 | - $this->_admin_page_title = esc_html__('Question Groups (Preview)', 'event_espresso'); |
|
327 | - $this->_template_args['preview_img'] = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot', |
|
328 | - 'event_espresso') . '" />'; |
|
329 | - $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.', |
|
330 | - 'event_espresso') . '</strong>'; |
|
331 | - $this->display_admin_caf_preview_page('question_groups_tab'); |
|
332 | - } |
|
333 | - |
|
334 | - |
|
335 | - /** |
|
336 | - * Extracts the question field's values from the POST request to update or insert them |
|
337 | - * |
|
338 | - * @param \EEM_Base $model |
|
339 | - * @return array where each key is the name of a model's field/db column, and each value is its value. |
|
340 | - */ |
|
341 | - protected function _set_column_values_for(EEM_Base $model) |
|
342 | - { |
|
343 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
344 | - $set_column_values = array(); |
|
345 | - |
|
346 | - //some initial checks for proper values. |
|
347 | - //if QST_admin_only, then no matter what QST_required is we disable. |
|
348 | - if (! empty($this->_req_data['QST_admin_only'])) { |
|
349 | - $this->_req_data['QST_required'] = 0; |
|
350 | - } |
|
351 | - foreach ($model->field_settings() as $fieldName => $settings) { |
|
352 | - // basically if QSG_identifier is empty or not set |
|
353 | - if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) { |
|
354 | - $QSG_name = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : ''; |
|
355 | - $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true); |
|
315 | + ); |
|
316 | + } |
|
317 | + } |
|
318 | + |
|
319 | + /** |
|
320 | + * This just previews the question groups tab that comes in caffeinated. |
|
321 | + * |
|
322 | + * @return string html |
|
323 | + */ |
|
324 | + protected function _questions_groups_preview() |
|
325 | + { |
|
326 | + $this->_admin_page_title = esc_html__('Question Groups (Preview)', 'event_espresso'); |
|
327 | + $this->_template_args['preview_img'] = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot', |
|
328 | + 'event_espresso') . '" />'; |
|
329 | + $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.', |
|
330 | + 'event_espresso') . '</strong>'; |
|
331 | + $this->display_admin_caf_preview_page('question_groups_tab'); |
|
332 | + } |
|
333 | + |
|
334 | + |
|
335 | + /** |
|
336 | + * Extracts the question field's values from the POST request to update or insert them |
|
337 | + * |
|
338 | + * @param \EEM_Base $model |
|
339 | + * @return array where each key is the name of a model's field/db column, and each value is its value. |
|
340 | + */ |
|
341 | + protected function _set_column_values_for(EEM_Base $model) |
|
342 | + { |
|
343 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
344 | + $set_column_values = array(); |
|
345 | + |
|
346 | + //some initial checks for proper values. |
|
347 | + //if QST_admin_only, then no matter what QST_required is we disable. |
|
348 | + if (! empty($this->_req_data['QST_admin_only'])) { |
|
349 | + $this->_req_data['QST_required'] = 0; |
|
350 | + } |
|
351 | + foreach ($model->field_settings() as $fieldName => $settings) { |
|
352 | + // basically if QSG_identifier is empty or not set |
|
353 | + if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) { |
|
354 | + $QSG_name = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : ''; |
|
355 | + $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true); |
|
356 | 356 | // dd($set_column_values); |
357 | - } //if the admin label is blank, use a slug version of the question text |
|
358 | - else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) { |
|
359 | - $QST_text = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : ''; |
|
360 | - $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10)); |
|
361 | - } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) { |
|
362 | - $set_column_values[$fieldName] = 0; |
|
363 | - } else if ($fieldName === 'QST_max') { |
|
364 | - $qst_system = EEM_Question::instance()->get_var( |
|
365 | - array( |
|
366 | - array( |
|
367 | - 'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0, |
|
368 | - ), |
|
369 | - ), |
|
370 | - 'QST_system'); |
|
371 | - $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system); |
|
372 | - if (empty($this->_req_data['QST_max']) || |
|
373 | - $this->_req_data['QST_max'] > $max_max |
|
374 | - ) { |
|
375 | - $set_column_values[$fieldName] = $max_max; |
|
376 | - } |
|
377 | - } |
|
378 | - |
|
379 | - |
|
380 | - //only add a property to the array if it's not null (otherwise the model should just use the default value) |
|
381 | - if ( |
|
382 | - ! isset($set_column_values[$fieldName]) && |
|
383 | - isset($this->_req_data[$fieldName]) |
|
384 | - ) { |
|
385 | - $set_column_values[$fieldName] = $this->_req_data[$fieldName]; |
|
386 | - } |
|
387 | - |
|
388 | - } |
|
389 | - return $set_column_values;//validation fo this data to be performed by the model before insertion. |
|
390 | - } |
|
391 | - |
|
392 | - |
|
393 | - /** |
|
394 | - *_questions_overview_list_table |
|
395 | - */ |
|
396 | - protected function _questions_overview_list_table() |
|
397 | - { |
|
398 | - $this->_search_btn_label = esc_html__('Questions', 'event_espresso'); |
|
399 | - $this->display_admin_list_table_page_with_sidebar(); |
|
400 | - } |
|
401 | - |
|
402 | - |
|
403 | - /** |
|
404 | - * _edit_question |
|
405 | - */ |
|
406 | - protected function _edit_question() |
|
407 | - { |
|
408 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
409 | - $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false; |
|
410 | - |
|
411 | - switch ($this->_req_action) { |
|
412 | - case 'add_question' : |
|
413 | - $this->_admin_page_title = esc_html__('Add Question', 'event_espresso'); |
|
414 | - break; |
|
415 | - case 'edit_question' : |
|
416 | - $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso'); |
|
417 | - break; |
|
418 | - default : |
|
419 | - $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action)); |
|
420 | - } |
|
421 | - |
|
422 | - // add PRC_ID to title if editing |
|
423 | - $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title; |
|
424 | - if ($ID) { |
|
425 | - $question = $this->_question_model->get_one_by_ID($ID); |
|
426 | - $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID)); |
|
427 | - $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields); |
|
428 | - } else { |
|
429 | - $question = EE_Question::new_instance(); |
|
430 | - $question->set_order_to_latest(); |
|
431 | - $this->_set_add_edit_form_tags('insert_question'); |
|
432 | - } |
|
433 | - if( $question->system_ID() === EEM_Attendee::system_question_phone ){ |
|
434 | - $question_types = array_intersect_key( |
|
435 | - EEM_Question::instance()->allowed_question_types(), |
|
436 | - array_flip( |
|
437 | - array( |
|
438 | - EEM_Question::QST_type_text, |
|
439 | - EEM_Question::QST_type_us_phone |
|
440 | - ) |
|
441 | - ) |
|
442 | - ); |
|
443 | - } else { |
|
444 | - $question_types = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types(); |
|
445 | - } |
|
446 | - $this->_template_args['QST_ID'] = $ID; |
|
447 | - $this->_template_args['question'] = $question; |
|
448 | - $this->_template_args['question_types'] = $question_types; |
|
449 | - $this->_template_args['max_max'] = EEM_Question::instance()->absolute_max_for_system_question( |
|
450 | - $question->system_ID() |
|
451 | - ); |
|
452 | - $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions(); |
|
453 | - $this->_set_publish_post_box_vars('id', $ID); |
|
454 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
455 | - REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php', |
|
456 | - $this->_template_args, true |
|
457 | - ); |
|
458 | - |
|
459 | - // the details template wrapper |
|
460 | - $this->display_admin_page_with_sidebar(); |
|
461 | - } |
|
462 | - |
|
463 | - |
|
464 | - /** |
|
465 | - * @return string |
|
466 | - */ |
|
467 | - protected function _get_question_type_descriptions() |
|
468 | - { |
|
469 | - EE_Registry::instance()->load_helper('HTML'); |
|
470 | - $descriptions = ''; |
|
471 | - $question_type_descriptions = EEM_Question::instance()->question_descriptions(); |
|
472 | - foreach ($question_type_descriptions as $type => $question_type_description) { |
|
473 | - if ($type == 'HTML_TEXTAREA') { |
|
474 | - $html = new EE_Simple_HTML_Validation_Strategy(); |
|
475 | - $question_type_description .= sprintf( |
|
476 | - esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'), |
|
477 | - '<br/>', |
|
478 | - $html->get_list_of_allowed_tags() |
|
479 | - ); |
|
480 | - } |
|
481 | - $descriptions .= EEH_HTML::p( |
|
482 | - $question_type_description, |
|
483 | - 'question_type_description-' . $type, |
|
484 | - 'question_type_description description', |
|
485 | - 'display:none;' |
|
486 | - ); |
|
487 | - } |
|
488 | - return $descriptions; |
|
489 | - } |
|
490 | - |
|
491 | - |
|
492 | - /** |
|
493 | - * @param bool|true $new_question |
|
494 | - * @throws \EE_Error |
|
495 | - */ |
|
496 | - protected function _insert_or_update_question($new_question = true) |
|
497 | - { |
|
498 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
499 | - $set_column_values = $this->_set_column_values_for($this->_question_model); |
|
500 | - if ($new_question) { |
|
501 | - $question = EE_Question::new_instance($set_column_values); |
|
502 | - $action_desc = 'added'; |
|
503 | - } else { |
|
504 | - $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID'])); |
|
505 | - foreach($set_column_values as $field => $new_value) { |
|
506 | - $question->set($field, $new_value); |
|
507 | - } |
|
508 | - $action_desc = 'updated'; |
|
509 | - } |
|
510 | - $success = $question->save(); |
|
511 | - $ID = $question->ID(); |
|
512 | - if ($ID && $question->should_have_question_options()) { |
|
513 | - //save the related options |
|
514 | - //trash removed options, save old ones |
|
515 | - //get list of all options |
|
516 | - $options = $question->options(); |
|
517 | - if (! empty($options)) { |
|
518 | - foreach ($options as $option_ID => $option) { |
|
519 | - $option_req_index = $this->_get_option_req_data_index($option_ID); |
|
520 | - if ($option_req_index !== false) { |
|
521 | - $option->save($this->_req_data['question_options'][$option_req_index]); |
|
522 | - } else { |
|
523 | - //not found, remove it |
|
524 | - $option->delete(); |
|
525 | - } |
|
526 | - } |
|
527 | - } |
|
528 | - //save new related options |
|
529 | - foreach ($this->_req_data['question_options'] as $index => $option_req_data) { |
|
530 | - //skip $index that is from our sample |
|
531 | - if ( $index === 'xxcountxx' ) { |
|
532 | - continue; |
|
533 | - } |
|
534 | - //note we allow saving blank options. |
|
535 | - if (empty($option_req_data['QSO_ID']) |
|
536 | - ) {//no ID! save it! |
|
537 | - $new_option = EE_Question_Option::new_instance(array( |
|
538 | - 'QSO_value' => $option_req_data['QSO_value'], |
|
539 | - 'QSO_desc' => $option_req_data['QSO_desc'], |
|
540 | - 'QSO_order' => $option_req_data['QSO_order'], |
|
541 | - 'QST_ID' => $question->ID(), |
|
542 | - )); |
|
543 | - $new_option->save(); |
|
544 | - } |
|
545 | - } |
|
546 | - } |
|
547 | - $query_args = array('action' => 'edit_question', 'QST_ID' => $ID); |
|
548 | - if ($success !== false) { |
|
549 | - $msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'), |
|
550 | - $this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'), |
|
551 | - $this->_question_model->item_name()); |
|
552 | - EE_Error::add_success($msg); |
|
553 | - } |
|
554 | - |
|
555 | - $this->_redirect_after_action(false, '', $action_desc, $query_args, true); |
|
556 | - } |
|
557 | - |
|
558 | - |
|
559 | - /** |
|
560 | - * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not |
|
561 | - * by ID |
|
562 | - * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously). |
|
563 | - * So, this function gets the index in that request data array called question_options. Returns FALSE if not found. |
|
564 | - * |
|
565 | - * @param int $ID of the question option to find |
|
566 | - * @return int index in question_options array if successful, FALSE if unsuccessful |
|
567 | - */ |
|
568 | - protected function _get_option_req_data_index($ID) |
|
569 | - { |
|
570 | - $req_data_for_question_options = $this->_req_data['question_options']; |
|
571 | - foreach ($req_data_for_question_options as $num => $option_data) { |
|
572 | - if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) { |
|
573 | - return $num; |
|
574 | - } |
|
575 | - } |
|
576 | - return false; |
|
577 | - } |
|
578 | - |
|
579 | - |
|
580 | - |
|
581 | - |
|
582 | - /***********/ |
|
583 | - /* QUERIES */ |
|
584 | - /** |
|
585 | - * For internal use in getting all the query parameters |
|
586 | - * (because it's pretty well the same between question, question groups, |
|
587 | - * and for both when searching for trashed and untrashed ones) |
|
588 | - * |
|
589 | - * @param EEM_Base $model either EEM_Question or EEM_Question_Group |
|
590 | - * @param int $per_page |
|
591 | - * @param int $current_page |
|
592 | - * @return array lik EEM_Base::get_all's $query_params parameter |
|
593 | - */ |
|
594 | - protected function get_query_params($model, $per_page = 10, $current_page = 10) |
|
595 | - { |
|
596 | - $query_params = array(); |
|
597 | - $offset = ($current_page - 1) * $per_page; |
|
598 | - $query_params['limit'] = array($offset, $per_page); |
|
599 | - $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC'; |
|
600 | - $orderby_field = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order'; |
|
601 | - $field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby']; |
|
602 | - $query_params['order_by'] = array($field_to_order_by => $order); |
|
603 | - $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null; |
|
604 | - if (! empty($search_string)) { |
|
605 | - if ($model instanceof EEM_Question_Group) { |
|
606 | - $query_params[0] = array( |
|
607 | - 'OR' => array( |
|
608 | - 'QSG_name' => array('LIKE', "%$search_string%"), |
|
609 | - 'QSG_desc' => array('LIKE', "%$search_string%"), |
|
610 | - ), |
|
611 | - ); |
|
612 | - } else { |
|
613 | - $query_params[0] = array( |
|
614 | - 'QST_display_text' => array('LIKE', "%$search_string%"), |
|
615 | - ); |
|
616 | - } |
|
617 | - } |
|
618 | - |
|
619 | - //capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented) |
|
620 | - /*if ( $model instanceof EEM_Question_Group ) { |
|
357 | + } //if the admin label is blank, use a slug version of the question text |
|
358 | + else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) { |
|
359 | + $QST_text = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : ''; |
|
360 | + $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10)); |
|
361 | + } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) { |
|
362 | + $set_column_values[$fieldName] = 0; |
|
363 | + } else if ($fieldName === 'QST_max') { |
|
364 | + $qst_system = EEM_Question::instance()->get_var( |
|
365 | + array( |
|
366 | + array( |
|
367 | + 'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0, |
|
368 | + ), |
|
369 | + ), |
|
370 | + 'QST_system'); |
|
371 | + $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system); |
|
372 | + if (empty($this->_req_data['QST_max']) || |
|
373 | + $this->_req_data['QST_max'] > $max_max |
|
374 | + ) { |
|
375 | + $set_column_values[$fieldName] = $max_max; |
|
376 | + } |
|
377 | + } |
|
378 | + |
|
379 | + |
|
380 | + //only add a property to the array if it's not null (otherwise the model should just use the default value) |
|
381 | + if ( |
|
382 | + ! isset($set_column_values[$fieldName]) && |
|
383 | + isset($this->_req_data[$fieldName]) |
|
384 | + ) { |
|
385 | + $set_column_values[$fieldName] = $this->_req_data[$fieldName]; |
|
386 | + } |
|
387 | + |
|
388 | + } |
|
389 | + return $set_column_values;//validation fo this data to be performed by the model before insertion. |
|
390 | + } |
|
391 | + |
|
392 | + |
|
393 | + /** |
|
394 | + *_questions_overview_list_table |
|
395 | + */ |
|
396 | + protected function _questions_overview_list_table() |
|
397 | + { |
|
398 | + $this->_search_btn_label = esc_html__('Questions', 'event_espresso'); |
|
399 | + $this->display_admin_list_table_page_with_sidebar(); |
|
400 | + } |
|
401 | + |
|
402 | + |
|
403 | + /** |
|
404 | + * _edit_question |
|
405 | + */ |
|
406 | + protected function _edit_question() |
|
407 | + { |
|
408 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
409 | + $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false; |
|
410 | + |
|
411 | + switch ($this->_req_action) { |
|
412 | + case 'add_question' : |
|
413 | + $this->_admin_page_title = esc_html__('Add Question', 'event_espresso'); |
|
414 | + break; |
|
415 | + case 'edit_question' : |
|
416 | + $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso'); |
|
417 | + break; |
|
418 | + default : |
|
419 | + $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action)); |
|
420 | + } |
|
421 | + |
|
422 | + // add PRC_ID to title if editing |
|
423 | + $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title; |
|
424 | + if ($ID) { |
|
425 | + $question = $this->_question_model->get_one_by_ID($ID); |
|
426 | + $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID)); |
|
427 | + $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields); |
|
428 | + } else { |
|
429 | + $question = EE_Question::new_instance(); |
|
430 | + $question->set_order_to_latest(); |
|
431 | + $this->_set_add_edit_form_tags('insert_question'); |
|
432 | + } |
|
433 | + if( $question->system_ID() === EEM_Attendee::system_question_phone ){ |
|
434 | + $question_types = array_intersect_key( |
|
435 | + EEM_Question::instance()->allowed_question_types(), |
|
436 | + array_flip( |
|
437 | + array( |
|
438 | + EEM_Question::QST_type_text, |
|
439 | + EEM_Question::QST_type_us_phone |
|
440 | + ) |
|
441 | + ) |
|
442 | + ); |
|
443 | + } else { |
|
444 | + $question_types = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types(); |
|
445 | + } |
|
446 | + $this->_template_args['QST_ID'] = $ID; |
|
447 | + $this->_template_args['question'] = $question; |
|
448 | + $this->_template_args['question_types'] = $question_types; |
|
449 | + $this->_template_args['max_max'] = EEM_Question::instance()->absolute_max_for_system_question( |
|
450 | + $question->system_ID() |
|
451 | + ); |
|
452 | + $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions(); |
|
453 | + $this->_set_publish_post_box_vars('id', $ID); |
|
454 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
455 | + REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php', |
|
456 | + $this->_template_args, true |
|
457 | + ); |
|
458 | + |
|
459 | + // the details template wrapper |
|
460 | + $this->display_admin_page_with_sidebar(); |
|
461 | + } |
|
462 | + |
|
463 | + |
|
464 | + /** |
|
465 | + * @return string |
|
466 | + */ |
|
467 | + protected function _get_question_type_descriptions() |
|
468 | + { |
|
469 | + EE_Registry::instance()->load_helper('HTML'); |
|
470 | + $descriptions = ''; |
|
471 | + $question_type_descriptions = EEM_Question::instance()->question_descriptions(); |
|
472 | + foreach ($question_type_descriptions as $type => $question_type_description) { |
|
473 | + if ($type == 'HTML_TEXTAREA') { |
|
474 | + $html = new EE_Simple_HTML_Validation_Strategy(); |
|
475 | + $question_type_description .= sprintf( |
|
476 | + esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'), |
|
477 | + '<br/>', |
|
478 | + $html->get_list_of_allowed_tags() |
|
479 | + ); |
|
480 | + } |
|
481 | + $descriptions .= EEH_HTML::p( |
|
482 | + $question_type_description, |
|
483 | + 'question_type_description-' . $type, |
|
484 | + 'question_type_description description', |
|
485 | + 'display:none;' |
|
486 | + ); |
|
487 | + } |
|
488 | + return $descriptions; |
|
489 | + } |
|
490 | + |
|
491 | + |
|
492 | + /** |
|
493 | + * @param bool|true $new_question |
|
494 | + * @throws \EE_Error |
|
495 | + */ |
|
496 | + protected function _insert_or_update_question($new_question = true) |
|
497 | + { |
|
498 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
499 | + $set_column_values = $this->_set_column_values_for($this->_question_model); |
|
500 | + if ($new_question) { |
|
501 | + $question = EE_Question::new_instance($set_column_values); |
|
502 | + $action_desc = 'added'; |
|
503 | + } else { |
|
504 | + $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID'])); |
|
505 | + foreach($set_column_values as $field => $new_value) { |
|
506 | + $question->set($field, $new_value); |
|
507 | + } |
|
508 | + $action_desc = 'updated'; |
|
509 | + } |
|
510 | + $success = $question->save(); |
|
511 | + $ID = $question->ID(); |
|
512 | + if ($ID && $question->should_have_question_options()) { |
|
513 | + //save the related options |
|
514 | + //trash removed options, save old ones |
|
515 | + //get list of all options |
|
516 | + $options = $question->options(); |
|
517 | + if (! empty($options)) { |
|
518 | + foreach ($options as $option_ID => $option) { |
|
519 | + $option_req_index = $this->_get_option_req_data_index($option_ID); |
|
520 | + if ($option_req_index !== false) { |
|
521 | + $option->save($this->_req_data['question_options'][$option_req_index]); |
|
522 | + } else { |
|
523 | + //not found, remove it |
|
524 | + $option->delete(); |
|
525 | + } |
|
526 | + } |
|
527 | + } |
|
528 | + //save new related options |
|
529 | + foreach ($this->_req_data['question_options'] as $index => $option_req_data) { |
|
530 | + //skip $index that is from our sample |
|
531 | + if ( $index === 'xxcountxx' ) { |
|
532 | + continue; |
|
533 | + } |
|
534 | + //note we allow saving blank options. |
|
535 | + if (empty($option_req_data['QSO_ID']) |
|
536 | + ) {//no ID! save it! |
|
537 | + $new_option = EE_Question_Option::new_instance(array( |
|
538 | + 'QSO_value' => $option_req_data['QSO_value'], |
|
539 | + 'QSO_desc' => $option_req_data['QSO_desc'], |
|
540 | + 'QSO_order' => $option_req_data['QSO_order'], |
|
541 | + 'QST_ID' => $question->ID(), |
|
542 | + )); |
|
543 | + $new_option->save(); |
|
544 | + } |
|
545 | + } |
|
546 | + } |
|
547 | + $query_args = array('action' => 'edit_question', 'QST_ID' => $ID); |
|
548 | + if ($success !== false) { |
|
549 | + $msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'), |
|
550 | + $this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'), |
|
551 | + $this->_question_model->item_name()); |
|
552 | + EE_Error::add_success($msg); |
|
553 | + } |
|
554 | + |
|
555 | + $this->_redirect_after_action(false, '', $action_desc, $query_args, true); |
|
556 | + } |
|
557 | + |
|
558 | + |
|
559 | + /** |
|
560 | + * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not |
|
561 | + * by ID |
|
562 | + * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously). |
|
563 | + * So, this function gets the index in that request data array called question_options. Returns FALSE if not found. |
|
564 | + * |
|
565 | + * @param int $ID of the question option to find |
|
566 | + * @return int index in question_options array if successful, FALSE if unsuccessful |
|
567 | + */ |
|
568 | + protected function _get_option_req_data_index($ID) |
|
569 | + { |
|
570 | + $req_data_for_question_options = $this->_req_data['question_options']; |
|
571 | + foreach ($req_data_for_question_options as $num => $option_data) { |
|
572 | + if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) { |
|
573 | + return $num; |
|
574 | + } |
|
575 | + } |
|
576 | + return false; |
|
577 | + } |
|
578 | + |
|
579 | + |
|
580 | + |
|
581 | + |
|
582 | + /***********/ |
|
583 | + /* QUERIES */ |
|
584 | + /** |
|
585 | + * For internal use in getting all the query parameters |
|
586 | + * (because it's pretty well the same between question, question groups, |
|
587 | + * and for both when searching for trashed and untrashed ones) |
|
588 | + * |
|
589 | + * @param EEM_Base $model either EEM_Question or EEM_Question_Group |
|
590 | + * @param int $per_page |
|
591 | + * @param int $current_page |
|
592 | + * @return array lik EEM_Base::get_all's $query_params parameter |
|
593 | + */ |
|
594 | + protected function get_query_params($model, $per_page = 10, $current_page = 10) |
|
595 | + { |
|
596 | + $query_params = array(); |
|
597 | + $offset = ($current_page - 1) * $per_page; |
|
598 | + $query_params['limit'] = array($offset, $per_page); |
|
599 | + $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC'; |
|
600 | + $orderby_field = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order'; |
|
601 | + $field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby']; |
|
602 | + $query_params['order_by'] = array($field_to_order_by => $order); |
|
603 | + $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null; |
|
604 | + if (! empty($search_string)) { |
|
605 | + if ($model instanceof EEM_Question_Group) { |
|
606 | + $query_params[0] = array( |
|
607 | + 'OR' => array( |
|
608 | + 'QSG_name' => array('LIKE', "%$search_string%"), |
|
609 | + 'QSG_desc' => array('LIKE', "%$search_string%"), |
|
610 | + ), |
|
611 | + ); |
|
612 | + } else { |
|
613 | + $query_params[0] = array( |
|
614 | + 'QST_display_text' => array('LIKE', "%$search_string%"), |
|
615 | + ); |
|
616 | + } |
|
617 | + } |
|
618 | + |
|
619 | + //capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented) |
|
620 | + /*if ( $model instanceof EEM_Question_Group ) { |
|
621 | 621 | if ( ! EE_Registry::instance()->CAP->current_user_can( 'edit_others_question_groups', 'espresso_registration_form_edit_question_group' ) ) { |
622 | 622 | $query_params[0] = array( |
623 | 623 | 'AND' => array( |
@@ -647,62 +647,62 @@ discard block |
||
647 | 647 | } |
648 | 648 | }/**/ |
649 | 649 | |
650 | - return $query_params; |
|
651 | - |
|
652 | - } |
|
653 | - |
|
654 | - |
|
655 | - /** |
|
656 | - * @param int $per_page |
|
657 | - * @param int $current_page |
|
658 | - * @param bool|false $count |
|
659 | - * @return \EE_Soft_Delete_Base_Class[]|int |
|
660 | - */ |
|
661 | - public function get_questions($per_page = 10, $current_page = 1, $count = false) |
|
662 | - { |
|
663 | - $QST = EEM_Question::instance(); |
|
664 | - $query_params = $this->get_query_params($QST, $per_page, $current_page); |
|
665 | - if ($count) { |
|
666 | - $where = isset($query_params[0]) ? array($query_params[0]) : array(); |
|
667 | - $results = $QST->count($where); |
|
668 | - } else { |
|
669 | - $results = $QST->get_all($query_params); |
|
670 | - } |
|
671 | - return $results; |
|
672 | - |
|
673 | - } |
|
674 | - |
|
675 | - |
|
676 | - /** |
|
677 | - * @param $per_page |
|
678 | - * @param int $current_page |
|
679 | - * @param bool|false $count |
|
680 | - * @return \EE_Soft_Delete_Base_Class[]|int |
|
681 | - */ |
|
682 | - public function get_trashed_questions($per_page, $current_page = 1, $count = false) |
|
683 | - { |
|
684 | - $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page); |
|
685 | - $where = isset($query_params[0]) ? array($query_params[0]) : array(); |
|
686 | - $questions = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params); |
|
687 | - return $questions; |
|
688 | - } |
|
689 | - |
|
690 | - |
|
691 | - /** |
|
692 | - * @param $per_page |
|
693 | - * @param int $current_page |
|
694 | - * @param bool|false $count |
|
695 | - * @return \EE_Soft_Delete_Base_Class[] |
|
696 | - */ |
|
697 | - public function get_question_groups($per_page, $current_page = 1, $count = false) |
|
698 | - { |
|
699 | - /** @type EEM_Question_Group $questionGroupModel */ |
|
700 | - $questionGroupModel = EEM_Question_Group::instance(); |
|
701 | - //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items |
|
702 | - return $questionGroupModel->get_all( |
|
703 | - $this->get_query_params($questionGroupModel, $per_page, $current_page) |
|
704 | - ); |
|
705 | - } |
|
650 | + return $query_params; |
|
651 | + |
|
652 | + } |
|
653 | + |
|
654 | + |
|
655 | + /** |
|
656 | + * @param int $per_page |
|
657 | + * @param int $current_page |
|
658 | + * @param bool|false $count |
|
659 | + * @return \EE_Soft_Delete_Base_Class[]|int |
|
660 | + */ |
|
661 | + public function get_questions($per_page = 10, $current_page = 1, $count = false) |
|
662 | + { |
|
663 | + $QST = EEM_Question::instance(); |
|
664 | + $query_params = $this->get_query_params($QST, $per_page, $current_page); |
|
665 | + if ($count) { |
|
666 | + $where = isset($query_params[0]) ? array($query_params[0]) : array(); |
|
667 | + $results = $QST->count($where); |
|
668 | + } else { |
|
669 | + $results = $QST->get_all($query_params); |
|
670 | + } |
|
671 | + return $results; |
|
672 | + |
|
673 | + } |
|
674 | + |
|
675 | + |
|
676 | + /** |
|
677 | + * @param $per_page |
|
678 | + * @param int $current_page |
|
679 | + * @param bool|false $count |
|
680 | + * @return \EE_Soft_Delete_Base_Class[]|int |
|
681 | + */ |
|
682 | + public function get_trashed_questions($per_page, $current_page = 1, $count = false) |
|
683 | + { |
|
684 | + $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page); |
|
685 | + $where = isset($query_params[0]) ? array($query_params[0]) : array(); |
|
686 | + $questions = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params); |
|
687 | + return $questions; |
|
688 | + } |
|
689 | + |
|
690 | + |
|
691 | + /** |
|
692 | + * @param $per_page |
|
693 | + * @param int $current_page |
|
694 | + * @param bool|false $count |
|
695 | + * @return \EE_Soft_Delete_Base_Class[] |
|
696 | + */ |
|
697 | + public function get_question_groups($per_page, $current_page = 1, $count = false) |
|
698 | + { |
|
699 | + /** @type EEM_Question_Group $questionGroupModel */ |
|
700 | + $questionGroupModel = EEM_Question_Group::instance(); |
|
701 | + //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items |
|
702 | + return $questionGroupModel->get_all( |
|
703 | + $this->get_query_params($questionGroupModel, $per_page, $current_page) |
|
704 | + ); |
|
705 | + } |
|
706 | 706 | |
707 | 707 | |
708 | 708 | } //ends Registration_Form_Admin_Page class |
@@ -1,5 +1,5 @@ discard block |
||
1 | 1 | <?php |
2 | -if (! defined('EVENT_ESPRESSO_VERSION')) { |
|
2 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
3 | 3 | exit('NO direct script access allowed'); |
4 | 4 | } |
5 | 5 | |
@@ -66,8 +66,8 @@ discard block |
||
66 | 66 | */ |
67 | 67 | public function __construct($routing = true) |
68 | 68 | { |
69 | - require_once(EE_MODELS . 'EEM_Question.model.php'); |
|
70 | - require_once(EE_MODELS . 'EEM_Question_Group.model.php'); |
|
69 | + require_once(EE_MODELS.'EEM_Question.model.php'); |
|
70 | + require_once(EE_MODELS.'EEM_Question_Group.model.php'); |
|
71 | 71 | $this->_question_model = EEM_Question::instance(); |
72 | 72 | $this->_question_group_model = EEM_Question_Group::instance(); |
73 | 73 | parent::__construct($routing); |
@@ -232,7 +232,7 @@ discard block |
||
232 | 232 | public function load_scripts_styles() |
233 | 233 | { |
234 | 234 | wp_register_style('espresso_registration', |
235 | - REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
235 | + REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
236 | 236 | wp_enqueue_style('espresso_registration'); |
237 | 237 | } |
238 | 238 | |
@@ -258,7 +258,7 @@ discard block |
||
258 | 258 | { |
259 | 259 | $this->load_scripts_styles_forms(); |
260 | 260 | wp_register_script('espresso_registration_form_single', |
261 | - REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
261 | + REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
262 | 262 | EVENT_ESPRESSO_VERSION, true); |
263 | 263 | wp_enqueue_script('espresso_registration_form_single'); |
264 | 264 | } |
@@ -267,7 +267,7 @@ discard block |
||
267 | 267 | { |
268 | 268 | $this->load_scripts_styles_forms(); |
269 | 269 | wp_register_script('espresso_registration_form_single', |
270 | - REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
270 | + REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'), |
|
271 | 271 | EVENT_ESPRESSO_VERSION, true); |
272 | 272 | wp_enqueue_script('espresso_registration_form_single'); |
273 | 273 | } |
@@ -275,7 +275,7 @@ discard block |
||
275 | 275 | |
276 | 276 | public function recaptcha_info_help_tab() |
277 | 277 | { |
278 | - $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php'; |
|
278 | + $template = REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php'; |
|
279 | 279 | EEH_Template::display_template($template, array()); |
280 | 280 | } |
281 | 281 | |
@@ -324,10 +324,10 @@ discard block |
||
324 | 324 | protected function _questions_groups_preview() |
325 | 325 | { |
326 | 326 | $this->_admin_page_title = esc_html__('Question Groups (Preview)', 'event_espresso'); |
327 | - $this->_template_args['preview_img'] = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot', |
|
328 | - 'event_espresso') . '" />'; |
|
329 | - $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.', |
|
330 | - 'event_espresso') . '</strong>'; |
|
327 | + $this->_template_args['preview_img'] = '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'.esc_attr__('Preview Question Groups Overview List Table screenshot', |
|
328 | + 'event_espresso').'" />'; |
|
329 | + $this->_template_args['preview_text'] = '<strong>'.esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.', |
|
330 | + 'event_espresso').'</strong>'; |
|
331 | 331 | $this->display_admin_caf_preview_page('question_groups_tab'); |
332 | 332 | } |
333 | 333 | |
@@ -345,20 +345,20 @@ discard block |
||
345 | 345 | |
346 | 346 | //some initial checks for proper values. |
347 | 347 | //if QST_admin_only, then no matter what QST_required is we disable. |
348 | - if (! empty($this->_req_data['QST_admin_only'])) { |
|
348 | + if ( ! empty($this->_req_data['QST_admin_only'])) { |
|
349 | 349 | $this->_req_data['QST_required'] = 0; |
350 | 350 | } |
351 | 351 | foreach ($model->field_settings() as $fieldName => $settings) { |
352 | 352 | // basically if QSG_identifier is empty or not set |
353 | 353 | if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) { |
354 | 354 | $QSG_name = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : ''; |
355 | - $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true); |
|
355 | + $set_column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true); |
|
356 | 356 | // dd($set_column_values); |
357 | 357 | } //if the admin label is blank, use a slug version of the question text |
358 | 358 | else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) { |
359 | 359 | $QST_text = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : ''; |
360 | 360 | $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10)); |
361 | - } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) { |
|
361 | + } else if ($fieldName === 'QST_admin_only' && ( ! isset($this->_req_data['QST_admin_only']))) { |
|
362 | 362 | $set_column_values[$fieldName] = 0; |
363 | 363 | } else if ($fieldName === 'QST_max') { |
364 | 364 | $qst_system = EEM_Question::instance()->get_var( |
@@ -368,7 +368,7 @@ discard block |
||
368 | 368 | ), |
369 | 369 | ), |
370 | 370 | 'QST_system'); |
371 | - $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system); |
|
371 | + $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system); |
|
372 | 372 | if (empty($this->_req_data['QST_max']) || |
373 | 373 | $this->_req_data['QST_max'] > $max_max |
374 | 374 | ) { |
@@ -386,7 +386,7 @@ discard block |
||
386 | 386 | } |
387 | 387 | |
388 | 388 | } |
389 | - return $set_column_values;//validation fo this data to be performed by the model before insertion. |
|
389 | + return $set_column_values; //validation fo this data to be performed by the model before insertion. |
|
390 | 390 | } |
391 | 391 | |
392 | 392 | |
@@ -420,7 +420,7 @@ discard block |
||
420 | 420 | } |
421 | 421 | |
422 | 422 | // add PRC_ID to title if editing |
423 | - $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title; |
|
423 | + $this->_admin_page_title = $ID ? $this->_admin_page_title.' # '.$ID : $this->_admin_page_title; |
|
424 | 424 | if ($ID) { |
425 | 425 | $question = $this->_question_model->get_one_by_ID($ID); |
426 | 426 | $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID)); |
@@ -430,7 +430,7 @@ discard block |
||
430 | 430 | $question->set_order_to_latest(); |
431 | 431 | $this->_set_add_edit_form_tags('insert_question'); |
432 | 432 | } |
433 | - if( $question->system_ID() === EEM_Attendee::system_question_phone ){ |
|
433 | + if ($question->system_ID() === EEM_Attendee::system_question_phone) { |
|
434 | 434 | $question_types = array_intersect_key( |
435 | 435 | EEM_Question::instance()->allowed_question_types(), |
436 | 436 | array_flip( |
@@ -452,7 +452,7 @@ discard block |
||
452 | 452 | $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions(); |
453 | 453 | $this->_set_publish_post_box_vars('id', $ID); |
454 | 454 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
455 | - REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php', |
|
455 | + REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php', |
|
456 | 456 | $this->_template_args, true |
457 | 457 | ); |
458 | 458 | |
@@ -480,7 +480,7 @@ discard block |
||
480 | 480 | } |
481 | 481 | $descriptions .= EEH_HTML::p( |
482 | 482 | $question_type_description, |
483 | - 'question_type_description-' . $type, |
|
483 | + 'question_type_description-'.$type, |
|
484 | 484 | 'question_type_description description', |
485 | 485 | 'display:none;' |
486 | 486 | ); |
@@ -501,8 +501,8 @@ discard block |
||
501 | 501 | $question = EE_Question::new_instance($set_column_values); |
502 | 502 | $action_desc = 'added'; |
503 | 503 | } else { |
504 | - $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID'])); |
|
505 | - foreach($set_column_values as $field => $new_value) { |
|
504 | + $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID'])); |
|
505 | + foreach ($set_column_values as $field => $new_value) { |
|
506 | 506 | $question->set($field, $new_value); |
507 | 507 | } |
508 | 508 | $action_desc = 'updated'; |
@@ -513,8 +513,8 @@ discard block |
||
513 | 513 | //save the related options |
514 | 514 | //trash removed options, save old ones |
515 | 515 | //get list of all options |
516 | - $options = $question->options(); |
|
517 | - if (! empty($options)) { |
|
516 | + $options = $question->options(); |
|
517 | + if ( ! empty($options)) { |
|
518 | 518 | foreach ($options as $option_ID => $option) { |
519 | 519 | $option_req_index = $this->_get_option_req_data_index($option_ID); |
520 | 520 | if ($option_req_index !== false) { |
@@ -528,7 +528,7 @@ discard block |
||
528 | 528 | //save new related options |
529 | 529 | foreach ($this->_req_data['question_options'] as $index => $option_req_data) { |
530 | 530 | //skip $index that is from our sample |
531 | - if ( $index === 'xxcountxx' ) { |
|
531 | + if ($index === 'xxcountxx') { |
|
532 | 532 | continue; |
533 | 533 | } |
534 | 534 | //note we allow saving blank options. |
@@ -569,7 +569,7 @@ discard block |
||
569 | 569 | { |
570 | 570 | $req_data_for_question_options = $this->_req_data['question_options']; |
571 | 571 | foreach ($req_data_for_question_options as $num => $option_data) { |
572 | - if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) { |
|
572 | + if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) { |
|
573 | 573 | return $num; |
574 | 574 | } |
575 | 575 | } |
@@ -601,7 +601,7 @@ discard block |
||
601 | 601 | $field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby']; |
602 | 602 | $query_params['order_by'] = array($field_to_order_by => $order); |
603 | 603 | $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null; |
604 | - if (! empty($search_string)) { |
|
604 | + if ( ! empty($search_string)) { |
|
605 | 605 | if ($model instanceof EEM_Question_Group) { |
606 | 606 | $query_params[0] = array( |
607 | 607 | 'OR' => array( |
@@ -38,217 +38,217 @@ |
||
38 | 38 | * @since 4.0 |
39 | 39 | */ |
40 | 40 | if (function_exists('espresso_version')) { |
41 | - if (! function_exists('espresso_duplicate_plugin_error')) { |
|
42 | - /** |
|
43 | - * espresso_duplicate_plugin_error |
|
44 | - * displays if more than one version of EE is activated at the same time |
|
45 | - */ |
|
46 | - function espresso_duplicate_plugin_error() |
|
47 | - { |
|
48 | - ?> |
|
41 | + if (! function_exists('espresso_duplicate_plugin_error')) { |
|
42 | + /** |
|
43 | + * espresso_duplicate_plugin_error |
|
44 | + * displays if more than one version of EE is activated at the same time |
|
45 | + */ |
|
46 | + function espresso_duplicate_plugin_error() |
|
47 | + { |
|
48 | + ?> |
|
49 | 49 | <div class="error"> |
50 | 50 | <p> |
51 | 51 | <?php |
52 | - echo esc_html__( |
|
53 | - 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
54 | - 'event_espresso' |
|
55 | - ); ?> |
|
52 | + echo esc_html__( |
|
53 | + 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
54 | + 'event_espresso' |
|
55 | + ); ?> |
|
56 | 56 | </p> |
57 | 57 | </div> |
58 | 58 | <?php |
59 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
60 | - } |
|
61 | - } |
|
62 | - add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
59 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
60 | + } |
|
61 | + } |
|
62 | + add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
63 | 63 | |
64 | 64 | } else { |
65 | - define('EE_MIN_PHP_VER_REQUIRED', '5.3.9'); |
|
66 | - if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
67 | - /** |
|
68 | - * espresso_minimum_php_version_error |
|
69 | - * |
|
70 | - * @return void |
|
71 | - */ |
|
72 | - function espresso_minimum_php_version_error() |
|
73 | - { |
|
74 | - ?> |
|
65 | + define('EE_MIN_PHP_VER_REQUIRED', '5.3.9'); |
|
66 | + if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
67 | + /** |
|
68 | + * espresso_minimum_php_version_error |
|
69 | + * |
|
70 | + * @return void |
|
71 | + */ |
|
72 | + function espresso_minimum_php_version_error() |
|
73 | + { |
|
74 | + ?> |
|
75 | 75 | <div class="error"> |
76 | 76 | <p> |
77 | 77 | <?php |
78 | - printf( |
|
79 | - esc_html__( |
|
80 | - 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
81 | - 'event_espresso' |
|
82 | - ), |
|
83 | - EE_MIN_PHP_VER_REQUIRED, |
|
84 | - PHP_VERSION, |
|
85 | - '<br/>', |
|
86 | - '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>' |
|
87 | - ); |
|
88 | - ?> |
|
78 | + printf( |
|
79 | + esc_html__( |
|
80 | + 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
81 | + 'event_espresso' |
|
82 | + ), |
|
83 | + EE_MIN_PHP_VER_REQUIRED, |
|
84 | + PHP_VERSION, |
|
85 | + '<br/>', |
|
86 | + '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>' |
|
87 | + ); |
|
88 | + ?> |
|
89 | 89 | </p> |
90 | 90 | </div> |
91 | 91 | <?php |
92 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
93 | - } |
|
92 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
93 | + } |
|
94 | 94 | |
95 | - add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
96 | - } else { |
|
97 | - define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
98 | - /** |
|
99 | - * espresso_version |
|
100 | - * Returns the plugin version |
|
101 | - * |
|
102 | - * @return string |
|
103 | - */ |
|
104 | - function espresso_version() |
|
105 | - { |
|
106 | - return apply_filters('FHEE__espresso__espresso_version', '4.9.52.rc.005'); |
|
107 | - } |
|
95 | + add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
96 | + } else { |
|
97 | + define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
98 | + /** |
|
99 | + * espresso_version |
|
100 | + * Returns the plugin version |
|
101 | + * |
|
102 | + * @return string |
|
103 | + */ |
|
104 | + function espresso_version() |
|
105 | + { |
|
106 | + return apply_filters('FHEE__espresso__espresso_version', '4.9.52.rc.005'); |
|
107 | + } |
|
108 | 108 | |
109 | - /** |
|
110 | - * espresso_plugin_activation |
|
111 | - * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
112 | - */ |
|
113 | - function espresso_plugin_activation() |
|
114 | - { |
|
115 | - update_option('ee_espresso_activation', true); |
|
116 | - } |
|
109 | + /** |
|
110 | + * espresso_plugin_activation |
|
111 | + * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
112 | + */ |
|
113 | + function espresso_plugin_activation() |
|
114 | + { |
|
115 | + update_option('ee_espresso_activation', true); |
|
116 | + } |
|
117 | 117 | |
118 | - register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
119 | - /** |
|
120 | - * espresso_load_error_handling |
|
121 | - * this function loads EE's class for handling exceptions and errors |
|
122 | - */ |
|
123 | - function espresso_load_error_handling() |
|
124 | - { |
|
125 | - static $error_handling_loaded = false; |
|
126 | - if ($error_handling_loaded) { |
|
127 | - return; |
|
128 | - } |
|
129 | - // load debugging tools |
|
130 | - if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) { |
|
131 | - require_once EE_HELPERS . 'EEH_Debug_Tools.helper.php'; |
|
132 | - \EEH_Debug_Tools::instance(); |
|
133 | - } |
|
134 | - // load error handling |
|
135 | - if (is_readable(EE_CORE . 'EE_Error.core.php')) { |
|
136 | - require_once EE_CORE . 'EE_Error.core.php'; |
|
137 | - } else { |
|
138 | - wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso')); |
|
139 | - } |
|
140 | - $error_handling_loaded = true; |
|
141 | - } |
|
118 | + register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
119 | + /** |
|
120 | + * espresso_load_error_handling |
|
121 | + * this function loads EE's class for handling exceptions and errors |
|
122 | + */ |
|
123 | + function espresso_load_error_handling() |
|
124 | + { |
|
125 | + static $error_handling_loaded = false; |
|
126 | + if ($error_handling_loaded) { |
|
127 | + return; |
|
128 | + } |
|
129 | + // load debugging tools |
|
130 | + if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) { |
|
131 | + require_once EE_HELPERS . 'EEH_Debug_Tools.helper.php'; |
|
132 | + \EEH_Debug_Tools::instance(); |
|
133 | + } |
|
134 | + // load error handling |
|
135 | + if (is_readable(EE_CORE . 'EE_Error.core.php')) { |
|
136 | + require_once EE_CORE . 'EE_Error.core.php'; |
|
137 | + } else { |
|
138 | + wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso')); |
|
139 | + } |
|
140 | + $error_handling_loaded = true; |
|
141 | + } |
|
142 | 142 | |
143 | - /** |
|
144 | - * espresso_load_required |
|
145 | - * given a class name and path, this function will load that file or throw an exception |
|
146 | - * |
|
147 | - * @param string $classname |
|
148 | - * @param string $full_path_to_file |
|
149 | - * @throws EE_Error |
|
150 | - */ |
|
151 | - function espresso_load_required($classname, $full_path_to_file) |
|
152 | - { |
|
153 | - if (is_readable($full_path_to_file)) { |
|
154 | - require_once $full_path_to_file; |
|
155 | - } else { |
|
156 | - throw new \EE_Error ( |
|
157 | - sprintf( |
|
158 | - esc_html__( |
|
159 | - 'The %s class file could not be located or is not readable due to file permissions.', |
|
160 | - 'event_espresso' |
|
161 | - ), |
|
162 | - $classname |
|
163 | - ) |
|
164 | - ); |
|
165 | - } |
|
166 | - } |
|
143 | + /** |
|
144 | + * espresso_load_required |
|
145 | + * given a class name and path, this function will load that file or throw an exception |
|
146 | + * |
|
147 | + * @param string $classname |
|
148 | + * @param string $full_path_to_file |
|
149 | + * @throws EE_Error |
|
150 | + */ |
|
151 | + function espresso_load_required($classname, $full_path_to_file) |
|
152 | + { |
|
153 | + if (is_readable($full_path_to_file)) { |
|
154 | + require_once $full_path_to_file; |
|
155 | + } else { |
|
156 | + throw new \EE_Error ( |
|
157 | + sprintf( |
|
158 | + esc_html__( |
|
159 | + 'The %s class file could not be located or is not readable due to file permissions.', |
|
160 | + 'event_espresso' |
|
161 | + ), |
|
162 | + $classname |
|
163 | + ) |
|
164 | + ); |
|
165 | + } |
|
166 | + } |
|
167 | 167 | |
168 | - /** |
|
169 | - * @since 4.9.27 |
|
170 | - * @throws \EE_Error |
|
171 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
172 | - * @throws \EventEspresso\core\exceptions\InvalidEntityException |
|
173 | - * @throws \EventEspresso\core\exceptions\InvalidIdentifierException |
|
174 | - * @throws \EventEspresso\core\exceptions\InvalidClassException |
|
175 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
176 | - * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException |
|
177 | - * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException |
|
178 | - * @throws \OutOfBoundsException |
|
179 | - */ |
|
180 | - function bootstrap_espresso() |
|
181 | - { |
|
182 | - require_once __DIR__ . '/core/espresso_definitions.php'; |
|
183 | - try { |
|
184 | - espresso_load_error_handling(); |
|
185 | - espresso_load_required( |
|
186 | - 'EEH_Base', |
|
187 | - EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php' |
|
188 | - ); |
|
189 | - espresso_load_required( |
|
190 | - 'EEH_File', |
|
191 | - EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php' |
|
192 | - ); |
|
193 | - espresso_load_required( |
|
194 | - 'EEH_File', |
|
195 | - EE_CORE . 'helpers' . DS . 'EEH_File.helper.php' |
|
196 | - ); |
|
197 | - espresso_load_required( |
|
198 | - 'EEH_Array', |
|
199 | - EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php' |
|
200 | - ); |
|
201 | - // instantiate and configure PSR4 autoloader |
|
202 | - espresso_load_required( |
|
203 | - 'Psr4Autoloader', |
|
204 | - EE_CORE . 'Psr4Autoloader.php' |
|
205 | - ); |
|
206 | - espresso_load_required( |
|
207 | - 'EE_Psr4AutoloaderInit', |
|
208 | - EE_CORE . 'EE_Psr4AutoloaderInit.core.php' |
|
209 | - ); |
|
210 | - $AutoloaderInit = new EE_Psr4AutoloaderInit(); |
|
211 | - $AutoloaderInit->initializeAutoloader(); |
|
212 | - espresso_load_required( |
|
213 | - 'EE_Request', |
|
214 | - EE_CORE . 'request_stack' . DS . 'EE_Request.core.php' |
|
215 | - ); |
|
216 | - espresso_load_required( |
|
217 | - 'EE_Response', |
|
218 | - EE_CORE . 'request_stack' . DS . 'EE_Response.core.php' |
|
219 | - ); |
|
220 | - espresso_load_required( |
|
221 | - 'EE_Bootstrap', |
|
222 | - EE_CORE . 'EE_Bootstrap.core.php' |
|
223 | - ); |
|
224 | - // bootstrap EE and the request stack |
|
225 | - new EE_Bootstrap( |
|
226 | - new EE_Request($_GET, $_POST, $_COOKIE), |
|
227 | - new EE_Response() |
|
228 | - ); |
|
229 | - } catch (Exception $e) { |
|
230 | - require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php'; |
|
231 | - new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e); |
|
232 | - } |
|
233 | - } |
|
234 | - bootstrap_espresso(); |
|
235 | - } |
|
168 | + /** |
|
169 | + * @since 4.9.27 |
|
170 | + * @throws \EE_Error |
|
171 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
172 | + * @throws \EventEspresso\core\exceptions\InvalidEntityException |
|
173 | + * @throws \EventEspresso\core\exceptions\InvalidIdentifierException |
|
174 | + * @throws \EventEspresso\core\exceptions\InvalidClassException |
|
175 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
176 | + * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException |
|
177 | + * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException |
|
178 | + * @throws \OutOfBoundsException |
|
179 | + */ |
|
180 | + function bootstrap_espresso() |
|
181 | + { |
|
182 | + require_once __DIR__ . '/core/espresso_definitions.php'; |
|
183 | + try { |
|
184 | + espresso_load_error_handling(); |
|
185 | + espresso_load_required( |
|
186 | + 'EEH_Base', |
|
187 | + EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php' |
|
188 | + ); |
|
189 | + espresso_load_required( |
|
190 | + 'EEH_File', |
|
191 | + EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php' |
|
192 | + ); |
|
193 | + espresso_load_required( |
|
194 | + 'EEH_File', |
|
195 | + EE_CORE . 'helpers' . DS . 'EEH_File.helper.php' |
|
196 | + ); |
|
197 | + espresso_load_required( |
|
198 | + 'EEH_Array', |
|
199 | + EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php' |
|
200 | + ); |
|
201 | + // instantiate and configure PSR4 autoloader |
|
202 | + espresso_load_required( |
|
203 | + 'Psr4Autoloader', |
|
204 | + EE_CORE . 'Psr4Autoloader.php' |
|
205 | + ); |
|
206 | + espresso_load_required( |
|
207 | + 'EE_Psr4AutoloaderInit', |
|
208 | + EE_CORE . 'EE_Psr4AutoloaderInit.core.php' |
|
209 | + ); |
|
210 | + $AutoloaderInit = new EE_Psr4AutoloaderInit(); |
|
211 | + $AutoloaderInit->initializeAutoloader(); |
|
212 | + espresso_load_required( |
|
213 | + 'EE_Request', |
|
214 | + EE_CORE . 'request_stack' . DS . 'EE_Request.core.php' |
|
215 | + ); |
|
216 | + espresso_load_required( |
|
217 | + 'EE_Response', |
|
218 | + EE_CORE . 'request_stack' . DS . 'EE_Response.core.php' |
|
219 | + ); |
|
220 | + espresso_load_required( |
|
221 | + 'EE_Bootstrap', |
|
222 | + EE_CORE . 'EE_Bootstrap.core.php' |
|
223 | + ); |
|
224 | + // bootstrap EE and the request stack |
|
225 | + new EE_Bootstrap( |
|
226 | + new EE_Request($_GET, $_POST, $_COOKIE), |
|
227 | + new EE_Response() |
|
228 | + ); |
|
229 | + } catch (Exception $e) { |
|
230 | + require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php'; |
|
231 | + new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e); |
|
232 | + } |
|
233 | + } |
|
234 | + bootstrap_espresso(); |
|
235 | + } |
|
236 | 236 | } |
237 | 237 | if (! function_exists('espresso_deactivate_plugin')) { |
238 | - /** |
|
239 | - * deactivate_plugin |
|
240 | - * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
241 | - * |
|
242 | - * @access public |
|
243 | - * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
244 | - * @return void |
|
245 | - */ |
|
246 | - function espresso_deactivate_plugin($plugin_basename = '') |
|
247 | - { |
|
248 | - if (! function_exists('deactivate_plugins')) { |
|
249 | - require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
250 | - } |
|
251 | - unset($_GET['activate'], $_REQUEST['activate']); |
|
252 | - deactivate_plugins($plugin_basename); |
|
253 | - } |
|
238 | + /** |
|
239 | + * deactivate_plugin |
|
240 | + * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
241 | + * |
|
242 | + * @access public |
|
243 | + * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
244 | + * @return void |
|
245 | + */ |
|
246 | + function espresso_deactivate_plugin($plugin_basename = '') |
|
247 | + { |
|
248 | + if (! function_exists('deactivate_plugins')) { |
|
249 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
250 | + } |
|
251 | + unset($_GET['activate'], $_REQUEST['activate']); |
|
252 | + deactivate_plugins($plugin_basename); |
|
253 | + } |
|
254 | 254 | } |