@@ -780,7 +780,7 @@ |
||
780 | 780 | /** |
781 | 781 | * @param EEM_Base $source_model |
782 | 782 | * @param EEM_Base $related_model |
783 | - * @param $version |
|
783 | + * @param string $version |
|
784 | 784 | * @return array |
785 | 785 | * @throws EE_Error |
786 | 786 | * @since $VID:$ |
@@ -22,1361 +22,1361 @@ |
||
22 | 22 | class EED_Core_Rest_Api extends EED_Module |
23 | 23 | { |
24 | 24 | |
25 | - const ee_api_namespace = Domain::API_NAMESPACE; |
|
26 | - |
|
27 | - const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
28 | - |
|
29 | - const saved_routes_option_names = 'ee_core_routes'; |
|
30 | - |
|
31 | - /** |
|
32 | - * string used in _links response bodies to make them globally unique. |
|
33 | - * |
|
34 | - * @see http://v2.wp-api.org/extending/linking/ |
|
35 | - */ |
|
36 | - const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
37 | - |
|
38 | - /** |
|
39 | - * @var CalculatedModelFields |
|
40 | - */ |
|
41 | - protected static $_field_calculator; |
|
42 | - |
|
43 | - |
|
44 | - /** |
|
45 | - * @return EED_Core_Rest_Api|EED_Module |
|
46 | - */ |
|
47 | - public static function instance() |
|
48 | - { |
|
49 | - return parent::get_instance(EED_Core_Rest_Api::class); |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - /** |
|
54 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
55 | - * |
|
56 | - * @access public |
|
57 | - * @return void |
|
58 | - */ |
|
59 | - public static function set_hooks() |
|
60 | - { |
|
61 | - EED_Core_Rest_Api::set_hooks_both(); |
|
62 | - } |
|
63 | - |
|
64 | - |
|
65 | - /** |
|
66 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
67 | - * |
|
68 | - * @access public |
|
69 | - * @return void |
|
70 | - */ |
|
71 | - public static function set_hooks_admin() |
|
72 | - { |
|
73 | - EED_Core_Rest_Api::set_hooks_both(); |
|
74 | - } |
|
75 | - |
|
76 | - |
|
77 | - public static function set_hooks_both() |
|
78 | - { |
|
79 | - /** @var EventEspresso\core\services\request\Request $request */ |
|
80 | - $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request'); |
|
81 | - if (! $request->isWordPressApi()) { |
|
82 | - return; |
|
83 | - } |
|
84 | - add_action('rest_api_init', ['EED_Core_Rest_Api', 'register_routes'], 10); |
|
85 | - add_action('rest_api_init', ['EED_Core_Rest_Api', 'set_hooks_rest_api'], 5); |
|
86 | - add_filter('rest_route_data', ['EED_Core_Rest_Api', 'hide_old_endpoints'], 10, 2); |
|
87 | - add_filter( |
|
88 | - 'rest_index', |
|
89 | - ['EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'] |
|
90 | - ); |
|
91 | - EED_Core_Rest_Api::$_field_calculator = LoaderFactory::getLoader()->load( |
|
92 | - 'EventEspresso\core\libraries\rest_api\CalculatedModelFields' |
|
93 | - ); |
|
94 | - EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - /** |
|
99 | - * sets up hooks which only need to be included as part of REST API requests; |
|
100 | - * other requests like to the frontend or admin etc don't need them |
|
101 | - * |
|
102 | - * @throws EE_Error |
|
103 | - */ |
|
104 | - public static function set_hooks_rest_api() |
|
105 | - { |
|
106 | - // set hooks which account for changes made to the API |
|
107 | - EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
108 | - } |
|
109 | - |
|
110 | - |
|
111 | - /** |
|
112 | - * public wrapper of _set_hooks_for_changes. |
|
113 | - * Loads all the hooks which make requests to old versions of the API |
|
114 | - * appear the same as they always did |
|
115 | - * |
|
116 | - * @throws EE_Error |
|
117 | - */ |
|
118 | - public static function set_hooks_for_changes() |
|
119 | - { |
|
120 | - EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
121 | - } |
|
122 | - |
|
123 | - |
|
124 | - /** |
|
125 | - * Loads all the hooks which make requests to old versions of the API |
|
126 | - * appear the same as they always did |
|
127 | - * |
|
128 | - * @throws EE_Error |
|
129 | - */ |
|
130 | - protected static function _set_hooks_for_changes() |
|
131 | - { |
|
132 | - $folder_contents = EEH_File::get_contents_of_folders([EE_LIBRARIES . 'rest_api/changes'], false); |
|
133 | - foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
134 | - // ignore the base parent class |
|
135 | - // and legacy named classes |
|
136 | - if ($classname_in_namespace === 'ChangesInBase' |
|
137 | - || strpos($classname_in_namespace, 'Changes_In_') === 0 |
|
138 | - ) { |
|
139 | - continue; |
|
140 | - } |
|
141 | - $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
142 | - if (class_exists($full_classname)) { |
|
143 | - $instance_of_class = new $full_classname; |
|
144 | - if ($instance_of_class instanceof ChangesInBase) { |
|
145 | - $instance_of_class->setHooks(); |
|
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 | - * @throws ReflectionException |
|
158 | - */ |
|
159 | - public static function register_routes() |
|
160 | - { |
|
161 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) { |
|
162 | - foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) { |
|
163 | - /** |
|
164 | - * @var array $data_for_multiple_endpoints numerically indexed array |
|
165 | - * but can also contain route options like { |
|
166 | - * @type array $schema { |
|
167 | - * @type callable $schema_callback |
|
168 | - * @type array $callback_args arguments that will be passed to the callback, after the |
|
169 | - * WP_REST_Request of course |
|
170 | - * } |
|
171 | - * } |
|
172 | - */ |
|
173 | - // when registering routes, register all the endpoints' data at the same time |
|
174 | - $multiple_endpoint_args = []; |
|
175 | - foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) { |
|
176 | - /** |
|
177 | - * @var array $data_for_single_endpoint { |
|
178 | - * @type callable $callback |
|
179 | - * @type string methods |
|
180 | - * @type array args |
|
181 | - * @type array _links |
|
182 | - * @type array $callback_args arguments that will be passed to the callback, after the |
|
183 | - * WP_REST_Request of course |
|
184 | - * } |
|
185 | - */ |
|
186 | - // skip route options |
|
187 | - if (! is_numeric($endpoint_key)) { |
|
188 | - continue; |
|
189 | - } |
|
190 | - if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
191 | - throw new EE_Error( |
|
192 | - esc_html__( |
|
193 | - // @codingStandardsIgnoreStart |
|
194 | - 'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).', |
|
195 | - // @codingStandardsIgnoreEnd |
|
196 | - 'event_espresso' |
|
197 | - ) |
|
198 | - ); |
|
199 | - } |
|
200 | - $callback = $data_for_single_endpoint['callback']; |
|
201 | - $single_endpoint_args = [ |
|
202 | - 'methods' => $data_for_single_endpoint['methods'], |
|
203 | - 'args' => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args'] |
|
204 | - : [], |
|
205 | - ]; |
|
206 | - if (isset($data_for_single_endpoint['_links'])) { |
|
207 | - $single_endpoint_args['_links'] = $data_for_single_endpoint['_links']; |
|
208 | - } |
|
209 | - if (isset($data_for_single_endpoint['callback_args'])) { |
|
210 | - $callback_args = $data_for_single_endpoint['callback_args']; |
|
211 | - $single_endpoint_args['callback'] = static function (WP_REST_Request $request) use ( |
|
212 | - $callback, |
|
213 | - $callback_args |
|
214 | - ) { |
|
215 | - array_unshift($callback_args, $request); |
|
216 | - return call_user_func_array( |
|
217 | - $callback, |
|
218 | - $callback_args |
|
219 | - ); |
|
220 | - }; |
|
221 | - } else { |
|
222 | - $single_endpoint_args['callback'] = $data_for_single_endpoint['callback']; |
|
223 | - } |
|
224 | - $multiple_endpoint_args[] = $single_endpoint_args; |
|
225 | - } |
|
226 | - if (isset($data_for_multiple_endpoints['schema'])) { |
|
227 | - $schema_route_data = $data_for_multiple_endpoints['schema']; |
|
228 | - $schema_callback = $schema_route_data['schema_callback']; |
|
229 | - $callback_args = $schema_route_data['callback_args']; |
|
230 | - $multiple_endpoint_args['schema'] = static function () use ($schema_callback, $callback_args) { |
|
231 | - return call_user_func_array( |
|
232 | - $schema_callback, |
|
233 | - $callback_args |
|
234 | - ); |
|
235 | - }; |
|
236 | - } |
|
237 | - register_rest_route( |
|
238 | - $namespace, |
|
239 | - $relative_route, |
|
240 | - $multiple_endpoint_args |
|
241 | - ); |
|
242 | - } |
|
243 | - } |
|
244 | - } |
|
245 | - |
|
246 | - |
|
247 | - /** |
|
248 | - * Checks if there was a version change or something that merits invalidating the cached |
|
249 | - * route data. If so, invalidates the cached route data so that it gets refreshed |
|
250 | - * next time the WP API is used |
|
251 | - */ |
|
252 | - public static function invalidate_cached_route_data_on_version_change() |
|
253 | - { |
|
254 | - if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) { |
|
255 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
256 | - } |
|
257 | - foreach (EE_Registry::instance()->addons as $addon) { |
|
258 | - if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) { |
|
259 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
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 | - * Gets the EE route data |
|
279 | - * |
|
280 | - * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
281 | - * @throws EE_Error |
|
282 | - * @throws ReflectionException |
|
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 = []; |
|
291 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoints) { |
|
292 | - $ee_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = EED_Core_Rest_Api::_get_ee_route_data_for_version( |
|
293 | - $version, |
|
294 | - $hidden_endpoints |
|
295 | - ); |
|
296 | - } |
|
297 | - return $ee_routes; |
|
298 | - } |
|
299 | - |
|
300 | - |
|
301 | - /** |
|
302 | - * Gets the EE route data from the wp options if it exists already, |
|
303 | - * otherwise re-generates it and saves it to the option |
|
304 | - * |
|
305 | - * @param string $version |
|
306 | - * @param boolean $hidden_endpoints |
|
307 | - * @return array |
|
308 | - * @throws EE_Error |
|
309 | - * @throws ReflectionException |
|
310 | - */ |
|
311 | - protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
312 | - { |
|
313 | - $ee_routes = get_option(EED_Core_Rest_Api::saved_routes_option_names . $version, null); |
|
314 | - if (! $ee_routes || EED_Core_Rest_Api::debugMode()) { |
|
315 | - $ee_routes = EED_Core_Rest_Api::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
316 | - } |
|
317 | - return $ee_routes; |
|
318 | - } |
|
319 | - |
|
320 | - |
|
321 | - /** |
|
322 | - * Saves the EE REST API route data to a wp option and returns it |
|
323 | - * |
|
324 | - * @param string $version |
|
325 | - * @param boolean $hidden_endpoints |
|
326 | - * @return mixed|null |
|
327 | - * @throws EE_Error |
|
328 | - * @throws ReflectionException |
|
329 | - */ |
|
330 | - protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
331 | - { |
|
332 | - $instance = EED_Core_Rest_Api::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 = EED_Core_Rest_Api::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 | - * Calculates all the EE routes and saves it to a WordPress option so we don't |
|
354 | - * need to calculate it on every request |
|
355 | - * |
|
356 | - * @return void |
|
357 | - * @deprecated since version 4.9.1 |
|
358 | - */ |
|
359 | - public static function save_ee_routes() |
|
360 | - { |
|
361 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
362 | - $instance = EED_Core_Rest_Api::instance(); |
|
363 | - $routes = apply_filters( |
|
364 | - 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
365 | - array_replace_recursive( |
|
366 | - $instance->_register_config_routes(), |
|
367 | - $instance->_register_meta_routes(), |
|
368 | - $instance->_register_model_routes(), |
|
369 | - $instance->_register_rpc_routes() |
|
370 | - ) |
|
371 | - ); |
|
372 | - update_option(EED_Core_Rest_Api::saved_routes_option_names, $routes, true); |
|
373 | - } |
|
374 | - } |
|
375 | - |
|
376 | - |
|
377 | - /** |
|
378 | - * Gets all the route information relating to EE models |
|
379 | - * |
|
380 | - * @return array @see get_ee_route_data |
|
381 | - * @deprecated since version 4.9.1 |
|
382 | - */ |
|
383 | - protected function _register_model_routes() |
|
384 | - { |
|
385 | - $model_routes = []; |
|
386 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
387 | - $model_routes[ EED_Core_Rest_Api::ee_api_namespace |
|
388 | - . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
389 | - } |
|
390 | - return $model_routes; |
|
391 | - } |
|
392 | - |
|
393 | - |
|
394 | - /** |
|
395 | - * Decides whether or not to add write endpoints for this model. |
|
396 | - * Currently, this defaults to exclude all global tables and models |
|
397 | - * which would allow inserting WP core data (we don't want to duplicate |
|
398 | - * what WP API does, as it's unnecessary, extra work, and potentially extra bugs) |
|
399 | - * |
|
400 | - * @param EEM_Base $model |
|
401 | - * @return bool |
|
402 | - */ |
|
403 | - public static function should_have_write_endpoints(EEM_Base $model) |
|
404 | - { |
|
405 | - if ($model->is_wp_core_model()) { |
|
406 | - return false; |
|
407 | - } |
|
408 | - foreach ($model->get_tables() as $table) { |
|
409 | - if ($table->is_global()) { |
|
410 | - return false; |
|
411 | - } |
|
412 | - } |
|
413 | - return true; |
|
414 | - } |
|
415 | - |
|
416 | - |
|
417 | - /** |
|
418 | - * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`) |
|
419 | - * in this versioned namespace of EE4 |
|
420 | - * |
|
421 | - * @param $version |
|
422 | - * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event') |
|
423 | - */ |
|
424 | - public static function model_names_with_plural_routes($version) |
|
425 | - { |
|
426 | - $model_version_info = new ModelVersionInfo($version); |
|
427 | - $models_to_register = $model_version_info->modelsForRequestedVersion(); |
|
428 | - // let's not bother having endpoints for extra metas |
|
429 | - unset( |
|
430 | - $models_to_register['Extra_Meta'], |
|
431 | - $models_to_register['Extra_Join'], |
|
432 | - $models_to_register['Post_Meta'] |
|
433 | - ); |
|
434 | - return apply_filters( |
|
435 | - 'FHEE__EED_Core_REST_API___register_model_routes', |
|
436 | - $models_to_register |
|
437 | - ); |
|
438 | - } |
|
439 | - |
|
440 | - |
|
441 | - /** |
|
442 | - * Gets the route data for EE models in the specified version |
|
443 | - * |
|
444 | - * @param string $version |
|
445 | - * @param boolean $hidden_endpoint |
|
446 | - * @return array |
|
447 | - * @throws EE_Error |
|
448 | - * @throws ReflectionException |
|
449 | - */ |
|
450 | - protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
451 | - { |
|
452 | - $model_routes = []; |
|
453 | - $model_version_info = new ModelVersionInfo($version); |
|
454 | - foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
|
455 | - $model = EE_Registry::instance()->load_model($model_name); |
|
456 | - // if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
457 | - if (! $model instanceof EEM_Base) { |
|
458 | - continue; |
|
459 | - } |
|
460 | - // yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
461 | - $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
|
462 | - $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
|
463 | - $model_routes[ $plural_model_route ] = [ |
|
464 | - [ |
|
465 | - 'callback' => [ |
|
466 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
467 | - 'handleRequestGetAll', |
|
468 | - ], |
|
469 | - 'callback_args' => [$version, $model_name], |
|
470 | - 'methods' => WP_REST_Server::READABLE, |
|
471 | - 'hidden_endpoint' => $hidden_endpoint, |
|
472 | - 'args' => $this->_get_read_query_params($model, $version), |
|
473 | - '_links' => [ |
|
474 | - 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
475 | - ], |
|
476 | - ], |
|
477 | - 'schema' => [ |
|
478 | - 'schema_callback' => [ |
|
479 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
480 | - 'handleSchemaRequest', |
|
481 | - ], |
|
482 | - 'callback_args' => [$version, $model_name], |
|
483 | - ], |
|
484 | - ]; |
|
485 | - $model_routes[ $singular_model_route ] = [ |
|
486 | - [ |
|
487 | - 'callback' => [ |
|
488 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
489 | - 'handleRequestGetOne', |
|
490 | - ], |
|
491 | - 'callback_args' => [$version, $model_name], |
|
492 | - 'methods' => WP_REST_Server::READABLE, |
|
493 | - 'hidden_endpoint' => $hidden_endpoint, |
|
494 | - 'args' => $this->_get_response_selection_query_params($model, $version, true), |
|
495 | - ], |
|
496 | - ]; |
|
497 | - if (apply_filters( |
|
498 | - 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints', |
|
499 | - EED_Core_Rest_Api::should_have_write_endpoints($model), |
|
500 | - $model |
|
501 | - )) { |
|
502 | - $model_routes[ $plural_model_route ][] = [ |
|
503 | - 'callback' => [ |
|
504 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
505 | - 'handleRequestInsert', |
|
506 | - ], |
|
507 | - 'callback_args' => [$version, $model_name], |
|
508 | - 'methods' => WP_REST_Server::CREATABLE, |
|
509 | - 'hidden_endpoint' => $hidden_endpoint, |
|
510 | - 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
|
511 | - ]; |
|
512 | - $model_routes[ $singular_model_route ] = array_merge( |
|
513 | - $model_routes[ $singular_model_route ], |
|
514 | - [ |
|
515 | - [ |
|
516 | - 'callback' => [ |
|
517 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
518 | - 'handleRequestUpdate', |
|
519 | - ], |
|
520 | - 'callback_args' => [$version, $model_name], |
|
521 | - 'methods' => WP_REST_Server::EDITABLE, |
|
522 | - 'hidden_endpoint' => $hidden_endpoint, |
|
523 | - 'args' => $this->_get_write_params($model_name, $model_version_info), |
|
524 | - ], |
|
525 | - [ |
|
526 | - 'callback' => [ |
|
527 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
528 | - 'handleRequestDelete', |
|
529 | - ], |
|
530 | - 'callback_args' => [$version, $model_name], |
|
531 | - 'methods' => WP_REST_Server::DELETABLE, |
|
532 | - 'hidden_endpoint' => $hidden_endpoint, |
|
533 | - 'args' => $this->_get_delete_query_params($model, $version), |
|
534 | - ], |
|
535 | - ] |
|
536 | - ); |
|
537 | - } |
|
538 | - foreach ($model->relation_settings() as $relation_name => $relation_obj) { |
|
539 | - $related_route = EED_Core_Rest_Api::get_relation_route_via( |
|
540 | - $model, |
|
541 | - '(?P<id>[^\/]+)', |
|
542 | - $relation_obj |
|
543 | - ); |
|
544 | - $model_routes[ $related_route ] = [ |
|
545 | - [ |
|
546 | - 'callback' => [ |
|
547 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
548 | - 'handleRequestGetRelated', |
|
549 | - ], |
|
550 | - 'callback_args' => [$version, $model_name, $relation_name], |
|
551 | - 'methods' => WP_REST_Server::READABLE, |
|
552 | - 'hidden_endpoint' => $hidden_endpoint, |
|
553 | - 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
554 | - ], |
|
555 | - ]; |
|
556 | - |
|
557 | - $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)'; |
|
558 | - $model_routes[ $related_write_route ] = [ |
|
559 | - [ |
|
560 | - 'callback' => [ |
|
561 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
562 | - 'handleRequestAddRelation', |
|
563 | - ], |
|
564 | - 'callback_args' => [$version, $model_name, $relation_name], |
|
565 | - 'methods' => WP_REST_Server::EDITABLE, |
|
566 | - 'hidden_endpoint' => $hidden_endpoint, |
|
567 | - 'args' => $this->_get_add_relation_query_params( |
|
568 | - $model, |
|
569 | - $relation_obj->get_other_model(), |
|
570 | - $version |
|
571 | - ), |
|
572 | - ], |
|
573 | - [ |
|
574 | - 'callback' => [ |
|
575 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
576 | - 'handleRequestRemoveRelation', |
|
577 | - ], |
|
578 | - 'callback_args' => [$version, $model_name, $relation_name], |
|
579 | - 'methods' => WP_REST_Server::DELETABLE, |
|
580 | - 'hidden_endpoint' => $hidden_endpoint, |
|
581 | - 'args' => [], |
|
582 | - ], |
|
583 | - ]; |
|
584 | - } |
|
585 | - } |
|
586 | - return $model_routes; |
|
587 | - } |
|
588 | - |
|
589 | - |
|
590 | - /** |
|
591 | - * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace, |
|
592 | - * excluding the preceding slash. |
|
593 | - * Eg you pass get_plural_route_to('Event') = 'events' |
|
594 | - * |
|
595 | - * @param EEM_Base $model |
|
596 | - * @return string |
|
597 | - */ |
|
598 | - public static function get_collection_route(EEM_Base $model) |
|
599 | - { |
|
600 | - return EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
601 | - } |
|
602 | - |
|
603 | - |
|
604 | - /** |
|
605 | - * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
606 | - * excluding the preceding slash. |
|
607 | - * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
608 | - * |
|
609 | - * @param EEM_Base $model eg Event or Venue |
|
610 | - * @param string $id |
|
611 | - * @return string |
|
612 | - */ |
|
613 | - public static function get_entity_route($model, $id) |
|
614 | - { |
|
615 | - return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id; |
|
616 | - } |
|
617 | - |
|
618 | - |
|
619 | - /** |
|
620 | - * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
621 | - * excluding the preceding slash. |
|
622 | - * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
623 | - * |
|
624 | - * @param EEM_Base $model eg Event or Venue |
|
625 | - * @param string $id |
|
626 | - * @param EE_Model_Relation_Base $relation_obj |
|
627 | - * @return string |
|
628 | - */ |
|
629 | - public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj) |
|
630 | - { |
|
631 | - $related_model_name_endpoint_part = ModelRead::getRelatedEntityName( |
|
632 | - $relation_obj->get_other_model()->get_this_model_name(), |
|
633 | - $relation_obj |
|
634 | - ); |
|
635 | - return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
636 | - } |
|
637 | - |
|
638 | - |
|
639 | - /** |
|
640 | - * Adds onto the $relative_route the EE4 REST API versioned namespace. |
|
641 | - * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events' |
|
642 | - * |
|
643 | - * @param string $relative_route |
|
644 | - * @param string $version |
|
645 | - * @return string |
|
646 | - */ |
|
647 | - public static function get_versioned_route_to($relative_route, $version = '4.8.36') |
|
648 | - { |
|
649 | - return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
650 | - } |
|
651 | - |
|
652 | - |
|
653 | - /** |
|
654 | - * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
655 | - * routes that don't conform to the traditional REST CRUD-style). |
|
656 | - * |
|
657 | - * @deprecated since 4.9.1 |
|
658 | - */ |
|
659 | - protected function _register_rpc_routes() |
|
660 | - { |
|
661 | - $routes = []; |
|
662 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
663 | - $routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version( |
|
664 | - $version, |
|
665 | - $hidden_endpoint |
|
666 | - ); |
|
667 | - } |
|
668 | - return $routes; |
|
669 | - } |
|
670 | - |
|
671 | - |
|
672 | - /** |
|
673 | - * @param string $version |
|
674 | - * @param boolean $hidden_endpoint |
|
675 | - * @return array |
|
676 | - */ |
|
677 | - protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
678 | - { |
|
679 | - $this_versions_routes = []; |
|
680 | - // checkin endpoint |
|
681 | - $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = [ |
|
682 | - [ |
|
683 | - 'callback' => [ |
|
684 | - 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
685 | - 'handleRequestToggleCheckin', |
|
686 | - ], |
|
687 | - 'methods' => WP_REST_Server::CREATABLE, |
|
688 | - 'hidden_endpoint' => $hidden_endpoint, |
|
689 | - 'args' => [ |
|
690 | - 'force' => [ |
|
691 | - 'required' => false, |
|
692 | - 'default' => false, |
|
693 | - 'description' => __( |
|
694 | - // @codingStandardsIgnoreStart |
|
695 | - 'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
696 | - // @codingStandardsIgnoreEnd |
|
697 | - 'event_espresso' |
|
698 | - ), |
|
699 | - ], |
|
700 | - ], |
|
701 | - 'callback_args' => [$version], |
|
702 | - ], |
|
703 | - ]; |
|
704 | - return apply_filters( |
|
705 | - 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
706 | - $this_versions_routes, |
|
707 | - $version, |
|
708 | - $hidden_endpoint |
|
709 | - ); |
|
710 | - } |
|
711 | - |
|
712 | - |
|
713 | - /** |
|
714 | - * Gets the query params that can be used when request one or many |
|
715 | - * |
|
716 | - * @param EEM_Base $model |
|
717 | - * @param string $version |
|
718 | - * @return array |
|
719 | - */ |
|
720 | - protected function _get_response_selection_query_params(EEM_Base $model, $version, $single_only = false) |
|
721 | - { |
|
722 | - $query_params = [ |
|
723 | - 'include' => [ |
|
724 | - 'required' => false, |
|
725 | - 'default' => '*', |
|
726 | - 'type' => 'string', |
|
727 | - ], |
|
728 | - 'calculate' => [ |
|
729 | - 'required' => false, |
|
730 | - 'default' => '', |
|
731 | - 'enum' => EED_Core_Rest_Api::$_field_calculator->retrieveCalculatedFieldsForModel($model), |
|
732 | - 'type' => 'string', |
|
733 | - // because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization |
|
734 | - // freaks out. We'll just validate this argument while handling the request |
|
735 | - 'validate_callback' => null, |
|
736 | - 'sanitize_callback' => null, |
|
737 | - ], |
|
738 | - 'password' => [ |
|
739 | - 'required' => false, |
|
740 | - 'default' => '', |
|
741 | - 'type' => 'string', |
|
742 | - ], |
|
743 | - ]; |
|
744 | - return apply_filters( |
|
745 | - 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
746 | - $query_params, |
|
747 | - $model, |
|
748 | - $version |
|
749 | - ); |
|
750 | - } |
|
751 | - |
|
752 | - |
|
753 | - /** |
|
754 | - * Gets the parameters acceptable for delete requests |
|
755 | - * |
|
756 | - * @param EEM_Base $model |
|
757 | - * @param string $version |
|
758 | - * @return array |
|
759 | - */ |
|
760 | - protected function _get_delete_query_params(EEM_Base $model, $version) |
|
761 | - { |
|
762 | - $params_for_delete = [ |
|
763 | - 'allow_blocking' => [ |
|
764 | - 'required' => false, |
|
765 | - 'default' => true, |
|
766 | - 'type' => 'boolean', |
|
767 | - ], |
|
768 | - ]; |
|
769 | - $params_for_delete['force'] = [ |
|
770 | - 'required' => false, |
|
771 | - 'default' => false, |
|
772 | - 'type' => 'boolean', |
|
773 | - ]; |
|
774 | - return apply_filters( |
|
775 | - 'FHEE__EED_Core_Rest_Api___get_delete_query_params', |
|
776 | - $params_for_delete, |
|
777 | - $model, |
|
778 | - $version |
|
779 | - ); |
|
780 | - } |
|
781 | - |
|
782 | - |
|
783 | - /** |
|
784 | - * @param EEM_Base $source_model |
|
785 | - * @param EEM_Base $related_model |
|
786 | - * @param $version |
|
787 | - * @return array |
|
788 | - * @throws EE_Error |
|
789 | - * @since $VID:$ |
|
790 | - */ |
|
791 | - protected function _get_add_relation_query_params(EEM_Base $source_model, EEM_Base $related_model, $version) |
|
792 | - { |
|
793 | - // if they're related through a HABTM relation, check for any non-FKs |
|
794 | - $all_relation_settings = $source_model->relation_settings(); |
|
795 | - $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ]; |
|
796 | - $params = []; |
|
797 | - if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) { |
|
798 | - foreach ($relation_settings->getNonKeyFields() as $field) { |
|
799 | - /* @var $field EE_Model_Field_Base */ |
|
800 | - $params[ $field->get_name() ] = [ |
|
801 | - 'required' => ! $field->is_nullable(), |
|
802 | - 'default' => ModelDataTranslator::prepareFieldValueForJson( |
|
803 | - $field, |
|
804 | - $field->get_default_value(), |
|
805 | - $version |
|
806 | - ), |
|
807 | - 'type' => $field->getSchemaType(), |
|
808 | - 'validate_callback' => null, |
|
809 | - 'sanitize_callback' => null, |
|
810 | - ]; |
|
811 | - } |
|
812 | - } |
|
813 | - return $params; |
|
814 | - } |
|
815 | - |
|
816 | - |
|
817 | - /** |
|
818 | - * Gets info about reading query params that are acceptable |
|
819 | - * |
|
820 | - * @param EEM_Base $model eg 'Event' or 'Venue' |
|
821 | - * @param string $version |
|
822 | - * @return array describing the args acceptable when querying this model |
|
823 | - * @throws EE_Error |
|
824 | - */ |
|
825 | - protected function _get_read_query_params(EEM_Base $model, $version) |
|
826 | - { |
|
827 | - $default_orderby = []; |
|
828 | - foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
829 | - $default_orderby[ $key_field->get_name() ] = 'ASC'; |
|
830 | - } |
|
831 | - return array_merge( |
|
832 | - $this->_get_response_selection_query_params($model, $version), |
|
833 | - [ |
|
834 | - 'where' => [ |
|
835 | - 'required' => false, |
|
836 | - 'default' => [], |
|
837 | - 'type' => 'object', |
|
838 | - // because we accept an almost infinite list of possible where conditions, WP |
|
839 | - // core validation and sanitization freaks out. We'll just validate this argument |
|
840 | - // while handling the request |
|
841 | - 'validate_callback' => null, |
|
842 | - 'sanitize_callback' => null, |
|
843 | - ], |
|
844 | - 'limit' => [ |
|
845 | - 'required' => false, |
|
846 | - 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
847 | - 'type' => [ |
|
848 | - 'array', |
|
849 | - 'string', |
|
850 | - 'integer', |
|
851 | - ], |
|
852 | - // because we accept a variety of types, WP core validation and sanitization |
|
853 | - // freaks out. We'll just validate this argument while handling the request |
|
854 | - 'validate_callback' => null, |
|
855 | - 'sanitize_callback' => null, |
|
856 | - ], |
|
857 | - 'order_by' => [ |
|
858 | - 'required' => false, |
|
859 | - 'default' => $default_orderby, |
|
860 | - 'type' => [ |
|
861 | - 'object', |
|
862 | - 'string', |
|
863 | - ],// because we accept a variety of types, WP core validation and sanitization |
|
864 | - // freaks out. We'll just validate this argument while handling the request |
|
865 | - 'validate_callback' => null, |
|
866 | - 'sanitize_callback' => null, |
|
867 | - ], |
|
868 | - 'group_by' => [ |
|
869 | - 'required' => false, |
|
870 | - 'default' => null, |
|
871 | - 'type' => [ |
|
872 | - 'object', |
|
873 | - 'string', |
|
874 | - ], |
|
875 | - // because we accept an almost infinite list of possible groupings, |
|
876 | - // WP core validation and sanitization |
|
877 | - // freaks out. We'll just validate this argument while handling the request |
|
878 | - 'validate_callback' => null, |
|
879 | - 'sanitize_callback' => null, |
|
880 | - ], |
|
881 | - 'having' => [ |
|
882 | - 'required' => false, |
|
883 | - 'default' => null, |
|
884 | - 'type' => 'object', |
|
885 | - // because we accept an almost infinite list of possible where conditions, WP |
|
886 | - // core validation and sanitization freaks out. We'll just validate this argument |
|
887 | - // while handling the request |
|
888 | - 'validate_callback' => null, |
|
889 | - 'sanitize_callback' => null, |
|
890 | - ], |
|
891 | - 'caps' => [ |
|
892 | - 'required' => false, |
|
893 | - 'default' => EEM_Base::caps_read, |
|
894 | - 'type' => 'string', |
|
895 | - 'enum' => [ |
|
896 | - EEM_Base::caps_read, |
|
897 | - EEM_Base::caps_read_admin, |
|
898 | - EEM_Base::caps_edit, |
|
899 | - EEM_Base::caps_delete, |
|
900 | - ], |
|
901 | - ], |
|
902 | - ] |
|
903 | - ); |
|
904 | - } |
|
905 | - |
|
906 | - |
|
907 | - /** |
|
908 | - * Gets parameter information for a model regarding writing data |
|
909 | - * |
|
910 | - * @param string $model_name |
|
911 | - * @param ModelVersionInfo $model_version_info |
|
912 | - * @param boolean $create whether this is for request to create (in |
|
913 | - * which case we need all required params) or |
|
914 | - * just to update (in which case we don't |
|
915 | - * need those on every request) |
|
916 | - * @return array |
|
917 | - * @throws EE_Error |
|
918 | - * @throws ReflectionException |
|
919 | - */ |
|
920 | - protected function _get_write_params( |
|
921 | - $model_name, |
|
922 | - ModelVersionInfo $model_version_info, |
|
923 | - $create = false |
|
924 | - ) { |
|
925 | - $model = EE_Registry::instance()->load_model($model_name); |
|
926 | - $fields = $model_version_info->fieldsOnModelInThisVersion($model); |
|
927 | - |
|
928 | - // we do our own validation and sanitization within the controller |
|
929 | - $sanitize_callback = function_exists('rest_validate_value_from_schema') |
|
930 | - ? ['EED_Core_Rest_Api', 'default_sanitize_callback'] |
|
931 | - : null; |
|
932 | - $args_info = []; |
|
933 | - foreach ($fields as $field_name => $field_obj) { |
|
934 | - if ($field_obj->is_auto_increment()) { |
|
935 | - // totally ignore auto increment IDs |
|
936 | - continue; |
|
937 | - } |
|
938 | - $arg_info = $field_obj->getSchema(); |
|
939 | - $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null; |
|
940 | - $arg_info['required'] = $required; |
|
941 | - // remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right? |
|
942 | - unset($arg_info['readonly']); |
|
943 | - $schema_properties = $field_obj->getSchemaProperties(); |
|
944 | - if (isset($schema_properties['raw']) |
|
945 | - && $field_obj->getSchemaType() === 'object' |
|
946 | - ) { |
|
947 | - // if there's a "raw" form of this argument, use those properties instead |
|
948 | - $arg_info = array_replace( |
|
949 | - $arg_info, |
|
950 | - $schema_properties['raw'] |
|
951 | - ); |
|
952 | - } |
|
953 | - $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson( |
|
954 | - $field_obj, |
|
955 | - $field_obj->get_default_value(), |
|
956 | - $model_version_info->requestedVersion() |
|
957 | - ); |
|
958 | - $arg_info['sanitize_callback'] = $sanitize_callback; |
|
959 | - $args_info[ $field_name ] = $arg_info; |
|
960 | - if ($field_obj instanceof EE_Datetime_Field) { |
|
961 | - $gmt_arg_info = $arg_info; |
|
962 | - $gmt_arg_info['description'] = sprintf( |
|
963 | - esc_html__( |
|
964 | - '%1$s - the value for this field in UTC. Ignored if %2$s is provided.', |
|
965 | - 'event_espresso' |
|
966 | - ), |
|
967 | - $field_obj->get_nicename(), |
|
968 | - $field_name |
|
969 | - ); |
|
970 | - $args_info[ $field_name . '_gmt' ] = $gmt_arg_info; |
|
971 | - } |
|
972 | - } |
|
973 | - return $args_info; |
|
974 | - } |
|
975 | - |
|
976 | - |
|
977 | - /** |
|
978 | - * Replacement for WP API's 'rest_parse_request_arg'. |
|
979 | - * If the value is blank but not required, don't bother validating it. |
|
980 | - * Also, it uses our email validation instead of WP API's default. |
|
981 | - * |
|
982 | - * @param $value |
|
983 | - * @param WP_REST_Request $request |
|
984 | - * @param $param |
|
985 | - * @return bool|true|WP_Error |
|
986 | - * @throws InvalidArgumentException |
|
987 | - * @throws InvalidInterfaceException |
|
988 | - * @throws InvalidDataTypeException |
|
989 | - */ |
|
990 | - public static function default_sanitize_callback($value, WP_REST_Request $request, $param) |
|
991 | - { |
|
992 | - $attributes = $request->get_attributes(); |
|
993 | - if (! isset($attributes['args'][ $param ]) |
|
994 | - || ! is_array($attributes['args'][ $param ])) { |
|
995 | - $validation_result = true; |
|
996 | - } else { |
|
997 | - $args = $attributes['args'][ $param ]; |
|
998 | - if (( |
|
999 | - $value === '' |
|
1000 | - || $value === null |
|
1001 | - ) |
|
1002 | - && (! isset($args['required']) |
|
1003 | - || $args['required'] === false |
|
1004 | - ) |
|
1005 | - ) { |
|
1006 | - // not required and not provided? that's cool |
|
1007 | - $validation_result = true; |
|
1008 | - } elseif (isset($args['format']) |
|
1009 | - && $args['format'] === 'email' |
|
1010 | - ) { |
|
1011 | - $validation_result = true; |
|
1012 | - if (! EED_Core_Rest_Api::_validate_email($value)) { |
|
1013 | - $validation_result = new WP_Error( |
|
1014 | - 'rest_invalid_param', |
|
1015 | - esc_html__( |
|
1016 | - 'The email address is not valid or does not exist.', |
|
1017 | - 'event_espresso' |
|
1018 | - ) |
|
1019 | - ); |
|
1020 | - } |
|
1021 | - } else { |
|
1022 | - $validation_result = rest_validate_value_from_schema($value, $args, $param); |
|
1023 | - } |
|
1024 | - } |
|
1025 | - if (is_wp_error($validation_result)) { |
|
1026 | - return $validation_result; |
|
1027 | - } |
|
1028 | - return rest_sanitize_request_arg($value, $request, $param); |
|
1029 | - } |
|
1030 | - |
|
1031 | - |
|
1032 | - /** |
|
1033 | - * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email() |
|
1034 | - * |
|
1035 | - * @param $email |
|
1036 | - * @return bool |
|
1037 | - * @throws InvalidArgumentException |
|
1038 | - * @throws InvalidInterfaceException |
|
1039 | - * @throws InvalidDataTypeException |
|
1040 | - */ |
|
1041 | - protected static function _validate_email($email) |
|
1042 | - { |
|
1043 | - try { |
|
1044 | - EmailAddressFactory::create($email); |
|
1045 | - return true; |
|
1046 | - } catch (EmailValidationException $e) { |
|
1047 | - return false; |
|
1048 | - } |
|
1049 | - } |
|
1050 | - |
|
1051 | - |
|
1052 | - /** |
|
1053 | - * Gets routes for the config |
|
1054 | - * |
|
1055 | - * @return array @see _register_model_routes |
|
1056 | - * @deprecated since version 4.9.1 |
|
1057 | - */ |
|
1058 | - protected function _register_config_routes() |
|
1059 | - { |
|
1060 | - $config_routes = []; |
|
1061 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1062 | - $config_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version( |
|
1063 | - $version, |
|
1064 | - $hidden_endpoint |
|
1065 | - ); |
|
1066 | - } |
|
1067 | - return $config_routes; |
|
1068 | - } |
|
1069 | - |
|
1070 | - |
|
1071 | - /** |
|
1072 | - * Gets routes for the config for the specified version |
|
1073 | - * |
|
1074 | - * @param string $version |
|
1075 | - * @param boolean $hidden_endpoint |
|
1076 | - * @return array |
|
1077 | - */ |
|
1078 | - protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
1079 | - { |
|
1080 | - return [ |
|
1081 | - 'config' => [ |
|
1082 | - [ |
|
1083 | - 'callback' => [ |
|
1084 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1085 | - 'handleRequest', |
|
1086 | - ], |
|
1087 | - 'methods' => WP_REST_Server::READABLE, |
|
1088 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1089 | - 'callback_args' => [$version], |
|
1090 | - ], |
|
1091 | - ], |
|
1092 | - 'site_info' => [ |
|
1093 | - [ |
|
1094 | - 'callback' => [ |
|
1095 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1096 | - 'handleRequestSiteInfo', |
|
1097 | - ], |
|
1098 | - 'methods' => WP_REST_Server::READABLE, |
|
1099 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1100 | - 'callback_args' => [$version], |
|
1101 | - ], |
|
1102 | - ], |
|
1103 | - ]; |
|
1104 | - } |
|
1105 | - |
|
1106 | - |
|
1107 | - /** |
|
1108 | - * Gets the meta info routes |
|
1109 | - * |
|
1110 | - * @return array @see _register_model_routes |
|
1111 | - * @deprecated since version 4.9.1 |
|
1112 | - */ |
|
1113 | - protected function _register_meta_routes() |
|
1114 | - { |
|
1115 | - $meta_routes = []; |
|
1116 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1117 | - $meta_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version( |
|
1118 | - $version, |
|
1119 | - $hidden_endpoint |
|
1120 | - ); |
|
1121 | - } |
|
1122 | - return $meta_routes; |
|
1123 | - } |
|
1124 | - |
|
1125 | - |
|
1126 | - /** |
|
1127 | - * @param string $version |
|
1128 | - * @param boolean $hidden_endpoint |
|
1129 | - * @return array |
|
1130 | - */ |
|
1131 | - protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
1132 | - { |
|
1133 | - return [ |
|
1134 | - 'resources' => [ |
|
1135 | - [ |
|
1136 | - 'callback' => [ |
|
1137 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
1138 | - 'handleRequestModelsMeta', |
|
1139 | - ], |
|
1140 | - 'methods' => WP_REST_Server::READABLE, |
|
1141 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1142 | - 'callback_args' => [$version], |
|
1143 | - ], |
|
1144 | - ], |
|
1145 | - ]; |
|
1146 | - } |
|
1147 | - |
|
1148 | - |
|
1149 | - /** |
|
1150 | - * Tries to hide old 4.6 endpoints from the |
|
1151 | - * |
|
1152 | - * @param array $route_data |
|
1153 | - * @return array |
|
1154 | - * @throws EE_Error |
|
1155 | - * @throws ReflectionException |
|
1156 | - */ |
|
1157 | - public static function hide_old_endpoints($route_data) |
|
1158 | - { |
|
1159 | - // allow API clients to override which endpoints get hidden, in case |
|
1160 | - // they want to discover particular endpoints |
|
1161 | - // also, we don't have access to the request so we have to just grab it from the superglobal |
|
1162 | - $force_show_ee_namespace = ltrim( |
|
1163 | - EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''), |
|
1164 | - '/' |
|
1165 | - ); |
|
1166 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
1167 | - foreach ($relative_urls as $resource_name => $endpoints) { |
|
1168 | - foreach ($endpoints as $key => $endpoint) { |
|
1169 | - // skip schema and other route options |
|
1170 | - if (! is_numeric($key)) { |
|
1171 | - continue; |
|
1172 | - } |
|
1173 | - // by default, hide "hidden_endpoint"s, unless the request indicates |
|
1174 | - // to $force_show_ee_namespace, in which case only show that one |
|
1175 | - // namespace's endpoints (and hide all others) |
|
1176 | - if (($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
1177 | - || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
1178 | - ) { |
|
1179 | - $full_route = '/' . ltrim($namespace, '/'); |
|
1180 | - $full_route .= '/' . ltrim($resource_name, '/'); |
|
1181 | - unset($route_data[ $full_route ]); |
|
1182 | - } |
|
1183 | - } |
|
1184 | - } |
|
1185 | - } |
|
1186 | - return $route_data; |
|
1187 | - } |
|
1188 | - |
|
1189 | - |
|
1190 | - /** |
|
1191 | - * Returns an array describing which versions of core support serving requests for. |
|
1192 | - * Keys are core versions' major and minor version, and values are the |
|
1193 | - * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
1194 | - * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
1195 | - * the answers table entirely, in which case it would be very difficult for |
|
1196 | - * it to serve 4.6-style responses. |
|
1197 | - * Versions of core that are missing from this array are unknowns. |
|
1198 | - * previous ver |
|
1199 | - * |
|
1200 | - * @return array |
|
1201 | - */ |
|
1202 | - public static function version_compatibilities() |
|
1203 | - { |
|
1204 | - return apply_filters( |
|
1205 | - 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
1206 | - [ |
|
1207 | - '4.8.29' => '4.8.29', |
|
1208 | - '4.8.33' => '4.8.29', |
|
1209 | - '4.8.34' => '4.8.29', |
|
1210 | - '4.8.36' => '4.8.29', |
|
1211 | - ] |
|
1212 | - ); |
|
1213 | - } |
|
1214 | - |
|
1215 | - |
|
1216 | - /** |
|
1217 | - * Gets the latest API version served. Eg if there |
|
1218 | - * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
1219 | - * we are on core version 4.8.34, it will return the string "4.8.32" |
|
1220 | - * |
|
1221 | - * @return string |
|
1222 | - */ |
|
1223 | - public static function latest_rest_api_version() |
|
1224 | - { |
|
1225 | - $versions_served = EED_Core_Rest_Api::versions_served(); |
|
1226 | - $versions_served_keys = array_keys($versions_served); |
|
1227 | - return end($versions_served_keys); |
|
1228 | - } |
|
1229 | - |
|
1230 | - |
|
1231 | - /** |
|
1232 | - * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
1233 | - * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
1234 | - * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
1235 | - * We also indicate whether or not this version should be put in the index or not |
|
1236 | - * |
|
1237 | - * @return array keys are API version numbers (just major and minor numbers), and values |
|
1238 | - * are whether or not they should be hidden |
|
1239 | - */ |
|
1240 | - public static function versions_served() |
|
1241 | - { |
|
1242 | - $versions_served = []; |
|
1243 | - $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
1244 | - $lowest_compatible_version = end($possibly_served_versions); |
|
1245 | - reset($possibly_served_versions); |
|
1246 | - $versions_served_historically = array_keys($possibly_served_versions); |
|
1247 | - $latest_version = end($versions_served_historically); |
|
1248 | - reset($versions_served_historically); |
|
1249 | - // for each version of core we have ever served: |
|
1250 | - foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
1251 | - // if it's not above the current core version, and it's compatible with the current version of core |
|
1252 | - |
|
1253 | - if ($key_versioned_endpoint === $latest_version) { |
|
1254 | - // don't hide the latest version in the index |
|
1255 | - $versions_served[ $key_versioned_endpoint ] = false; |
|
1256 | - } elseif (version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=') |
|
1257 | - && version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<') |
|
1258 | - ) { |
|
1259 | - // include, but hide, previous versions which are still supported |
|
1260 | - $versions_served[ $key_versioned_endpoint ] = true; |
|
1261 | - } elseif (apply_filters( |
|
1262 | - 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
1263 | - false, |
|
1264 | - $possibly_served_versions |
|
1265 | - )) { |
|
1266 | - // if a version is no longer supported, don't include it in index or list of versions served |
|
1267 | - $versions_served[ $key_versioned_endpoint ] = true; |
|
1268 | - } |
|
1269 | - } |
|
1270 | - return $versions_served; |
|
1271 | - } |
|
1272 | - |
|
1273 | - |
|
1274 | - /** |
|
1275 | - * Gets the major and minor version of EE core's version string |
|
1276 | - * |
|
1277 | - * @return string |
|
1278 | - */ |
|
1279 | - public static function core_version() |
|
1280 | - { |
|
1281 | - return apply_filters( |
|
1282 | - 'FHEE__EED_Core_REST_API__core_version', |
|
1283 | - implode( |
|
1284 | - '.', |
|
1285 | - array_slice( |
|
1286 | - explode( |
|
1287 | - '.', |
|
1288 | - espresso_version() |
|
1289 | - ), |
|
1290 | - 0, |
|
1291 | - 3 |
|
1292 | - ) |
|
1293 | - ) |
|
1294 | - ); |
|
1295 | - } |
|
1296 | - |
|
1297 | - |
|
1298 | - /** |
|
1299 | - * Gets the default limit that should be used when querying for resources |
|
1300 | - * |
|
1301 | - * @return int |
|
1302 | - */ |
|
1303 | - public static function get_default_query_limit() |
|
1304 | - { |
|
1305 | - // we actually don't use a const because we want folks to always use |
|
1306 | - // this method, not the const directly |
|
1307 | - return apply_filters( |
|
1308 | - 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
1309 | - 50 |
|
1310 | - ); |
|
1311 | - } |
|
1312 | - |
|
1313 | - |
|
1314 | - /** |
|
1315 | - * @param string $version api version string (i.e. '4.8.36') |
|
1316 | - * @return array |
|
1317 | - */ |
|
1318 | - public static function getCollectionRoutesIndexedByModelName($version = '') |
|
1319 | - { |
|
1320 | - $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1321 | - $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1322 | - $collection_routes = []; |
|
1323 | - foreach ($model_names as $model_name => $model_class_name) { |
|
1324 | - $collection_routes[ strtolower($model_name) ] = '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' |
|
1325 | - . EEH_Inflector::pluralize_and_lower($model_name); |
|
1326 | - } |
|
1327 | - return $collection_routes; |
|
1328 | - } |
|
1329 | - |
|
1330 | - |
|
1331 | - /** |
|
1332 | - * Returns an array of primary key names indexed by model names. |
|
1333 | - * |
|
1334 | - * @param string $version |
|
1335 | - * @return array |
|
1336 | - */ |
|
1337 | - public static function getPrimaryKeyNamesIndexedByModelName($version = '') |
|
1338 | - { |
|
1339 | - $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1340 | - $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1341 | - $primary_key_items = []; |
|
1342 | - foreach ($model_names as $model_name => $model_class_name) { |
|
1343 | - $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields(); |
|
1344 | - foreach ($primary_keys as $primary_key_name => $primary_key_field) { |
|
1345 | - if (count($primary_keys) > 1) { |
|
1346 | - $primary_key_items[ strtolower($model_name) ][] = $primary_key_name; |
|
1347 | - } else { |
|
1348 | - $primary_key_items[ strtolower($model_name) ] = $primary_key_name; |
|
1349 | - } |
|
1350 | - } |
|
1351 | - } |
|
1352 | - return $primary_key_items; |
|
1353 | - } |
|
1354 | - |
|
1355 | - |
|
1356 | - /** |
|
1357 | - * Determines the EE REST API debug mode is activated, or not. |
|
1358 | - * |
|
1359 | - * @return bool |
|
1360 | - * @since 4.9.76.p |
|
1361 | - */ |
|
1362 | - public static function debugMode() |
|
1363 | - { |
|
1364 | - static $debug_mode = null; // could be class prop |
|
1365 | - if ($debug_mode === null) { |
|
1366 | - $debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE; |
|
1367 | - } |
|
1368 | - return $debug_mode; |
|
1369 | - } |
|
1370 | - |
|
1371 | - |
|
1372 | - /** |
|
1373 | - * run - initial module setup |
|
1374 | - * |
|
1375 | - * @access public |
|
1376 | - * @param WP $WP |
|
1377 | - * @return void |
|
1378 | - */ |
|
1379 | - public function run($WP) |
|
1380 | - { |
|
1381 | - } |
|
25 | + const ee_api_namespace = Domain::API_NAMESPACE; |
|
26 | + |
|
27 | + const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
28 | + |
|
29 | + const saved_routes_option_names = 'ee_core_routes'; |
|
30 | + |
|
31 | + /** |
|
32 | + * string used in _links response bodies to make them globally unique. |
|
33 | + * |
|
34 | + * @see http://v2.wp-api.org/extending/linking/ |
|
35 | + */ |
|
36 | + const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
37 | + |
|
38 | + /** |
|
39 | + * @var CalculatedModelFields |
|
40 | + */ |
|
41 | + protected static $_field_calculator; |
|
42 | + |
|
43 | + |
|
44 | + /** |
|
45 | + * @return EED_Core_Rest_Api|EED_Module |
|
46 | + */ |
|
47 | + public static function instance() |
|
48 | + { |
|
49 | + return parent::get_instance(EED_Core_Rest_Api::class); |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + /** |
|
54 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
55 | + * |
|
56 | + * @access public |
|
57 | + * @return void |
|
58 | + */ |
|
59 | + public static function set_hooks() |
|
60 | + { |
|
61 | + EED_Core_Rest_Api::set_hooks_both(); |
|
62 | + } |
|
63 | + |
|
64 | + |
|
65 | + /** |
|
66 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
67 | + * |
|
68 | + * @access public |
|
69 | + * @return void |
|
70 | + */ |
|
71 | + public static function set_hooks_admin() |
|
72 | + { |
|
73 | + EED_Core_Rest_Api::set_hooks_both(); |
|
74 | + } |
|
75 | + |
|
76 | + |
|
77 | + public static function set_hooks_both() |
|
78 | + { |
|
79 | + /** @var EventEspresso\core\services\request\Request $request */ |
|
80 | + $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request'); |
|
81 | + if (! $request->isWordPressApi()) { |
|
82 | + return; |
|
83 | + } |
|
84 | + add_action('rest_api_init', ['EED_Core_Rest_Api', 'register_routes'], 10); |
|
85 | + add_action('rest_api_init', ['EED_Core_Rest_Api', 'set_hooks_rest_api'], 5); |
|
86 | + add_filter('rest_route_data', ['EED_Core_Rest_Api', 'hide_old_endpoints'], 10, 2); |
|
87 | + add_filter( |
|
88 | + 'rest_index', |
|
89 | + ['EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'] |
|
90 | + ); |
|
91 | + EED_Core_Rest_Api::$_field_calculator = LoaderFactory::getLoader()->load( |
|
92 | + 'EventEspresso\core\libraries\rest_api\CalculatedModelFields' |
|
93 | + ); |
|
94 | + EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + /** |
|
99 | + * sets up hooks which only need to be included as part of REST API requests; |
|
100 | + * other requests like to the frontend or admin etc don't need them |
|
101 | + * |
|
102 | + * @throws EE_Error |
|
103 | + */ |
|
104 | + public static function set_hooks_rest_api() |
|
105 | + { |
|
106 | + // set hooks which account for changes made to the API |
|
107 | + EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
108 | + } |
|
109 | + |
|
110 | + |
|
111 | + /** |
|
112 | + * public wrapper of _set_hooks_for_changes. |
|
113 | + * Loads all the hooks which make requests to old versions of the API |
|
114 | + * appear the same as they always did |
|
115 | + * |
|
116 | + * @throws EE_Error |
|
117 | + */ |
|
118 | + public static function set_hooks_for_changes() |
|
119 | + { |
|
120 | + EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
121 | + } |
|
122 | + |
|
123 | + |
|
124 | + /** |
|
125 | + * Loads all the hooks which make requests to old versions of the API |
|
126 | + * appear the same as they always did |
|
127 | + * |
|
128 | + * @throws EE_Error |
|
129 | + */ |
|
130 | + protected static function _set_hooks_for_changes() |
|
131 | + { |
|
132 | + $folder_contents = EEH_File::get_contents_of_folders([EE_LIBRARIES . 'rest_api/changes'], false); |
|
133 | + foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
134 | + // ignore the base parent class |
|
135 | + // and legacy named classes |
|
136 | + if ($classname_in_namespace === 'ChangesInBase' |
|
137 | + || strpos($classname_in_namespace, 'Changes_In_') === 0 |
|
138 | + ) { |
|
139 | + continue; |
|
140 | + } |
|
141 | + $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
142 | + if (class_exists($full_classname)) { |
|
143 | + $instance_of_class = new $full_classname; |
|
144 | + if ($instance_of_class instanceof ChangesInBase) { |
|
145 | + $instance_of_class->setHooks(); |
|
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 | + * @throws ReflectionException |
|
158 | + */ |
|
159 | + public static function register_routes() |
|
160 | + { |
|
161 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) { |
|
162 | + foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) { |
|
163 | + /** |
|
164 | + * @var array $data_for_multiple_endpoints numerically indexed array |
|
165 | + * but can also contain route options like { |
|
166 | + * @type array $schema { |
|
167 | + * @type callable $schema_callback |
|
168 | + * @type array $callback_args arguments that will be passed to the callback, after the |
|
169 | + * WP_REST_Request of course |
|
170 | + * } |
|
171 | + * } |
|
172 | + */ |
|
173 | + // when registering routes, register all the endpoints' data at the same time |
|
174 | + $multiple_endpoint_args = []; |
|
175 | + foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) { |
|
176 | + /** |
|
177 | + * @var array $data_for_single_endpoint { |
|
178 | + * @type callable $callback |
|
179 | + * @type string methods |
|
180 | + * @type array args |
|
181 | + * @type array _links |
|
182 | + * @type array $callback_args arguments that will be passed to the callback, after the |
|
183 | + * WP_REST_Request of course |
|
184 | + * } |
|
185 | + */ |
|
186 | + // skip route options |
|
187 | + if (! is_numeric($endpoint_key)) { |
|
188 | + continue; |
|
189 | + } |
|
190 | + if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
191 | + throw new EE_Error( |
|
192 | + esc_html__( |
|
193 | + // @codingStandardsIgnoreStart |
|
194 | + 'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).', |
|
195 | + // @codingStandardsIgnoreEnd |
|
196 | + 'event_espresso' |
|
197 | + ) |
|
198 | + ); |
|
199 | + } |
|
200 | + $callback = $data_for_single_endpoint['callback']; |
|
201 | + $single_endpoint_args = [ |
|
202 | + 'methods' => $data_for_single_endpoint['methods'], |
|
203 | + 'args' => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args'] |
|
204 | + : [], |
|
205 | + ]; |
|
206 | + if (isset($data_for_single_endpoint['_links'])) { |
|
207 | + $single_endpoint_args['_links'] = $data_for_single_endpoint['_links']; |
|
208 | + } |
|
209 | + if (isset($data_for_single_endpoint['callback_args'])) { |
|
210 | + $callback_args = $data_for_single_endpoint['callback_args']; |
|
211 | + $single_endpoint_args['callback'] = static function (WP_REST_Request $request) use ( |
|
212 | + $callback, |
|
213 | + $callback_args |
|
214 | + ) { |
|
215 | + array_unshift($callback_args, $request); |
|
216 | + return call_user_func_array( |
|
217 | + $callback, |
|
218 | + $callback_args |
|
219 | + ); |
|
220 | + }; |
|
221 | + } else { |
|
222 | + $single_endpoint_args['callback'] = $data_for_single_endpoint['callback']; |
|
223 | + } |
|
224 | + $multiple_endpoint_args[] = $single_endpoint_args; |
|
225 | + } |
|
226 | + if (isset($data_for_multiple_endpoints['schema'])) { |
|
227 | + $schema_route_data = $data_for_multiple_endpoints['schema']; |
|
228 | + $schema_callback = $schema_route_data['schema_callback']; |
|
229 | + $callback_args = $schema_route_data['callback_args']; |
|
230 | + $multiple_endpoint_args['schema'] = static function () use ($schema_callback, $callback_args) { |
|
231 | + return call_user_func_array( |
|
232 | + $schema_callback, |
|
233 | + $callback_args |
|
234 | + ); |
|
235 | + }; |
|
236 | + } |
|
237 | + register_rest_route( |
|
238 | + $namespace, |
|
239 | + $relative_route, |
|
240 | + $multiple_endpoint_args |
|
241 | + ); |
|
242 | + } |
|
243 | + } |
|
244 | + } |
|
245 | + |
|
246 | + |
|
247 | + /** |
|
248 | + * Checks if there was a version change or something that merits invalidating the cached |
|
249 | + * route data. If so, invalidates the cached route data so that it gets refreshed |
|
250 | + * next time the WP API is used |
|
251 | + */ |
|
252 | + public static function invalidate_cached_route_data_on_version_change() |
|
253 | + { |
|
254 | + if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) { |
|
255 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
256 | + } |
|
257 | + foreach (EE_Registry::instance()->addons as $addon) { |
|
258 | + if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) { |
|
259 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
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 | + * Gets the EE route data |
|
279 | + * |
|
280 | + * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
281 | + * @throws EE_Error |
|
282 | + * @throws ReflectionException |
|
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 = []; |
|
291 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoints) { |
|
292 | + $ee_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = EED_Core_Rest_Api::_get_ee_route_data_for_version( |
|
293 | + $version, |
|
294 | + $hidden_endpoints |
|
295 | + ); |
|
296 | + } |
|
297 | + return $ee_routes; |
|
298 | + } |
|
299 | + |
|
300 | + |
|
301 | + /** |
|
302 | + * Gets the EE route data from the wp options if it exists already, |
|
303 | + * otherwise re-generates it and saves it to the option |
|
304 | + * |
|
305 | + * @param string $version |
|
306 | + * @param boolean $hidden_endpoints |
|
307 | + * @return array |
|
308 | + * @throws EE_Error |
|
309 | + * @throws ReflectionException |
|
310 | + */ |
|
311 | + protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
312 | + { |
|
313 | + $ee_routes = get_option(EED_Core_Rest_Api::saved_routes_option_names . $version, null); |
|
314 | + if (! $ee_routes || EED_Core_Rest_Api::debugMode()) { |
|
315 | + $ee_routes = EED_Core_Rest_Api::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
316 | + } |
|
317 | + return $ee_routes; |
|
318 | + } |
|
319 | + |
|
320 | + |
|
321 | + /** |
|
322 | + * Saves the EE REST API route data to a wp option and returns it |
|
323 | + * |
|
324 | + * @param string $version |
|
325 | + * @param boolean $hidden_endpoints |
|
326 | + * @return mixed|null |
|
327 | + * @throws EE_Error |
|
328 | + * @throws ReflectionException |
|
329 | + */ |
|
330 | + protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
331 | + { |
|
332 | + $instance = EED_Core_Rest_Api::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 = EED_Core_Rest_Api::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 | + * Calculates all the EE routes and saves it to a WordPress option so we don't |
|
354 | + * need to calculate it on every request |
|
355 | + * |
|
356 | + * @return void |
|
357 | + * @deprecated since version 4.9.1 |
|
358 | + */ |
|
359 | + public static function save_ee_routes() |
|
360 | + { |
|
361 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
362 | + $instance = EED_Core_Rest_Api::instance(); |
|
363 | + $routes = apply_filters( |
|
364 | + 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
365 | + array_replace_recursive( |
|
366 | + $instance->_register_config_routes(), |
|
367 | + $instance->_register_meta_routes(), |
|
368 | + $instance->_register_model_routes(), |
|
369 | + $instance->_register_rpc_routes() |
|
370 | + ) |
|
371 | + ); |
|
372 | + update_option(EED_Core_Rest_Api::saved_routes_option_names, $routes, true); |
|
373 | + } |
|
374 | + } |
|
375 | + |
|
376 | + |
|
377 | + /** |
|
378 | + * Gets all the route information relating to EE models |
|
379 | + * |
|
380 | + * @return array @see get_ee_route_data |
|
381 | + * @deprecated since version 4.9.1 |
|
382 | + */ |
|
383 | + protected function _register_model_routes() |
|
384 | + { |
|
385 | + $model_routes = []; |
|
386 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
387 | + $model_routes[ EED_Core_Rest_Api::ee_api_namespace |
|
388 | + . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
389 | + } |
|
390 | + return $model_routes; |
|
391 | + } |
|
392 | + |
|
393 | + |
|
394 | + /** |
|
395 | + * Decides whether or not to add write endpoints for this model. |
|
396 | + * Currently, this defaults to exclude all global tables and models |
|
397 | + * which would allow inserting WP core data (we don't want to duplicate |
|
398 | + * what WP API does, as it's unnecessary, extra work, and potentially extra bugs) |
|
399 | + * |
|
400 | + * @param EEM_Base $model |
|
401 | + * @return bool |
|
402 | + */ |
|
403 | + public static function should_have_write_endpoints(EEM_Base $model) |
|
404 | + { |
|
405 | + if ($model->is_wp_core_model()) { |
|
406 | + return false; |
|
407 | + } |
|
408 | + foreach ($model->get_tables() as $table) { |
|
409 | + if ($table->is_global()) { |
|
410 | + return false; |
|
411 | + } |
|
412 | + } |
|
413 | + return true; |
|
414 | + } |
|
415 | + |
|
416 | + |
|
417 | + /** |
|
418 | + * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`) |
|
419 | + * in this versioned namespace of EE4 |
|
420 | + * |
|
421 | + * @param $version |
|
422 | + * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event') |
|
423 | + */ |
|
424 | + public static function model_names_with_plural_routes($version) |
|
425 | + { |
|
426 | + $model_version_info = new ModelVersionInfo($version); |
|
427 | + $models_to_register = $model_version_info->modelsForRequestedVersion(); |
|
428 | + // let's not bother having endpoints for extra metas |
|
429 | + unset( |
|
430 | + $models_to_register['Extra_Meta'], |
|
431 | + $models_to_register['Extra_Join'], |
|
432 | + $models_to_register['Post_Meta'] |
|
433 | + ); |
|
434 | + return apply_filters( |
|
435 | + 'FHEE__EED_Core_REST_API___register_model_routes', |
|
436 | + $models_to_register |
|
437 | + ); |
|
438 | + } |
|
439 | + |
|
440 | + |
|
441 | + /** |
|
442 | + * Gets the route data for EE models in the specified version |
|
443 | + * |
|
444 | + * @param string $version |
|
445 | + * @param boolean $hidden_endpoint |
|
446 | + * @return array |
|
447 | + * @throws EE_Error |
|
448 | + * @throws ReflectionException |
|
449 | + */ |
|
450 | + protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
451 | + { |
|
452 | + $model_routes = []; |
|
453 | + $model_version_info = new ModelVersionInfo($version); |
|
454 | + foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
|
455 | + $model = EE_Registry::instance()->load_model($model_name); |
|
456 | + // if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
457 | + if (! $model instanceof EEM_Base) { |
|
458 | + continue; |
|
459 | + } |
|
460 | + // yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
461 | + $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
|
462 | + $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
|
463 | + $model_routes[ $plural_model_route ] = [ |
|
464 | + [ |
|
465 | + 'callback' => [ |
|
466 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
467 | + 'handleRequestGetAll', |
|
468 | + ], |
|
469 | + 'callback_args' => [$version, $model_name], |
|
470 | + 'methods' => WP_REST_Server::READABLE, |
|
471 | + 'hidden_endpoint' => $hidden_endpoint, |
|
472 | + 'args' => $this->_get_read_query_params($model, $version), |
|
473 | + '_links' => [ |
|
474 | + 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
475 | + ], |
|
476 | + ], |
|
477 | + 'schema' => [ |
|
478 | + 'schema_callback' => [ |
|
479 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
480 | + 'handleSchemaRequest', |
|
481 | + ], |
|
482 | + 'callback_args' => [$version, $model_name], |
|
483 | + ], |
|
484 | + ]; |
|
485 | + $model_routes[ $singular_model_route ] = [ |
|
486 | + [ |
|
487 | + 'callback' => [ |
|
488 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
489 | + 'handleRequestGetOne', |
|
490 | + ], |
|
491 | + 'callback_args' => [$version, $model_name], |
|
492 | + 'methods' => WP_REST_Server::READABLE, |
|
493 | + 'hidden_endpoint' => $hidden_endpoint, |
|
494 | + 'args' => $this->_get_response_selection_query_params($model, $version, true), |
|
495 | + ], |
|
496 | + ]; |
|
497 | + if (apply_filters( |
|
498 | + 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints', |
|
499 | + EED_Core_Rest_Api::should_have_write_endpoints($model), |
|
500 | + $model |
|
501 | + )) { |
|
502 | + $model_routes[ $plural_model_route ][] = [ |
|
503 | + 'callback' => [ |
|
504 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
505 | + 'handleRequestInsert', |
|
506 | + ], |
|
507 | + 'callback_args' => [$version, $model_name], |
|
508 | + 'methods' => WP_REST_Server::CREATABLE, |
|
509 | + 'hidden_endpoint' => $hidden_endpoint, |
|
510 | + 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
|
511 | + ]; |
|
512 | + $model_routes[ $singular_model_route ] = array_merge( |
|
513 | + $model_routes[ $singular_model_route ], |
|
514 | + [ |
|
515 | + [ |
|
516 | + 'callback' => [ |
|
517 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
518 | + 'handleRequestUpdate', |
|
519 | + ], |
|
520 | + 'callback_args' => [$version, $model_name], |
|
521 | + 'methods' => WP_REST_Server::EDITABLE, |
|
522 | + 'hidden_endpoint' => $hidden_endpoint, |
|
523 | + 'args' => $this->_get_write_params($model_name, $model_version_info), |
|
524 | + ], |
|
525 | + [ |
|
526 | + 'callback' => [ |
|
527 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
528 | + 'handleRequestDelete', |
|
529 | + ], |
|
530 | + 'callback_args' => [$version, $model_name], |
|
531 | + 'methods' => WP_REST_Server::DELETABLE, |
|
532 | + 'hidden_endpoint' => $hidden_endpoint, |
|
533 | + 'args' => $this->_get_delete_query_params($model, $version), |
|
534 | + ], |
|
535 | + ] |
|
536 | + ); |
|
537 | + } |
|
538 | + foreach ($model->relation_settings() as $relation_name => $relation_obj) { |
|
539 | + $related_route = EED_Core_Rest_Api::get_relation_route_via( |
|
540 | + $model, |
|
541 | + '(?P<id>[^\/]+)', |
|
542 | + $relation_obj |
|
543 | + ); |
|
544 | + $model_routes[ $related_route ] = [ |
|
545 | + [ |
|
546 | + 'callback' => [ |
|
547 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
548 | + 'handleRequestGetRelated', |
|
549 | + ], |
|
550 | + 'callback_args' => [$version, $model_name, $relation_name], |
|
551 | + 'methods' => WP_REST_Server::READABLE, |
|
552 | + 'hidden_endpoint' => $hidden_endpoint, |
|
553 | + 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
554 | + ], |
|
555 | + ]; |
|
556 | + |
|
557 | + $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)'; |
|
558 | + $model_routes[ $related_write_route ] = [ |
|
559 | + [ |
|
560 | + 'callback' => [ |
|
561 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
562 | + 'handleRequestAddRelation', |
|
563 | + ], |
|
564 | + 'callback_args' => [$version, $model_name, $relation_name], |
|
565 | + 'methods' => WP_REST_Server::EDITABLE, |
|
566 | + 'hidden_endpoint' => $hidden_endpoint, |
|
567 | + 'args' => $this->_get_add_relation_query_params( |
|
568 | + $model, |
|
569 | + $relation_obj->get_other_model(), |
|
570 | + $version |
|
571 | + ), |
|
572 | + ], |
|
573 | + [ |
|
574 | + 'callback' => [ |
|
575 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
576 | + 'handleRequestRemoveRelation', |
|
577 | + ], |
|
578 | + 'callback_args' => [$version, $model_name, $relation_name], |
|
579 | + 'methods' => WP_REST_Server::DELETABLE, |
|
580 | + 'hidden_endpoint' => $hidden_endpoint, |
|
581 | + 'args' => [], |
|
582 | + ], |
|
583 | + ]; |
|
584 | + } |
|
585 | + } |
|
586 | + return $model_routes; |
|
587 | + } |
|
588 | + |
|
589 | + |
|
590 | + /** |
|
591 | + * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace, |
|
592 | + * excluding the preceding slash. |
|
593 | + * Eg you pass get_plural_route_to('Event') = 'events' |
|
594 | + * |
|
595 | + * @param EEM_Base $model |
|
596 | + * @return string |
|
597 | + */ |
|
598 | + public static function get_collection_route(EEM_Base $model) |
|
599 | + { |
|
600 | + return EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
601 | + } |
|
602 | + |
|
603 | + |
|
604 | + /** |
|
605 | + * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
606 | + * excluding the preceding slash. |
|
607 | + * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
608 | + * |
|
609 | + * @param EEM_Base $model eg Event or Venue |
|
610 | + * @param string $id |
|
611 | + * @return string |
|
612 | + */ |
|
613 | + public static function get_entity_route($model, $id) |
|
614 | + { |
|
615 | + return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id; |
|
616 | + } |
|
617 | + |
|
618 | + |
|
619 | + /** |
|
620 | + * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
621 | + * excluding the preceding slash. |
|
622 | + * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
623 | + * |
|
624 | + * @param EEM_Base $model eg Event or Venue |
|
625 | + * @param string $id |
|
626 | + * @param EE_Model_Relation_Base $relation_obj |
|
627 | + * @return string |
|
628 | + */ |
|
629 | + public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj) |
|
630 | + { |
|
631 | + $related_model_name_endpoint_part = ModelRead::getRelatedEntityName( |
|
632 | + $relation_obj->get_other_model()->get_this_model_name(), |
|
633 | + $relation_obj |
|
634 | + ); |
|
635 | + return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
636 | + } |
|
637 | + |
|
638 | + |
|
639 | + /** |
|
640 | + * Adds onto the $relative_route the EE4 REST API versioned namespace. |
|
641 | + * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events' |
|
642 | + * |
|
643 | + * @param string $relative_route |
|
644 | + * @param string $version |
|
645 | + * @return string |
|
646 | + */ |
|
647 | + public static function get_versioned_route_to($relative_route, $version = '4.8.36') |
|
648 | + { |
|
649 | + return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
650 | + } |
|
651 | + |
|
652 | + |
|
653 | + /** |
|
654 | + * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
655 | + * routes that don't conform to the traditional REST CRUD-style). |
|
656 | + * |
|
657 | + * @deprecated since 4.9.1 |
|
658 | + */ |
|
659 | + protected function _register_rpc_routes() |
|
660 | + { |
|
661 | + $routes = []; |
|
662 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
663 | + $routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version( |
|
664 | + $version, |
|
665 | + $hidden_endpoint |
|
666 | + ); |
|
667 | + } |
|
668 | + return $routes; |
|
669 | + } |
|
670 | + |
|
671 | + |
|
672 | + /** |
|
673 | + * @param string $version |
|
674 | + * @param boolean $hidden_endpoint |
|
675 | + * @return array |
|
676 | + */ |
|
677 | + protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
678 | + { |
|
679 | + $this_versions_routes = []; |
|
680 | + // checkin endpoint |
|
681 | + $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = [ |
|
682 | + [ |
|
683 | + 'callback' => [ |
|
684 | + 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
685 | + 'handleRequestToggleCheckin', |
|
686 | + ], |
|
687 | + 'methods' => WP_REST_Server::CREATABLE, |
|
688 | + 'hidden_endpoint' => $hidden_endpoint, |
|
689 | + 'args' => [ |
|
690 | + 'force' => [ |
|
691 | + 'required' => false, |
|
692 | + 'default' => false, |
|
693 | + 'description' => __( |
|
694 | + // @codingStandardsIgnoreStart |
|
695 | + 'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
696 | + // @codingStandardsIgnoreEnd |
|
697 | + 'event_espresso' |
|
698 | + ), |
|
699 | + ], |
|
700 | + ], |
|
701 | + 'callback_args' => [$version], |
|
702 | + ], |
|
703 | + ]; |
|
704 | + return apply_filters( |
|
705 | + 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
706 | + $this_versions_routes, |
|
707 | + $version, |
|
708 | + $hidden_endpoint |
|
709 | + ); |
|
710 | + } |
|
711 | + |
|
712 | + |
|
713 | + /** |
|
714 | + * Gets the query params that can be used when request one or many |
|
715 | + * |
|
716 | + * @param EEM_Base $model |
|
717 | + * @param string $version |
|
718 | + * @return array |
|
719 | + */ |
|
720 | + protected function _get_response_selection_query_params(EEM_Base $model, $version, $single_only = false) |
|
721 | + { |
|
722 | + $query_params = [ |
|
723 | + 'include' => [ |
|
724 | + 'required' => false, |
|
725 | + 'default' => '*', |
|
726 | + 'type' => 'string', |
|
727 | + ], |
|
728 | + 'calculate' => [ |
|
729 | + 'required' => false, |
|
730 | + 'default' => '', |
|
731 | + 'enum' => EED_Core_Rest_Api::$_field_calculator->retrieveCalculatedFieldsForModel($model), |
|
732 | + 'type' => 'string', |
|
733 | + // because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization |
|
734 | + // freaks out. We'll just validate this argument while handling the request |
|
735 | + 'validate_callback' => null, |
|
736 | + 'sanitize_callback' => null, |
|
737 | + ], |
|
738 | + 'password' => [ |
|
739 | + 'required' => false, |
|
740 | + 'default' => '', |
|
741 | + 'type' => 'string', |
|
742 | + ], |
|
743 | + ]; |
|
744 | + return apply_filters( |
|
745 | + 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
746 | + $query_params, |
|
747 | + $model, |
|
748 | + $version |
|
749 | + ); |
|
750 | + } |
|
751 | + |
|
752 | + |
|
753 | + /** |
|
754 | + * Gets the parameters acceptable for delete requests |
|
755 | + * |
|
756 | + * @param EEM_Base $model |
|
757 | + * @param string $version |
|
758 | + * @return array |
|
759 | + */ |
|
760 | + protected function _get_delete_query_params(EEM_Base $model, $version) |
|
761 | + { |
|
762 | + $params_for_delete = [ |
|
763 | + 'allow_blocking' => [ |
|
764 | + 'required' => false, |
|
765 | + 'default' => true, |
|
766 | + 'type' => 'boolean', |
|
767 | + ], |
|
768 | + ]; |
|
769 | + $params_for_delete['force'] = [ |
|
770 | + 'required' => false, |
|
771 | + 'default' => false, |
|
772 | + 'type' => 'boolean', |
|
773 | + ]; |
|
774 | + return apply_filters( |
|
775 | + 'FHEE__EED_Core_Rest_Api___get_delete_query_params', |
|
776 | + $params_for_delete, |
|
777 | + $model, |
|
778 | + $version |
|
779 | + ); |
|
780 | + } |
|
781 | + |
|
782 | + |
|
783 | + /** |
|
784 | + * @param EEM_Base $source_model |
|
785 | + * @param EEM_Base $related_model |
|
786 | + * @param $version |
|
787 | + * @return array |
|
788 | + * @throws EE_Error |
|
789 | + * @since $VID:$ |
|
790 | + */ |
|
791 | + protected function _get_add_relation_query_params(EEM_Base $source_model, EEM_Base $related_model, $version) |
|
792 | + { |
|
793 | + // if they're related through a HABTM relation, check for any non-FKs |
|
794 | + $all_relation_settings = $source_model->relation_settings(); |
|
795 | + $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ]; |
|
796 | + $params = []; |
|
797 | + if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) { |
|
798 | + foreach ($relation_settings->getNonKeyFields() as $field) { |
|
799 | + /* @var $field EE_Model_Field_Base */ |
|
800 | + $params[ $field->get_name() ] = [ |
|
801 | + 'required' => ! $field->is_nullable(), |
|
802 | + 'default' => ModelDataTranslator::prepareFieldValueForJson( |
|
803 | + $field, |
|
804 | + $field->get_default_value(), |
|
805 | + $version |
|
806 | + ), |
|
807 | + 'type' => $field->getSchemaType(), |
|
808 | + 'validate_callback' => null, |
|
809 | + 'sanitize_callback' => null, |
|
810 | + ]; |
|
811 | + } |
|
812 | + } |
|
813 | + return $params; |
|
814 | + } |
|
815 | + |
|
816 | + |
|
817 | + /** |
|
818 | + * Gets info about reading query params that are acceptable |
|
819 | + * |
|
820 | + * @param EEM_Base $model eg 'Event' or 'Venue' |
|
821 | + * @param string $version |
|
822 | + * @return array describing the args acceptable when querying this model |
|
823 | + * @throws EE_Error |
|
824 | + */ |
|
825 | + protected function _get_read_query_params(EEM_Base $model, $version) |
|
826 | + { |
|
827 | + $default_orderby = []; |
|
828 | + foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
829 | + $default_orderby[ $key_field->get_name() ] = 'ASC'; |
|
830 | + } |
|
831 | + return array_merge( |
|
832 | + $this->_get_response_selection_query_params($model, $version), |
|
833 | + [ |
|
834 | + 'where' => [ |
|
835 | + 'required' => false, |
|
836 | + 'default' => [], |
|
837 | + 'type' => 'object', |
|
838 | + // because we accept an almost infinite list of possible where conditions, WP |
|
839 | + // core validation and sanitization freaks out. We'll just validate this argument |
|
840 | + // while handling the request |
|
841 | + 'validate_callback' => null, |
|
842 | + 'sanitize_callback' => null, |
|
843 | + ], |
|
844 | + 'limit' => [ |
|
845 | + 'required' => false, |
|
846 | + 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
847 | + 'type' => [ |
|
848 | + 'array', |
|
849 | + 'string', |
|
850 | + 'integer', |
|
851 | + ], |
|
852 | + // because we accept a variety of types, WP core validation and sanitization |
|
853 | + // freaks out. We'll just validate this argument while handling the request |
|
854 | + 'validate_callback' => null, |
|
855 | + 'sanitize_callback' => null, |
|
856 | + ], |
|
857 | + 'order_by' => [ |
|
858 | + 'required' => false, |
|
859 | + 'default' => $default_orderby, |
|
860 | + 'type' => [ |
|
861 | + 'object', |
|
862 | + 'string', |
|
863 | + ],// because we accept a variety of types, WP core validation and sanitization |
|
864 | + // freaks out. We'll just validate this argument while handling the request |
|
865 | + 'validate_callback' => null, |
|
866 | + 'sanitize_callback' => null, |
|
867 | + ], |
|
868 | + 'group_by' => [ |
|
869 | + 'required' => false, |
|
870 | + 'default' => null, |
|
871 | + 'type' => [ |
|
872 | + 'object', |
|
873 | + 'string', |
|
874 | + ], |
|
875 | + // because we accept an almost infinite list of possible groupings, |
|
876 | + // WP core validation and sanitization |
|
877 | + // freaks out. We'll just validate this argument while handling the request |
|
878 | + 'validate_callback' => null, |
|
879 | + 'sanitize_callback' => null, |
|
880 | + ], |
|
881 | + 'having' => [ |
|
882 | + 'required' => false, |
|
883 | + 'default' => null, |
|
884 | + 'type' => 'object', |
|
885 | + // because we accept an almost infinite list of possible where conditions, WP |
|
886 | + // core validation and sanitization freaks out. We'll just validate this argument |
|
887 | + // while handling the request |
|
888 | + 'validate_callback' => null, |
|
889 | + 'sanitize_callback' => null, |
|
890 | + ], |
|
891 | + 'caps' => [ |
|
892 | + 'required' => false, |
|
893 | + 'default' => EEM_Base::caps_read, |
|
894 | + 'type' => 'string', |
|
895 | + 'enum' => [ |
|
896 | + EEM_Base::caps_read, |
|
897 | + EEM_Base::caps_read_admin, |
|
898 | + EEM_Base::caps_edit, |
|
899 | + EEM_Base::caps_delete, |
|
900 | + ], |
|
901 | + ], |
|
902 | + ] |
|
903 | + ); |
|
904 | + } |
|
905 | + |
|
906 | + |
|
907 | + /** |
|
908 | + * Gets parameter information for a model regarding writing data |
|
909 | + * |
|
910 | + * @param string $model_name |
|
911 | + * @param ModelVersionInfo $model_version_info |
|
912 | + * @param boolean $create whether this is for request to create (in |
|
913 | + * which case we need all required params) or |
|
914 | + * just to update (in which case we don't |
|
915 | + * need those on every request) |
|
916 | + * @return array |
|
917 | + * @throws EE_Error |
|
918 | + * @throws ReflectionException |
|
919 | + */ |
|
920 | + protected function _get_write_params( |
|
921 | + $model_name, |
|
922 | + ModelVersionInfo $model_version_info, |
|
923 | + $create = false |
|
924 | + ) { |
|
925 | + $model = EE_Registry::instance()->load_model($model_name); |
|
926 | + $fields = $model_version_info->fieldsOnModelInThisVersion($model); |
|
927 | + |
|
928 | + // we do our own validation and sanitization within the controller |
|
929 | + $sanitize_callback = function_exists('rest_validate_value_from_schema') |
|
930 | + ? ['EED_Core_Rest_Api', 'default_sanitize_callback'] |
|
931 | + : null; |
|
932 | + $args_info = []; |
|
933 | + foreach ($fields as $field_name => $field_obj) { |
|
934 | + if ($field_obj->is_auto_increment()) { |
|
935 | + // totally ignore auto increment IDs |
|
936 | + continue; |
|
937 | + } |
|
938 | + $arg_info = $field_obj->getSchema(); |
|
939 | + $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null; |
|
940 | + $arg_info['required'] = $required; |
|
941 | + // remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right? |
|
942 | + unset($arg_info['readonly']); |
|
943 | + $schema_properties = $field_obj->getSchemaProperties(); |
|
944 | + if (isset($schema_properties['raw']) |
|
945 | + && $field_obj->getSchemaType() === 'object' |
|
946 | + ) { |
|
947 | + // if there's a "raw" form of this argument, use those properties instead |
|
948 | + $arg_info = array_replace( |
|
949 | + $arg_info, |
|
950 | + $schema_properties['raw'] |
|
951 | + ); |
|
952 | + } |
|
953 | + $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson( |
|
954 | + $field_obj, |
|
955 | + $field_obj->get_default_value(), |
|
956 | + $model_version_info->requestedVersion() |
|
957 | + ); |
|
958 | + $arg_info['sanitize_callback'] = $sanitize_callback; |
|
959 | + $args_info[ $field_name ] = $arg_info; |
|
960 | + if ($field_obj instanceof EE_Datetime_Field) { |
|
961 | + $gmt_arg_info = $arg_info; |
|
962 | + $gmt_arg_info['description'] = sprintf( |
|
963 | + esc_html__( |
|
964 | + '%1$s - the value for this field in UTC. Ignored if %2$s is provided.', |
|
965 | + 'event_espresso' |
|
966 | + ), |
|
967 | + $field_obj->get_nicename(), |
|
968 | + $field_name |
|
969 | + ); |
|
970 | + $args_info[ $field_name . '_gmt' ] = $gmt_arg_info; |
|
971 | + } |
|
972 | + } |
|
973 | + return $args_info; |
|
974 | + } |
|
975 | + |
|
976 | + |
|
977 | + /** |
|
978 | + * Replacement for WP API's 'rest_parse_request_arg'. |
|
979 | + * If the value is blank but not required, don't bother validating it. |
|
980 | + * Also, it uses our email validation instead of WP API's default. |
|
981 | + * |
|
982 | + * @param $value |
|
983 | + * @param WP_REST_Request $request |
|
984 | + * @param $param |
|
985 | + * @return bool|true|WP_Error |
|
986 | + * @throws InvalidArgumentException |
|
987 | + * @throws InvalidInterfaceException |
|
988 | + * @throws InvalidDataTypeException |
|
989 | + */ |
|
990 | + public static function default_sanitize_callback($value, WP_REST_Request $request, $param) |
|
991 | + { |
|
992 | + $attributes = $request->get_attributes(); |
|
993 | + if (! isset($attributes['args'][ $param ]) |
|
994 | + || ! is_array($attributes['args'][ $param ])) { |
|
995 | + $validation_result = true; |
|
996 | + } else { |
|
997 | + $args = $attributes['args'][ $param ]; |
|
998 | + if (( |
|
999 | + $value === '' |
|
1000 | + || $value === null |
|
1001 | + ) |
|
1002 | + && (! isset($args['required']) |
|
1003 | + || $args['required'] === false |
|
1004 | + ) |
|
1005 | + ) { |
|
1006 | + // not required and not provided? that's cool |
|
1007 | + $validation_result = true; |
|
1008 | + } elseif (isset($args['format']) |
|
1009 | + && $args['format'] === 'email' |
|
1010 | + ) { |
|
1011 | + $validation_result = true; |
|
1012 | + if (! EED_Core_Rest_Api::_validate_email($value)) { |
|
1013 | + $validation_result = new WP_Error( |
|
1014 | + 'rest_invalid_param', |
|
1015 | + esc_html__( |
|
1016 | + 'The email address is not valid or does not exist.', |
|
1017 | + 'event_espresso' |
|
1018 | + ) |
|
1019 | + ); |
|
1020 | + } |
|
1021 | + } else { |
|
1022 | + $validation_result = rest_validate_value_from_schema($value, $args, $param); |
|
1023 | + } |
|
1024 | + } |
|
1025 | + if (is_wp_error($validation_result)) { |
|
1026 | + return $validation_result; |
|
1027 | + } |
|
1028 | + return rest_sanitize_request_arg($value, $request, $param); |
|
1029 | + } |
|
1030 | + |
|
1031 | + |
|
1032 | + /** |
|
1033 | + * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email() |
|
1034 | + * |
|
1035 | + * @param $email |
|
1036 | + * @return bool |
|
1037 | + * @throws InvalidArgumentException |
|
1038 | + * @throws InvalidInterfaceException |
|
1039 | + * @throws InvalidDataTypeException |
|
1040 | + */ |
|
1041 | + protected static function _validate_email($email) |
|
1042 | + { |
|
1043 | + try { |
|
1044 | + EmailAddressFactory::create($email); |
|
1045 | + return true; |
|
1046 | + } catch (EmailValidationException $e) { |
|
1047 | + return false; |
|
1048 | + } |
|
1049 | + } |
|
1050 | + |
|
1051 | + |
|
1052 | + /** |
|
1053 | + * Gets routes for the config |
|
1054 | + * |
|
1055 | + * @return array @see _register_model_routes |
|
1056 | + * @deprecated since version 4.9.1 |
|
1057 | + */ |
|
1058 | + protected function _register_config_routes() |
|
1059 | + { |
|
1060 | + $config_routes = []; |
|
1061 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1062 | + $config_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version( |
|
1063 | + $version, |
|
1064 | + $hidden_endpoint |
|
1065 | + ); |
|
1066 | + } |
|
1067 | + return $config_routes; |
|
1068 | + } |
|
1069 | + |
|
1070 | + |
|
1071 | + /** |
|
1072 | + * Gets routes for the config for the specified version |
|
1073 | + * |
|
1074 | + * @param string $version |
|
1075 | + * @param boolean $hidden_endpoint |
|
1076 | + * @return array |
|
1077 | + */ |
|
1078 | + protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
1079 | + { |
|
1080 | + return [ |
|
1081 | + 'config' => [ |
|
1082 | + [ |
|
1083 | + 'callback' => [ |
|
1084 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1085 | + 'handleRequest', |
|
1086 | + ], |
|
1087 | + 'methods' => WP_REST_Server::READABLE, |
|
1088 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1089 | + 'callback_args' => [$version], |
|
1090 | + ], |
|
1091 | + ], |
|
1092 | + 'site_info' => [ |
|
1093 | + [ |
|
1094 | + 'callback' => [ |
|
1095 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1096 | + 'handleRequestSiteInfo', |
|
1097 | + ], |
|
1098 | + 'methods' => WP_REST_Server::READABLE, |
|
1099 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1100 | + 'callback_args' => [$version], |
|
1101 | + ], |
|
1102 | + ], |
|
1103 | + ]; |
|
1104 | + } |
|
1105 | + |
|
1106 | + |
|
1107 | + /** |
|
1108 | + * Gets the meta info routes |
|
1109 | + * |
|
1110 | + * @return array @see _register_model_routes |
|
1111 | + * @deprecated since version 4.9.1 |
|
1112 | + */ |
|
1113 | + protected function _register_meta_routes() |
|
1114 | + { |
|
1115 | + $meta_routes = []; |
|
1116 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1117 | + $meta_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version( |
|
1118 | + $version, |
|
1119 | + $hidden_endpoint |
|
1120 | + ); |
|
1121 | + } |
|
1122 | + return $meta_routes; |
|
1123 | + } |
|
1124 | + |
|
1125 | + |
|
1126 | + /** |
|
1127 | + * @param string $version |
|
1128 | + * @param boolean $hidden_endpoint |
|
1129 | + * @return array |
|
1130 | + */ |
|
1131 | + protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
1132 | + { |
|
1133 | + return [ |
|
1134 | + 'resources' => [ |
|
1135 | + [ |
|
1136 | + 'callback' => [ |
|
1137 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
1138 | + 'handleRequestModelsMeta', |
|
1139 | + ], |
|
1140 | + 'methods' => WP_REST_Server::READABLE, |
|
1141 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1142 | + 'callback_args' => [$version], |
|
1143 | + ], |
|
1144 | + ], |
|
1145 | + ]; |
|
1146 | + } |
|
1147 | + |
|
1148 | + |
|
1149 | + /** |
|
1150 | + * Tries to hide old 4.6 endpoints from the |
|
1151 | + * |
|
1152 | + * @param array $route_data |
|
1153 | + * @return array |
|
1154 | + * @throws EE_Error |
|
1155 | + * @throws ReflectionException |
|
1156 | + */ |
|
1157 | + public static function hide_old_endpoints($route_data) |
|
1158 | + { |
|
1159 | + // allow API clients to override which endpoints get hidden, in case |
|
1160 | + // they want to discover particular endpoints |
|
1161 | + // also, we don't have access to the request so we have to just grab it from the superglobal |
|
1162 | + $force_show_ee_namespace = ltrim( |
|
1163 | + EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''), |
|
1164 | + '/' |
|
1165 | + ); |
|
1166 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
1167 | + foreach ($relative_urls as $resource_name => $endpoints) { |
|
1168 | + foreach ($endpoints as $key => $endpoint) { |
|
1169 | + // skip schema and other route options |
|
1170 | + if (! is_numeric($key)) { |
|
1171 | + continue; |
|
1172 | + } |
|
1173 | + // by default, hide "hidden_endpoint"s, unless the request indicates |
|
1174 | + // to $force_show_ee_namespace, in which case only show that one |
|
1175 | + // namespace's endpoints (and hide all others) |
|
1176 | + if (($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
1177 | + || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
1178 | + ) { |
|
1179 | + $full_route = '/' . ltrim($namespace, '/'); |
|
1180 | + $full_route .= '/' . ltrim($resource_name, '/'); |
|
1181 | + unset($route_data[ $full_route ]); |
|
1182 | + } |
|
1183 | + } |
|
1184 | + } |
|
1185 | + } |
|
1186 | + return $route_data; |
|
1187 | + } |
|
1188 | + |
|
1189 | + |
|
1190 | + /** |
|
1191 | + * Returns an array describing which versions of core support serving requests for. |
|
1192 | + * Keys are core versions' major and minor version, and values are the |
|
1193 | + * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
1194 | + * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
1195 | + * the answers table entirely, in which case it would be very difficult for |
|
1196 | + * it to serve 4.6-style responses. |
|
1197 | + * Versions of core that are missing from this array are unknowns. |
|
1198 | + * previous ver |
|
1199 | + * |
|
1200 | + * @return array |
|
1201 | + */ |
|
1202 | + public static function version_compatibilities() |
|
1203 | + { |
|
1204 | + return apply_filters( |
|
1205 | + 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
1206 | + [ |
|
1207 | + '4.8.29' => '4.8.29', |
|
1208 | + '4.8.33' => '4.8.29', |
|
1209 | + '4.8.34' => '4.8.29', |
|
1210 | + '4.8.36' => '4.8.29', |
|
1211 | + ] |
|
1212 | + ); |
|
1213 | + } |
|
1214 | + |
|
1215 | + |
|
1216 | + /** |
|
1217 | + * Gets the latest API version served. Eg if there |
|
1218 | + * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
1219 | + * we are on core version 4.8.34, it will return the string "4.8.32" |
|
1220 | + * |
|
1221 | + * @return string |
|
1222 | + */ |
|
1223 | + public static function latest_rest_api_version() |
|
1224 | + { |
|
1225 | + $versions_served = EED_Core_Rest_Api::versions_served(); |
|
1226 | + $versions_served_keys = array_keys($versions_served); |
|
1227 | + return end($versions_served_keys); |
|
1228 | + } |
|
1229 | + |
|
1230 | + |
|
1231 | + /** |
|
1232 | + * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
1233 | + * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
1234 | + * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
1235 | + * We also indicate whether or not this version should be put in the index or not |
|
1236 | + * |
|
1237 | + * @return array keys are API version numbers (just major and minor numbers), and values |
|
1238 | + * are whether or not they should be hidden |
|
1239 | + */ |
|
1240 | + public static function versions_served() |
|
1241 | + { |
|
1242 | + $versions_served = []; |
|
1243 | + $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
1244 | + $lowest_compatible_version = end($possibly_served_versions); |
|
1245 | + reset($possibly_served_versions); |
|
1246 | + $versions_served_historically = array_keys($possibly_served_versions); |
|
1247 | + $latest_version = end($versions_served_historically); |
|
1248 | + reset($versions_served_historically); |
|
1249 | + // for each version of core we have ever served: |
|
1250 | + foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
1251 | + // if it's not above the current core version, and it's compatible with the current version of core |
|
1252 | + |
|
1253 | + if ($key_versioned_endpoint === $latest_version) { |
|
1254 | + // don't hide the latest version in the index |
|
1255 | + $versions_served[ $key_versioned_endpoint ] = false; |
|
1256 | + } elseif (version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=') |
|
1257 | + && version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<') |
|
1258 | + ) { |
|
1259 | + // include, but hide, previous versions which are still supported |
|
1260 | + $versions_served[ $key_versioned_endpoint ] = true; |
|
1261 | + } elseif (apply_filters( |
|
1262 | + 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
1263 | + false, |
|
1264 | + $possibly_served_versions |
|
1265 | + )) { |
|
1266 | + // if a version is no longer supported, don't include it in index or list of versions served |
|
1267 | + $versions_served[ $key_versioned_endpoint ] = true; |
|
1268 | + } |
|
1269 | + } |
|
1270 | + return $versions_served; |
|
1271 | + } |
|
1272 | + |
|
1273 | + |
|
1274 | + /** |
|
1275 | + * Gets the major and minor version of EE core's version string |
|
1276 | + * |
|
1277 | + * @return string |
|
1278 | + */ |
|
1279 | + public static function core_version() |
|
1280 | + { |
|
1281 | + return apply_filters( |
|
1282 | + 'FHEE__EED_Core_REST_API__core_version', |
|
1283 | + implode( |
|
1284 | + '.', |
|
1285 | + array_slice( |
|
1286 | + explode( |
|
1287 | + '.', |
|
1288 | + espresso_version() |
|
1289 | + ), |
|
1290 | + 0, |
|
1291 | + 3 |
|
1292 | + ) |
|
1293 | + ) |
|
1294 | + ); |
|
1295 | + } |
|
1296 | + |
|
1297 | + |
|
1298 | + /** |
|
1299 | + * Gets the default limit that should be used when querying for resources |
|
1300 | + * |
|
1301 | + * @return int |
|
1302 | + */ |
|
1303 | + public static function get_default_query_limit() |
|
1304 | + { |
|
1305 | + // we actually don't use a const because we want folks to always use |
|
1306 | + // this method, not the const directly |
|
1307 | + return apply_filters( |
|
1308 | + 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
1309 | + 50 |
|
1310 | + ); |
|
1311 | + } |
|
1312 | + |
|
1313 | + |
|
1314 | + /** |
|
1315 | + * @param string $version api version string (i.e. '4.8.36') |
|
1316 | + * @return array |
|
1317 | + */ |
|
1318 | + public static function getCollectionRoutesIndexedByModelName($version = '') |
|
1319 | + { |
|
1320 | + $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1321 | + $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1322 | + $collection_routes = []; |
|
1323 | + foreach ($model_names as $model_name => $model_class_name) { |
|
1324 | + $collection_routes[ strtolower($model_name) ] = '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' |
|
1325 | + . EEH_Inflector::pluralize_and_lower($model_name); |
|
1326 | + } |
|
1327 | + return $collection_routes; |
|
1328 | + } |
|
1329 | + |
|
1330 | + |
|
1331 | + /** |
|
1332 | + * Returns an array of primary key names indexed by model names. |
|
1333 | + * |
|
1334 | + * @param string $version |
|
1335 | + * @return array |
|
1336 | + */ |
|
1337 | + public static function getPrimaryKeyNamesIndexedByModelName($version = '') |
|
1338 | + { |
|
1339 | + $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1340 | + $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1341 | + $primary_key_items = []; |
|
1342 | + foreach ($model_names as $model_name => $model_class_name) { |
|
1343 | + $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields(); |
|
1344 | + foreach ($primary_keys as $primary_key_name => $primary_key_field) { |
|
1345 | + if (count($primary_keys) > 1) { |
|
1346 | + $primary_key_items[ strtolower($model_name) ][] = $primary_key_name; |
|
1347 | + } else { |
|
1348 | + $primary_key_items[ strtolower($model_name) ] = $primary_key_name; |
|
1349 | + } |
|
1350 | + } |
|
1351 | + } |
|
1352 | + return $primary_key_items; |
|
1353 | + } |
|
1354 | + |
|
1355 | + |
|
1356 | + /** |
|
1357 | + * Determines the EE REST API debug mode is activated, or not. |
|
1358 | + * |
|
1359 | + * @return bool |
|
1360 | + * @since 4.9.76.p |
|
1361 | + */ |
|
1362 | + public static function debugMode() |
|
1363 | + { |
|
1364 | + static $debug_mode = null; // could be class prop |
|
1365 | + if ($debug_mode === null) { |
|
1366 | + $debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE; |
|
1367 | + } |
|
1368 | + return $debug_mode; |
|
1369 | + } |
|
1370 | + |
|
1371 | + |
|
1372 | + /** |
|
1373 | + * run - initial module setup |
|
1374 | + * |
|
1375 | + * @access public |
|
1376 | + * @param WP $WP |
|
1377 | + * @return void |
|
1378 | + */ |
|
1379 | + public function run($WP) |
|
1380 | + { |
|
1381 | + } |
|
1382 | 1382 | } |
@@ -78,7 +78,7 @@ discard block |
||
78 | 78 | { |
79 | 79 | /** @var EventEspresso\core\services\request\Request $request */ |
80 | 80 | $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request'); |
81 | - if (! $request->isWordPressApi()) { |
|
81 | + if ( ! $request->isWordPressApi()) { |
|
82 | 82 | return; |
83 | 83 | } |
84 | 84 | add_action('rest_api_init', ['EED_Core_Rest_Api', 'register_routes'], 10); |
@@ -129,7 +129,7 @@ discard block |
||
129 | 129 | */ |
130 | 130 | protected static function _set_hooks_for_changes() |
131 | 131 | { |
132 | - $folder_contents = EEH_File::get_contents_of_folders([EE_LIBRARIES . 'rest_api/changes'], false); |
|
132 | + $folder_contents = EEH_File::get_contents_of_folders([EE_LIBRARIES.'rest_api/changes'], false); |
|
133 | 133 | foreach ($folder_contents as $classname_in_namespace => $filepath) { |
134 | 134 | // ignore the base parent class |
135 | 135 | // and legacy named classes |
@@ -138,7 +138,7 @@ discard block |
||
138 | 138 | ) { |
139 | 139 | continue; |
140 | 140 | } |
141 | - $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
141 | + $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\'.$classname_in_namespace; |
|
142 | 142 | if (class_exists($full_classname)) { |
143 | 143 | $instance_of_class = new $full_classname; |
144 | 144 | if ($instance_of_class instanceof ChangesInBase) { |
@@ -184,10 +184,10 @@ discard block |
||
184 | 184 | * } |
185 | 185 | */ |
186 | 186 | // skip route options |
187 | - if (! is_numeric($endpoint_key)) { |
|
187 | + if ( ! is_numeric($endpoint_key)) { |
|
188 | 188 | continue; |
189 | 189 | } |
190 | - if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
190 | + if ( ! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
191 | 191 | throw new EE_Error( |
192 | 192 | esc_html__( |
193 | 193 | // @codingStandardsIgnoreStart |
@@ -208,7 +208,7 @@ discard block |
||
208 | 208 | } |
209 | 209 | if (isset($data_for_single_endpoint['callback_args'])) { |
210 | 210 | $callback_args = $data_for_single_endpoint['callback_args']; |
211 | - $single_endpoint_args['callback'] = static function (WP_REST_Request $request) use ( |
|
211 | + $single_endpoint_args['callback'] = static function(WP_REST_Request $request) use ( |
|
212 | 212 | $callback, |
213 | 213 | $callback_args |
214 | 214 | ) { |
@@ -227,7 +227,7 @@ discard block |
||
227 | 227 | $schema_route_data = $data_for_multiple_endpoints['schema']; |
228 | 228 | $schema_callback = $schema_route_data['schema_callback']; |
229 | 229 | $callback_args = $schema_route_data['callback_args']; |
230 | - $multiple_endpoint_args['schema'] = static function () use ($schema_callback, $callback_args) { |
|
230 | + $multiple_endpoint_args['schema'] = static function() use ($schema_callback, $callback_args) { |
|
231 | 231 | return call_user_func_array( |
232 | 232 | $schema_callback, |
233 | 233 | $callback_args |
@@ -269,7 +269,7 @@ discard block |
||
269 | 269 | { |
270 | 270 | // delete the saved EE REST API routes |
271 | 271 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
272 | - delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
272 | + delete_option(EED_Core_Rest_Api::saved_routes_option_names.$version); |
|
273 | 273 | } |
274 | 274 | } |
275 | 275 | |
@@ -289,7 +289,7 @@ discard block |
||
289 | 289 | { |
290 | 290 | $ee_routes = []; |
291 | 291 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoints) { |
292 | - $ee_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = EED_Core_Rest_Api::_get_ee_route_data_for_version( |
|
292 | + $ee_routes[EED_Core_Rest_Api::ee_api_namespace.$version] = EED_Core_Rest_Api::_get_ee_route_data_for_version( |
|
293 | 293 | $version, |
294 | 294 | $hidden_endpoints |
295 | 295 | ); |
@@ -310,8 +310,8 @@ discard block |
||
310 | 310 | */ |
311 | 311 | protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
312 | 312 | { |
313 | - $ee_routes = get_option(EED_Core_Rest_Api::saved_routes_option_names . $version, null); |
|
314 | - if (! $ee_routes || EED_Core_Rest_Api::debugMode()) { |
|
313 | + $ee_routes = get_option(EED_Core_Rest_Api::saved_routes_option_names.$version, null); |
|
314 | + if ( ! $ee_routes || EED_Core_Rest_Api::debugMode()) { |
|
315 | 315 | $ee_routes = EED_Core_Rest_Api::_save_ee_route_data_for_version($version, $hidden_endpoints); |
316 | 316 | } |
317 | 317 | return $ee_routes; |
@@ -339,7 +339,7 @@ discard block |
||
339 | 339 | $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
340 | 340 | ) |
341 | 341 | ); |
342 | - $option_name = EED_Core_Rest_Api::saved_routes_option_names . $version; |
|
342 | + $option_name = EED_Core_Rest_Api::saved_routes_option_names.$version; |
|
343 | 343 | if (get_option($option_name)) { |
344 | 344 | update_option($option_name, $routes, true); |
345 | 345 | } else { |
@@ -384,8 +384,8 @@ discard block |
||
384 | 384 | { |
385 | 385 | $model_routes = []; |
386 | 386 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
387 | - $model_routes[ EED_Core_Rest_Api::ee_api_namespace |
|
388 | - . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
387 | + $model_routes[EED_Core_Rest_Api::ee_api_namespace |
|
388 | + . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
389 | 389 | } |
390 | 390 | return $model_routes; |
391 | 391 | } |
@@ -454,13 +454,13 @@ discard block |
||
454 | 454 | foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
455 | 455 | $model = EE_Registry::instance()->load_model($model_name); |
456 | 456 | // if this isn't a valid model then let's skip iterate to the next item in the loop. |
457 | - if (! $model instanceof EEM_Base) { |
|
457 | + if ( ! $model instanceof EEM_Base) { |
|
458 | 458 | continue; |
459 | 459 | } |
460 | 460 | // yes we could just register one route for ALL models, but then they wouldn't show up in the index |
461 | 461 | $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
462 | 462 | $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
463 | - $model_routes[ $plural_model_route ] = [ |
|
463 | + $model_routes[$plural_model_route] = [ |
|
464 | 464 | [ |
465 | 465 | 'callback' => [ |
466 | 466 | 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
@@ -471,7 +471,7 @@ discard block |
||
471 | 471 | 'hidden_endpoint' => $hidden_endpoint, |
472 | 472 | 'args' => $this->_get_read_query_params($model, $version), |
473 | 473 | '_links' => [ |
474 | - 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
474 | + 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace.$version.$singular_model_route), |
|
475 | 475 | ], |
476 | 476 | ], |
477 | 477 | 'schema' => [ |
@@ -482,7 +482,7 @@ discard block |
||
482 | 482 | 'callback_args' => [$version, $model_name], |
483 | 483 | ], |
484 | 484 | ]; |
485 | - $model_routes[ $singular_model_route ] = [ |
|
485 | + $model_routes[$singular_model_route] = [ |
|
486 | 486 | [ |
487 | 487 | 'callback' => [ |
488 | 488 | 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
@@ -499,7 +499,7 @@ discard block |
||
499 | 499 | EED_Core_Rest_Api::should_have_write_endpoints($model), |
500 | 500 | $model |
501 | 501 | )) { |
502 | - $model_routes[ $plural_model_route ][] = [ |
|
502 | + $model_routes[$plural_model_route][] = [ |
|
503 | 503 | 'callback' => [ |
504 | 504 | 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
505 | 505 | 'handleRequestInsert', |
@@ -509,8 +509,8 @@ discard block |
||
509 | 509 | 'hidden_endpoint' => $hidden_endpoint, |
510 | 510 | 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
511 | 511 | ]; |
512 | - $model_routes[ $singular_model_route ] = array_merge( |
|
513 | - $model_routes[ $singular_model_route ], |
|
512 | + $model_routes[$singular_model_route] = array_merge( |
|
513 | + $model_routes[$singular_model_route], |
|
514 | 514 | [ |
515 | 515 | [ |
516 | 516 | 'callback' => [ |
@@ -541,7 +541,7 @@ discard block |
||
541 | 541 | '(?P<id>[^\/]+)', |
542 | 542 | $relation_obj |
543 | 543 | ); |
544 | - $model_routes[ $related_route ] = [ |
|
544 | + $model_routes[$related_route] = [ |
|
545 | 545 | [ |
546 | 546 | 'callback' => [ |
547 | 547 | 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
@@ -554,8 +554,8 @@ discard block |
||
554 | 554 | ], |
555 | 555 | ]; |
556 | 556 | |
557 | - $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)'; |
|
558 | - $model_routes[ $related_write_route ] = [ |
|
557 | + $related_write_route = $related_route.'/'.'(?P<related_id>[^\/]+)'; |
|
558 | + $model_routes[$related_write_route] = [ |
|
559 | 559 | [ |
560 | 560 | 'callback' => [ |
561 | 561 | 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
@@ -612,7 +612,7 @@ discard block |
||
612 | 612 | */ |
613 | 613 | public static function get_entity_route($model, $id) |
614 | 614 | { |
615 | - return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id; |
|
615 | + return EED_Core_Rest_Api::get_collection_route($model).'/'.$id; |
|
616 | 616 | } |
617 | 617 | |
618 | 618 | |
@@ -632,7 +632,7 @@ discard block |
||
632 | 632 | $relation_obj->get_other_model()->get_this_model_name(), |
633 | 633 | $relation_obj |
634 | 634 | ); |
635 | - return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
635 | + return EED_Core_Rest_Api::get_entity_route($model, $id).'/'.$related_model_name_endpoint_part; |
|
636 | 636 | } |
637 | 637 | |
638 | 638 | |
@@ -646,7 +646,7 @@ discard block |
||
646 | 646 | */ |
647 | 647 | public static function get_versioned_route_to($relative_route, $version = '4.8.36') |
648 | 648 | { |
649 | - return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
649 | + return '/'.EED_Core_Rest_Api::ee_api_namespace.$version.'/'.$relative_route; |
|
650 | 650 | } |
651 | 651 | |
652 | 652 | |
@@ -660,7 +660,7 @@ discard block |
||
660 | 660 | { |
661 | 661 | $routes = []; |
662 | 662 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
663 | - $routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version( |
|
663 | + $routes[EED_Core_Rest_Api::ee_api_namespace.$version] = $this->_get_rpc_route_data_for_version( |
|
664 | 664 | $version, |
665 | 665 | $hidden_endpoint |
666 | 666 | ); |
@@ -792,12 +792,12 @@ discard block |
||
792 | 792 | { |
793 | 793 | // if they're related through a HABTM relation, check for any non-FKs |
794 | 794 | $all_relation_settings = $source_model->relation_settings(); |
795 | - $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ]; |
|
795 | + $relation_settings = $all_relation_settings[$related_model->get_this_model_name()]; |
|
796 | 796 | $params = []; |
797 | 797 | if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) { |
798 | 798 | foreach ($relation_settings->getNonKeyFields() as $field) { |
799 | 799 | /* @var $field EE_Model_Field_Base */ |
800 | - $params[ $field->get_name() ] = [ |
|
800 | + $params[$field->get_name()] = [ |
|
801 | 801 | 'required' => ! $field->is_nullable(), |
802 | 802 | 'default' => ModelDataTranslator::prepareFieldValueForJson( |
803 | 803 | $field, |
@@ -826,7 +826,7 @@ discard block |
||
826 | 826 | { |
827 | 827 | $default_orderby = []; |
828 | 828 | foreach ($model->get_combined_primary_key_fields() as $key_field) { |
829 | - $default_orderby[ $key_field->get_name() ] = 'ASC'; |
|
829 | + $default_orderby[$key_field->get_name()] = 'ASC'; |
|
830 | 830 | } |
831 | 831 | return array_merge( |
832 | 832 | $this->_get_response_selection_query_params($model, $version), |
@@ -860,7 +860,7 @@ discard block |
||
860 | 860 | 'type' => [ |
861 | 861 | 'object', |
862 | 862 | 'string', |
863 | - ],// because we accept a variety of types, WP core validation and sanitization |
|
863 | + ], // because we accept a variety of types, WP core validation and sanitization |
|
864 | 864 | // freaks out. We'll just validate this argument while handling the request |
865 | 865 | 'validate_callback' => null, |
866 | 866 | 'sanitize_callback' => null, |
@@ -956,7 +956,7 @@ discard block |
||
956 | 956 | $model_version_info->requestedVersion() |
957 | 957 | ); |
958 | 958 | $arg_info['sanitize_callback'] = $sanitize_callback; |
959 | - $args_info[ $field_name ] = $arg_info; |
|
959 | + $args_info[$field_name] = $arg_info; |
|
960 | 960 | if ($field_obj instanceof EE_Datetime_Field) { |
961 | 961 | $gmt_arg_info = $arg_info; |
962 | 962 | $gmt_arg_info['description'] = sprintf( |
@@ -967,7 +967,7 @@ discard block |
||
967 | 967 | $field_obj->get_nicename(), |
968 | 968 | $field_name |
969 | 969 | ); |
970 | - $args_info[ $field_name . '_gmt' ] = $gmt_arg_info; |
|
970 | + $args_info[$field_name.'_gmt'] = $gmt_arg_info; |
|
971 | 971 | } |
972 | 972 | } |
973 | 973 | return $args_info; |
@@ -990,16 +990,16 @@ discard block |
||
990 | 990 | public static function default_sanitize_callback($value, WP_REST_Request $request, $param) |
991 | 991 | { |
992 | 992 | $attributes = $request->get_attributes(); |
993 | - if (! isset($attributes['args'][ $param ]) |
|
994 | - || ! is_array($attributes['args'][ $param ])) { |
|
993 | + if ( ! isset($attributes['args'][$param]) |
|
994 | + || ! is_array($attributes['args'][$param])) { |
|
995 | 995 | $validation_result = true; |
996 | 996 | } else { |
997 | - $args = $attributes['args'][ $param ]; |
|
997 | + $args = $attributes['args'][$param]; |
|
998 | 998 | if (( |
999 | 999 | $value === '' |
1000 | 1000 | || $value === null |
1001 | 1001 | ) |
1002 | - && (! isset($args['required']) |
|
1002 | + && ( ! isset($args['required']) |
|
1003 | 1003 | || $args['required'] === false |
1004 | 1004 | ) |
1005 | 1005 | ) { |
@@ -1009,7 +1009,7 @@ discard block |
||
1009 | 1009 | && $args['format'] === 'email' |
1010 | 1010 | ) { |
1011 | 1011 | $validation_result = true; |
1012 | - if (! EED_Core_Rest_Api::_validate_email($value)) { |
|
1012 | + if ( ! EED_Core_Rest_Api::_validate_email($value)) { |
|
1013 | 1013 | $validation_result = new WP_Error( |
1014 | 1014 | 'rest_invalid_param', |
1015 | 1015 | esc_html__( |
@@ -1059,7 +1059,7 @@ discard block |
||
1059 | 1059 | { |
1060 | 1060 | $config_routes = []; |
1061 | 1061 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
1062 | - $config_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version( |
|
1062 | + $config_routes[EED_Core_Rest_Api::ee_api_namespace.$version] = $this->_get_config_route_data_for_version( |
|
1063 | 1063 | $version, |
1064 | 1064 | $hidden_endpoint |
1065 | 1065 | ); |
@@ -1114,7 +1114,7 @@ discard block |
||
1114 | 1114 | { |
1115 | 1115 | $meta_routes = []; |
1116 | 1116 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
1117 | - $meta_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version( |
|
1117 | + $meta_routes[EED_Core_Rest_Api::ee_api_namespace.$version] = $this->_get_meta_route_data_for_version( |
|
1118 | 1118 | $version, |
1119 | 1119 | $hidden_endpoint |
1120 | 1120 | ); |
@@ -1167,7 +1167,7 @@ discard block |
||
1167 | 1167 | foreach ($relative_urls as $resource_name => $endpoints) { |
1168 | 1168 | foreach ($endpoints as $key => $endpoint) { |
1169 | 1169 | // skip schema and other route options |
1170 | - if (! is_numeric($key)) { |
|
1170 | + if ( ! is_numeric($key)) { |
|
1171 | 1171 | continue; |
1172 | 1172 | } |
1173 | 1173 | // by default, hide "hidden_endpoint"s, unless the request indicates |
@@ -1176,9 +1176,9 @@ discard block |
||
1176 | 1176 | if (($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
1177 | 1177 | || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
1178 | 1178 | ) { |
1179 | - $full_route = '/' . ltrim($namespace, '/'); |
|
1180 | - $full_route .= '/' . ltrim($resource_name, '/'); |
|
1181 | - unset($route_data[ $full_route ]); |
|
1179 | + $full_route = '/'.ltrim($namespace, '/'); |
|
1180 | + $full_route .= '/'.ltrim($resource_name, '/'); |
|
1181 | + unset($route_data[$full_route]); |
|
1182 | 1182 | } |
1183 | 1183 | } |
1184 | 1184 | } |
@@ -1252,19 +1252,19 @@ discard block |
||
1252 | 1252 | |
1253 | 1253 | if ($key_versioned_endpoint === $latest_version) { |
1254 | 1254 | // don't hide the latest version in the index |
1255 | - $versions_served[ $key_versioned_endpoint ] = false; |
|
1255 | + $versions_served[$key_versioned_endpoint] = false; |
|
1256 | 1256 | } elseif (version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=') |
1257 | 1257 | && version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<') |
1258 | 1258 | ) { |
1259 | 1259 | // include, but hide, previous versions which are still supported |
1260 | - $versions_served[ $key_versioned_endpoint ] = true; |
|
1260 | + $versions_served[$key_versioned_endpoint] = true; |
|
1261 | 1261 | } elseif (apply_filters( |
1262 | 1262 | 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
1263 | 1263 | false, |
1264 | 1264 | $possibly_served_versions |
1265 | 1265 | )) { |
1266 | 1266 | // if a version is no longer supported, don't include it in index or list of versions served |
1267 | - $versions_served[ $key_versioned_endpoint ] = true; |
|
1267 | + $versions_served[$key_versioned_endpoint] = true; |
|
1268 | 1268 | } |
1269 | 1269 | } |
1270 | 1270 | return $versions_served; |
@@ -1321,7 +1321,7 @@ discard block |
||
1321 | 1321 | $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
1322 | 1322 | $collection_routes = []; |
1323 | 1323 | foreach ($model_names as $model_name => $model_class_name) { |
1324 | - $collection_routes[ strtolower($model_name) ] = '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' |
|
1324 | + $collection_routes[strtolower($model_name)] = '/'.EED_Core_Rest_Api::ee_api_namespace.$version.'/' |
|
1325 | 1325 | . EEH_Inflector::pluralize_and_lower($model_name); |
1326 | 1326 | } |
1327 | 1327 | return $collection_routes; |
@@ -1343,9 +1343,9 @@ discard block |
||
1343 | 1343 | $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields(); |
1344 | 1344 | foreach ($primary_keys as $primary_key_name => $primary_key_field) { |
1345 | 1345 | if (count($primary_keys) > 1) { |
1346 | - $primary_key_items[ strtolower($model_name) ][] = $primary_key_name; |
|
1346 | + $primary_key_items[strtolower($model_name)][] = $primary_key_name; |
|
1347 | 1347 | } else { |
1348 | - $primary_key_items[ strtolower($model_name) ] = $primary_key_name; |
|
1348 | + $primary_key_items[strtolower($model_name)] = $primary_key_name; |
|
1349 | 1349 | } |
1350 | 1350 | } |
1351 | 1351 | } |
@@ -15,121 +15,121 @@ |
||
15 | 15 | class EspressoLegacyAdminAssetManager extends AssetManager |
16 | 16 | { |
17 | 17 | |
18 | - const JS_HANDLE_INJECT_WP = 'ee-inject-wp'; |
|
19 | - |
|
20 | - const JS_HANDLE_JQUERY_COOKIE = 'jquery-cookie'; |
|
21 | - |
|
22 | - const JS_HANDLE_JOYRIDE_MODERNIZR = 'joyride-modernizr'; |
|
23 | - |
|
24 | - const JS_HANDLE_JQUERY_JOYRIDE = 'jquery-joyride'; |
|
25 | - |
|
26 | - const CSS_HANDLE_EE_JOYRIDE = 'ee-joyride-css'; |
|
27 | - |
|
28 | - const CSS_HANDLE_JOYRIDE = 'joyride-css'; |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * @inheritDoc |
|
33 | - */ |
|
34 | - public function addAssets() |
|
35 | - { |
|
36 | - $joyride = filter_var(apply_filters('FHEE_load_joyride', false), FILTER_VALIDATE_BOOLEAN); |
|
37 | - $this->registerJavascript($joyride); |
|
38 | - $this->registerStyleSheets($joyride); |
|
39 | - } |
|
40 | - |
|
41 | - |
|
42 | - /** |
|
43 | - * Register javascript assets |
|
44 | - * |
|
45 | - * @param bool $joyride |
|
46 | - */ |
|
47 | - private function registerJavascript($joyride = false) |
|
48 | - { |
|
49 | - // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js. |
|
50 | - // Note: the intention of this script is to only do TARGETED injections. |
|
51 | - //ie: only injecting on certain script calls. |
|
52 | - $this->addJavascript( |
|
53 | - EspressoLegacyAdminAssetManager::JS_HANDLE_INJECT_WP, |
|
54 | - EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
55 | - ['jquery'], |
|
56 | - true, |
|
57 | - EVENT_ESPRESSO_VERSION |
|
58 | - ); |
|
59 | - // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, |
|
60 | - // can be turned back on again via: add_filter('FHEE_load_joyride', '__return_true' ); |
|
61 | - if (! $joyride) { |
|
62 | - return; |
|
63 | - } |
|
64 | - // register cookie script for future dependencies |
|
65 | - $this->addJavascript( |
|
66 | - EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE, |
|
67 | - EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
68 | - ['jquery'], |
|
69 | - true, |
|
70 | - '2.1' |
|
71 | - ); |
|
72 | - $this->addJavascript( |
|
73 | - EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR, |
|
74 | - EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
75 | - [], |
|
76 | - true, |
|
77 | - '2.1' |
|
78 | - ); |
|
79 | - // wanna go for a joyride? |
|
80 | - $this->addJavascript( |
|
81 | - EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_JOYRIDE, |
|
82 | - EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
83 | - [ |
|
84 | - EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE, |
|
85 | - EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR |
|
86 | - ], |
|
87 | - '2.1', |
|
88 | - true |
|
89 | - )->enqueueAsset(); |
|
90 | - $this->loadQtipJs(); |
|
91 | - } |
|
92 | - |
|
93 | - |
|
94 | - /** |
|
95 | - * Register CSS assets. |
|
96 | - * |
|
97 | - * @param bool $joyride |
|
98 | - */ |
|
99 | - private function registerStyleSheets($joyride = false) |
|
100 | - { |
|
101 | - if (! $joyride) { |
|
102 | - return; |
|
103 | - } // joyride style |
|
104 | - $this->addStylesheet( |
|
105 | - EspressoLegacyAdminAssetManager::CSS_HANDLE_JOYRIDE, |
|
106 | - EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', |
|
107 | - [], |
|
108 | - 'all', |
|
109 | - '2.1' |
|
110 | - ); |
|
111 | - $this->addStylesheet( |
|
112 | - EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_JOYRIDE, |
|
113 | - EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
114 | - ['joyride-css'], |
|
115 | - 'all', |
|
116 | - EVENT_ESPRESSO_VERSION |
|
117 | - )->enqueueAsset(); |
|
118 | - } |
|
119 | - |
|
120 | - |
|
121 | - /** |
|
122 | - * registers assets for cleaning your ears |
|
123 | - */ |
|
124 | - public function loadQtipJs() |
|
125 | - { |
|
126 | - // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook, |
|
127 | - // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' ); |
|
128 | - if (apply_filters('FHEE_load_qtip', false)) { |
|
129 | - $qtip_loader = EEH_Qtip_Loader::instance(); |
|
130 | - if ($qtip_loader instanceof EEH_Qtip_Loader) { |
|
131 | - $qtip_loader->register_and_enqueue(); |
|
132 | - } |
|
133 | - } |
|
134 | - } |
|
18 | + const JS_HANDLE_INJECT_WP = 'ee-inject-wp'; |
|
19 | + |
|
20 | + const JS_HANDLE_JQUERY_COOKIE = 'jquery-cookie'; |
|
21 | + |
|
22 | + const JS_HANDLE_JOYRIDE_MODERNIZR = 'joyride-modernizr'; |
|
23 | + |
|
24 | + const JS_HANDLE_JQUERY_JOYRIDE = 'jquery-joyride'; |
|
25 | + |
|
26 | + const CSS_HANDLE_EE_JOYRIDE = 'ee-joyride-css'; |
|
27 | + |
|
28 | + const CSS_HANDLE_JOYRIDE = 'joyride-css'; |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * @inheritDoc |
|
33 | + */ |
|
34 | + public function addAssets() |
|
35 | + { |
|
36 | + $joyride = filter_var(apply_filters('FHEE_load_joyride', false), FILTER_VALIDATE_BOOLEAN); |
|
37 | + $this->registerJavascript($joyride); |
|
38 | + $this->registerStyleSheets($joyride); |
|
39 | + } |
|
40 | + |
|
41 | + |
|
42 | + /** |
|
43 | + * Register javascript assets |
|
44 | + * |
|
45 | + * @param bool $joyride |
|
46 | + */ |
|
47 | + private function registerJavascript($joyride = false) |
|
48 | + { |
|
49 | + // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js. |
|
50 | + // Note: the intention of this script is to only do TARGETED injections. |
|
51 | + //ie: only injecting on certain script calls. |
|
52 | + $this->addJavascript( |
|
53 | + EspressoLegacyAdminAssetManager::JS_HANDLE_INJECT_WP, |
|
54 | + EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
55 | + ['jquery'], |
|
56 | + true, |
|
57 | + EVENT_ESPRESSO_VERSION |
|
58 | + ); |
|
59 | + // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, |
|
60 | + // can be turned back on again via: add_filter('FHEE_load_joyride', '__return_true' ); |
|
61 | + if (! $joyride) { |
|
62 | + return; |
|
63 | + } |
|
64 | + // register cookie script for future dependencies |
|
65 | + $this->addJavascript( |
|
66 | + EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE, |
|
67 | + EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
68 | + ['jquery'], |
|
69 | + true, |
|
70 | + '2.1' |
|
71 | + ); |
|
72 | + $this->addJavascript( |
|
73 | + EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR, |
|
74 | + EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
75 | + [], |
|
76 | + true, |
|
77 | + '2.1' |
|
78 | + ); |
|
79 | + // wanna go for a joyride? |
|
80 | + $this->addJavascript( |
|
81 | + EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_JOYRIDE, |
|
82 | + EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
83 | + [ |
|
84 | + EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE, |
|
85 | + EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR |
|
86 | + ], |
|
87 | + '2.1', |
|
88 | + true |
|
89 | + )->enqueueAsset(); |
|
90 | + $this->loadQtipJs(); |
|
91 | + } |
|
92 | + |
|
93 | + |
|
94 | + /** |
|
95 | + * Register CSS assets. |
|
96 | + * |
|
97 | + * @param bool $joyride |
|
98 | + */ |
|
99 | + private function registerStyleSheets($joyride = false) |
|
100 | + { |
|
101 | + if (! $joyride) { |
|
102 | + return; |
|
103 | + } // joyride style |
|
104 | + $this->addStylesheet( |
|
105 | + EspressoLegacyAdminAssetManager::CSS_HANDLE_JOYRIDE, |
|
106 | + EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', |
|
107 | + [], |
|
108 | + 'all', |
|
109 | + '2.1' |
|
110 | + ); |
|
111 | + $this->addStylesheet( |
|
112 | + EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_JOYRIDE, |
|
113 | + EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
114 | + ['joyride-css'], |
|
115 | + 'all', |
|
116 | + EVENT_ESPRESSO_VERSION |
|
117 | + )->enqueueAsset(); |
|
118 | + } |
|
119 | + |
|
120 | + |
|
121 | + /** |
|
122 | + * registers assets for cleaning your ears |
|
123 | + */ |
|
124 | + public function loadQtipJs() |
|
125 | + { |
|
126 | + // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook, |
|
127 | + // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' ); |
|
128 | + if (apply_filters('FHEE_load_qtip', false)) { |
|
129 | + $qtip_loader = EEH_Qtip_Loader::instance(); |
|
130 | + if ($qtip_loader instanceof EEH_Qtip_Loader) { |
|
131 | + $qtip_loader->register_and_enqueue(); |
|
132 | + } |
|
133 | + } |
|
134 | + } |
|
135 | 135 | } |
@@ -51,27 +51,27 @@ discard block |
||
51 | 51 | //ie: only injecting on certain script calls. |
52 | 52 | $this->addJavascript( |
53 | 53 | EspressoLegacyAdminAssetManager::JS_HANDLE_INJECT_WP, |
54 | - EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js', |
|
54 | + EE_ADMIN_URL.'assets/ee-cpt-wp-injects.js', |
|
55 | 55 | ['jquery'], |
56 | 56 | true, |
57 | 57 | EVENT_ESPRESSO_VERSION |
58 | 58 | ); |
59 | 59 | // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, |
60 | 60 | // can be turned back on again via: add_filter('FHEE_load_joyride', '__return_true' ); |
61 | - if (! $joyride) { |
|
61 | + if ( ! $joyride) { |
|
62 | 62 | return; |
63 | 63 | } |
64 | 64 | // register cookie script for future dependencies |
65 | 65 | $this->addJavascript( |
66 | 66 | EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE, |
67 | - EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js', |
|
67 | + EE_THIRD_PARTY_URL.'joyride/jquery.cookie.js', |
|
68 | 68 | ['jquery'], |
69 | 69 | true, |
70 | 70 | '2.1' |
71 | 71 | ); |
72 | 72 | $this->addJavascript( |
73 | 73 | EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR, |
74 | - EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js', |
|
74 | + EE_THIRD_PARTY_URL.'joyride/modernizr.mq.js', |
|
75 | 75 | [], |
76 | 76 | true, |
77 | 77 | '2.1' |
@@ -79,7 +79,7 @@ discard block |
||
79 | 79 | // wanna go for a joyride? |
80 | 80 | $this->addJavascript( |
81 | 81 | EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_JOYRIDE, |
82 | - EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js', |
|
82 | + EE_THIRD_PARTY_URL.'joyride/jquery.joyride-2.1.js', |
|
83 | 83 | [ |
84 | 84 | EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE, |
85 | 85 | EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR |
@@ -98,19 +98,19 @@ discard block |
||
98 | 98 | */ |
99 | 99 | private function registerStyleSheets($joyride = false) |
100 | 100 | { |
101 | - if (! $joyride) { |
|
101 | + if ( ! $joyride) { |
|
102 | 102 | return; |
103 | 103 | } // joyride style |
104 | 104 | $this->addStylesheet( |
105 | 105 | EspressoLegacyAdminAssetManager::CSS_HANDLE_JOYRIDE, |
106 | - EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', |
|
106 | + EE_THIRD_PARTY_URL.'joyride/joyride-2.1.css', |
|
107 | 107 | [], |
108 | 108 | 'all', |
109 | 109 | '2.1' |
110 | 110 | ); |
111 | 111 | $this->addStylesheet( |
112 | 112 | EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_JOYRIDE, |
113 | - EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css', |
|
113 | + EE_GLOBAL_ASSETS_URL.'css/ee-joyride-styles.css', |
|
114 | 114 | ['joyride-css'], |
115 | 115 | 'all', |
116 | 116 | EVENT_ESPRESSO_VERSION |
@@ -183,7 +183,7 @@ |
||
183 | 183 | $this->resolveDependenciesForClass($param_class); |
184 | 184 | } |
185 | 185 | $param_class = $this->resolveAlias($param_class); |
186 | - $dependencies[ $param_class ] = EE_Dependency_Map::load_from_cache; |
|
186 | + $dependencies[$param_class] = EE_Dependency_Map::load_from_cache; |
|
187 | 187 | } |
188 | 188 | $this->dependencyMap()->registerDependencies($fqcn, $dependencies); |
189 | 189 | } |
@@ -23,168 +23,168 @@ |
||
23 | 23 | class DependencyResolver implements DependencyResolverInterface |
24 | 24 | { |
25 | 25 | |
26 | - /** |
|
27 | - * @var Mirror $mirror |
|
28 | - */ |
|
29 | - private $mirror; |
|
30 | - |
|
31 | - /** |
|
32 | - * @var ClassInterfaceCache $class_cache |
|
33 | - */ |
|
34 | - protected $class_cache; |
|
35 | - |
|
36 | - /** |
|
37 | - * @var EE_Dependency_Map $dependency_map |
|
38 | - */ |
|
39 | - private $dependency_map; |
|
40 | - |
|
41 | - /** |
|
42 | - * @var ClassAlias[] $aliases |
|
43 | - */ |
|
44 | - protected $aliases = array(); |
|
45 | - |
|
46 | - /** |
|
47 | - * @var array $namespace_roots |
|
48 | - */ |
|
49 | - protected $namespace_roots = array(); |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * RouteMatchSpecificationDependencyResolver constructor. |
|
54 | - * |
|
55 | - * @param Mirror $mirror |
|
56 | - * @param ClassInterfaceCache $class_cache |
|
57 | - * @param EE_Dependency_Map $dependency_map |
|
58 | - */ |
|
59 | - public function __construct( |
|
60 | - Mirror $mirror, |
|
61 | - ClassInterfaceCache $class_cache, |
|
62 | - EE_Dependency_Map $dependency_map |
|
63 | - ) { |
|
64 | - $this->mirror = $mirror; |
|
65 | - $this->class_cache = $class_cache; |
|
66 | - $this->dependency_map = $dependency_map; |
|
67 | - $this->initialize(); |
|
68 | - } |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * Used to configure and/or setup any aliases or namespace roots required by the DependencyResolver |
|
73 | - * |
|
74 | - * @throws InvalidAliasException |
|
75 | - * @since 4.9.71.p |
|
76 | - */ |
|
77 | - public function initialize() |
|
78 | - { |
|
79 | - // nothing to do here for default resolver |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - /** |
|
84 | - * @return Mirror |
|
85 | - */ |
|
86 | - public function mirror() |
|
87 | - { |
|
88 | - return $this->mirror; |
|
89 | - } |
|
90 | - |
|
91 | - /** |
|
92 | - * @return ClassInterfaceCache |
|
93 | - */ |
|
94 | - public function classCache() |
|
95 | - { |
|
96 | - return $this->class_cache; |
|
97 | - } |
|
98 | - |
|
99 | - /** |
|
100 | - * @return EE_Dependency_Map |
|
101 | - */ |
|
102 | - public function dependencyMap() |
|
103 | - { |
|
104 | - return $this->dependency_map; |
|
105 | - } |
|
106 | - |
|
107 | - /** |
|
108 | - * @param string $fqcn the class name that should be used (concrete class to replace interface) |
|
109 | - * @param string $alias the class name that would be type hinted for (abstract parent or interface) |
|
110 | - * @param string $for_class the class that has the dependency (is type hinting for the interface) |
|
111 | - * @throws InvalidAliasException |
|
112 | - */ |
|
113 | - public function addAlias($fqcn, $alias, $for_class = '') |
|
114 | - { |
|
115 | - $this->class_cache->addAlias($fqcn, $alias, $for_class); |
|
116 | - } |
|
117 | - |
|
118 | - /** |
|
119 | - * @param string $param_fqcn Fully Qualified Class Name for dependency parameter |
|
120 | - * @return string |
|
121 | - */ |
|
122 | - public function resolveAlias($param_fqcn) |
|
123 | - { |
|
124 | - return $this->class_cache->getFqnForAlias($param_fqcn); |
|
125 | - } |
|
126 | - |
|
127 | - /** |
|
128 | - * Primarily used to indicate the namespace root for composite objects |
|
129 | - * so that dependencies requiring the same DependencyResolver can be acquired |
|
130 | - * for example: |
|
131 | - * Vendor\path\to\class\A, Vendor\path\to\class\B, and Vendor\path\to\class\C |
|
132 | - * may all implement Vendor\path\to\Interface, |
|
133 | - * but Vendor\path\to\class\C could be a composite object |
|
134 | - * that requires Vendor\path\to\class\A and Vendor\path\to\class\B, |
|
135 | - * and needs both of those dependencies resolved, which would therefore require |
|
136 | - * the use of the same DependencyResolver. |
|
137 | - * |
|
138 | - * By specifying a namespace root of "Vendor\path\to\", |
|
139 | - * then all classes that are descendants of that namespace |
|
140 | - * will use DependencyResolver to acquire the classes they need |
|
141 | - * |
|
142 | - * @param string $namespace_root Partial namespace used for detecting other classes |
|
143 | - * that should employ this same DependencyResolver |
|
144 | - */ |
|
145 | - public function addNamespaceRoot($namespace_root) |
|
146 | - { |
|
147 | - $this->namespace_roots[] = $namespace_root; |
|
148 | - } |
|
149 | - |
|
150 | - /** |
|
151 | - * Returns true if the parameter FQCN belongs to one of |
|
152 | - * the namespaces that utilizes this DependencyResolver |
|
153 | - * |
|
154 | - * @param string $param_fqcn Fully Qualified Class Name for dependency parameter |
|
155 | - * @return boolean |
|
156 | - * @since 4.9.71.p |
|
157 | - */ |
|
158 | - public function dependencyRecursionExists($param_fqcn) |
|
159 | - { |
|
160 | - foreach ($this->namespace_roots as $namespace_root) { |
|
161 | - if (strpos($param_fqcn, $namespace_root) !== false) { |
|
162 | - return true; |
|
163 | - } |
|
164 | - } |
|
165 | - return false; |
|
166 | - } |
|
167 | - |
|
168 | - |
|
169 | - /** |
|
170 | - * @param string $fqcn Fully Qualified Class Name |
|
171 | - * @throws InvalidDataTypeException |
|
172 | - * @throws ReflectionException |
|
173 | - * @since 4.9.71.p |
|
174 | - */ |
|
175 | - public function resolveDependenciesForClass($fqcn) |
|
176 | - { |
|
177 | - $dependencies = array(); |
|
178 | - $params = $this->mirror()->getParameters($fqcn); |
|
179 | - foreach ($params as $index => $param) { |
|
180 | - // is this a dependency for a specific class ? |
|
181 | - $param_class = $this->mirror()->getParameterClassName($param, $fqcn, $index); |
|
182 | - if ($this->dependencyRecursionExists($param_class)) { |
|
183 | - $this->resolveDependenciesForClass($param_class); |
|
184 | - } |
|
185 | - $param_class = $this->resolveAlias($param_class); |
|
186 | - $dependencies[ $param_class ] = EE_Dependency_Map::load_from_cache; |
|
187 | - } |
|
188 | - $this->dependencyMap()->registerDependencies($fqcn, $dependencies); |
|
189 | - } |
|
26 | + /** |
|
27 | + * @var Mirror $mirror |
|
28 | + */ |
|
29 | + private $mirror; |
|
30 | + |
|
31 | + /** |
|
32 | + * @var ClassInterfaceCache $class_cache |
|
33 | + */ |
|
34 | + protected $class_cache; |
|
35 | + |
|
36 | + /** |
|
37 | + * @var EE_Dependency_Map $dependency_map |
|
38 | + */ |
|
39 | + private $dependency_map; |
|
40 | + |
|
41 | + /** |
|
42 | + * @var ClassAlias[] $aliases |
|
43 | + */ |
|
44 | + protected $aliases = array(); |
|
45 | + |
|
46 | + /** |
|
47 | + * @var array $namespace_roots |
|
48 | + */ |
|
49 | + protected $namespace_roots = array(); |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * RouteMatchSpecificationDependencyResolver constructor. |
|
54 | + * |
|
55 | + * @param Mirror $mirror |
|
56 | + * @param ClassInterfaceCache $class_cache |
|
57 | + * @param EE_Dependency_Map $dependency_map |
|
58 | + */ |
|
59 | + public function __construct( |
|
60 | + Mirror $mirror, |
|
61 | + ClassInterfaceCache $class_cache, |
|
62 | + EE_Dependency_Map $dependency_map |
|
63 | + ) { |
|
64 | + $this->mirror = $mirror; |
|
65 | + $this->class_cache = $class_cache; |
|
66 | + $this->dependency_map = $dependency_map; |
|
67 | + $this->initialize(); |
|
68 | + } |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * Used to configure and/or setup any aliases or namespace roots required by the DependencyResolver |
|
73 | + * |
|
74 | + * @throws InvalidAliasException |
|
75 | + * @since 4.9.71.p |
|
76 | + */ |
|
77 | + public function initialize() |
|
78 | + { |
|
79 | + // nothing to do here for default resolver |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + /** |
|
84 | + * @return Mirror |
|
85 | + */ |
|
86 | + public function mirror() |
|
87 | + { |
|
88 | + return $this->mirror; |
|
89 | + } |
|
90 | + |
|
91 | + /** |
|
92 | + * @return ClassInterfaceCache |
|
93 | + */ |
|
94 | + public function classCache() |
|
95 | + { |
|
96 | + return $this->class_cache; |
|
97 | + } |
|
98 | + |
|
99 | + /** |
|
100 | + * @return EE_Dependency_Map |
|
101 | + */ |
|
102 | + public function dependencyMap() |
|
103 | + { |
|
104 | + return $this->dependency_map; |
|
105 | + } |
|
106 | + |
|
107 | + /** |
|
108 | + * @param string $fqcn the class name that should be used (concrete class to replace interface) |
|
109 | + * @param string $alias the class name that would be type hinted for (abstract parent or interface) |
|
110 | + * @param string $for_class the class that has the dependency (is type hinting for the interface) |
|
111 | + * @throws InvalidAliasException |
|
112 | + */ |
|
113 | + public function addAlias($fqcn, $alias, $for_class = '') |
|
114 | + { |
|
115 | + $this->class_cache->addAlias($fqcn, $alias, $for_class); |
|
116 | + } |
|
117 | + |
|
118 | + /** |
|
119 | + * @param string $param_fqcn Fully Qualified Class Name for dependency parameter |
|
120 | + * @return string |
|
121 | + */ |
|
122 | + public function resolveAlias($param_fqcn) |
|
123 | + { |
|
124 | + return $this->class_cache->getFqnForAlias($param_fqcn); |
|
125 | + } |
|
126 | + |
|
127 | + /** |
|
128 | + * Primarily used to indicate the namespace root for composite objects |
|
129 | + * so that dependencies requiring the same DependencyResolver can be acquired |
|
130 | + * for example: |
|
131 | + * Vendor\path\to\class\A, Vendor\path\to\class\B, and Vendor\path\to\class\C |
|
132 | + * may all implement Vendor\path\to\Interface, |
|
133 | + * but Vendor\path\to\class\C could be a composite object |
|
134 | + * that requires Vendor\path\to\class\A and Vendor\path\to\class\B, |
|
135 | + * and needs both of those dependencies resolved, which would therefore require |
|
136 | + * the use of the same DependencyResolver. |
|
137 | + * |
|
138 | + * By specifying a namespace root of "Vendor\path\to\", |
|
139 | + * then all classes that are descendants of that namespace |
|
140 | + * will use DependencyResolver to acquire the classes they need |
|
141 | + * |
|
142 | + * @param string $namespace_root Partial namespace used for detecting other classes |
|
143 | + * that should employ this same DependencyResolver |
|
144 | + */ |
|
145 | + public function addNamespaceRoot($namespace_root) |
|
146 | + { |
|
147 | + $this->namespace_roots[] = $namespace_root; |
|
148 | + } |
|
149 | + |
|
150 | + /** |
|
151 | + * Returns true if the parameter FQCN belongs to one of |
|
152 | + * the namespaces that utilizes this DependencyResolver |
|
153 | + * |
|
154 | + * @param string $param_fqcn Fully Qualified Class Name for dependency parameter |
|
155 | + * @return boolean |
|
156 | + * @since 4.9.71.p |
|
157 | + */ |
|
158 | + public function dependencyRecursionExists($param_fqcn) |
|
159 | + { |
|
160 | + foreach ($this->namespace_roots as $namespace_root) { |
|
161 | + if (strpos($param_fqcn, $namespace_root) !== false) { |
|
162 | + return true; |
|
163 | + } |
|
164 | + } |
|
165 | + return false; |
|
166 | + } |
|
167 | + |
|
168 | + |
|
169 | + /** |
|
170 | + * @param string $fqcn Fully Qualified Class Name |
|
171 | + * @throws InvalidDataTypeException |
|
172 | + * @throws ReflectionException |
|
173 | + * @since 4.9.71.p |
|
174 | + */ |
|
175 | + public function resolveDependenciesForClass($fqcn) |
|
176 | + { |
|
177 | + $dependencies = array(); |
|
178 | + $params = $this->mirror()->getParameters($fqcn); |
|
179 | + foreach ($params as $index => $param) { |
|
180 | + // is this a dependency for a specific class ? |
|
181 | + $param_class = $this->mirror()->getParameterClassName($param, $fqcn, $index); |
|
182 | + if ($this->dependencyRecursionExists($param_class)) { |
|
183 | + $this->resolveDependenciesForClass($param_class); |
|
184 | + } |
|
185 | + $param_class = $this->resolveAlias($param_class); |
|
186 | + $dependencies[ $param_class ] = EE_Dependency_Map::load_from_cache; |
|
187 | + } |
|
188 | + $this->dependencyMap()->registerDependencies($fqcn, $dependencies); |
|
189 | + } |
|
190 | 190 | } |
@@ -21,18 +21,18 @@ |
||
21 | 21 | class RouteMatchSpecificationDependencyResolver extends DependencyResolver |
22 | 22 | { |
23 | 23 | |
24 | - /** |
|
25 | - * Used to configure and/or setup any aliases or namespace roots required by the DependencyResolver |
|
26 | - * |
|
27 | - * @since 4.9.71.p |
|
28 | - * @throws InvalidAliasException |
|
29 | - */ |
|
30 | - public function initialize() |
|
31 | - { |
|
32 | - $this->addAlias( |
|
33 | - 'EventEspresso\core\services\request\Request', |
|
34 | - 'EventEspresso\core\services\request\RequestInterface' |
|
35 | - ); |
|
36 | - $this->addNamespaceRoot('EventEspresso\core\domain\entities\routing\specifications'); |
|
37 | - } |
|
24 | + /** |
|
25 | + * Used to configure and/or setup any aliases or namespace roots required by the DependencyResolver |
|
26 | + * |
|
27 | + * @since 4.9.71.p |
|
28 | + * @throws InvalidAliasException |
|
29 | + */ |
|
30 | + public function initialize() |
|
31 | + { |
|
32 | + $this->addAlias( |
|
33 | + 'EventEspresso\core\services\request\Request', |
|
34 | + 'EventEspresso\core\services\request\RequestInterface' |
|
35 | + ); |
|
36 | + $this->addNamespaceRoot('EventEspresso\core\domain\entities\routing\specifications'); |
|
37 | + } |
|
38 | 38 | } |
@@ -56,7 +56,7 @@ |
||
56 | 56 | { |
57 | 57 | try { |
58 | 58 | $route = $this->loader->getShared($fqcn); |
59 | - if (! $route instanceof RouteInterface) { |
|
59 | + if ( ! $route instanceof RouteInterface) { |
|
60 | 60 | throw new InvalidClassException( |
61 | 61 | sprintf( |
62 | 62 | esc_html__( |
@@ -19,81 +19,81 @@ |
||
19 | 19 | class RouteHandler |
20 | 20 | { |
21 | 21 | |
22 | - /** |
|
23 | - * @var LoaderInterface |
|
24 | - */ |
|
25 | - private $loader; |
|
22 | + /** |
|
23 | + * @var LoaderInterface |
|
24 | + */ |
|
25 | + private $loader; |
|
26 | 26 | |
27 | - /** |
|
28 | - * @var RouteCollection $routes |
|
29 | - */ |
|
30 | - private $routes; |
|
27 | + /** |
|
28 | + * @var RouteCollection $routes |
|
29 | + */ |
|
30 | + private $routes; |
|
31 | 31 | |
32 | 32 | |
33 | - /** |
|
34 | - * RouteHandler constructor. |
|
35 | - * |
|
36 | - * @param LoaderInterface $loader |
|
37 | - * @param RouteCollection $routes |
|
38 | - */ |
|
39 | - public function __construct(LoaderInterface $loader, RouteCollection $routes) |
|
40 | - { |
|
41 | - $this->loader = $loader; |
|
42 | - $this->routes = $routes; |
|
43 | - } |
|
33 | + /** |
|
34 | + * RouteHandler constructor. |
|
35 | + * |
|
36 | + * @param LoaderInterface $loader |
|
37 | + * @param RouteCollection $routes |
|
38 | + */ |
|
39 | + public function __construct(LoaderInterface $loader, RouteCollection $routes) |
|
40 | + { |
|
41 | + $this->loader = $loader; |
|
42 | + $this->routes = $routes; |
|
43 | + } |
|
44 | 44 | |
45 | 45 | |
46 | - /** |
|
47 | - * @param string $fqcn Fully Qualified Class Name for Route |
|
48 | - * @param bool $handle if true [default] will immediately call RouteInterface::handleRequest() |
|
49 | - * @throws Exception |
|
50 | - * @since $VID:$ |
|
51 | - */ |
|
52 | - public function addRoute($fqcn, $handle = true) |
|
53 | - { |
|
54 | - try { |
|
55 | - $route = $this->loader->getShared($fqcn); |
|
56 | - if (! $route instanceof RouteInterface) { |
|
57 | - throw new InvalidClassException( |
|
58 | - sprintf( |
|
59 | - esc_html__( |
|
60 | - 'The supplied FQCN (%1$s) must be an instance of RouteInterface.', |
|
61 | - 'event_espresso' |
|
62 | - ), |
|
63 | - $fqcn |
|
64 | - ) |
|
65 | - ); |
|
66 | - } |
|
67 | - $this->routes->add($route); |
|
68 | - if ($handle) { |
|
69 | - $route->handleRequest(); |
|
70 | - } |
|
71 | - } catch (Exception $exception) { |
|
72 | - new ExceptionStackTraceDisplay($exception); |
|
73 | - } |
|
74 | - } |
|
46 | + /** |
|
47 | + * @param string $fqcn Fully Qualified Class Name for Route |
|
48 | + * @param bool $handle if true [default] will immediately call RouteInterface::handleRequest() |
|
49 | + * @throws Exception |
|
50 | + * @since $VID:$ |
|
51 | + */ |
|
52 | + public function addRoute($fqcn, $handle = true) |
|
53 | + { |
|
54 | + try { |
|
55 | + $route = $this->loader->getShared($fqcn); |
|
56 | + if (! $route instanceof RouteInterface) { |
|
57 | + throw new InvalidClassException( |
|
58 | + sprintf( |
|
59 | + esc_html__( |
|
60 | + 'The supplied FQCN (%1$s) must be an instance of RouteInterface.', |
|
61 | + 'event_espresso' |
|
62 | + ), |
|
63 | + $fqcn |
|
64 | + ) |
|
65 | + ); |
|
66 | + } |
|
67 | + $this->routes->add($route); |
|
68 | + if ($handle) { |
|
69 | + $route->handleRequest(); |
|
70 | + } |
|
71 | + } catch (Exception $exception) { |
|
72 | + new ExceptionStackTraceDisplay($exception); |
|
73 | + } |
|
74 | + } |
|
75 | 75 | |
76 | 76 | |
77 | - /** |
|
78 | - * finds and returns all Routes that have yet to be handled |
|
79 | - * |
|
80 | - * @return RouteInterface[] |
|
81 | - */ |
|
82 | - public function getRoutesForCurrentRequest() |
|
83 | - { |
|
84 | - return $this->routes->getRoutesForCurrentRequest(); |
|
85 | - } |
|
77 | + /** |
|
78 | + * finds and returns all Routes that have yet to be handled |
|
79 | + * |
|
80 | + * @return RouteInterface[] |
|
81 | + */ |
|
82 | + public function getRoutesForCurrentRequest() |
|
83 | + { |
|
84 | + return $this->routes->getRoutesForCurrentRequest(); |
|
85 | + } |
|
86 | 86 | |
87 | 87 | |
88 | - /** |
|
89 | - * calls RouteInterface::handleRequest() on all Routes that |
|
90 | - * - match current request |
|
91 | - * - have yet to be handled |
|
92 | - * |
|
93 | - * @return void |
|
94 | - */ |
|
95 | - public function handleRoutesForCurrentRequest() |
|
96 | - { |
|
97 | - $this->routes->handleRoutesForCurrentRequest(); |
|
98 | - } |
|
88 | + /** |
|
89 | + * calls RouteInterface::handleRequest() on all Routes that |
|
90 | + * - match current request |
|
91 | + * - have yet to be handled |
|
92 | + * |
|
93 | + * @return void |
|
94 | + */ |
|
95 | + public function handleRoutesForCurrentRequest() |
|
96 | + { |
|
97 | + $this->routes->handleRoutesForCurrentRequest(); |
|
98 | + } |
|
99 | 99 | } |
@@ -16,1151 +16,1151 @@ |
||
16 | 16 | class Payments_Admin_Page extends EE_Admin_Page |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * Variables used for when we're re-sorting the logs results, in case |
|
21 | - * we needed to do two queries and we need to resort |
|
22 | - * |
|
23 | - * @var string |
|
24 | - */ |
|
25 | - private $_sort_logs_again_direction; |
|
26 | - |
|
27 | - |
|
28 | - /** |
|
29 | - * @Constructor |
|
30 | - * @access public |
|
31 | - * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object. |
|
32 | - * @throws EE_Error |
|
33 | - * @throws InvalidArgumentException |
|
34 | - * @throws InvalidDataTypeException |
|
35 | - * @throws InvalidInterfaceException |
|
36 | - * @throws ReflectionException |
|
37 | - */ |
|
38 | - public function __construct($routing = true) |
|
39 | - { |
|
40 | - parent::__construct($routing); |
|
41 | - } |
|
42 | - |
|
43 | - |
|
44 | - protected function _init_page_props() |
|
45 | - { |
|
46 | - $this->page_slug = EE_PAYMENTS_PG_SLUG; |
|
47 | - $this->page_label = __('Payment Methods', 'event_espresso'); |
|
48 | - $this->_admin_base_url = EE_PAYMENTS_ADMIN_URL; |
|
49 | - $this->_admin_base_path = EE_PAYMENTS_ADMIN; |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - protected function _ajax_hooks() |
|
54 | - { |
|
55 | - // todo: all hooks for ajax goes here. |
|
56 | - } |
|
57 | - |
|
58 | - |
|
59 | - protected function _define_page_props() |
|
60 | - { |
|
61 | - $this->_admin_page_title = $this->page_label; |
|
62 | - $this->_labels = array( |
|
63 | - 'publishbox' => __('Update Settings', 'event_espresso'), |
|
64 | - ); |
|
65 | - } |
|
66 | - |
|
67 | - |
|
68 | - protected function _set_page_routes() |
|
69 | - { |
|
70 | - /** |
|
71 | - * note that with payment method capabilities, although we've implemented |
|
72 | - * capability mapping which will be used for accessing payment methods owned by |
|
73 | - * other users. This is not fully implemented yet in the payment method ui. |
|
74 | - * Currently only the "plural" caps are in active use. |
|
75 | - * When cap mapping is implemented, some routes will need to use the singular form of |
|
76 | - * capability method and also include the $id of the payment method for the route. |
|
77 | - **/ |
|
78 | - $this->_page_routes = array( |
|
79 | - 'default' => array( |
|
80 | - 'func' => '_payment_methods_list', |
|
81 | - 'capability' => 'ee_edit_payment_methods', |
|
82 | - ), |
|
83 | - 'payment_settings' => array( |
|
84 | - 'func' => '_payment_settings', |
|
85 | - 'capability' => 'ee_manage_gateways', |
|
86 | - ), |
|
87 | - 'activate_payment_method' => array( |
|
88 | - 'func' => '_activate_payment_method', |
|
89 | - 'noheader' => true, |
|
90 | - 'capability' => 'ee_edit_payment_methods', |
|
91 | - ), |
|
92 | - 'deactivate_payment_method' => array( |
|
93 | - 'func' => '_deactivate_payment_method', |
|
94 | - 'noheader' => true, |
|
95 | - 'capability' => 'ee_delete_payment_methods', |
|
96 | - ), |
|
97 | - 'update_payment_method' => array( |
|
98 | - 'func' => '_update_payment_method', |
|
99 | - 'noheader' => true, |
|
100 | - 'headers_sent_route' => 'default', |
|
101 | - 'capability' => 'ee_edit_payment_methods', |
|
102 | - ), |
|
103 | - 'update_payment_settings' => array( |
|
104 | - 'func' => '_update_payment_settings', |
|
105 | - 'noheader' => true, |
|
106 | - 'capability' => 'ee_manage_gateways', |
|
107 | - ), |
|
108 | - 'payment_log' => array( |
|
109 | - 'func' => '_payment_log_overview_list_table', |
|
110 | - 'capability' => 'ee_read_payment_methods', |
|
111 | - ), |
|
112 | - 'payment_log_details' => array( |
|
113 | - 'func' => '_payment_log_details', |
|
114 | - 'capability' => 'ee_read_payment_methods', |
|
115 | - ), |
|
116 | - ); |
|
117 | - } |
|
118 | - |
|
119 | - |
|
120 | - protected function _set_page_config() |
|
121 | - { |
|
122 | - $payment_method_list_config = array( |
|
123 | - 'nav' => array( |
|
124 | - 'label' => __('Payment Methods', 'event_espresso'), |
|
125 | - 'order' => 10, |
|
126 | - ), |
|
127 | - 'metaboxes' => $this->_default_espresso_metaboxes, |
|
128 | - 'help_tabs' => array_merge( |
|
129 | - array( |
|
130 | - 'payment_methods_overview_help_tab' => array( |
|
131 | - 'title' => __('Payment Methods Overview', 'event_espresso'), |
|
132 | - 'filename' => 'payment_methods_overview', |
|
133 | - ), |
|
134 | - ), |
|
135 | - $this->_add_payment_method_help_tabs() |
|
136 | - ), |
|
137 | - 'help_tour' => array('Payment_Methods_Selection_Help_Tour'), |
|
138 | - 'require_nonce' => false, |
|
139 | - ); |
|
140 | - $this->_page_config = array( |
|
141 | - 'default' => $payment_method_list_config, |
|
142 | - 'payment_settings' => array( |
|
143 | - 'nav' => array( |
|
144 | - 'label' => __('Settings', 'event_espresso'), |
|
145 | - 'order' => 20, |
|
146 | - ), |
|
147 | - 'help_tabs' => array( |
|
148 | - 'payment_methods_settings_help_tab' => array( |
|
149 | - 'title' => __('Payment Method Settings', 'event_espresso'), |
|
150 | - 'filename' => 'payment_methods_settings', |
|
151 | - ), |
|
152 | - ), |
|
153 | - // 'help_tour' => array( 'Payment_Methods_Settings_Help_Tour' ), |
|
154 | - 'metaboxes' => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')), |
|
155 | - 'require_nonce' => false, |
|
156 | - ), |
|
157 | - 'payment_log' => array( |
|
158 | - 'nav' => array( |
|
159 | - 'label' => __("Logs", 'event_espresso'), |
|
160 | - 'order' => 30, |
|
161 | - ), |
|
162 | - 'list_table' => 'Payment_Log_Admin_List_Table', |
|
163 | - 'metaboxes' => $this->_default_espresso_metaboxes, |
|
164 | - 'require_nonce' => false, |
|
165 | - ), |
|
166 | - ); |
|
167 | - } |
|
168 | - |
|
169 | - |
|
170 | - /** |
|
171 | - * @return array |
|
172 | - * @throws DomainException |
|
173 | - * @throws EE_Error |
|
174 | - * @throws InvalidArgumentException |
|
175 | - * @throws InvalidDataTypeException |
|
176 | - * @throws InvalidInterfaceException |
|
177 | - * @throws ReflectionException |
|
178 | - */ |
|
179 | - protected function _add_payment_method_help_tabs() |
|
180 | - { |
|
181 | - EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
182 | - $payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types(); |
|
183 | - $all_pmt_help_tabs_config = array(); |
|
184 | - foreach ($payment_method_types as $payment_method_type) { |
|
185 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
186 | - $payment_method_type->cap_name(), |
|
187 | - 'specific_payment_method_type_access' |
|
188 | - ) |
|
189 | - ) { |
|
190 | - continue; |
|
191 | - } |
|
192 | - foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) { |
|
193 | - $template_args = isset($config['template_args']) ? $config['template_args'] : array(); |
|
194 | - $template_args['admin_page_obj'] = $this; |
|
195 | - $all_pmt_help_tabs_config[ $help_tab_name ] = array( |
|
196 | - 'title' => $config['title'], |
|
197 | - 'content' => EEH_Template::display_template( |
|
198 | - $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php', |
|
199 | - $template_args, |
|
200 | - true |
|
201 | - ), |
|
202 | - ); |
|
203 | - } |
|
204 | - } |
|
205 | - return $all_pmt_help_tabs_config; |
|
206 | - } |
|
207 | - |
|
208 | - |
|
209 | - // none of the below group are currently used for Gateway Settings |
|
210 | - protected function _add_screen_options() |
|
211 | - { |
|
212 | - } |
|
213 | - |
|
214 | - |
|
215 | - protected function _add_feature_pointers() |
|
216 | - { |
|
217 | - } |
|
218 | - |
|
219 | - |
|
220 | - public function admin_init() |
|
221 | - { |
|
222 | - } |
|
223 | - |
|
224 | - |
|
225 | - public function admin_notices() |
|
226 | - { |
|
227 | - } |
|
228 | - |
|
229 | - |
|
230 | - public function admin_footer_scripts() |
|
231 | - { |
|
232 | - } |
|
233 | - |
|
234 | - |
|
235 | - public function load_scripts_styles() |
|
236 | - { |
|
237 | - wp_enqueue_script('ee_admin_js'); |
|
238 | - wp_enqueue_script('ee-text-links'); |
|
239 | - wp_enqueue_script( |
|
240 | - 'espresso_payments', |
|
241 | - EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js', |
|
242 | - ['ee-datepicker'], |
|
243 | - EVENT_ESPRESSO_VERSION, |
|
244 | - true |
|
245 | - ); |
|
246 | - wp_enqueue_style('espresso-ui-theme'); |
|
247 | - } |
|
248 | - |
|
249 | - |
|
250 | - public function load_scripts_styles_default() |
|
251 | - { |
|
252 | - // styles |
|
253 | - wp_register_style( |
|
254 | - 'espresso_payments', |
|
255 | - EE_PAYMENTS_ASSETS_URL . 'ee-payments.css', |
|
256 | - array(), |
|
257 | - EVENT_ESPRESSO_VERSION |
|
258 | - ); |
|
259 | - wp_enqueue_style('espresso_payments'); |
|
260 | - wp_enqueue_style('ee-text-links'); |
|
261 | - // scripts |
|
262 | - } |
|
263 | - |
|
264 | - |
|
265 | - protected function _payment_methods_list() |
|
266 | - { |
|
267 | - /** |
|
268 | - * first let's ensure payment methods have been setup. We do this here because when people activate a |
|
269 | - * payment method for the first time (as an addon), it may not setup its capabilities or get registered |
|
270 | - * correctly due to the loading process. However, people MUST setup the details for the payment method so its |
|
271 | - * safe to do a recheck here. |
|
272 | - */ |
|
273 | - EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
274 | - EEM_Payment_Method::instance()->verify_button_urls(); |
|
275 | - // setup tabs, one for each payment method type |
|
276 | - $tabs = array(); |
|
277 | - $payment_methods = array(); |
|
278 | - foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) { |
|
279 | - // we don't want to show admin-only PMTs for now |
|
280 | - if ($pmt_obj instanceof EE_PMT_Admin_Only) { |
|
281 | - continue; |
|
282 | - } |
|
283 | - // check access |
|
284 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
285 | - $pmt_obj->cap_name(), |
|
286 | - 'specific_payment_method_type_access' |
|
287 | - ) |
|
288 | - ) { |
|
289 | - continue; |
|
290 | - } |
|
291 | - // check for any active pms of that type |
|
292 | - $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name()); |
|
293 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
294 | - $payment_method = EE_Payment_Method::new_instance( |
|
295 | - array( |
|
296 | - 'PMD_slug' => sanitize_key($pmt_obj->system_name()), |
|
297 | - 'PMD_type' => $pmt_obj->system_name(), |
|
298 | - 'PMD_name' => $pmt_obj->pretty_name(), |
|
299 | - 'PMD_admin_name' => $pmt_obj->pretty_name(), |
|
300 | - ) |
|
301 | - ); |
|
302 | - } |
|
303 | - $payment_methods[ $payment_method->slug() ] = $payment_method; |
|
304 | - } |
|
305 | - $payment_methods = apply_filters( |
|
306 | - 'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods', |
|
307 | - $payment_methods |
|
308 | - ); |
|
309 | - foreach ($payment_methods as $payment_method) { |
|
310 | - if ($payment_method instanceof EE_Payment_Method) { |
|
311 | - add_meta_box( |
|
312 | - // html id |
|
313 | - 'espresso_' . $payment_method->slug() . '_payment_settings', |
|
314 | - // title |
|
315 | - sprintf(__('%s Settings', 'event_espresso'), $payment_method->admin_name()), |
|
316 | - // callback |
|
317 | - array($this, 'payment_method_settings_meta_box'), |
|
318 | - // post type |
|
319 | - null, |
|
320 | - // context |
|
321 | - 'normal', |
|
322 | - // priority |
|
323 | - 'default', |
|
324 | - // callback args |
|
325 | - array('payment_method' => $payment_method) |
|
326 | - ); |
|
327 | - // setup for tabbed content |
|
328 | - $tabs[ $payment_method->slug() ] = array( |
|
329 | - 'label' => $payment_method->admin_name(), |
|
330 | - 'class' => $payment_method->active() ? 'gateway-active' : '', |
|
331 | - 'href' => 'espresso_' . $payment_method->slug() . '_payment_settings', |
|
332 | - 'title' => __('Modify this Payment Method', 'event_espresso'), |
|
333 | - 'slug' => $payment_method->slug(), |
|
334 | - ); |
|
335 | - } |
|
336 | - } |
|
337 | - $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links( |
|
338 | - $tabs, |
|
339 | - 'payment_method_links', |
|
340 | - '|', |
|
341 | - $this->_get_active_payment_method_slug() |
|
342 | - ); |
|
343 | - $this->display_admin_page_with_sidebar(); |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - /** |
|
348 | - * _get_active_payment_method_slug |
|
349 | - * |
|
350 | - * @return string |
|
351 | - */ |
|
352 | - protected function _get_active_payment_method_slug() |
|
353 | - { |
|
354 | - $payment_method_slug = false; |
|
355 | - // decide which payment method tab to open first, as dictated by the request's 'payment_method' |
|
356 | - if (isset($this->_req_data['payment_method'])) { |
|
357 | - // if they provided the current payment method, use it |
|
358 | - $payment_method_slug = sanitize_key($this->_req_data['payment_method']); |
|
359 | - } |
|
360 | - $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug))); |
|
361 | - // if that didn't work or wasn't provided, find another way to select the current pm |
|
362 | - if (! $this->_verify_payment_method($payment_method)) { |
|
363 | - // like, looking for an active one |
|
364 | - $payment_method = EEM_Payment_Method::instance()->get_one_active('CART'); |
|
365 | - // test that one as well |
|
366 | - if ($this->_verify_payment_method($payment_method)) { |
|
367 | - $payment_method_slug = $payment_method->slug(); |
|
368 | - } else { |
|
369 | - $payment_method_slug = 'paypal_standard'; |
|
370 | - } |
|
371 | - } |
|
372 | - return $payment_method_slug; |
|
373 | - } |
|
374 | - |
|
375 | - |
|
376 | - /** |
|
377 | - * payment_method_settings_meta_box |
|
378 | - * returns TRUE if the passed payment method is properly constructed and the logged in user has the correct |
|
379 | - * capabilities to access it |
|
380 | - * |
|
381 | - * @param EE_Payment_Method $payment_method |
|
382 | - * @return boolean |
|
383 | - */ |
|
384 | - protected function _verify_payment_method($payment_method) |
|
385 | - { |
|
386 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base |
|
387 | - && EE_Registry::instance()->CAP->current_user_can( |
|
388 | - $payment_method->type_obj()->cap_name(), |
|
389 | - 'specific_payment_method_type_access' |
|
390 | - ) |
|
391 | - ) { |
|
392 | - return true; |
|
393 | - } |
|
394 | - return false; |
|
395 | - } |
|
396 | - |
|
397 | - |
|
398 | - /** |
|
399 | - * payment_method_settings_meta_box |
|
400 | - * |
|
401 | - * @param NULL $post_obj_which_is_null is an object containing the current post (as a $post object) |
|
402 | - * @param array $metabox is an array with metabox id, title, callback, and args elements. the value |
|
403 | - * at 'args' has key 'payment_method', as set within _payment_methods_list |
|
404 | - * @return string |
|
405 | - * @throws EE_Error |
|
406 | - */ |
|
407 | - public function payment_method_settings_meta_box($post_obj_which_is_null, $metabox) |
|
408 | - { |
|
409 | - $payment_method = isset($metabox['args'], $metabox['args']['payment_method']) |
|
410 | - ? $metabox['args']['payment_method'] : null; |
|
411 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
412 | - throw new EE_Error( |
|
413 | - sprintf( |
|
414 | - __( |
|
415 | - 'Payment method metabox setup incorrectly. No Payment method object was supplied', |
|
416 | - 'event_espresso' |
|
417 | - ) |
|
418 | - ) |
|
419 | - ); |
|
420 | - } |
|
421 | - $payment_method_scopes = $payment_method->active(); |
|
422 | - // if the payment method really exists show its form, otherwise the activation template |
|
423 | - if ($payment_method->ID() && ! empty($payment_method_scopes)) { |
|
424 | - $form = $this->_generate_payment_method_settings_form($payment_method); |
|
425 | - if ($form->form_data_present_in($this->_req_data)) { |
|
426 | - $form->receive_form_submission($this->_req_data); |
|
427 | - } |
|
428 | - echo $form->form_open() . $form->get_html_and_js() . $form->form_close(); |
|
429 | - } else { |
|
430 | - echo $this->_activate_payment_method_button($payment_method)->get_html_and_js(); |
|
431 | - } |
|
432 | - } |
|
433 | - |
|
434 | - |
|
435 | - /** |
|
436 | - * Gets the form for all the settings related to this payment method type |
|
437 | - * |
|
438 | - * @access protected |
|
439 | - * @param EE_Payment_Method $payment_method |
|
440 | - * @return EE_Form_Section_Proper |
|
441 | - */ |
|
442 | - protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method) |
|
443 | - { |
|
444 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
445 | - return new EE_Form_Section_Proper(); |
|
446 | - } |
|
447 | - return new EE_Form_Section_Proper( |
|
448 | - array( |
|
449 | - 'name' => $payment_method->slug() . '_settings_form', |
|
450 | - 'html_id' => $payment_method->slug() . '_settings_form', |
|
451 | - 'action' => EE_Admin_Page::add_query_args_and_nonce( |
|
452 | - array( |
|
453 | - 'action' => 'update_payment_method', |
|
454 | - 'payment_method' => $payment_method->slug(), |
|
455 | - ), |
|
456 | - EE_PAYMENTS_ADMIN_URL |
|
457 | - ), |
|
458 | - 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
459 | - 'subsections' => apply_filters( |
|
460 | - 'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections', |
|
461 | - array( |
|
462 | - 'pci_dss_compliance' => $this->_pci_dss_compliance($payment_method), |
|
463 | - 'currency_support' => $this->_currency_support($payment_method), |
|
464 | - 'payment_method_settings' => $this->_payment_method_settings($payment_method), |
|
465 | - 'update' => $this->_update_payment_method_button($payment_method), |
|
466 | - 'deactivate' => $this->_deactivate_payment_method_button($payment_method), |
|
467 | - 'fine_print' => $this->_fine_print(), |
|
468 | - ), |
|
469 | - $payment_method |
|
470 | - ), |
|
471 | - ) |
|
472 | - ); |
|
473 | - } |
|
474 | - |
|
475 | - |
|
476 | - /** |
|
477 | - * _pci_dss_compliance |
|
478 | - * |
|
479 | - * @access protected |
|
480 | - * @param EE_Payment_Method $payment_method |
|
481 | - * @return EE_Form_Section_Proper |
|
482 | - */ |
|
483 | - protected function _pci_dss_compliance(EE_Payment_Method $payment_method) |
|
484 | - { |
|
485 | - if ($payment_method->type_obj()->requires_https()) { |
|
486 | - return new EE_Form_Section_HTML( |
|
487 | - EEH_HTML::table( |
|
488 | - EEH_HTML::tr( |
|
489 | - EEH_HTML::th( |
|
490 | - EEH_HTML::label( |
|
491 | - EEH_HTML::strong(__('IMPORTANT', 'event_espresso'), '', 'important-notice') |
|
492 | - ) |
|
493 | - ) . |
|
494 | - EEH_HTML::td( |
|
495 | - EEH_HTML::strong( |
|
496 | - __( |
|
497 | - 'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.', |
|
498 | - 'event_espresso' |
|
499 | - ) |
|
500 | - ) |
|
501 | - . |
|
502 | - EEH_HTML::br() |
|
503 | - . |
|
504 | - __('Learn more about ', 'event_espresso') |
|
505 | - . EEH_HTML::link( |
|
506 | - 'https://www.pcisecuritystandards.org/merchants/index.php', |
|
507 | - __('PCI DSS compliance', 'event_espresso') |
|
508 | - ) |
|
509 | - ) |
|
510 | - ) |
|
511 | - ) |
|
512 | - ); |
|
513 | - } else { |
|
514 | - return new EE_Form_Section_HTML(''); |
|
515 | - } |
|
516 | - } |
|
517 | - |
|
518 | - |
|
519 | - /** |
|
520 | - * _currency_support |
|
521 | - * |
|
522 | - * @access protected |
|
523 | - * @param EE_Payment_Method $payment_method |
|
524 | - * @return EE_Form_Section_Proper |
|
525 | - */ |
|
526 | - protected function _currency_support(EE_Payment_Method $payment_method) |
|
527 | - { |
|
528 | - if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) { |
|
529 | - return new EE_Form_Section_HTML( |
|
530 | - EEH_HTML::table( |
|
531 | - EEH_HTML::tr( |
|
532 | - EEH_HTML::th( |
|
533 | - EEH_HTML::label( |
|
534 | - EEH_HTML::strong(__('IMPORTANT', 'event_espresso'), '', 'important-notice') |
|
535 | - ) |
|
536 | - ) . |
|
537 | - EEH_HTML::td( |
|
538 | - EEH_HTML::strong( |
|
539 | - sprintf( |
|
540 | - __( |
|
541 | - 'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.', |
|
542 | - 'event_espresso' |
|
543 | - ), |
|
544 | - EE_Config::instance()->currency->code |
|
545 | - ) |
|
546 | - ) |
|
547 | - ) |
|
548 | - ) |
|
549 | - ) |
|
550 | - ); |
|
551 | - } else { |
|
552 | - return new EE_Form_Section_HTML(''); |
|
553 | - } |
|
554 | - } |
|
555 | - |
|
556 | - |
|
557 | - /** |
|
558 | - * _update_payment_method_button |
|
559 | - * |
|
560 | - * @access protected |
|
561 | - * @param EE_Payment_Method $payment_method |
|
562 | - * @return EE_Payment_Method_Form |
|
563 | - */ |
|
564 | - protected function _payment_method_settings(EE_Payment_Method $payment_method) |
|
565 | - { |
|
566 | - // modify the form so we only have/show fields that will be implemented for this version |
|
567 | - return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name()); |
|
568 | - } |
|
569 | - |
|
570 | - |
|
571 | - /** |
|
572 | - * Simplifies the form to merely reproduce 4.1's gateway settings functionality |
|
573 | - * |
|
574 | - * @param EE_Form_Section_Proper $form_section |
|
575 | - * @param string $payment_method_name |
|
576 | - * @return EE_Payment_Method_Form |
|
577 | - * @throws EE_Error |
|
578 | - */ |
|
579 | - protected function _simplify_form($form_section, $payment_method_name = '') |
|
580 | - { |
|
581 | - if ($form_section instanceof EE_Payment_Method_Form) { |
|
582 | - $form_section->exclude( |
|
583 | - array( |
|
584 | - 'PMD_type', // dont want them changing the type |
|
585 | - 'PMD_slug', // or the slug (probably never) |
|
586 | - 'PMD_wp_user', // or the user's ID |
|
587 | - 'Currency' // or the currency, until the rest of EE supports simultaneous currencies |
|
588 | - ) |
|
589 | - ); |
|
590 | - return $form_section; |
|
591 | - } else { |
|
592 | - throw new EE_Error( |
|
593 | - sprintf( |
|
594 | - __( |
|
595 | - 'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.', |
|
596 | - 'event_espresso' |
|
597 | - ), |
|
598 | - $payment_method_name |
|
599 | - ) |
|
600 | - ); |
|
601 | - } |
|
602 | - } |
|
603 | - |
|
604 | - |
|
605 | - /** |
|
606 | - * _update_payment_method_button |
|
607 | - * |
|
608 | - * @access protected |
|
609 | - * @param EE_Payment_Method $payment_method |
|
610 | - * @return EE_Form_Section_HTML |
|
611 | - */ |
|
612 | - protected function _update_payment_method_button(EE_Payment_Method $payment_method) |
|
613 | - { |
|
614 | - $update_button = new EE_Submit_Input( |
|
615 | - array( |
|
616 | - 'name' => 'submit', |
|
617 | - 'html_id' => 'save_' . $payment_method->slug() . '_settings', |
|
618 | - 'default' => sprintf( |
|
619 | - __('Update %s Payment Settings', 'event_espresso'), |
|
620 | - $payment_method->admin_name() |
|
621 | - ), |
|
622 | - 'html_label' => EEH_HTML::nbsp(), |
|
623 | - ) |
|
624 | - ); |
|
625 | - return new EE_Form_Section_HTML( |
|
626 | - EEH_HTML::table( |
|
627 | - EEH_HTML::no_row(EEH_HTML::br(2)) . |
|
628 | - EEH_HTML::tr( |
|
629 | - EEH_HTML::th(__('Update Settings', 'event_espresso')) . |
|
630 | - EEH_HTML::td( |
|
631 | - $update_button->get_html_for_input() |
|
632 | - ) |
|
633 | - ) |
|
634 | - ) |
|
635 | - ); |
|
636 | - } |
|
637 | - |
|
638 | - |
|
639 | - /** |
|
640 | - * _deactivate_payment_method_button |
|
641 | - * |
|
642 | - * @access protected |
|
643 | - * @param EE_Payment_Method $payment_method |
|
644 | - * @return EE_Form_Section_Proper |
|
645 | - */ |
|
646 | - protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method) |
|
647 | - { |
|
648 | - $link_text_and_title = sprintf( |
|
649 | - __('Deactivate %1$s Payments?', 'event_espresso'), |
|
650 | - $payment_method->admin_name() |
|
651 | - ); |
|
652 | - return new EE_Form_Section_HTML( |
|
653 | - EEH_HTML::table( |
|
654 | - EEH_HTML::tr( |
|
655 | - EEH_HTML::th(__('Deactivate Payment Method', 'event_espresso')) . |
|
656 | - EEH_HTML::td( |
|
657 | - EEH_HTML::link( |
|
658 | - EE_Admin_Page::add_query_args_and_nonce( |
|
659 | - array( |
|
660 | - 'action' => 'deactivate_payment_method', |
|
661 | - 'payment_method' => $payment_method->slug(), |
|
662 | - ), |
|
663 | - EE_PAYMENTS_ADMIN_URL |
|
664 | - ), |
|
665 | - $link_text_and_title, |
|
666 | - $link_text_and_title, |
|
667 | - 'deactivate_' . $payment_method->slug(), |
|
668 | - 'espresso-button button-secondary' |
|
669 | - ) |
|
670 | - ) |
|
671 | - ) |
|
672 | - ) |
|
673 | - ); |
|
674 | - } |
|
675 | - |
|
676 | - |
|
677 | - /** |
|
678 | - * _activate_payment_method_button |
|
679 | - * |
|
680 | - * @access protected |
|
681 | - * @param EE_Payment_Method $payment_method |
|
682 | - * @return EE_Form_Section_Proper |
|
683 | - */ |
|
684 | - protected function _activate_payment_method_button(EE_Payment_Method $payment_method) |
|
685 | - { |
|
686 | - $link_text_and_title = sprintf( |
|
687 | - __('Activate %1$s Payment Method?', 'event_espresso'), |
|
688 | - $payment_method->admin_name() |
|
689 | - ); |
|
690 | - return new EE_Form_Section_Proper( |
|
691 | - array( |
|
692 | - 'name' => 'activate_' . $payment_method->slug() . '_settings_form', |
|
693 | - 'html_id' => 'activate_' . $payment_method->slug() . '_settings_form', |
|
694 | - 'action' => '#', |
|
695 | - 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
696 | - 'subsections' => apply_filters( |
|
697 | - 'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections', |
|
698 | - array( |
|
699 | - new EE_Form_Section_HTML( |
|
700 | - EEH_HTML::table( |
|
701 | - EEH_HTML::tr( |
|
702 | - EEH_HTML::td( |
|
703 | - $payment_method->type_obj()->introductory_html(), |
|
704 | - '', |
|
705 | - '', |
|
706 | - '', |
|
707 | - 'colspan="2"' |
|
708 | - ) |
|
709 | - ) . |
|
710 | - EEH_HTML::tr( |
|
711 | - EEH_HTML::th( |
|
712 | - EEH_HTML::label(__('Click to Activate ', 'event_espresso')) |
|
713 | - ) . |
|
714 | - EEH_HTML::td( |
|
715 | - EEH_HTML::link( |
|
716 | - EE_Admin_Page::add_query_args_and_nonce( |
|
717 | - array( |
|
718 | - 'action' => 'activate_payment_method', |
|
719 | - 'payment_method_type' => $payment_method->type(), |
|
720 | - ), |
|
721 | - EE_PAYMENTS_ADMIN_URL |
|
722 | - ), |
|
723 | - $link_text_and_title, |
|
724 | - $link_text_and_title, |
|
725 | - 'activate_' . $payment_method->slug(), |
|
726 | - 'espresso-button-green button-primary' |
|
727 | - ) |
|
728 | - ) |
|
729 | - ) |
|
730 | - ) |
|
731 | - ), |
|
732 | - ), |
|
733 | - $payment_method |
|
734 | - ), |
|
735 | - ) |
|
736 | - ); |
|
737 | - } |
|
738 | - |
|
739 | - |
|
740 | - /** |
|
741 | - * _fine_print |
|
742 | - * |
|
743 | - * @access protected |
|
744 | - * @return EE_Form_Section_HTML |
|
745 | - */ |
|
746 | - protected function _fine_print() |
|
747 | - { |
|
748 | - return new EE_Form_Section_HTML( |
|
749 | - EEH_HTML::table( |
|
750 | - EEH_HTML::tr( |
|
751 | - EEH_HTML::th() . |
|
752 | - EEH_HTML::td( |
|
753 | - EEH_HTML::p(__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text') |
|
754 | - ) |
|
755 | - ) |
|
756 | - ) |
|
757 | - ); |
|
758 | - } |
|
759 | - |
|
760 | - |
|
761 | - /** |
|
762 | - * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far) |
|
763 | - * |
|
764 | - * @global WP_User $current_user |
|
765 | - */ |
|
766 | - protected function _activate_payment_method() |
|
767 | - { |
|
768 | - if (isset($this->_req_data['payment_method_type'])) { |
|
769 | - $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']); |
|
770 | - // see if one exists |
|
771 | - EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
772 | - $payment_method = EE_Payment_Method_Manager::instance() |
|
773 | - ->activate_a_payment_method_of_type($payment_method_type); |
|
774 | - $this->_redirect_after_action( |
|
775 | - 1, |
|
776 | - 'Payment Method', |
|
777 | - 'activated', |
|
778 | - array('action' => 'default', 'payment_method' => $payment_method->slug()) |
|
779 | - ); |
|
780 | - } else { |
|
781 | - $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default')); |
|
782 | - } |
|
783 | - } |
|
784 | - |
|
785 | - |
|
786 | - /** |
|
787 | - * Deactivates the payment method with the specified slug, and redirects. |
|
788 | - */ |
|
789 | - protected function _deactivate_payment_method() |
|
790 | - { |
|
791 | - if (isset($this->_req_data['payment_method'])) { |
|
792 | - $payment_method_slug = sanitize_key($this->_req_data['payment_method']); |
|
793 | - // deactivate it |
|
794 | - EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
795 | - $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug); |
|
796 | - $this->_redirect_after_action( |
|
797 | - $count_updated, |
|
798 | - 'Payment Method', |
|
799 | - 'deactivated', |
|
800 | - array('action' => 'default', 'payment_method' => $payment_method_slug) |
|
801 | - ); |
|
802 | - } else { |
|
803 | - $this->_redirect_after_action(false, 'Payment Method', 'deactivated', array('action' => 'default')); |
|
804 | - } |
|
805 | - } |
|
806 | - |
|
807 | - |
|
808 | - /** |
|
809 | - * Processes the payment method form that was submitted. This is slightly trickier than usual form |
|
810 | - * processing because we first need to identify WHICH form was processed and which payment method |
|
811 | - * it corresponds to. Once we have done that, we see if the form is valid. If it is, the |
|
812 | - * form's data is saved and we redirect to the default payment methods page, setting the updated payment method |
|
813 | - * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the |
|
814 | - * subsequently called 'headers_sent_func' which is _payment_methods_list) |
|
815 | - * |
|
816 | - * @return void |
|
817 | - */ |
|
818 | - protected function _update_payment_method() |
|
819 | - { |
|
820 | - if ($_SERVER['REQUEST_METHOD'] == 'POST') { |
|
821 | - // ok let's find which gateway form to use based on the form input |
|
822 | - EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
823 | - /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */ |
|
824 | - $correct_pmt_form_to_use = null; |
|
825 | - $payment_method = null; |
|
826 | - foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) { |
|
827 | - // get the form and simplify it, like what we do when we display it |
|
828 | - $pmt_form = $this->_generate_payment_method_settings_form($payment_method); |
|
829 | - if ($pmt_form->form_data_present_in($this->_req_data)) { |
|
830 | - $correct_pmt_form_to_use = $pmt_form; |
|
831 | - break; |
|
832 | - } |
|
833 | - } |
|
834 | - // if we couldn't find the correct payment method type... |
|
835 | - if (! $correct_pmt_form_to_use) { |
|
836 | - EE_Error::add_error( |
|
837 | - __( |
|
838 | - "We could not find which payment method type your form submission related to. Please contact support", |
|
839 | - 'event_espresso' |
|
840 | - ), |
|
841 | - __FILE__, |
|
842 | - __FUNCTION__, |
|
843 | - __LINE__ |
|
844 | - ); |
|
845 | - $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default')); |
|
846 | - } |
|
847 | - $correct_pmt_form_to_use->receive_form_submission($this->_req_data); |
|
848 | - if ($correct_pmt_form_to_use->is_valid()) { |
|
849 | - $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings'); |
|
850 | - if (! $payment_settings_subform instanceof EE_Payment_Method_Form) { |
|
851 | - throw new EE_Error( |
|
852 | - sprintf( |
|
853 | - __( |
|
854 | - 'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.', |
|
855 | - 'event_espresso' |
|
856 | - ), |
|
857 | - 'payment_method_settings' |
|
858 | - ) |
|
859 | - ); |
|
860 | - } |
|
861 | - $payment_settings_subform->save(); |
|
862 | - /** @var $pm EE_Payment_Method */ |
|
863 | - $this->_redirect_after_action( |
|
864 | - true, |
|
865 | - 'Payment Method', |
|
866 | - 'updated', |
|
867 | - array('action' => 'default', 'payment_method' => $payment_method->slug()) |
|
868 | - ); |
|
869 | - } else { |
|
870 | - EE_Error::add_error( |
|
871 | - sprintf( |
|
872 | - __( |
|
873 | - 'Payment method of type %s was not saved because there were validation errors. They have been marked in the form', |
|
874 | - 'event_espresso' |
|
875 | - ), |
|
876 | - $payment_method instanceof EE_Payment_Method ? $payment_method->type_obj()->pretty_name() |
|
877 | - : __('"(unknown)"', 'event_espresso') |
|
878 | - ), |
|
879 | - __FILE__, |
|
880 | - __FUNCTION__, |
|
881 | - __LINE__ |
|
882 | - ); |
|
883 | - } |
|
884 | - } |
|
885 | - return; |
|
886 | - } |
|
887 | - |
|
888 | - |
|
889 | - /** |
|
890 | - * Displays payment settings (not payment METHOD settings, that's _payment_method_settings) |
|
891 | - * @throws DomainException |
|
892 | - * @throws EE_Error |
|
893 | - * @throws InvalidArgumentException |
|
894 | - * @throws InvalidDataTypeException |
|
895 | - * @throws InvalidInterfaceException |
|
896 | - */ |
|
897 | - protected function _payment_settings() |
|
898 | - { |
|
899 | - $form = $this->getPaymentSettingsForm(); |
|
900 | - $this->_set_add_edit_form_tags('update_payment_settings'); |
|
901 | - $this->_set_publish_post_box_vars(null, false, false, null, false); |
|
902 | - $this->_template_args['admin_page_content'] = $form->get_html_and_js(); |
|
903 | - $this->display_admin_page_with_sidebar(); |
|
904 | - } |
|
905 | - |
|
906 | - |
|
907 | - /** |
|
908 | - * _update_payment_settings |
|
909 | - * |
|
910 | - * @access protected |
|
911 | - * @return void |
|
912 | - * @throws EE_Error |
|
913 | - * @throws InvalidArgumentException |
|
914 | - * @throws InvalidDataTypeException |
|
915 | - * @throws InvalidInterfaceException |
|
916 | - */ |
|
917 | - protected function _update_payment_settings() |
|
918 | - { |
|
919 | - $form = $this->getPaymentSettingsForm(); |
|
920 | - if ($form->was_submitted($this->_req_data)) { |
|
921 | - $form->receive_form_submission($this->_req_data); |
|
922 | - if ($form->is_valid()) { |
|
923 | - /** |
|
924 | - * @var $reg_config EE_Registration_Config |
|
925 | - */ |
|
926 | - $loader = LoaderFactory::getLoader(); |
|
927 | - $reg_config = $loader->getShared('EE_Registration_Config'); |
|
928 | - $valid_data = $form->valid_data(); |
|
929 | - $reg_config->show_pending_payment_options = $valid_data['show_pending_payment_options']; |
|
930 | - $reg_config->gateway_log_lifespan = $valid_data['gateway_log_lifespan']; |
|
931 | - } |
|
932 | - } |
|
933 | - EE_Registry::instance()->CFG = apply_filters( |
|
934 | - 'FHEE__Payments_Admin_Page___update_payment_settings__CFG', |
|
935 | - EE_Registry::instance()->CFG |
|
936 | - ); |
|
937 | - |
|
938 | - $cfg = EE_Registry::instance()->CFG ; |
|
939 | - |
|
940 | - $what = __('Payment Settings', 'event_espresso'); |
|
941 | - $success = $this->_update_espresso_configuration( |
|
942 | - $what, |
|
943 | - EE_Registry::instance()->CFG, |
|
944 | - __FILE__, |
|
945 | - __FUNCTION__, |
|
946 | - __LINE__ |
|
947 | - ); |
|
948 | - $this->_redirect_after_action( |
|
949 | - $success, |
|
950 | - $what, |
|
951 | - __('updated', 'event_espresso'), |
|
952 | - array('action' => 'payment_settings') |
|
953 | - ); |
|
954 | - } |
|
955 | - |
|
956 | - |
|
957 | - /** |
|
958 | - * Gets the form used for updating payment settings |
|
959 | - * |
|
960 | - * @return EE_Form_Section_Proper |
|
961 | - * @throws EE_Error |
|
962 | - * @throws InvalidArgumentException |
|
963 | - * @throws InvalidDataTypeException |
|
964 | - * @throws InvalidInterfaceException |
|
965 | - */ |
|
966 | - protected function getPaymentSettingsForm() |
|
967 | - { |
|
968 | - /** |
|
969 | - * @var $reg_config EE_Registration_Config |
|
970 | - */ |
|
971 | - $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config'); |
|
972 | - return new EE_Form_Section_Proper( |
|
973 | - array( |
|
974 | - 'name' => 'payment-settings', |
|
975 | - 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
976 | - 'subsections' => array( |
|
977 | - 'show_pending_payment_options' => new EE_Yes_No_Input( |
|
978 | - array( |
|
979 | - 'html_name' => 'show_pending_payment_options', |
|
980 | - 'default' => $reg_config->show_pending_payment_options, |
|
981 | - 'html_help_text' => esc_html__( |
|
982 | - "If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ", |
|
983 | - 'event_espresso' |
|
984 | - ) |
|
985 | - ) |
|
986 | - ), |
|
987 | - 'gateway_log_lifespan' => new EE_Select_Input( |
|
988 | - $reg_config->gatewayLogLifespanOptions(), |
|
989 | - array( |
|
990 | - 'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'), |
|
991 | - 'html_help_text' => esc_html__('If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.', 'event_espresso'), |
|
992 | - 'default' => $reg_config->gateway_log_lifespan, |
|
993 | - ) |
|
994 | - ) |
|
995 | - ) |
|
996 | - ) |
|
997 | - ); |
|
998 | - } |
|
999 | - |
|
1000 | - |
|
1001 | - protected function _payment_log_overview_list_table() |
|
1002 | - { |
|
1003 | - $this->display_admin_list_table_page_with_sidebar(); |
|
1004 | - } |
|
1005 | - |
|
1006 | - |
|
1007 | - protected function _set_list_table_views_payment_log() |
|
1008 | - { |
|
1009 | - $this->_views = array( |
|
1010 | - 'all' => array( |
|
1011 | - 'slug' => 'all', |
|
1012 | - 'label' => __('View All Logs', 'event_espresso'), |
|
1013 | - 'count' => 0, |
|
1014 | - ), |
|
1015 | - ); |
|
1016 | - } |
|
1017 | - |
|
1018 | - |
|
1019 | - /** |
|
1020 | - * @param int $per_page |
|
1021 | - * @param int $current_page |
|
1022 | - * @param bool $count |
|
1023 | - * @return array |
|
1024 | - */ |
|
1025 | - public function get_payment_logs($per_page = 50, $current_page = 0, $count = false) |
|
1026 | - { |
|
1027 | - EE_Registry::instance()->load_model('Change_Log'); |
|
1028 | - // we may need to do multiple queries (joining differently), so we actually wan tan array of query params |
|
1029 | - $query_params = array(array('LOG_type' => EEM_Change_Log::type_gateway)); |
|
1030 | - // check if they've selected a specific payment method |
|
1031 | - if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') { |
|
1032 | - $query_params[0]['OR*pm_or_pay_pm'] = array( |
|
1033 | - 'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'], |
|
1034 | - 'Payment_Method.PMD_ID' => $this->_req_data['_payment_method'], |
|
1035 | - ); |
|
1036 | - } |
|
1037 | - // take into account search |
|
1038 | - if (isset($this->_req_data['s']) && $this->_req_data['s']) { |
|
1039 | - $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'); |
|
1040 | - $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string; |
|
1041 | - $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string; |
|
1042 | - $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string; |
|
1043 | - $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name'] = $similarity_string; |
|
1044 | - $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name'] = $similarity_string; |
|
1045 | - $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type'] = $similarity_string; |
|
1046 | - $query_params[0]['OR*s']['LOG_message'] = $similarity_string; |
|
1047 | - $query_params[0]['OR*s']['Payment_Method.PMD_name'] = $similarity_string; |
|
1048 | - $query_params[0]['OR*s']['Payment_Method.PMD_admin_name'] = $similarity_string; |
|
1049 | - $query_params[0]['OR*s']['Payment_Method.PMD_type'] = $similarity_string; |
|
1050 | - $query_params[0]['OR*s']['LOG_message'] = $similarity_string; |
|
1051 | - } |
|
1052 | - if (isset($this->_req_data['payment-filter-start-date']) |
|
1053 | - && isset($this->_req_data['payment-filter-end-date']) |
|
1054 | - ) { |
|
1055 | - // add date |
|
1056 | - $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']); |
|
1057 | - $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']); |
|
1058 | - // make sure our timestamps start and end right at the boundaries for each day |
|
1059 | - $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00'; |
|
1060 | - $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59'; |
|
1061 | - // convert to timestamps |
|
1062 | - $start_date = strtotime($start_date); |
|
1063 | - $end_date = strtotime($end_date); |
|
1064 | - // makes sure start date is the lowest value and vice versa |
|
1065 | - $start_date = min($start_date, $end_date); |
|
1066 | - $end_date = max($start_date, $end_date); |
|
1067 | - // convert for query |
|
1068 | - $start_date = EEM_Change_Log::instance() |
|
1069 | - ->convert_datetime_for_query( |
|
1070 | - 'LOG_time', |
|
1071 | - date('Y-m-d H:i:s', $start_date), |
|
1072 | - 'Y-m-d H:i:s' |
|
1073 | - ); |
|
1074 | - $end_date = EEM_Change_Log::instance() |
|
1075 | - ->convert_datetime_for_query( |
|
1076 | - 'LOG_time', |
|
1077 | - date('Y-m-d H:i:s', $end_date), |
|
1078 | - 'Y-m-d H:i:s' |
|
1079 | - ); |
|
1080 | - $query_params[0]['LOG_time'] = array('BETWEEN', array($start_date, $end_date)); |
|
1081 | - } |
|
1082 | - if ($count) { |
|
1083 | - return EEM_Change_Log::instance()->count($query_params); |
|
1084 | - } |
|
1085 | - if (isset($this->_req_data['order'])) { |
|
1086 | - $sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] |
|
1087 | - : 'DESC'; |
|
1088 | - $query_params['order_by'] = array('LOG_time' => $sort); |
|
1089 | - } else { |
|
1090 | - $query_params['order_by'] = array('LOG_time' => 'DESC'); |
|
1091 | - } |
|
1092 | - $offset = ($current_page - 1) * $per_page; |
|
1093 | - if (! isset($this->_req_data['download_results'])) { |
|
1094 | - $query_params['limit'] = array($offset, $per_page); |
|
1095 | - } |
|
1096 | - // now they've requested to instead just download the file instead of viewing it. |
|
1097 | - if (isset($this->_req_data['download_results'])) { |
|
1098 | - $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params); |
|
1099 | - header('Content-Disposition: attachment'); |
|
1100 | - header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url())); |
|
1101 | - echo "<h1>Payment Logs for " . site_url() . "</h1>"; |
|
1102 | - echo "<h3>Query:</h3>"; |
|
1103 | - var_dump($query_params); |
|
1104 | - echo "<h3>Results:</h3>"; |
|
1105 | - var_dump($wpdb_results); |
|
1106 | - die; |
|
1107 | - } |
|
1108 | - $results = EEM_Change_Log::instance()->get_all($query_params); |
|
1109 | - return $results; |
|
1110 | - } |
|
1111 | - |
|
1112 | - |
|
1113 | - /** |
|
1114 | - * Used by usort to RE-sort log query results, because we lose the ordering |
|
1115 | - * because we're possibly combining the results from two queries |
|
1116 | - * |
|
1117 | - * @param EE_Change_Log $logA |
|
1118 | - * @param EE_Change_Log $logB |
|
1119 | - * @return int |
|
1120 | - */ |
|
1121 | - protected function _sort_logs_again($logA, $logB) |
|
1122 | - { |
|
1123 | - $timeA = $logA->get_raw('LOG_time'); |
|
1124 | - $timeB = $logB->get_raw('LOG_time'); |
|
1125 | - if ($timeA == $timeB) { |
|
1126 | - return 0; |
|
1127 | - } |
|
1128 | - $comparison = $timeA < $timeB ? -1 : 1; |
|
1129 | - if (strtoupper($this->_sort_logs_again_direction) == 'DESC') { |
|
1130 | - return $comparison * -1; |
|
1131 | - } else { |
|
1132 | - return $comparison; |
|
1133 | - } |
|
1134 | - } |
|
1135 | - |
|
1136 | - |
|
1137 | - protected function _payment_log_details() |
|
1138 | - { |
|
1139 | - EE_Registry::instance()->load_model('Change_Log'); |
|
1140 | - /** @var $payment_log EE_Change_Log */ |
|
1141 | - $payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']); |
|
1142 | - $payment_method = null; |
|
1143 | - $transaction = null; |
|
1144 | - if ($payment_log instanceof EE_Change_Log) { |
|
1145 | - if ($payment_log->object() instanceof EE_Payment) { |
|
1146 | - $payment_method = $payment_log->object()->payment_method(); |
|
1147 | - $transaction = $payment_log->object()->transaction(); |
|
1148 | - } elseif ($payment_log->object() instanceof EE_Payment_Method) { |
|
1149 | - $payment_method = $payment_log->object(); |
|
1150 | - } elseif ($payment_log->object() instanceof EE_Transaction) { |
|
1151 | - $transaction = $payment_log->object(); |
|
1152 | - $payment_method = $transaction->payment_method(); |
|
1153 | - } |
|
1154 | - } |
|
1155 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
1156 | - EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php', |
|
1157 | - array( |
|
1158 | - 'payment_log' => $payment_log, |
|
1159 | - 'payment_method' => $payment_method, |
|
1160 | - 'transaction' => $transaction, |
|
1161 | - ), |
|
1162 | - true |
|
1163 | - ); |
|
1164 | - $this->display_admin_page_with_sidebar(); |
|
1165 | - } |
|
19 | + /** |
|
20 | + * Variables used for when we're re-sorting the logs results, in case |
|
21 | + * we needed to do two queries and we need to resort |
|
22 | + * |
|
23 | + * @var string |
|
24 | + */ |
|
25 | + private $_sort_logs_again_direction; |
|
26 | + |
|
27 | + |
|
28 | + /** |
|
29 | + * @Constructor |
|
30 | + * @access public |
|
31 | + * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object. |
|
32 | + * @throws EE_Error |
|
33 | + * @throws InvalidArgumentException |
|
34 | + * @throws InvalidDataTypeException |
|
35 | + * @throws InvalidInterfaceException |
|
36 | + * @throws ReflectionException |
|
37 | + */ |
|
38 | + public function __construct($routing = true) |
|
39 | + { |
|
40 | + parent::__construct($routing); |
|
41 | + } |
|
42 | + |
|
43 | + |
|
44 | + protected function _init_page_props() |
|
45 | + { |
|
46 | + $this->page_slug = EE_PAYMENTS_PG_SLUG; |
|
47 | + $this->page_label = __('Payment Methods', 'event_espresso'); |
|
48 | + $this->_admin_base_url = EE_PAYMENTS_ADMIN_URL; |
|
49 | + $this->_admin_base_path = EE_PAYMENTS_ADMIN; |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + protected function _ajax_hooks() |
|
54 | + { |
|
55 | + // todo: all hooks for ajax goes here. |
|
56 | + } |
|
57 | + |
|
58 | + |
|
59 | + protected function _define_page_props() |
|
60 | + { |
|
61 | + $this->_admin_page_title = $this->page_label; |
|
62 | + $this->_labels = array( |
|
63 | + 'publishbox' => __('Update Settings', 'event_espresso'), |
|
64 | + ); |
|
65 | + } |
|
66 | + |
|
67 | + |
|
68 | + protected function _set_page_routes() |
|
69 | + { |
|
70 | + /** |
|
71 | + * note that with payment method capabilities, although we've implemented |
|
72 | + * capability mapping which will be used for accessing payment methods owned by |
|
73 | + * other users. This is not fully implemented yet in the payment method ui. |
|
74 | + * Currently only the "plural" caps are in active use. |
|
75 | + * When cap mapping is implemented, some routes will need to use the singular form of |
|
76 | + * capability method and also include the $id of the payment method for the route. |
|
77 | + **/ |
|
78 | + $this->_page_routes = array( |
|
79 | + 'default' => array( |
|
80 | + 'func' => '_payment_methods_list', |
|
81 | + 'capability' => 'ee_edit_payment_methods', |
|
82 | + ), |
|
83 | + 'payment_settings' => array( |
|
84 | + 'func' => '_payment_settings', |
|
85 | + 'capability' => 'ee_manage_gateways', |
|
86 | + ), |
|
87 | + 'activate_payment_method' => array( |
|
88 | + 'func' => '_activate_payment_method', |
|
89 | + 'noheader' => true, |
|
90 | + 'capability' => 'ee_edit_payment_methods', |
|
91 | + ), |
|
92 | + 'deactivate_payment_method' => array( |
|
93 | + 'func' => '_deactivate_payment_method', |
|
94 | + 'noheader' => true, |
|
95 | + 'capability' => 'ee_delete_payment_methods', |
|
96 | + ), |
|
97 | + 'update_payment_method' => array( |
|
98 | + 'func' => '_update_payment_method', |
|
99 | + 'noheader' => true, |
|
100 | + 'headers_sent_route' => 'default', |
|
101 | + 'capability' => 'ee_edit_payment_methods', |
|
102 | + ), |
|
103 | + 'update_payment_settings' => array( |
|
104 | + 'func' => '_update_payment_settings', |
|
105 | + 'noheader' => true, |
|
106 | + 'capability' => 'ee_manage_gateways', |
|
107 | + ), |
|
108 | + 'payment_log' => array( |
|
109 | + 'func' => '_payment_log_overview_list_table', |
|
110 | + 'capability' => 'ee_read_payment_methods', |
|
111 | + ), |
|
112 | + 'payment_log_details' => array( |
|
113 | + 'func' => '_payment_log_details', |
|
114 | + 'capability' => 'ee_read_payment_methods', |
|
115 | + ), |
|
116 | + ); |
|
117 | + } |
|
118 | + |
|
119 | + |
|
120 | + protected function _set_page_config() |
|
121 | + { |
|
122 | + $payment_method_list_config = array( |
|
123 | + 'nav' => array( |
|
124 | + 'label' => __('Payment Methods', 'event_espresso'), |
|
125 | + 'order' => 10, |
|
126 | + ), |
|
127 | + 'metaboxes' => $this->_default_espresso_metaboxes, |
|
128 | + 'help_tabs' => array_merge( |
|
129 | + array( |
|
130 | + 'payment_methods_overview_help_tab' => array( |
|
131 | + 'title' => __('Payment Methods Overview', 'event_espresso'), |
|
132 | + 'filename' => 'payment_methods_overview', |
|
133 | + ), |
|
134 | + ), |
|
135 | + $this->_add_payment_method_help_tabs() |
|
136 | + ), |
|
137 | + 'help_tour' => array('Payment_Methods_Selection_Help_Tour'), |
|
138 | + 'require_nonce' => false, |
|
139 | + ); |
|
140 | + $this->_page_config = array( |
|
141 | + 'default' => $payment_method_list_config, |
|
142 | + 'payment_settings' => array( |
|
143 | + 'nav' => array( |
|
144 | + 'label' => __('Settings', 'event_espresso'), |
|
145 | + 'order' => 20, |
|
146 | + ), |
|
147 | + 'help_tabs' => array( |
|
148 | + 'payment_methods_settings_help_tab' => array( |
|
149 | + 'title' => __('Payment Method Settings', 'event_espresso'), |
|
150 | + 'filename' => 'payment_methods_settings', |
|
151 | + ), |
|
152 | + ), |
|
153 | + // 'help_tour' => array( 'Payment_Methods_Settings_Help_Tour' ), |
|
154 | + 'metaboxes' => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')), |
|
155 | + 'require_nonce' => false, |
|
156 | + ), |
|
157 | + 'payment_log' => array( |
|
158 | + 'nav' => array( |
|
159 | + 'label' => __("Logs", 'event_espresso'), |
|
160 | + 'order' => 30, |
|
161 | + ), |
|
162 | + 'list_table' => 'Payment_Log_Admin_List_Table', |
|
163 | + 'metaboxes' => $this->_default_espresso_metaboxes, |
|
164 | + 'require_nonce' => false, |
|
165 | + ), |
|
166 | + ); |
|
167 | + } |
|
168 | + |
|
169 | + |
|
170 | + /** |
|
171 | + * @return array |
|
172 | + * @throws DomainException |
|
173 | + * @throws EE_Error |
|
174 | + * @throws InvalidArgumentException |
|
175 | + * @throws InvalidDataTypeException |
|
176 | + * @throws InvalidInterfaceException |
|
177 | + * @throws ReflectionException |
|
178 | + */ |
|
179 | + protected function _add_payment_method_help_tabs() |
|
180 | + { |
|
181 | + EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
182 | + $payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types(); |
|
183 | + $all_pmt_help_tabs_config = array(); |
|
184 | + foreach ($payment_method_types as $payment_method_type) { |
|
185 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
186 | + $payment_method_type->cap_name(), |
|
187 | + 'specific_payment_method_type_access' |
|
188 | + ) |
|
189 | + ) { |
|
190 | + continue; |
|
191 | + } |
|
192 | + foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) { |
|
193 | + $template_args = isset($config['template_args']) ? $config['template_args'] : array(); |
|
194 | + $template_args['admin_page_obj'] = $this; |
|
195 | + $all_pmt_help_tabs_config[ $help_tab_name ] = array( |
|
196 | + 'title' => $config['title'], |
|
197 | + 'content' => EEH_Template::display_template( |
|
198 | + $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php', |
|
199 | + $template_args, |
|
200 | + true |
|
201 | + ), |
|
202 | + ); |
|
203 | + } |
|
204 | + } |
|
205 | + return $all_pmt_help_tabs_config; |
|
206 | + } |
|
207 | + |
|
208 | + |
|
209 | + // none of the below group are currently used for Gateway Settings |
|
210 | + protected function _add_screen_options() |
|
211 | + { |
|
212 | + } |
|
213 | + |
|
214 | + |
|
215 | + protected function _add_feature_pointers() |
|
216 | + { |
|
217 | + } |
|
218 | + |
|
219 | + |
|
220 | + public function admin_init() |
|
221 | + { |
|
222 | + } |
|
223 | + |
|
224 | + |
|
225 | + public function admin_notices() |
|
226 | + { |
|
227 | + } |
|
228 | + |
|
229 | + |
|
230 | + public function admin_footer_scripts() |
|
231 | + { |
|
232 | + } |
|
233 | + |
|
234 | + |
|
235 | + public function load_scripts_styles() |
|
236 | + { |
|
237 | + wp_enqueue_script('ee_admin_js'); |
|
238 | + wp_enqueue_script('ee-text-links'); |
|
239 | + wp_enqueue_script( |
|
240 | + 'espresso_payments', |
|
241 | + EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js', |
|
242 | + ['ee-datepicker'], |
|
243 | + EVENT_ESPRESSO_VERSION, |
|
244 | + true |
|
245 | + ); |
|
246 | + wp_enqueue_style('espresso-ui-theme'); |
|
247 | + } |
|
248 | + |
|
249 | + |
|
250 | + public function load_scripts_styles_default() |
|
251 | + { |
|
252 | + // styles |
|
253 | + wp_register_style( |
|
254 | + 'espresso_payments', |
|
255 | + EE_PAYMENTS_ASSETS_URL . 'ee-payments.css', |
|
256 | + array(), |
|
257 | + EVENT_ESPRESSO_VERSION |
|
258 | + ); |
|
259 | + wp_enqueue_style('espresso_payments'); |
|
260 | + wp_enqueue_style('ee-text-links'); |
|
261 | + // scripts |
|
262 | + } |
|
263 | + |
|
264 | + |
|
265 | + protected function _payment_methods_list() |
|
266 | + { |
|
267 | + /** |
|
268 | + * first let's ensure payment methods have been setup. We do this here because when people activate a |
|
269 | + * payment method for the first time (as an addon), it may not setup its capabilities or get registered |
|
270 | + * correctly due to the loading process. However, people MUST setup the details for the payment method so its |
|
271 | + * safe to do a recheck here. |
|
272 | + */ |
|
273 | + EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
274 | + EEM_Payment_Method::instance()->verify_button_urls(); |
|
275 | + // setup tabs, one for each payment method type |
|
276 | + $tabs = array(); |
|
277 | + $payment_methods = array(); |
|
278 | + foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) { |
|
279 | + // we don't want to show admin-only PMTs for now |
|
280 | + if ($pmt_obj instanceof EE_PMT_Admin_Only) { |
|
281 | + continue; |
|
282 | + } |
|
283 | + // check access |
|
284 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
285 | + $pmt_obj->cap_name(), |
|
286 | + 'specific_payment_method_type_access' |
|
287 | + ) |
|
288 | + ) { |
|
289 | + continue; |
|
290 | + } |
|
291 | + // check for any active pms of that type |
|
292 | + $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name()); |
|
293 | + if (! $payment_method instanceof EE_Payment_Method) { |
|
294 | + $payment_method = EE_Payment_Method::new_instance( |
|
295 | + array( |
|
296 | + 'PMD_slug' => sanitize_key($pmt_obj->system_name()), |
|
297 | + 'PMD_type' => $pmt_obj->system_name(), |
|
298 | + 'PMD_name' => $pmt_obj->pretty_name(), |
|
299 | + 'PMD_admin_name' => $pmt_obj->pretty_name(), |
|
300 | + ) |
|
301 | + ); |
|
302 | + } |
|
303 | + $payment_methods[ $payment_method->slug() ] = $payment_method; |
|
304 | + } |
|
305 | + $payment_methods = apply_filters( |
|
306 | + 'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods', |
|
307 | + $payment_methods |
|
308 | + ); |
|
309 | + foreach ($payment_methods as $payment_method) { |
|
310 | + if ($payment_method instanceof EE_Payment_Method) { |
|
311 | + add_meta_box( |
|
312 | + // html id |
|
313 | + 'espresso_' . $payment_method->slug() . '_payment_settings', |
|
314 | + // title |
|
315 | + sprintf(__('%s Settings', 'event_espresso'), $payment_method->admin_name()), |
|
316 | + // callback |
|
317 | + array($this, 'payment_method_settings_meta_box'), |
|
318 | + // post type |
|
319 | + null, |
|
320 | + // context |
|
321 | + 'normal', |
|
322 | + // priority |
|
323 | + 'default', |
|
324 | + // callback args |
|
325 | + array('payment_method' => $payment_method) |
|
326 | + ); |
|
327 | + // setup for tabbed content |
|
328 | + $tabs[ $payment_method->slug() ] = array( |
|
329 | + 'label' => $payment_method->admin_name(), |
|
330 | + 'class' => $payment_method->active() ? 'gateway-active' : '', |
|
331 | + 'href' => 'espresso_' . $payment_method->slug() . '_payment_settings', |
|
332 | + 'title' => __('Modify this Payment Method', 'event_espresso'), |
|
333 | + 'slug' => $payment_method->slug(), |
|
334 | + ); |
|
335 | + } |
|
336 | + } |
|
337 | + $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links( |
|
338 | + $tabs, |
|
339 | + 'payment_method_links', |
|
340 | + '|', |
|
341 | + $this->_get_active_payment_method_slug() |
|
342 | + ); |
|
343 | + $this->display_admin_page_with_sidebar(); |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + /** |
|
348 | + * _get_active_payment_method_slug |
|
349 | + * |
|
350 | + * @return string |
|
351 | + */ |
|
352 | + protected function _get_active_payment_method_slug() |
|
353 | + { |
|
354 | + $payment_method_slug = false; |
|
355 | + // decide which payment method tab to open first, as dictated by the request's 'payment_method' |
|
356 | + if (isset($this->_req_data['payment_method'])) { |
|
357 | + // if they provided the current payment method, use it |
|
358 | + $payment_method_slug = sanitize_key($this->_req_data['payment_method']); |
|
359 | + } |
|
360 | + $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug))); |
|
361 | + // if that didn't work or wasn't provided, find another way to select the current pm |
|
362 | + if (! $this->_verify_payment_method($payment_method)) { |
|
363 | + // like, looking for an active one |
|
364 | + $payment_method = EEM_Payment_Method::instance()->get_one_active('CART'); |
|
365 | + // test that one as well |
|
366 | + if ($this->_verify_payment_method($payment_method)) { |
|
367 | + $payment_method_slug = $payment_method->slug(); |
|
368 | + } else { |
|
369 | + $payment_method_slug = 'paypal_standard'; |
|
370 | + } |
|
371 | + } |
|
372 | + return $payment_method_slug; |
|
373 | + } |
|
374 | + |
|
375 | + |
|
376 | + /** |
|
377 | + * payment_method_settings_meta_box |
|
378 | + * returns TRUE if the passed payment method is properly constructed and the logged in user has the correct |
|
379 | + * capabilities to access it |
|
380 | + * |
|
381 | + * @param EE_Payment_Method $payment_method |
|
382 | + * @return boolean |
|
383 | + */ |
|
384 | + protected function _verify_payment_method($payment_method) |
|
385 | + { |
|
386 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base |
|
387 | + && EE_Registry::instance()->CAP->current_user_can( |
|
388 | + $payment_method->type_obj()->cap_name(), |
|
389 | + 'specific_payment_method_type_access' |
|
390 | + ) |
|
391 | + ) { |
|
392 | + return true; |
|
393 | + } |
|
394 | + return false; |
|
395 | + } |
|
396 | + |
|
397 | + |
|
398 | + /** |
|
399 | + * payment_method_settings_meta_box |
|
400 | + * |
|
401 | + * @param NULL $post_obj_which_is_null is an object containing the current post (as a $post object) |
|
402 | + * @param array $metabox is an array with metabox id, title, callback, and args elements. the value |
|
403 | + * at 'args' has key 'payment_method', as set within _payment_methods_list |
|
404 | + * @return string |
|
405 | + * @throws EE_Error |
|
406 | + */ |
|
407 | + public function payment_method_settings_meta_box($post_obj_which_is_null, $metabox) |
|
408 | + { |
|
409 | + $payment_method = isset($metabox['args'], $metabox['args']['payment_method']) |
|
410 | + ? $metabox['args']['payment_method'] : null; |
|
411 | + if (! $payment_method instanceof EE_Payment_Method) { |
|
412 | + throw new EE_Error( |
|
413 | + sprintf( |
|
414 | + __( |
|
415 | + 'Payment method metabox setup incorrectly. No Payment method object was supplied', |
|
416 | + 'event_espresso' |
|
417 | + ) |
|
418 | + ) |
|
419 | + ); |
|
420 | + } |
|
421 | + $payment_method_scopes = $payment_method->active(); |
|
422 | + // if the payment method really exists show its form, otherwise the activation template |
|
423 | + if ($payment_method->ID() && ! empty($payment_method_scopes)) { |
|
424 | + $form = $this->_generate_payment_method_settings_form($payment_method); |
|
425 | + if ($form->form_data_present_in($this->_req_data)) { |
|
426 | + $form->receive_form_submission($this->_req_data); |
|
427 | + } |
|
428 | + echo $form->form_open() . $form->get_html_and_js() . $form->form_close(); |
|
429 | + } else { |
|
430 | + echo $this->_activate_payment_method_button($payment_method)->get_html_and_js(); |
|
431 | + } |
|
432 | + } |
|
433 | + |
|
434 | + |
|
435 | + /** |
|
436 | + * Gets the form for all the settings related to this payment method type |
|
437 | + * |
|
438 | + * @access protected |
|
439 | + * @param EE_Payment_Method $payment_method |
|
440 | + * @return EE_Form_Section_Proper |
|
441 | + */ |
|
442 | + protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method) |
|
443 | + { |
|
444 | + if (! $payment_method instanceof EE_Payment_Method) { |
|
445 | + return new EE_Form_Section_Proper(); |
|
446 | + } |
|
447 | + return new EE_Form_Section_Proper( |
|
448 | + array( |
|
449 | + 'name' => $payment_method->slug() . '_settings_form', |
|
450 | + 'html_id' => $payment_method->slug() . '_settings_form', |
|
451 | + 'action' => EE_Admin_Page::add_query_args_and_nonce( |
|
452 | + array( |
|
453 | + 'action' => 'update_payment_method', |
|
454 | + 'payment_method' => $payment_method->slug(), |
|
455 | + ), |
|
456 | + EE_PAYMENTS_ADMIN_URL |
|
457 | + ), |
|
458 | + 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
459 | + 'subsections' => apply_filters( |
|
460 | + 'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections', |
|
461 | + array( |
|
462 | + 'pci_dss_compliance' => $this->_pci_dss_compliance($payment_method), |
|
463 | + 'currency_support' => $this->_currency_support($payment_method), |
|
464 | + 'payment_method_settings' => $this->_payment_method_settings($payment_method), |
|
465 | + 'update' => $this->_update_payment_method_button($payment_method), |
|
466 | + 'deactivate' => $this->_deactivate_payment_method_button($payment_method), |
|
467 | + 'fine_print' => $this->_fine_print(), |
|
468 | + ), |
|
469 | + $payment_method |
|
470 | + ), |
|
471 | + ) |
|
472 | + ); |
|
473 | + } |
|
474 | + |
|
475 | + |
|
476 | + /** |
|
477 | + * _pci_dss_compliance |
|
478 | + * |
|
479 | + * @access protected |
|
480 | + * @param EE_Payment_Method $payment_method |
|
481 | + * @return EE_Form_Section_Proper |
|
482 | + */ |
|
483 | + protected function _pci_dss_compliance(EE_Payment_Method $payment_method) |
|
484 | + { |
|
485 | + if ($payment_method->type_obj()->requires_https()) { |
|
486 | + return new EE_Form_Section_HTML( |
|
487 | + EEH_HTML::table( |
|
488 | + EEH_HTML::tr( |
|
489 | + EEH_HTML::th( |
|
490 | + EEH_HTML::label( |
|
491 | + EEH_HTML::strong(__('IMPORTANT', 'event_espresso'), '', 'important-notice') |
|
492 | + ) |
|
493 | + ) . |
|
494 | + EEH_HTML::td( |
|
495 | + EEH_HTML::strong( |
|
496 | + __( |
|
497 | + 'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.', |
|
498 | + 'event_espresso' |
|
499 | + ) |
|
500 | + ) |
|
501 | + . |
|
502 | + EEH_HTML::br() |
|
503 | + . |
|
504 | + __('Learn more about ', 'event_espresso') |
|
505 | + . EEH_HTML::link( |
|
506 | + 'https://www.pcisecuritystandards.org/merchants/index.php', |
|
507 | + __('PCI DSS compliance', 'event_espresso') |
|
508 | + ) |
|
509 | + ) |
|
510 | + ) |
|
511 | + ) |
|
512 | + ); |
|
513 | + } else { |
|
514 | + return new EE_Form_Section_HTML(''); |
|
515 | + } |
|
516 | + } |
|
517 | + |
|
518 | + |
|
519 | + /** |
|
520 | + * _currency_support |
|
521 | + * |
|
522 | + * @access protected |
|
523 | + * @param EE_Payment_Method $payment_method |
|
524 | + * @return EE_Form_Section_Proper |
|
525 | + */ |
|
526 | + protected function _currency_support(EE_Payment_Method $payment_method) |
|
527 | + { |
|
528 | + if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) { |
|
529 | + return new EE_Form_Section_HTML( |
|
530 | + EEH_HTML::table( |
|
531 | + EEH_HTML::tr( |
|
532 | + EEH_HTML::th( |
|
533 | + EEH_HTML::label( |
|
534 | + EEH_HTML::strong(__('IMPORTANT', 'event_espresso'), '', 'important-notice') |
|
535 | + ) |
|
536 | + ) . |
|
537 | + EEH_HTML::td( |
|
538 | + EEH_HTML::strong( |
|
539 | + sprintf( |
|
540 | + __( |
|
541 | + 'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.', |
|
542 | + 'event_espresso' |
|
543 | + ), |
|
544 | + EE_Config::instance()->currency->code |
|
545 | + ) |
|
546 | + ) |
|
547 | + ) |
|
548 | + ) |
|
549 | + ) |
|
550 | + ); |
|
551 | + } else { |
|
552 | + return new EE_Form_Section_HTML(''); |
|
553 | + } |
|
554 | + } |
|
555 | + |
|
556 | + |
|
557 | + /** |
|
558 | + * _update_payment_method_button |
|
559 | + * |
|
560 | + * @access protected |
|
561 | + * @param EE_Payment_Method $payment_method |
|
562 | + * @return EE_Payment_Method_Form |
|
563 | + */ |
|
564 | + protected function _payment_method_settings(EE_Payment_Method $payment_method) |
|
565 | + { |
|
566 | + // modify the form so we only have/show fields that will be implemented for this version |
|
567 | + return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name()); |
|
568 | + } |
|
569 | + |
|
570 | + |
|
571 | + /** |
|
572 | + * Simplifies the form to merely reproduce 4.1's gateway settings functionality |
|
573 | + * |
|
574 | + * @param EE_Form_Section_Proper $form_section |
|
575 | + * @param string $payment_method_name |
|
576 | + * @return EE_Payment_Method_Form |
|
577 | + * @throws EE_Error |
|
578 | + */ |
|
579 | + protected function _simplify_form($form_section, $payment_method_name = '') |
|
580 | + { |
|
581 | + if ($form_section instanceof EE_Payment_Method_Form) { |
|
582 | + $form_section->exclude( |
|
583 | + array( |
|
584 | + 'PMD_type', // dont want them changing the type |
|
585 | + 'PMD_slug', // or the slug (probably never) |
|
586 | + 'PMD_wp_user', // or the user's ID |
|
587 | + 'Currency' // or the currency, until the rest of EE supports simultaneous currencies |
|
588 | + ) |
|
589 | + ); |
|
590 | + return $form_section; |
|
591 | + } else { |
|
592 | + throw new EE_Error( |
|
593 | + sprintf( |
|
594 | + __( |
|
595 | + 'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.', |
|
596 | + 'event_espresso' |
|
597 | + ), |
|
598 | + $payment_method_name |
|
599 | + ) |
|
600 | + ); |
|
601 | + } |
|
602 | + } |
|
603 | + |
|
604 | + |
|
605 | + /** |
|
606 | + * _update_payment_method_button |
|
607 | + * |
|
608 | + * @access protected |
|
609 | + * @param EE_Payment_Method $payment_method |
|
610 | + * @return EE_Form_Section_HTML |
|
611 | + */ |
|
612 | + protected function _update_payment_method_button(EE_Payment_Method $payment_method) |
|
613 | + { |
|
614 | + $update_button = new EE_Submit_Input( |
|
615 | + array( |
|
616 | + 'name' => 'submit', |
|
617 | + 'html_id' => 'save_' . $payment_method->slug() . '_settings', |
|
618 | + 'default' => sprintf( |
|
619 | + __('Update %s Payment Settings', 'event_espresso'), |
|
620 | + $payment_method->admin_name() |
|
621 | + ), |
|
622 | + 'html_label' => EEH_HTML::nbsp(), |
|
623 | + ) |
|
624 | + ); |
|
625 | + return new EE_Form_Section_HTML( |
|
626 | + EEH_HTML::table( |
|
627 | + EEH_HTML::no_row(EEH_HTML::br(2)) . |
|
628 | + EEH_HTML::tr( |
|
629 | + EEH_HTML::th(__('Update Settings', 'event_espresso')) . |
|
630 | + EEH_HTML::td( |
|
631 | + $update_button->get_html_for_input() |
|
632 | + ) |
|
633 | + ) |
|
634 | + ) |
|
635 | + ); |
|
636 | + } |
|
637 | + |
|
638 | + |
|
639 | + /** |
|
640 | + * _deactivate_payment_method_button |
|
641 | + * |
|
642 | + * @access protected |
|
643 | + * @param EE_Payment_Method $payment_method |
|
644 | + * @return EE_Form_Section_Proper |
|
645 | + */ |
|
646 | + protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method) |
|
647 | + { |
|
648 | + $link_text_and_title = sprintf( |
|
649 | + __('Deactivate %1$s Payments?', 'event_espresso'), |
|
650 | + $payment_method->admin_name() |
|
651 | + ); |
|
652 | + return new EE_Form_Section_HTML( |
|
653 | + EEH_HTML::table( |
|
654 | + EEH_HTML::tr( |
|
655 | + EEH_HTML::th(__('Deactivate Payment Method', 'event_espresso')) . |
|
656 | + EEH_HTML::td( |
|
657 | + EEH_HTML::link( |
|
658 | + EE_Admin_Page::add_query_args_and_nonce( |
|
659 | + array( |
|
660 | + 'action' => 'deactivate_payment_method', |
|
661 | + 'payment_method' => $payment_method->slug(), |
|
662 | + ), |
|
663 | + EE_PAYMENTS_ADMIN_URL |
|
664 | + ), |
|
665 | + $link_text_and_title, |
|
666 | + $link_text_and_title, |
|
667 | + 'deactivate_' . $payment_method->slug(), |
|
668 | + 'espresso-button button-secondary' |
|
669 | + ) |
|
670 | + ) |
|
671 | + ) |
|
672 | + ) |
|
673 | + ); |
|
674 | + } |
|
675 | + |
|
676 | + |
|
677 | + /** |
|
678 | + * _activate_payment_method_button |
|
679 | + * |
|
680 | + * @access protected |
|
681 | + * @param EE_Payment_Method $payment_method |
|
682 | + * @return EE_Form_Section_Proper |
|
683 | + */ |
|
684 | + protected function _activate_payment_method_button(EE_Payment_Method $payment_method) |
|
685 | + { |
|
686 | + $link_text_and_title = sprintf( |
|
687 | + __('Activate %1$s Payment Method?', 'event_espresso'), |
|
688 | + $payment_method->admin_name() |
|
689 | + ); |
|
690 | + return new EE_Form_Section_Proper( |
|
691 | + array( |
|
692 | + 'name' => 'activate_' . $payment_method->slug() . '_settings_form', |
|
693 | + 'html_id' => 'activate_' . $payment_method->slug() . '_settings_form', |
|
694 | + 'action' => '#', |
|
695 | + 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
696 | + 'subsections' => apply_filters( |
|
697 | + 'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections', |
|
698 | + array( |
|
699 | + new EE_Form_Section_HTML( |
|
700 | + EEH_HTML::table( |
|
701 | + EEH_HTML::tr( |
|
702 | + EEH_HTML::td( |
|
703 | + $payment_method->type_obj()->introductory_html(), |
|
704 | + '', |
|
705 | + '', |
|
706 | + '', |
|
707 | + 'colspan="2"' |
|
708 | + ) |
|
709 | + ) . |
|
710 | + EEH_HTML::tr( |
|
711 | + EEH_HTML::th( |
|
712 | + EEH_HTML::label(__('Click to Activate ', 'event_espresso')) |
|
713 | + ) . |
|
714 | + EEH_HTML::td( |
|
715 | + EEH_HTML::link( |
|
716 | + EE_Admin_Page::add_query_args_and_nonce( |
|
717 | + array( |
|
718 | + 'action' => 'activate_payment_method', |
|
719 | + 'payment_method_type' => $payment_method->type(), |
|
720 | + ), |
|
721 | + EE_PAYMENTS_ADMIN_URL |
|
722 | + ), |
|
723 | + $link_text_and_title, |
|
724 | + $link_text_and_title, |
|
725 | + 'activate_' . $payment_method->slug(), |
|
726 | + 'espresso-button-green button-primary' |
|
727 | + ) |
|
728 | + ) |
|
729 | + ) |
|
730 | + ) |
|
731 | + ), |
|
732 | + ), |
|
733 | + $payment_method |
|
734 | + ), |
|
735 | + ) |
|
736 | + ); |
|
737 | + } |
|
738 | + |
|
739 | + |
|
740 | + /** |
|
741 | + * _fine_print |
|
742 | + * |
|
743 | + * @access protected |
|
744 | + * @return EE_Form_Section_HTML |
|
745 | + */ |
|
746 | + protected function _fine_print() |
|
747 | + { |
|
748 | + return new EE_Form_Section_HTML( |
|
749 | + EEH_HTML::table( |
|
750 | + EEH_HTML::tr( |
|
751 | + EEH_HTML::th() . |
|
752 | + EEH_HTML::td( |
|
753 | + EEH_HTML::p(__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text') |
|
754 | + ) |
|
755 | + ) |
|
756 | + ) |
|
757 | + ); |
|
758 | + } |
|
759 | + |
|
760 | + |
|
761 | + /** |
|
762 | + * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far) |
|
763 | + * |
|
764 | + * @global WP_User $current_user |
|
765 | + */ |
|
766 | + protected function _activate_payment_method() |
|
767 | + { |
|
768 | + if (isset($this->_req_data['payment_method_type'])) { |
|
769 | + $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']); |
|
770 | + // see if one exists |
|
771 | + EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
772 | + $payment_method = EE_Payment_Method_Manager::instance() |
|
773 | + ->activate_a_payment_method_of_type($payment_method_type); |
|
774 | + $this->_redirect_after_action( |
|
775 | + 1, |
|
776 | + 'Payment Method', |
|
777 | + 'activated', |
|
778 | + array('action' => 'default', 'payment_method' => $payment_method->slug()) |
|
779 | + ); |
|
780 | + } else { |
|
781 | + $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default')); |
|
782 | + } |
|
783 | + } |
|
784 | + |
|
785 | + |
|
786 | + /** |
|
787 | + * Deactivates the payment method with the specified slug, and redirects. |
|
788 | + */ |
|
789 | + protected function _deactivate_payment_method() |
|
790 | + { |
|
791 | + if (isset($this->_req_data['payment_method'])) { |
|
792 | + $payment_method_slug = sanitize_key($this->_req_data['payment_method']); |
|
793 | + // deactivate it |
|
794 | + EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
795 | + $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug); |
|
796 | + $this->_redirect_after_action( |
|
797 | + $count_updated, |
|
798 | + 'Payment Method', |
|
799 | + 'deactivated', |
|
800 | + array('action' => 'default', 'payment_method' => $payment_method_slug) |
|
801 | + ); |
|
802 | + } else { |
|
803 | + $this->_redirect_after_action(false, 'Payment Method', 'deactivated', array('action' => 'default')); |
|
804 | + } |
|
805 | + } |
|
806 | + |
|
807 | + |
|
808 | + /** |
|
809 | + * Processes the payment method form that was submitted. This is slightly trickier than usual form |
|
810 | + * processing because we first need to identify WHICH form was processed and which payment method |
|
811 | + * it corresponds to. Once we have done that, we see if the form is valid. If it is, the |
|
812 | + * form's data is saved and we redirect to the default payment methods page, setting the updated payment method |
|
813 | + * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the |
|
814 | + * subsequently called 'headers_sent_func' which is _payment_methods_list) |
|
815 | + * |
|
816 | + * @return void |
|
817 | + */ |
|
818 | + protected function _update_payment_method() |
|
819 | + { |
|
820 | + if ($_SERVER['REQUEST_METHOD'] == 'POST') { |
|
821 | + // ok let's find which gateway form to use based on the form input |
|
822 | + EE_Registry::instance()->load_lib('Payment_Method_Manager'); |
|
823 | + /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */ |
|
824 | + $correct_pmt_form_to_use = null; |
|
825 | + $payment_method = null; |
|
826 | + foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) { |
|
827 | + // get the form and simplify it, like what we do when we display it |
|
828 | + $pmt_form = $this->_generate_payment_method_settings_form($payment_method); |
|
829 | + if ($pmt_form->form_data_present_in($this->_req_data)) { |
|
830 | + $correct_pmt_form_to_use = $pmt_form; |
|
831 | + break; |
|
832 | + } |
|
833 | + } |
|
834 | + // if we couldn't find the correct payment method type... |
|
835 | + if (! $correct_pmt_form_to_use) { |
|
836 | + EE_Error::add_error( |
|
837 | + __( |
|
838 | + "We could not find which payment method type your form submission related to. Please contact support", |
|
839 | + 'event_espresso' |
|
840 | + ), |
|
841 | + __FILE__, |
|
842 | + __FUNCTION__, |
|
843 | + __LINE__ |
|
844 | + ); |
|
845 | + $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default')); |
|
846 | + } |
|
847 | + $correct_pmt_form_to_use->receive_form_submission($this->_req_data); |
|
848 | + if ($correct_pmt_form_to_use->is_valid()) { |
|
849 | + $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings'); |
|
850 | + if (! $payment_settings_subform instanceof EE_Payment_Method_Form) { |
|
851 | + throw new EE_Error( |
|
852 | + sprintf( |
|
853 | + __( |
|
854 | + 'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.', |
|
855 | + 'event_espresso' |
|
856 | + ), |
|
857 | + 'payment_method_settings' |
|
858 | + ) |
|
859 | + ); |
|
860 | + } |
|
861 | + $payment_settings_subform->save(); |
|
862 | + /** @var $pm EE_Payment_Method */ |
|
863 | + $this->_redirect_after_action( |
|
864 | + true, |
|
865 | + 'Payment Method', |
|
866 | + 'updated', |
|
867 | + array('action' => 'default', 'payment_method' => $payment_method->slug()) |
|
868 | + ); |
|
869 | + } else { |
|
870 | + EE_Error::add_error( |
|
871 | + sprintf( |
|
872 | + __( |
|
873 | + 'Payment method of type %s was not saved because there were validation errors. They have been marked in the form', |
|
874 | + 'event_espresso' |
|
875 | + ), |
|
876 | + $payment_method instanceof EE_Payment_Method ? $payment_method->type_obj()->pretty_name() |
|
877 | + : __('"(unknown)"', 'event_espresso') |
|
878 | + ), |
|
879 | + __FILE__, |
|
880 | + __FUNCTION__, |
|
881 | + __LINE__ |
|
882 | + ); |
|
883 | + } |
|
884 | + } |
|
885 | + return; |
|
886 | + } |
|
887 | + |
|
888 | + |
|
889 | + /** |
|
890 | + * Displays payment settings (not payment METHOD settings, that's _payment_method_settings) |
|
891 | + * @throws DomainException |
|
892 | + * @throws EE_Error |
|
893 | + * @throws InvalidArgumentException |
|
894 | + * @throws InvalidDataTypeException |
|
895 | + * @throws InvalidInterfaceException |
|
896 | + */ |
|
897 | + protected function _payment_settings() |
|
898 | + { |
|
899 | + $form = $this->getPaymentSettingsForm(); |
|
900 | + $this->_set_add_edit_form_tags('update_payment_settings'); |
|
901 | + $this->_set_publish_post_box_vars(null, false, false, null, false); |
|
902 | + $this->_template_args['admin_page_content'] = $form->get_html_and_js(); |
|
903 | + $this->display_admin_page_with_sidebar(); |
|
904 | + } |
|
905 | + |
|
906 | + |
|
907 | + /** |
|
908 | + * _update_payment_settings |
|
909 | + * |
|
910 | + * @access protected |
|
911 | + * @return void |
|
912 | + * @throws EE_Error |
|
913 | + * @throws InvalidArgumentException |
|
914 | + * @throws InvalidDataTypeException |
|
915 | + * @throws InvalidInterfaceException |
|
916 | + */ |
|
917 | + protected function _update_payment_settings() |
|
918 | + { |
|
919 | + $form = $this->getPaymentSettingsForm(); |
|
920 | + if ($form->was_submitted($this->_req_data)) { |
|
921 | + $form->receive_form_submission($this->_req_data); |
|
922 | + if ($form->is_valid()) { |
|
923 | + /** |
|
924 | + * @var $reg_config EE_Registration_Config |
|
925 | + */ |
|
926 | + $loader = LoaderFactory::getLoader(); |
|
927 | + $reg_config = $loader->getShared('EE_Registration_Config'); |
|
928 | + $valid_data = $form->valid_data(); |
|
929 | + $reg_config->show_pending_payment_options = $valid_data['show_pending_payment_options']; |
|
930 | + $reg_config->gateway_log_lifespan = $valid_data['gateway_log_lifespan']; |
|
931 | + } |
|
932 | + } |
|
933 | + EE_Registry::instance()->CFG = apply_filters( |
|
934 | + 'FHEE__Payments_Admin_Page___update_payment_settings__CFG', |
|
935 | + EE_Registry::instance()->CFG |
|
936 | + ); |
|
937 | + |
|
938 | + $cfg = EE_Registry::instance()->CFG ; |
|
939 | + |
|
940 | + $what = __('Payment Settings', 'event_espresso'); |
|
941 | + $success = $this->_update_espresso_configuration( |
|
942 | + $what, |
|
943 | + EE_Registry::instance()->CFG, |
|
944 | + __FILE__, |
|
945 | + __FUNCTION__, |
|
946 | + __LINE__ |
|
947 | + ); |
|
948 | + $this->_redirect_after_action( |
|
949 | + $success, |
|
950 | + $what, |
|
951 | + __('updated', 'event_espresso'), |
|
952 | + array('action' => 'payment_settings') |
|
953 | + ); |
|
954 | + } |
|
955 | + |
|
956 | + |
|
957 | + /** |
|
958 | + * Gets the form used for updating payment settings |
|
959 | + * |
|
960 | + * @return EE_Form_Section_Proper |
|
961 | + * @throws EE_Error |
|
962 | + * @throws InvalidArgumentException |
|
963 | + * @throws InvalidDataTypeException |
|
964 | + * @throws InvalidInterfaceException |
|
965 | + */ |
|
966 | + protected function getPaymentSettingsForm() |
|
967 | + { |
|
968 | + /** |
|
969 | + * @var $reg_config EE_Registration_Config |
|
970 | + */ |
|
971 | + $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config'); |
|
972 | + return new EE_Form_Section_Proper( |
|
973 | + array( |
|
974 | + 'name' => 'payment-settings', |
|
975 | + 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
976 | + 'subsections' => array( |
|
977 | + 'show_pending_payment_options' => new EE_Yes_No_Input( |
|
978 | + array( |
|
979 | + 'html_name' => 'show_pending_payment_options', |
|
980 | + 'default' => $reg_config->show_pending_payment_options, |
|
981 | + 'html_help_text' => esc_html__( |
|
982 | + "If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ", |
|
983 | + 'event_espresso' |
|
984 | + ) |
|
985 | + ) |
|
986 | + ), |
|
987 | + 'gateway_log_lifespan' => new EE_Select_Input( |
|
988 | + $reg_config->gatewayLogLifespanOptions(), |
|
989 | + array( |
|
990 | + 'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'), |
|
991 | + 'html_help_text' => esc_html__('If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.', 'event_espresso'), |
|
992 | + 'default' => $reg_config->gateway_log_lifespan, |
|
993 | + ) |
|
994 | + ) |
|
995 | + ) |
|
996 | + ) |
|
997 | + ); |
|
998 | + } |
|
999 | + |
|
1000 | + |
|
1001 | + protected function _payment_log_overview_list_table() |
|
1002 | + { |
|
1003 | + $this->display_admin_list_table_page_with_sidebar(); |
|
1004 | + } |
|
1005 | + |
|
1006 | + |
|
1007 | + protected function _set_list_table_views_payment_log() |
|
1008 | + { |
|
1009 | + $this->_views = array( |
|
1010 | + 'all' => array( |
|
1011 | + 'slug' => 'all', |
|
1012 | + 'label' => __('View All Logs', 'event_espresso'), |
|
1013 | + 'count' => 0, |
|
1014 | + ), |
|
1015 | + ); |
|
1016 | + } |
|
1017 | + |
|
1018 | + |
|
1019 | + /** |
|
1020 | + * @param int $per_page |
|
1021 | + * @param int $current_page |
|
1022 | + * @param bool $count |
|
1023 | + * @return array |
|
1024 | + */ |
|
1025 | + public function get_payment_logs($per_page = 50, $current_page = 0, $count = false) |
|
1026 | + { |
|
1027 | + EE_Registry::instance()->load_model('Change_Log'); |
|
1028 | + // we may need to do multiple queries (joining differently), so we actually wan tan array of query params |
|
1029 | + $query_params = array(array('LOG_type' => EEM_Change_Log::type_gateway)); |
|
1030 | + // check if they've selected a specific payment method |
|
1031 | + if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') { |
|
1032 | + $query_params[0]['OR*pm_or_pay_pm'] = array( |
|
1033 | + 'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'], |
|
1034 | + 'Payment_Method.PMD_ID' => $this->_req_data['_payment_method'], |
|
1035 | + ); |
|
1036 | + } |
|
1037 | + // take into account search |
|
1038 | + if (isset($this->_req_data['s']) && $this->_req_data['s']) { |
|
1039 | + $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'); |
|
1040 | + $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string; |
|
1041 | + $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string; |
|
1042 | + $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string; |
|
1043 | + $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name'] = $similarity_string; |
|
1044 | + $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name'] = $similarity_string; |
|
1045 | + $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type'] = $similarity_string; |
|
1046 | + $query_params[0]['OR*s']['LOG_message'] = $similarity_string; |
|
1047 | + $query_params[0]['OR*s']['Payment_Method.PMD_name'] = $similarity_string; |
|
1048 | + $query_params[0]['OR*s']['Payment_Method.PMD_admin_name'] = $similarity_string; |
|
1049 | + $query_params[0]['OR*s']['Payment_Method.PMD_type'] = $similarity_string; |
|
1050 | + $query_params[0]['OR*s']['LOG_message'] = $similarity_string; |
|
1051 | + } |
|
1052 | + if (isset($this->_req_data['payment-filter-start-date']) |
|
1053 | + && isset($this->_req_data['payment-filter-end-date']) |
|
1054 | + ) { |
|
1055 | + // add date |
|
1056 | + $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']); |
|
1057 | + $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']); |
|
1058 | + // make sure our timestamps start and end right at the boundaries for each day |
|
1059 | + $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00'; |
|
1060 | + $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59'; |
|
1061 | + // convert to timestamps |
|
1062 | + $start_date = strtotime($start_date); |
|
1063 | + $end_date = strtotime($end_date); |
|
1064 | + // makes sure start date is the lowest value and vice versa |
|
1065 | + $start_date = min($start_date, $end_date); |
|
1066 | + $end_date = max($start_date, $end_date); |
|
1067 | + // convert for query |
|
1068 | + $start_date = EEM_Change_Log::instance() |
|
1069 | + ->convert_datetime_for_query( |
|
1070 | + 'LOG_time', |
|
1071 | + date('Y-m-d H:i:s', $start_date), |
|
1072 | + 'Y-m-d H:i:s' |
|
1073 | + ); |
|
1074 | + $end_date = EEM_Change_Log::instance() |
|
1075 | + ->convert_datetime_for_query( |
|
1076 | + 'LOG_time', |
|
1077 | + date('Y-m-d H:i:s', $end_date), |
|
1078 | + 'Y-m-d H:i:s' |
|
1079 | + ); |
|
1080 | + $query_params[0]['LOG_time'] = array('BETWEEN', array($start_date, $end_date)); |
|
1081 | + } |
|
1082 | + if ($count) { |
|
1083 | + return EEM_Change_Log::instance()->count($query_params); |
|
1084 | + } |
|
1085 | + if (isset($this->_req_data['order'])) { |
|
1086 | + $sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] |
|
1087 | + : 'DESC'; |
|
1088 | + $query_params['order_by'] = array('LOG_time' => $sort); |
|
1089 | + } else { |
|
1090 | + $query_params['order_by'] = array('LOG_time' => 'DESC'); |
|
1091 | + } |
|
1092 | + $offset = ($current_page - 1) * $per_page; |
|
1093 | + if (! isset($this->_req_data['download_results'])) { |
|
1094 | + $query_params['limit'] = array($offset, $per_page); |
|
1095 | + } |
|
1096 | + // now they've requested to instead just download the file instead of viewing it. |
|
1097 | + if (isset($this->_req_data['download_results'])) { |
|
1098 | + $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params); |
|
1099 | + header('Content-Disposition: attachment'); |
|
1100 | + header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url())); |
|
1101 | + echo "<h1>Payment Logs for " . site_url() . "</h1>"; |
|
1102 | + echo "<h3>Query:</h3>"; |
|
1103 | + var_dump($query_params); |
|
1104 | + echo "<h3>Results:</h3>"; |
|
1105 | + var_dump($wpdb_results); |
|
1106 | + die; |
|
1107 | + } |
|
1108 | + $results = EEM_Change_Log::instance()->get_all($query_params); |
|
1109 | + return $results; |
|
1110 | + } |
|
1111 | + |
|
1112 | + |
|
1113 | + /** |
|
1114 | + * Used by usort to RE-sort log query results, because we lose the ordering |
|
1115 | + * because we're possibly combining the results from two queries |
|
1116 | + * |
|
1117 | + * @param EE_Change_Log $logA |
|
1118 | + * @param EE_Change_Log $logB |
|
1119 | + * @return int |
|
1120 | + */ |
|
1121 | + protected function _sort_logs_again($logA, $logB) |
|
1122 | + { |
|
1123 | + $timeA = $logA->get_raw('LOG_time'); |
|
1124 | + $timeB = $logB->get_raw('LOG_time'); |
|
1125 | + if ($timeA == $timeB) { |
|
1126 | + return 0; |
|
1127 | + } |
|
1128 | + $comparison = $timeA < $timeB ? -1 : 1; |
|
1129 | + if (strtoupper($this->_sort_logs_again_direction) == 'DESC') { |
|
1130 | + return $comparison * -1; |
|
1131 | + } else { |
|
1132 | + return $comparison; |
|
1133 | + } |
|
1134 | + } |
|
1135 | + |
|
1136 | + |
|
1137 | + protected function _payment_log_details() |
|
1138 | + { |
|
1139 | + EE_Registry::instance()->load_model('Change_Log'); |
|
1140 | + /** @var $payment_log EE_Change_Log */ |
|
1141 | + $payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']); |
|
1142 | + $payment_method = null; |
|
1143 | + $transaction = null; |
|
1144 | + if ($payment_log instanceof EE_Change_Log) { |
|
1145 | + if ($payment_log->object() instanceof EE_Payment) { |
|
1146 | + $payment_method = $payment_log->object()->payment_method(); |
|
1147 | + $transaction = $payment_log->object()->transaction(); |
|
1148 | + } elseif ($payment_log->object() instanceof EE_Payment_Method) { |
|
1149 | + $payment_method = $payment_log->object(); |
|
1150 | + } elseif ($payment_log->object() instanceof EE_Transaction) { |
|
1151 | + $transaction = $payment_log->object(); |
|
1152 | + $payment_method = $transaction->payment_method(); |
|
1153 | + } |
|
1154 | + } |
|
1155 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
1156 | + EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php', |
|
1157 | + array( |
|
1158 | + 'payment_log' => $payment_log, |
|
1159 | + 'payment_method' => $payment_method, |
|
1160 | + 'transaction' => $transaction, |
|
1161 | + ), |
|
1162 | + true |
|
1163 | + ); |
|
1164 | + $this->display_admin_page_with_sidebar(); |
|
1165 | + } |
|
1166 | 1166 | } |
@@ -182,7 +182,7 @@ discard block |
||
182 | 182 | $payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types(); |
183 | 183 | $all_pmt_help_tabs_config = array(); |
184 | 184 | foreach ($payment_method_types as $payment_method_type) { |
185 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
185 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
186 | 186 | $payment_method_type->cap_name(), |
187 | 187 | 'specific_payment_method_type_access' |
188 | 188 | ) |
@@ -192,10 +192,10 @@ discard block |
||
192 | 192 | foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) { |
193 | 193 | $template_args = isset($config['template_args']) ? $config['template_args'] : array(); |
194 | 194 | $template_args['admin_page_obj'] = $this; |
195 | - $all_pmt_help_tabs_config[ $help_tab_name ] = array( |
|
195 | + $all_pmt_help_tabs_config[$help_tab_name] = array( |
|
196 | 196 | 'title' => $config['title'], |
197 | 197 | 'content' => EEH_Template::display_template( |
198 | - $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php', |
|
198 | + $payment_method_type->file_folder().'help_tabs/'.$config['filename'].'.help_tab.php', |
|
199 | 199 | $template_args, |
200 | 200 | true |
201 | 201 | ), |
@@ -238,7 +238,7 @@ discard block |
||
238 | 238 | wp_enqueue_script('ee-text-links'); |
239 | 239 | wp_enqueue_script( |
240 | 240 | 'espresso_payments', |
241 | - EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js', |
|
241 | + EE_PAYMENTS_ASSETS_URL.'espresso_payments_admin.js', |
|
242 | 242 | ['ee-datepicker'], |
243 | 243 | EVENT_ESPRESSO_VERSION, |
244 | 244 | true |
@@ -252,7 +252,7 @@ discard block |
||
252 | 252 | // styles |
253 | 253 | wp_register_style( |
254 | 254 | 'espresso_payments', |
255 | - EE_PAYMENTS_ASSETS_URL . 'ee-payments.css', |
|
255 | + EE_PAYMENTS_ASSETS_URL.'ee-payments.css', |
|
256 | 256 | array(), |
257 | 257 | EVENT_ESPRESSO_VERSION |
258 | 258 | ); |
@@ -281,7 +281,7 @@ discard block |
||
281 | 281 | continue; |
282 | 282 | } |
283 | 283 | // check access |
284 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
284 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
285 | 285 | $pmt_obj->cap_name(), |
286 | 286 | 'specific_payment_method_type_access' |
287 | 287 | ) |
@@ -290,7 +290,7 @@ discard block |
||
290 | 290 | } |
291 | 291 | // check for any active pms of that type |
292 | 292 | $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name()); |
293 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
293 | + if ( ! $payment_method instanceof EE_Payment_Method) { |
|
294 | 294 | $payment_method = EE_Payment_Method::new_instance( |
295 | 295 | array( |
296 | 296 | 'PMD_slug' => sanitize_key($pmt_obj->system_name()), |
@@ -300,7 +300,7 @@ discard block |
||
300 | 300 | ) |
301 | 301 | ); |
302 | 302 | } |
303 | - $payment_methods[ $payment_method->slug() ] = $payment_method; |
|
303 | + $payment_methods[$payment_method->slug()] = $payment_method; |
|
304 | 304 | } |
305 | 305 | $payment_methods = apply_filters( |
306 | 306 | 'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods', |
@@ -310,7 +310,7 @@ discard block |
||
310 | 310 | if ($payment_method instanceof EE_Payment_Method) { |
311 | 311 | add_meta_box( |
312 | 312 | // html id |
313 | - 'espresso_' . $payment_method->slug() . '_payment_settings', |
|
313 | + 'espresso_'.$payment_method->slug().'_payment_settings', |
|
314 | 314 | // title |
315 | 315 | sprintf(__('%s Settings', 'event_espresso'), $payment_method->admin_name()), |
316 | 316 | // callback |
@@ -325,10 +325,10 @@ discard block |
||
325 | 325 | array('payment_method' => $payment_method) |
326 | 326 | ); |
327 | 327 | // setup for tabbed content |
328 | - $tabs[ $payment_method->slug() ] = array( |
|
328 | + $tabs[$payment_method->slug()] = array( |
|
329 | 329 | 'label' => $payment_method->admin_name(), |
330 | 330 | 'class' => $payment_method->active() ? 'gateway-active' : '', |
331 | - 'href' => 'espresso_' . $payment_method->slug() . '_payment_settings', |
|
331 | + 'href' => 'espresso_'.$payment_method->slug().'_payment_settings', |
|
332 | 332 | 'title' => __('Modify this Payment Method', 'event_espresso'), |
333 | 333 | 'slug' => $payment_method->slug(), |
334 | 334 | ); |
@@ -359,7 +359,7 @@ discard block |
||
359 | 359 | } |
360 | 360 | $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug))); |
361 | 361 | // if that didn't work or wasn't provided, find another way to select the current pm |
362 | - if (! $this->_verify_payment_method($payment_method)) { |
|
362 | + if ( ! $this->_verify_payment_method($payment_method)) { |
|
363 | 363 | // like, looking for an active one |
364 | 364 | $payment_method = EEM_Payment_Method::instance()->get_one_active('CART'); |
365 | 365 | // test that one as well |
@@ -408,7 +408,7 @@ discard block |
||
408 | 408 | { |
409 | 409 | $payment_method = isset($metabox['args'], $metabox['args']['payment_method']) |
410 | 410 | ? $metabox['args']['payment_method'] : null; |
411 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
411 | + if ( ! $payment_method instanceof EE_Payment_Method) { |
|
412 | 412 | throw new EE_Error( |
413 | 413 | sprintf( |
414 | 414 | __( |
@@ -425,7 +425,7 @@ discard block |
||
425 | 425 | if ($form->form_data_present_in($this->_req_data)) { |
426 | 426 | $form->receive_form_submission($this->_req_data); |
427 | 427 | } |
428 | - echo $form->form_open() . $form->get_html_and_js() . $form->form_close(); |
|
428 | + echo $form->form_open().$form->get_html_and_js().$form->form_close(); |
|
429 | 429 | } else { |
430 | 430 | echo $this->_activate_payment_method_button($payment_method)->get_html_and_js(); |
431 | 431 | } |
@@ -441,13 +441,13 @@ discard block |
||
441 | 441 | */ |
442 | 442 | protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method) |
443 | 443 | { |
444 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
444 | + if ( ! $payment_method instanceof EE_Payment_Method) { |
|
445 | 445 | return new EE_Form_Section_Proper(); |
446 | 446 | } |
447 | 447 | return new EE_Form_Section_Proper( |
448 | 448 | array( |
449 | - 'name' => $payment_method->slug() . '_settings_form', |
|
450 | - 'html_id' => $payment_method->slug() . '_settings_form', |
|
449 | + 'name' => $payment_method->slug().'_settings_form', |
|
450 | + 'html_id' => $payment_method->slug().'_settings_form', |
|
451 | 451 | 'action' => EE_Admin_Page::add_query_args_and_nonce( |
452 | 452 | array( |
453 | 453 | 'action' => 'update_payment_method', |
@@ -490,7 +490,7 @@ discard block |
||
490 | 490 | EEH_HTML::label( |
491 | 491 | EEH_HTML::strong(__('IMPORTANT', 'event_espresso'), '', 'important-notice') |
492 | 492 | ) |
493 | - ) . |
|
493 | + ). |
|
494 | 494 | EEH_HTML::td( |
495 | 495 | EEH_HTML::strong( |
496 | 496 | __( |
@@ -525,7 +525,7 @@ discard block |
||
525 | 525 | */ |
526 | 526 | protected function _currency_support(EE_Payment_Method $payment_method) |
527 | 527 | { |
528 | - if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) { |
|
528 | + if ( ! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) { |
|
529 | 529 | return new EE_Form_Section_HTML( |
530 | 530 | EEH_HTML::table( |
531 | 531 | EEH_HTML::tr( |
@@ -533,7 +533,7 @@ discard block |
||
533 | 533 | EEH_HTML::label( |
534 | 534 | EEH_HTML::strong(__('IMPORTANT', 'event_espresso'), '', 'important-notice') |
535 | 535 | ) |
536 | - ) . |
|
536 | + ). |
|
537 | 537 | EEH_HTML::td( |
538 | 538 | EEH_HTML::strong( |
539 | 539 | sprintf( |
@@ -614,7 +614,7 @@ discard block |
||
614 | 614 | $update_button = new EE_Submit_Input( |
615 | 615 | array( |
616 | 616 | 'name' => 'submit', |
617 | - 'html_id' => 'save_' . $payment_method->slug() . '_settings', |
|
617 | + 'html_id' => 'save_'.$payment_method->slug().'_settings', |
|
618 | 618 | 'default' => sprintf( |
619 | 619 | __('Update %s Payment Settings', 'event_espresso'), |
620 | 620 | $payment_method->admin_name() |
@@ -624,9 +624,9 @@ discard block |
||
624 | 624 | ); |
625 | 625 | return new EE_Form_Section_HTML( |
626 | 626 | EEH_HTML::table( |
627 | - EEH_HTML::no_row(EEH_HTML::br(2)) . |
|
627 | + EEH_HTML::no_row(EEH_HTML::br(2)). |
|
628 | 628 | EEH_HTML::tr( |
629 | - EEH_HTML::th(__('Update Settings', 'event_espresso')) . |
|
629 | + EEH_HTML::th(__('Update Settings', 'event_espresso')). |
|
630 | 630 | EEH_HTML::td( |
631 | 631 | $update_button->get_html_for_input() |
632 | 632 | ) |
@@ -652,7 +652,7 @@ discard block |
||
652 | 652 | return new EE_Form_Section_HTML( |
653 | 653 | EEH_HTML::table( |
654 | 654 | EEH_HTML::tr( |
655 | - EEH_HTML::th(__('Deactivate Payment Method', 'event_espresso')) . |
|
655 | + EEH_HTML::th(__('Deactivate Payment Method', 'event_espresso')). |
|
656 | 656 | EEH_HTML::td( |
657 | 657 | EEH_HTML::link( |
658 | 658 | EE_Admin_Page::add_query_args_and_nonce( |
@@ -664,7 +664,7 @@ discard block |
||
664 | 664 | ), |
665 | 665 | $link_text_and_title, |
666 | 666 | $link_text_and_title, |
667 | - 'deactivate_' . $payment_method->slug(), |
|
667 | + 'deactivate_'.$payment_method->slug(), |
|
668 | 668 | 'espresso-button button-secondary' |
669 | 669 | ) |
670 | 670 | ) |
@@ -689,8 +689,8 @@ discard block |
||
689 | 689 | ); |
690 | 690 | return new EE_Form_Section_Proper( |
691 | 691 | array( |
692 | - 'name' => 'activate_' . $payment_method->slug() . '_settings_form', |
|
693 | - 'html_id' => 'activate_' . $payment_method->slug() . '_settings_form', |
|
692 | + 'name' => 'activate_'.$payment_method->slug().'_settings_form', |
|
693 | + 'html_id' => 'activate_'.$payment_method->slug().'_settings_form', |
|
694 | 694 | 'action' => '#', |
695 | 695 | 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
696 | 696 | 'subsections' => apply_filters( |
@@ -706,11 +706,11 @@ discard block |
||
706 | 706 | '', |
707 | 707 | 'colspan="2"' |
708 | 708 | ) |
709 | - ) . |
|
709 | + ). |
|
710 | 710 | EEH_HTML::tr( |
711 | 711 | EEH_HTML::th( |
712 | 712 | EEH_HTML::label(__('Click to Activate ', 'event_espresso')) |
713 | - ) . |
|
713 | + ). |
|
714 | 714 | EEH_HTML::td( |
715 | 715 | EEH_HTML::link( |
716 | 716 | EE_Admin_Page::add_query_args_and_nonce( |
@@ -722,7 +722,7 @@ discard block |
||
722 | 722 | ), |
723 | 723 | $link_text_and_title, |
724 | 724 | $link_text_and_title, |
725 | - 'activate_' . $payment_method->slug(), |
|
725 | + 'activate_'.$payment_method->slug(), |
|
726 | 726 | 'espresso-button-green button-primary' |
727 | 727 | ) |
728 | 728 | ) |
@@ -748,7 +748,7 @@ discard block |
||
748 | 748 | return new EE_Form_Section_HTML( |
749 | 749 | EEH_HTML::table( |
750 | 750 | EEH_HTML::tr( |
751 | - EEH_HTML::th() . |
|
751 | + EEH_HTML::th(). |
|
752 | 752 | EEH_HTML::td( |
753 | 753 | EEH_HTML::p(__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text') |
754 | 754 | ) |
@@ -832,7 +832,7 @@ discard block |
||
832 | 832 | } |
833 | 833 | } |
834 | 834 | // if we couldn't find the correct payment method type... |
835 | - if (! $correct_pmt_form_to_use) { |
|
835 | + if ( ! $correct_pmt_form_to_use) { |
|
836 | 836 | EE_Error::add_error( |
837 | 837 | __( |
838 | 838 | "We could not find which payment method type your form submission related to. Please contact support", |
@@ -847,7 +847,7 @@ discard block |
||
847 | 847 | $correct_pmt_form_to_use->receive_form_submission($this->_req_data); |
848 | 848 | if ($correct_pmt_form_to_use->is_valid()) { |
849 | 849 | $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings'); |
850 | - if (! $payment_settings_subform instanceof EE_Payment_Method_Form) { |
|
850 | + if ( ! $payment_settings_subform instanceof EE_Payment_Method_Form) { |
|
851 | 851 | throw new EE_Error( |
852 | 852 | sprintf( |
853 | 853 | __( |
@@ -899,7 +899,7 @@ discard block |
||
899 | 899 | $form = $this->getPaymentSettingsForm(); |
900 | 900 | $this->_set_add_edit_form_tags('update_payment_settings'); |
901 | 901 | $this->_set_publish_post_box_vars(null, false, false, null, false); |
902 | - $this->_template_args['admin_page_content'] = $form->get_html_and_js(); |
|
902 | + $this->_template_args['admin_page_content'] = $form->get_html_and_js(); |
|
903 | 903 | $this->display_admin_page_with_sidebar(); |
904 | 904 | } |
905 | 905 | |
@@ -935,7 +935,7 @@ discard block |
||
935 | 935 | EE_Registry::instance()->CFG |
936 | 936 | ); |
937 | 937 | |
938 | - $cfg = EE_Registry::instance()->CFG ; |
|
938 | + $cfg = EE_Registry::instance()->CFG; |
|
939 | 939 | |
940 | 940 | $what = __('Payment Settings', 'event_espresso'); |
941 | 941 | $success = $this->_update_espresso_configuration( |
@@ -1036,7 +1036,7 @@ discard block |
||
1036 | 1036 | } |
1037 | 1037 | // take into account search |
1038 | 1038 | if (isset($this->_req_data['s']) && $this->_req_data['s']) { |
1039 | - $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'); |
|
1039 | + $similarity_string = array('LIKE', '%'.str_replace("", "%", $this->_req_data['s']).'%'); |
|
1040 | 1040 | $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string; |
1041 | 1041 | $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string; |
1042 | 1042 | $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string; |
@@ -1056,8 +1056,8 @@ discard block |
||
1056 | 1056 | $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']); |
1057 | 1057 | $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']); |
1058 | 1058 | // make sure our timestamps start and end right at the boundaries for each day |
1059 | - $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00'; |
|
1060 | - $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59'; |
|
1059 | + $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00'; |
|
1060 | + $end_date = date('Y-m-d', strtotime($end_date)).' 23:59:59'; |
|
1061 | 1061 | // convert to timestamps |
1062 | 1062 | $start_date = strtotime($start_date); |
1063 | 1063 | $end_date = strtotime($end_date); |
@@ -1090,15 +1090,15 @@ discard block |
||
1090 | 1090 | $query_params['order_by'] = array('LOG_time' => 'DESC'); |
1091 | 1091 | } |
1092 | 1092 | $offset = ($current_page - 1) * $per_page; |
1093 | - if (! isset($this->_req_data['download_results'])) { |
|
1093 | + if ( ! isset($this->_req_data['download_results'])) { |
|
1094 | 1094 | $query_params['limit'] = array($offset, $per_page); |
1095 | 1095 | } |
1096 | 1096 | // now they've requested to instead just download the file instead of viewing it. |
1097 | 1097 | if (isset($this->_req_data['download_results'])) { |
1098 | 1098 | $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params); |
1099 | 1099 | header('Content-Disposition: attachment'); |
1100 | - header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url())); |
|
1101 | - echo "<h1>Payment Logs for " . site_url() . "</h1>"; |
|
1100 | + header("Content-Disposition: attachment; filename=ee_payment_logs_for_".sanitize_key(site_url())); |
|
1101 | + echo "<h1>Payment Logs for ".site_url()."</h1>"; |
|
1102 | 1102 | echo "<h3>Query:</h3>"; |
1103 | 1103 | var_dump($query_params); |
1104 | 1104 | echo "<h3>Results:</h3>"; |
@@ -1153,7 +1153,7 @@ discard block |
||
1153 | 1153 | } |
1154 | 1154 | } |
1155 | 1155 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
1156 | - EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php', |
|
1156 | + EE_PAYMENTS_TEMPLATE_PATH.'payment_log_details.template.php', |
|
1157 | 1157 | array( |
1158 | 1158 | 'payment_log' => $payment_log, |
1159 | 1159 | 'payment_method' => $payment_method, |
@@ -26,467 +26,467 @@ discard block |
||
26 | 26 | { |
27 | 27 | |
28 | 28 | |
29 | - /** |
|
30 | - * This gets set in _setup_cpt |
|
31 | - * It will contain the object for the custom post type. |
|
32 | - * |
|
33 | - * @var EE_CPT_Base |
|
34 | - */ |
|
35 | - protected $_cpt_object; |
|
36 | - |
|
37 | - |
|
38 | - /** |
|
39 | - * a boolean flag to set whether the current route is a cpt route or not. |
|
40 | - * |
|
41 | - * @var bool |
|
42 | - */ |
|
43 | - protected $_cpt_route = false; |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * This property allows cpt classes to define multiple routes as cpt routes. |
|
48 | - * //in this array we define what the custom post type for this route is. |
|
49 | - * array( |
|
50 | - * 'route_name' => 'custom_post_type_slug' |
|
51 | - * ) |
|
52 | - * |
|
53 | - * @var array |
|
54 | - */ |
|
55 | - protected $_cpt_routes = array(); |
|
56 | - |
|
57 | - |
|
58 | - /** |
|
59 | - * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update. |
|
60 | - * in this format: |
|
61 | - * array( |
|
62 | - * 'post_type_slug' => 'edit_route' |
|
63 | - * ) |
|
64 | - * |
|
65 | - * @var array |
|
66 | - */ |
|
67 | - protected $_cpt_edit_routes = array(); |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will |
|
72 | - * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the |
|
73 | - * _cpt_model_names property should be in the following format: array( |
|
74 | - * 'route_defined_by_action_param' => 'Model_Name') |
|
75 | - * |
|
76 | - * @var array $_cpt_model_names |
|
77 | - */ |
|
78 | - protected $_cpt_model_names = array(); |
|
79 | - |
|
80 | - |
|
81 | - /** |
|
82 | - * @var EE_CPT_Base |
|
83 | - */ |
|
84 | - protected $_cpt_model_obj = false; |
|
85 | - |
|
86 | - |
|
87 | - /** |
|
88 | - * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP |
|
89 | - * autosave so we can save our inputs on the save_post hook! Children classes should add to this array by using |
|
90 | - * the _register_autosave_containers() method so that we don't override any other containers already registered. |
|
91 | - * Registration of containers should be done before load_page_dependencies() is run. |
|
92 | - * |
|
93 | - * @var array() |
|
94 | - */ |
|
95 | - protected $_autosave_containers = array(); |
|
96 | - protected $_autosave_fields = array(); |
|
97 | - |
|
98 | - /** |
|
99 | - * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits |
|
100 | - * a page for an action, it will appear as if they were visiting the wp core page for that custom post type |
|
101 | - * |
|
102 | - * @var array |
|
103 | - */ |
|
104 | - protected $_pagenow_map; |
|
105 | - |
|
106 | - |
|
107 | - |
|
108 | - /** |
|
109 | - * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been |
|
110 | - * saved. Child classes are required to declare this method. Typically you would use this to save any additional |
|
111 | - * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important. When a |
|
112 | - * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data |
|
113 | - * containing any extra info you may have from other meta saves. So MAKE sure that you handle this accordingly. |
|
114 | - * |
|
115 | - * @access protected |
|
116 | - * @abstract |
|
117 | - * @param string $post_id The ID of the cpt that was saved (so you can link relationally) |
|
118 | - * @param EE_CPT_Base $post The post object of the cpt that was saved. |
|
119 | - * @return void |
|
120 | - */ |
|
121 | - abstract protected function _insert_update_cpt_item($post_id, $post); |
|
122 | - |
|
123 | - |
|
124 | - /** |
|
125 | - * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed. |
|
126 | - * |
|
127 | - * @abstract |
|
128 | - * @access public |
|
129 | - * @param string $post_id The ID of the cpt that was trashed |
|
130 | - * @return void |
|
131 | - */ |
|
132 | - abstract public function trash_cpt_item($post_id); |
|
133 | - |
|
134 | - |
|
135 | - /** |
|
136 | - * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed |
|
137 | - * |
|
138 | - * @param string $post_id theID of the cpt that was untrashed |
|
139 | - * @return void |
|
140 | - */ |
|
141 | - abstract public function restore_cpt_item($post_id); |
|
142 | - |
|
143 | - |
|
144 | - /** |
|
145 | - * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted |
|
146 | - * from the db |
|
147 | - * |
|
148 | - * @param string $post_id the ID of the cpt that was deleted |
|
149 | - * @return void |
|
150 | - */ |
|
151 | - abstract public function delete_cpt_item($post_id); |
|
152 | - |
|
153 | - |
|
154 | - /** |
|
155 | - * Just utilizing the method EE_Admin exposes for doing things before page setup. |
|
156 | - * |
|
157 | - * @access protected |
|
158 | - * @return void |
|
159 | - */ |
|
160 | - protected function _before_page_setup() |
|
161 | - { |
|
162 | - $page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug; |
|
163 | - $this->_cpt_routes = array_merge( |
|
164 | - array( |
|
165 | - 'create_new' => $this->page_slug, |
|
166 | - 'edit' => $this->page_slug, |
|
167 | - 'trash' => $this->page_slug, |
|
168 | - ), |
|
169 | - $this->_cpt_routes |
|
170 | - ); |
|
171 | - // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page |
|
172 | - $this->_cpt_object = isset($this->_req_data['action'], $this->_cpt_routes[ $this->_req_data['action'] ]) |
|
173 | - ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
174 | - : get_post_type_object($page); |
|
175 | - // tweak pagenow for page loading. |
|
176 | - if (! $this->_pagenow_map) { |
|
177 | - $this->_pagenow_map = array( |
|
178 | - 'create_new' => 'post-new.php', |
|
179 | - 'edit' => 'post.php', |
|
180 | - 'trash' => 'post.php', |
|
181 | - ); |
|
182 | - } |
|
183 | - add_action('current_screen', array($this, 'modify_pagenow')); |
|
184 | - // TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param. |
|
185 | - // get current page from autosave |
|
186 | - $current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']) |
|
187 | - ? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'] |
|
188 | - : null; |
|
189 | - $this->_current_page = isset($this->_req_data['current_page']) |
|
190 | - ? $this->_req_data['current_page'] |
|
191 | - : $current_page; |
|
192 | - // autosave... make sure its only for the correct page |
|
193 | - // if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) { |
|
194 | - // setup autosave ajax hook |
|
195 | - // add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented |
|
196 | - // } |
|
197 | - } |
|
198 | - |
|
199 | - |
|
200 | - /** |
|
201 | - * Simply ensure that we simulate the correct post route for cpt screens |
|
202 | - * |
|
203 | - * @param WP_Screen $current_screen |
|
204 | - * @return void |
|
205 | - */ |
|
206 | - public function modify_pagenow($current_screen) |
|
207 | - { |
|
208 | - global $pagenow, $hook_suffix; |
|
209 | - // possibly reset pagenow. |
|
210 | - if (! empty($this->_req_data['page']) |
|
211 | - && $this->_req_data['page'] === $this->page_slug |
|
212 | - && ! empty($this->_req_data['action']) |
|
213 | - && isset($this->_pagenow_map[ $this->_req_data['action'] ]) |
|
214 | - ) { |
|
215 | - $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ]; |
|
216 | - $hook_suffix = $pagenow; |
|
217 | - } |
|
218 | - } |
|
219 | - |
|
220 | - |
|
221 | - /** |
|
222 | - * This method is used to register additional autosave containers to the _autosave_containers property. |
|
223 | - * |
|
224 | - * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we |
|
225 | - * automatically register the id for the post metabox as a container. |
|
226 | - * @param array $ids an array of ids for containers that hold form inputs we want autosave to pickup. Typically |
|
227 | - * you would send along the id of a metabox container. |
|
228 | - * @return void |
|
229 | - */ |
|
230 | - protected function _register_autosave_containers($ids) |
|
231 | - { |
|
232 | - $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids); |
|
233 | - } |
|
234 | - |
|
235 | - |
|
236 | - /** |
|
237 | - * Something nifty. We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of |
|
238 | - * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array. |
|
239 | - */ |
|
240 | - protected function _set_autosave_containers() |
|
241 | - { |
|
242 | - global $wp_meta_boxes; |
|
243 | - $containers = array(); |
|
244 | - if (empty($wp_meta_boxes)) { |
|
245 | - return; |
|
246 | - } |
|
247 | - $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array(); |
|
248 | - foreach ($current_metaboxes as $box_context) { |
|
249 | - foreach ($box_context as $box_details) { |
|
250 | - foreach ($box_details as $box) { |
|
251 | - if (is_array($box) && is_array($box['callback']) |
|
252 | - && ( |
|
253 | - $box['callback'][0] instanceof EE_Admin_Page |
|
254 | - || $box['callback'][0] instanceof EE_Admin_Hooks |
|
255 | - ) |
|
256 | - ) { |
|
257 | - $containers[] = $box['id']; |
|
258 | - } |
|
259 | - } |
|
260 | - } |
|
261 | - } |
|
262 | - $this->_autosave_containers = array_merge($this->_autosave_containers, $containers); |
|
263 | - // add hidden inputs container |
|
264 | - $this->_autosave_containers[] = 'ee-cpt-hidden-inputs'; |
|
265 | - } |
|
266 | - |
|
267 | - |
|
268 | - protected function _load_autosave_scripts_styles() |
|
269 | - { |
|
270 | - /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE ); |
|
29 | + /** |
|
30 | + * This gets set in _setup_cpt |
|
31 | + * It will contain the object for the custom post type. |
|
32 | + * |
|
33 | + * @var EE_CPT_Base |
|
34 | + */ |
|
35 | + protected $_cpt_object; |
|
36 | + |
|
37 | + |
|
38 | + /** |
|
39 | + * a boolean flag to set whether the current route is a cpt route or not. |
|
40 | + * |
|
41 | + * @var bool |
|
42 | + */ |
|
43 | + protected $_cpt_route = false; |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * This property allows cpt classes to define multiple routes as cpt routes. |
|
48 | + * //in this array we define what the custom post type for this route is. |
|
49 | + * array( |
|
50 | + * 'route_name' => 'custom_post_type_slug' |
|
51 | + * ) |
|
52 | + * |
|
53 | + * @var array |
|
54 | + */ |
|
55 | + protected $_cpt_routes = array(); |
|
56 | + |
|
57 | + |
|
58 | + /** |
|
59 | + * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update. |
|
60 | + * in this format: |
|
61 | + * array( |
|
62 | + * 'post_type_slug' => 'edit_route' |
|
63 | + * ) |
|
64 | + * |
|
65 | + * @var array |
|
66 | + */ |
|
67 | + protected $_cpt_edit_routes = array(); |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will |
|
72 | + * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the |
|
73 | + * _cpt_model_names property should be in the following format: array( |
|
74 | + * 'route_defined_by_action_param' => 'Model_Name') |
|
75 | + * |
|
76 | + * @var array $_cpt_model_names |
|
77 | + */ |
|
78 | + protected $_cpt_model_names = array(); |
|
79 | + |
|
80 | + |
|
81 | + /** |
|
82 | + * @var EE_CPT_Base |
|
83 | + */ |
|
84 | + protected $_cpt_model_obj = false; |
|
85 | + |
|
86 | + |
|
87 | + /** |
|
88 | + * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP |
|
89 | + * autosave so we can save our inputs on the save_post hook! Children classes should add to this array by using |
|
90 | + * the _register_autosave_containers() method so that we don't override any other containers already registered. |
|
91 | + * Registration of containers should be done before load_page_dependencies() is run. |
|
92 | + * |
|
93 | + * @var array() |
|
94 | + */ |
|
95 | + protected $_autosave_containers = array(); |
|
96 | + protected $_autosave_fields = array(); |
|
97 | + |
|
98 | + /** |
|
99 | + * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits |
|
100 | + * a page for an action, it will appear as if they were visiting the wp core page for that custom post type |
|
101 | + * |
|
102 | + * @var array |
|
103 | + */ |
|
104 | + protected $_pagenow_map; |
|
105 | + |
|
106 | + |
|
107 | + |
|
108 | + /** |
|
109 | + * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been |
|
110 | + * saved. Child classes are required to declare this method. Typically you would use this to save any additional |
|
111 | + * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important. When a |
|
112 | + * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data |
|
113 | + * containing any extra info you may have from other meta saves. So MAKE sure that you handle this accordingly. |
|
114 | + * |
|
115 | + * @access protected |
|
116 | + * @abstract |
|
117 | + * @param string $post_id The ID of the cpt that was saved (so you can link relationally) |
|
118 | + * @param EE_CPT_Base $post The post object of the cpt that was saved. |
|
119 | + * @return void |
|
120 | + */ |
|
121 | + abstract protected function _insert_update_cpt_item($post_id, $post); |
|
122 | + |
|
123 | + |
|
124 | + /** |
|
125 | + * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed. |
|
126 | + * |
|
127 | + * @abstract |
|
128 | + * @access public |
|
129 | + * @param string $post_id The ID of the cpt that was trashed |
|
130 | + * @return void |
|
131 | + */ |
|
132 | + abstract public function trash_cpt_item($post_id); |
|
133 | + |
|
134 | + |
|
135 | + /** |
|
136 | + * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed |
|
137 | + * |
|
138 | + * @param string $post_id theID of the cpt that was untrashed |
|
139 | + * @return void |
|
140 | + */ |
|
141 | + abstract public function restore_cpt_item($post_id); |
|
142 | + |
|
143 | + |
|
144 | + /** |
|
145 | + * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted |
|
146 | + * from the db |
|
147 | + * |
|
148 | + * @param string $post_id the ID of the cpt that was deleted |
|
149 | + * @return void |
|
150 | + */ |
|
151 | + abstract public function delete_cpt_item($post_id); |
|
152 | + |
|
153 | + |
|
154 | + /** |
|
155 | + * Just utilizing the method EE_Admin exposes for doing things before page setup. |
|
156 | + * |
|
157 | + * @access protected |
|
158 | + * @return void |
|
159 | + */ |
|
160 | + protected function _before_page_setup() |
|
161 | + { |
|
162 | + $page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug; |
|
163 | + $this->_cpt_routes = array_merge( |
|
164 | + array( |
|
165 | + 'create_new' => $this->page_slug, |
|
166 | + 'edit' => $this->page_slug, |
|
167 | + 'trash' => $this->page_slug, |
|
168 | + ), |
|
169 | + $this->_cpt_routes |
|
170 | + ); |
|
171 | + // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page |
|
172 | + $this->_cpt_object = isset($this->_req_data['action'], $this->_cpt_routes[ $this->_req_data['action'] ]) |
|
173 | + ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
174 | + : get_post_type_object($page); |
|
175 | + // tweak pagenow for page loading. |
|
176 | + if (! $this->_pagenow_map) { |
|
177 | + $this->_pagenow_map = array( |
|
178 | + 'create_new' => 'post-new.php', |
|
179 | + 'edit' => 'post.php', |
|
180 | + 'trash' => 'post.php', |
|
181 | + ); |
|
182 | + } |
|
183 | + add_action('current_screen', array($this, 'modify_pagenow')); |
|
184 | + // TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param. |
|
185 | + // get current page from autosave |
|
186 | + $current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']) |
|
187 | + ? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'] |
|
188 | + : null; |
|
189 | + $this->_current_page = isset($this->_req_data['current_page']) |
|
190 | + ? $this->_req_data['current_page'] |
|
191 | + : $current_page; |
|
192 | + // autosave... make sure its only for the correct page |
|
193 | + // if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) { |
|
194 | + // setup autosave ajax hook |
|
195 | + // add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented |
|
196 | + // } |
|
197 | + } |
|
198 | + |
|
199 | + |
|
200 | + /** |
|
201 | + * Simply ensure that we simulate the correct post route for cpt screens |
|
202 | + * |
|
203 | + * @param WP_Screen $current_screen |
|
204 | + * @return void |
|
205 | + */ |
|
206 | + public function modify_pagenow($current_screen) |
|
207 | + { |
|
208 | + global $pagenow, $hook_suffix; |
|
209 | + // possibly reset pagenow. |
|
210 | + if (! empty($this->_req_data['page']) |
|
211 | + && $this->_req_data['page'] === $this->page_slug |
|
212 | + && ! empty($this->_req_data['action']) |
|
213 | + && isset($this->_pagenow_map[ $this->_req_data['action'] ]) |
|
214 | + ) { |
|
215 | + $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ]; |
|
216 | + $hook_suffix = $pagenow; |
|
217 | + } |
|
218 | + } |
|
219 | + |
|
220 | + |
|
221 | + /** |
|
222 | + * This method is used to register additional autosave containers to the _autosave_containers property. |
|
223 | + * |
|
224 | + * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we |
|
225 | + * automatically register the id for the post metabox as a container. |
|
226 | + * @param array $ids an array of ids for containers that hold form inputs we want autosave to pickup. Typically |
|
227 | + * you would send along the id of a metabox container. |
|
228 | + * @return void |
|
229 | + */ |
|
230 | + protected function _register_autosave_containers($ids) |
|
231 | + { |
|
232 | + $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids); |
|
233 | + } |
|
234 | + |
|
235 | + |
|
236 | + /** |
|
237 | + * Something nifty. We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of |
|
238 | + * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array. |
|
239 | + */ |
|
240 | + protected function _set_autosave_containers() |
|
241 | + { |
|
242 | + global $wp_meta_boxes; |
|
243 | + $containers = array(); |
|
244 | + if (empty($wp_meta_boxes)) { |
|
245 | + return; |
|
246 | + } |
|
247 | + $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array(); |
|
248 | + foreach ($current_metaboxes as $box_context) { |
|
249 | + foreach ($box_context as $box_details) { |
|
250 | + foreach ($box_details as $box) { |
|
251 | + if (is_array($box) && is_array($box['callback']) |
|
252 | + && ( |
|
253 | + $box['callback'][0] instanceof EE_Admin_Page |
|
254 | + || $box['callback'][0] instanceof EE_Admin_Hooks |
|
255 | + ) |
|
256 | + ) { |
|
257 | + $containers[] = $box['id']; |
|
258 | + } |
|
259 | + } |
|
260 | + } |
|
261 | + } |
|
262 | + $this->_autosave_containers = array_merge($this->_autosave_containers, $containers); |
|
263 | + // add hidden inputs container |
|
264 | + $this->_autosave_containers[] = 'ee-cpt-hidden-inputs'; |
|
265 | + } |
|
266 | + |
|
267 | + |
|
268 | + protected function _load_autosave_scripts_styles() |
|
269 | + { |
|
270 | + /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE ); |
|
271 | 271 | wp_enqueue_script('cpt-autosave');/**/ // todo re-enable when we start doing autosave again in 4.2 |
272 | 272 | |
273 | - // filter _autosave_containers |
|
274 | - $containers = apply_filters( |
|
275 | - 'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers', |
|
276 | - $this->_autosave_containers, |
|
277 | - $this |
|
278 | - ); |
|
279 | - $containers = apply_filters( |
|
280 | - 'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers', |
|
281 | - $containers, |
|
282 | - $this |
|
283 | - ); |
|
284 | - |
|
285 | - wp_localize_script( |
|
286 | - 'event_editor_js', |
|
287 | - 'EE_AUTOSAVE_IDS', |
|
288 | - $containers |
|
289 | - ); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave" |
|
290 | - |
|
291 | - $unsaved_data_msg = array( |
|
292 | - 'eventmsg' => sprintf( |
|
293 | - __( |
|
294 | - 'The changes you made to this %s will be lost if you navigate away from this page.', |
|
295 | - 'event_espresso' |
|
296 | - ), |
|
297 | - $this->_cpt_object->labels->singular_name |
|
298 | - ), |
|
299 | - 'inputChanged' => 0, |
|
300 | - ); |
|
301 | - wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg); |
|
302 | - } |
|
303 | - |
|
304 | - |
|
305 | - /** |
|
306 | - * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately |
|
307 | - * |
|
308 | - * @access protected |
|
309 | - * @return void |
|
310 | - * @throws EE_Error |
|
311 | - * @throws ReflectionException |
|
312 | - */ |
|
313 | - protected function _load_page_dependencies() |
|
314 | - { |
|
315 | - // we only add stuff if this is a cpt_route! |
|
316 | - if (! $this->_cpt_route) { |
|
317 | - parent::_load_page_dependencies(); |
|
318 | - return; |
|
319 | - } |
|
320 | - // now let's do some automatic filters into the wp_system |
|
321 | - // and we'll check to make sure the CHILD class |
|
322 | - // automatically has the required methods in place. |
|
323 | - // the following filters are for setting all the redirects |
|
324 | - // on DEFAULT WP custom post type actions |
|
325 | - // let's add a hidden input to the post-edit form |
|
326 | - // so we know when we have to trigger our custom redirects! |
|
327 | - // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course! |
|
328 | - add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input')); |
|
329 | - // inject our Admin page nav tabs... |
|
330 | - // let's make sure the nav tabs are set if they aren't already |
|
331 | - // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs(); |
|
332 | - add_action('post_edit_form_tag', array($this, 'inject_nav_tabs')); |
|
333 | - // modify the post_updated messages array |
|
334 | - add_action('post_updated_messages', array($this, 'post_update_messages'), 10); |
|
335 | - // add shortlink button to cpt edit screens. We can do this as a universal thing BECAUSE, |
|
336 | - // cpts use the same format for shortlinks as posts! |
|
337 | - add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4); |
|
338 | - // This basically allows us to change the title of the "publish" metabox area |
|
339 | - // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class. |
|
340 | - if (! empty($this->_labels['publishbox'])) { |
|
341 | - $box_label = is_array($this->_labels['publishbox']) |
|
342 | - && isset($this->_labels['publishbox'][ $this->_req_action ]) |
|
343 | - ? $this->_labels['publishbox'][ $this->_req_action ] |
|
344 | - : $this->_labels['publishbox']; |
|
345 | - add_meta_box( |
|
346 | - 'submitdiv', |
|
347 | - $box_label, |
|
348 | - 'post_submit_meta_box', |
|
349 | - $this->_cpt_routes[ $this->_req_action ], |
|
350 | - 'side', |
|
351 | - 'core' |
|
352 | - ); |
|
353 | - } |
|
354 | - // let's add page_templates metabox if this cpt added support for it. |
|
355 | - if ($this->_supports_page_templates($this->_cpt_object->name)) { |
|
356 | - add_meta_box( |
|
357 | - 'page_templates', |
|
358 | - __('Page Template', 'event_espresso'), |
|
359 | - array($this, 'page_template_meta_box'), |
|
360 | - $this->_cpt_routes[ $this->_req_action ], |
|
361 | - 'side', |
|
362 | - 'default' |
|
363 | - ); |
|
364 | - } |
|
365 | - // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form |
|
366 | - if (method_exists($this, 'extra_permalink_field_buttons')) { |
|
367 | - add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4); |
|
368 | - } |
|
369 | - // add preview button |
|
370 | - add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4); |
|
371 | - // insert our own post_stati dropdown |
|
372 | - add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10); |
|
373 | - // This allows adding additional information to the publish post submitbox on the wp post edit form |
|
374 | - if (method_exists($this, 'extra_misc_actions_publish_box')) { |
|
375 | - add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10); |
|
376 | - } |
|
377 | - // This allows for adding additional stuff after the title field on the wp post edit form. |
|
378 | - // This is also before the wp_editor for post description field. |
|
379 | - if (method_exists($this, 'edit_form_after_title')) { |
|
380 | - add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10); |
|
381 | - } |
|
382 | - /** |
|
383 | - * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route. |
|
384 | - */ |
|
385 | - add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3); |
|
386 | - parent::_load_page_dependencies(); |
|
387 | - // notice we are ALSO going to load the pagenow hook set for this route |
|
388 | - // (see _before_page_setup for the reset of the pagenow global ). |
|
389 | - // This is for any plugins that are doing things properly |
|
390 | - // and hooking into the load page hook for core wp cpt routes. |
|
391 | - global $pagenow; |
|
392 | - add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20); |
|
393 | - do_action('load-' . $pagenow); |
|
394 | - add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30); |
|
395 | - // we route REALLY early. |
|
396 | - try { |
|
397 | - $this->_route_admin_request(); |
|
398 | - } catch (EE_Error $e) { |
|
399 | - $e->get_error(); |
|
400 | - } |
|
401 | - } |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * Since we don't want users going to default core wp routes, this will check any wp urls run through the |
|
406 | - * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR |
|
407 | - * route instead. |
|
408 | - * |
|
409 | - * @param string $good_protocol_url The escaped url. |
|
410 | - * @param string $original_url The original url. |
|
411 | - * @param string $_context The context sent to the esc_url method. |
|
412 | - * @return string possibly a new url for our route. |
|
413 | - */ |
|
414 | - public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context) |
|
415 | - { |
|
416 | - $routes_to_match = array( |
|
417 | - 0 => array( |
|
418 | - 'edit.php?post_type=espresso_attendees', |
|
419 | - 'admin.php?page=espresso_registrations&action=contact_list', |
|
420 | - ), |
|
421 | - 1 => array( |
|
422 | - 'edit.php?post_type=' . $this->_cpt_object->name, |
|
423 | - 'admin.php?page=' . $this->_cpt_object->name, |
|
424 | - ), |
|
425 | - ); |
|
426 | - foreach ($routes_to_match as $route_matches) { |
|
427 | - if (strpos($good_protocol_url, $route_matches[0]) !== false) { |
|
428 | - return str_replace($route_matches[0], $route_matches[1], $good_protocol_url); |
|
429 | - } |
|
430 | - } |
|
431 | - return $good_protocol_url; |
|
432 | - } |
|
433 | - |
|
434 | - |
|
435 | - /** |
|
436 | - * Determine whether the current cpt supports page templates or not. |
|
437 | - * |
|
438 | - * @since %VER% |
|
439 | - * @param string $cpt_name The cpt slug we're checking on. |
|
440 | - * @return bool True supported, false not. |
|
441 | - * @throws InvalidArgumentException |
|
442 | - * @throws InvalidDataTypeException |
|
443 | - * @throws InvalidInterfaceException |
|
444 | - */ |
|
445 | - private function _supports_page_templates($cpt_name) |
|
446 | - { |
|
447 | - /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */ |
|
448 | - $custom_post_types = $this->loader->getShared( |
|
449 | - 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' |
|
450 | - ); |
|
451 | - $cpt_args = $custom_post_types->getDefinitions(); |
|
452 | - $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array(); |
|
453 | - $cpt_has_support = ! empty($cpt_args['page_templates']); |
|
454 | - |
|
455 | - // if the installed version of WP is > 4.7 we do some additional checks. |
|
456 | - if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) { |
|
457 | - $post_templates = wp_get_theme()->get_post_templates(); |
|
458 | - // if there are $post_templates for this cpt, then we return false for this method because |
|
459 | - // that means we aren't going to load our page template manager and leave that up to the native |
|
460 | - // cpt template manager. |
|
461 | - $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false; |
|
462 | - } |
|
463 | - |
|
464 | - return $cpt_has_support; |
|
465 | - } |
|
466 | - |
|
467 | - |
|
468 | - /** |
|
469 | - * Callback for the page_templates metabox selector. |
|
470 | - * |
|
471 | - * @since %VER% |
|
472 | - * @return void |
|
473 | - */ |
|
474 | - public function page_template_meta_box() |
|
475 | - { |
|
476 | - global $post; |
|
477 | - $template = ''; |
|
478 | - |
|
479 | - if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) { |
|
480 | - $page_template_count = count(get_page_templates()); |
|
481 | - } else { |
|
482 | - $page_template_count = count(get_page_templates($post)); |
|
483 | - } |
|
484 | - |
|
485 | - if ($page_template_count) { |
|
486 | - $page_template = get_post_meta($post->ID, '_wp_page_template', true); |
|
487 | - $template = ! empty($page_template) ? $page_template : ''; |
|
488 | - } |
|
489 | - ?> |
|
273 | + // filter _autosave_containers |
|
274 | + $containers = apply_filters( |
|
275 | + 'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers', |
|
276 | + $this->_autosave_containers, |
|
277 | + $this |
|
278 | + ); |
|
279 | + $containers = apply_filters( |
|
280 | + 'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers', |
|
281 | + $containers, |
|
282 | + $this |
|
283 | + ); |
|
284 | + |
|
285 | + wp_localize_script( |
|
286 | + 'event_editor_js', |
|
287 | + 'EE_AUTOSAVE_IDS', |
|
288 | + $containers |
|
289 | + ); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave" |
|
290 | + |
|
291 | + $unsaved_data_msg = array( |
|
292 | + 'eventmsg' => sprintf( |
|
293 | + __( |
|
294 | + 'The changes you made to this %s will be lost if you navigate away from this page.', |
|
295 | + 'event_espresso' |
|
296 | + ), |
|
297 | + $this->_cpt_object->labels->singular_name |
|
298 | + ), |
|
299 | + 'inputChanged' => 0, |
|
300 | + ); |
|
301 | + wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg); |
|
302 | + } |
|
303 | + |
|
304 | + |
|
305 | + /** |
|
306 | + * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately |
|
307 | + * |
|
308 | + * @access protected |
|
309 | + * @return void |
|
310 | + * @throws EE_Error |
|
311 | + * @throws ReflectionException |
|
312 | + */ |
|
313 | + protected function _load_page_dependencies() |
|
314 | + { |
|
315 | + // we only add stuff if this is a cpt_route! |
|
316 | + if (! $this->_cpt_route) { |
|
317 | + parent::_load_page_dependencies(); |
|
318 | + return; |
|
319 | + } |
|
320 | + // now let's do some automatic filters into the wp_system |
|
321 | + // and we'll check to make sure the CHILD class |
|
322 | + // automatically has the required methods in place. |
|
323 | + // the following filters are for setting all the redirects |
|
324 | + // on DEFAULT WP custom post type actions |
|
325 | + // let's add a hidden input to the post-edit form |
|
326 | + // so we know when we have to trigger our custom redirects! |
|
327 | + // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course! |
|
328 | + add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input')); |
|
329 | + // inject our Admin page nav tabs... |
|
330 | + // let's make sure the nav tabs are set if they aren't already |
|
331 | + // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs(); |
|
332 | + add_action('post_edit_form_tag', array($this, 'inject_nav_tabs')); |
|
333 | + // modify the post_updated messages array |
|
334 | + add_action('post_updated_messages', array($this, 'post_update_messages'), 10); |
|
335 | + // add shortlink button to cpt edit screens. We can do this as a universal thing BECAUSE, |
|
336 | + // cpts use the same format for shortlinks as posts! |
|
337 | + add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4); |
|
338 | + // This basically allows us to change the title of the "publish" metabox area |
|
339 | + // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class. |
|
340 | + if (! empty($this->_labels['publishbox'])) { |
|
341 | + $box_label = is_array($this->_labels['publishbox']) |
|
342 | + && isset($this->_labels['publishbox'][ $this->_req_action ]) |
|
343 | + ? $this->_labels['publishbox'][ $this->_req_action ] |
|
344 | + : $this->_labels['publishbox']; |
|
345 | + add_meta_box( |
|
346 | + 'submitdiv', |
|
347 | + $box_label, |
|
348 | + 'post_submit_meta_box', |
|
349 | + $this->_cpt_routes[ $this->_req_action ], |
|
350 | + 'side', |
|
351 | + 'core' |
|
352 | + ); |
|
353 | + } |
|
354 | + // let's add page_templates metabox if this cpt added support for it. |
|
355 | + if ($this->_supports_page_templates($this->_cpt_object->name)) { |
|
356 | + add_meta_box( |
|
357 | + 'page_templates', |
|
358 | + __('Page Template', 'event_espresso'), |
|
359 | + array($this, 'page_template_meta_box'), |
|
360 | + $this->_cpt_routes[ $this->_req_action ], |
|
361 | + 'side', |
|
362 | + 'default' |
|
363 | + ); |
|
364 | + } |
|
365 | + // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form |
|
366 | + if (method_exists($this, 'extra_permalink_field_buttons')) { |
|
367 | + add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4); |
|
368 | + } |
|
369 | + // add preview button |
|
370 | + add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4); |
|
371 | + // insert our own post_stati dropdown |
|
372 | + add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10); |
|
373 | + // This allows adding additional information to the publish post submitbox on the wp post edit form |
|
374 | + if (method_exists($this, 'extra_misc_actions_publish_box')) { |
|
375 | + add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10); |
|
376 | + } |
|
377 | + // This allows for adding additional stuff after the title field on the wp post edit form. |
|
378 | + // This is also before the wp_editor for post description field. |
|
379 | + if (method_exists($this, 'edit_form_after_title')) { |
|
380 | + add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10); |
|
381 | + } |
|
382 | + /** |
|
383 | + * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route. |
|
384 | + */ |
|
385 | + add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3); |
|
386 | + parent::_load_page_dependencies(); |
|
387 | + // notice we are ALSO going to load the pagenow hook set for this route |
|
388 | + // (see _before_page_setup for the reset of the pagenow global ). |
|
389 | + // This is for any plugins that are doing things properly |
|
390 | + // and hooking into the load page hook for core wp cpt routes. |
|
391 | + global $pagenow; |
|
392 | + add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20); |
|
393 | + do_action('load-' . $pagenow); |
|
394 | + add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30); |
|
395 | + // we route REALLY early. |
|
396 | + try { |
|
397 | + $this->_route_admin_request(); |
|
398 | + } catch (EE_Error $e) { |
|
399 | + $e->get_error(); |
|
400 | + } |
|
401 | + } |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * Since we don't want users going to default core wp routes, this will check any wp urls run through the |
|
406 | + * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR |
|
407 | + * route instead. |
|
408 | + * |
|
409 | + * @param string $good_protocol_url The escaped url. |
|
410 | + * @param string $original_url The original url. |
|
411 | + * @param string $_context The context sent to the esc_url method. |
|
412 | + * @return string possibly a new url for our route. |
|
413 | + */ |
|
414 | + public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context) |
|
415 | + { |
|
416 | + $routes_to_match = array( |
|
417 | + 0 => array( |
|
418 | + 'edit.php?post_type=espresso_attendees', |
|
419 | + 'admin.php?page=espresso_registrations&action=contact_list', |
|
420 | + ), |
|
421 | + 1 => array( |
|
422 | + 'edit.php?post_type=' . $this->_cpt_object->name, |
|
423 | + 'admin.php?page=' . $this->_cpt_object->name, |
|
424 | + ), |
|
425 | + ); |
|
426 | + foreach ($routes_to_match as $route_matches) { |
|
427 | + if (strpos($good_protocol_url, $route_matches[0]) !== false) { |
|
428 | + return str_replace($route_matches[0], $route_matches[1], $good_protocol_url); |
|
429 | + } |
|
430 | + } |
|
431 | + return $good_protocol_url; |
|
432 | + } |
|
433 | + |
|
434 | + |
|
435 | + /** |
|
436 | + * Determine whether the current cpt supports page templates or not. |
|
437 | + * |
|
438 | + * @since %VER% |
|
439 | + * @param string $cpt_name The cpt slug we're checking on. |
|
440 | + * @return bool True supported, false not. |
|
441 | + * @throws InvalidArgumentException |
|
442 | + * @throws InvalidDataTypeException |
|
443 | + * @throws InvalidInterfaceException |
|
444 | + */ |
|
445 | + private function _supports_page_templates($cpt_name) |
|
446 | + { |
|
447 | + /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */ |
|
448 | + $custom_post_types = $this->loader->getShared( |
|
449 | + 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' |
|
450 | + ); |
|
451 | + $cpt_args = $custom_post_types->getDefinitions(); |
|
452 | + $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array(); |
|
453 | + $cpt_has_support = ! empty($cpt_args['page_templates']); |
|
454 | + |
|
455 | + // if the installed version of WP is > 4.7 we do some additional checks. |
|
456 | + if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) { |
|
457 | + $post_templates = wp_get_theme()->get_post_templates(); |
|
458 | + // if there are $post_templates for this cpt, then we return false for this method because |
|
459 | + // that means we aren't going to load our page template manager and leave that up to the native |
|
460 | + // cpt template manager. |
|
461 | + $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false; |
|
462 | + } |
|
463 | + |
|
464 | + return $cpt_has_support; |
|
465 | + } |
|
466 | + |
|
467 | + |
|
468 | + /** |
|
469 | + * Callback for the page_templates metabox selector. |
|
470 | + * |
|
471 | + * @since %VER% |
|
472 | + * @return void |
|
473 | + */ |
|
474 | + public function page_template_meta_box() |
|
475 | + { |
|
476 | + global $post; |
|
477 | + $template = ''; |
|
478 | + |
|
479 | + if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) { |
|
480 | + $page_template_count = count(get_page_templates()); |
|
481 | + } else { |
|
482 | + $page_template_count = count(get_page_templates($post)); |
|
483 | + } |
|
484 | + |
|
485 | + if ($page_template_count) { |
|
486 | + $page_template = get_post_meta($post->ID, '_wp_page_template', true); |
|
487 | + $template = ! empty($page_template) ? $page_template : ''; |
|
488 | + } |
|
489 | + ?> |
|
490 | 490 | <p><strong><?php _e('Template', 'event_espresso') ?></strong></p> |
491 | 491 | <label class="screen-reader-text" for="page_template"><?php _e('Page Template', 'event_espresso') ?></label><select |
492 | 492 | name="page_template" id="page_template"> |
@@ -494,478 +494,478 @@ discard block |
||
494 | 494 | <?php page_template_dropdown($template); ?> |
495 | 495 | </select> |
496 | 496 | <?php |
497 | - } |
|
498 | - |
|
499 | - |
|
500 | - /** |
|
501 | - * if this post is a draft or scheduled post then we provide a preview button for user to click |
|
502 | - * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter. |
|
503 | - * |
|
504 | - * @param string $return the current html |
|
505 | - * @param int $id the post id for the page |
|
506 | - * @param string $new_title What the title is |
|
507 | - * @param string $new_slug what the slug is |
|
508 | - * @return string The new html string for the permalink area |
|
509 | - */ |
|
510 | - public function preview_button_html($return, $id, $new_title, $new_slug) |
|
511 | - { |
|
512 | - $post = get_post($id); |
|
513 | - if ('publish' !== get_post_status($post)) { |
|
514 | - $return .= '<span_id="view-post-btn"><a target="_blank" href="' |
|
515 | - . get_preview_post_link($id) |
|
516 | - . '" class="button button-small">' |
|
517 | - . __('Preview', 'event_espresso') |
|
518 | - . '</a></span>' |
|
519 | - . "\n"; |
|
520 | - } |
|
521 | - return $return; |
|
522 | - } |
|
523 | - |
|
524 | - |
|
525 | - /** |
|
526 | - * add our custom post stati dropdown on the wp post page for this cpt |
|
527 | - * |
|
528 | - * @return void |
|
529 | - */ |
|
530 | - public function custom_post_stati_dropdown() |
|
531 | - { |
|
532 | - |
|
533 | - $statuses = $this->_cpt_model_obj->get_custom_post_statuses(); |
|
534 | - $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses) |
|
535 | - ? $statuses[ $this->_cpt_model_obj->status() ] |
|
536 | - : ''; |
|
537 | - $template_args = array( |
|
538 | - 'cur_status' => $this->_cpt_model_obj->status(), |
|
539 | - 'statuses' => $statuses, |
|
540 | - 'cur_status_label' => $cur_status_label, |
|
541 | - 'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label), |
|
542 | - ); |
|
543 | - // we'll add a trash post status (WP doesn't add one for some reason) |
|
544 | - if ($this->_cpt_model_obj->status() === 'trash') { |
|
545 | - $template_args['cur_status_label'] = __('Trashed', 'event_espresso'); |
|
546 | - $statuses['trash'] = __('Trashed', 'event_espresso'); |
|
547 | - $template_args['statuses'] = $statuses; |
|
548 | - } |
|
549 | - |
|
550 | - $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php'; |
|
551 | - EEH_Template::display_template($template, $template_args); |
|
552 | - } |
|
553 | - |
|
554 | - |
|
555 | - public function setup_autosave_hooks() |
|
556 | - { |
|
557 | - $this->_set_autosave_containers(); |
|
558 | - $this->_load_autosave_scripts_styles(); |
|
559 | - } |
|
560 | - |
|
561 | - |
|
562 | - /** |
|
563 | - * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available |
|
564 | - * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check |
|
565 | - * for the nonce in here, but then this method looks for two things: |
|
566 | - * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR |
|
567 | - * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an |
|
568 | - * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the |
|
569 | - * $_template_args property should be used to hold the $data array. We're expecting the following things set in |
|
570 | - * template args. |
|
571 | - * 1. $template_args['error'] = IF there is an error you can add the message in here. |
|
572 | - * 2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go' |
|
573 | - * => 'values_to_add'. In other words, for the datetime metabox we'll have something like |
|
574 | - * $this->_template_args['data']['items'] = array( |
|
575 | - * 'event-datetime-ids' => '1,2,3'; |
|
576 | - * ); |
|
577 | - * Keep in mind the following things: |
|
578 | - * - "where" index is for the input with the id as that string. |
|
579 | - * - "what" index is what will be used for the value of that input. |
|
580 | - * |
|
581 | - * @return void |
|
582 | - * @throws EE_Error |
|
583 | - */ |
|
584 | - public function do_extra_autosave_stuff() |
|
585 | - { |
|
586 | - // next let's check for the autosave nonce (we'll use _verify_nonce ) |
|
587 | - $nonce = isset($this->_req_data['autosavenonce']) |
|
588 | - ? $this->_req_data['autosavenonce'] |
|
589 | - : null; |
|
590 | - $this->_verify_nonce($nonce, 'autosave'); |
|
591 | - // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it) |
|
592 | - if (! defined('DOING_AUTOSAVE')) { |
|
593 | - define('DOING_AUTOSAVE', true); |
|
594 | - } |
|
595 | - // if we made it here then the nonce checked out. Let's run our methods and actions |
|
596 | - $autosave = "_ee_autosave_{$this->_current_view}"; |
|
597 | - if (method_exists($this, $autosave)) { |
|
598 | - $this->$autosave(); |
|
599 | - } else { |
|
600 | - $this->_template_args['success'] = true; |
|
601 | - } |
|
602 | - do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this); |
|
603 | - do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this); |
|
604 | - // now let's return json |
|
605 | - $this->_return_json(); |
|
606 | - } |
|
607 | - |
|
608 | - |
|
609 | - /** |
|
610 | - * This takes care of setting up default routes and pages that utilize the core WP admin pages. |
|
611 | - * Child classes can override the defaults (in cases for adding metaboxes etc.) |
|
612 | - * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work! |
|
613 | - * |
|
614 | - * @access protected |
|
615 | - * @return void |
|
616 | - * @throws ReflectionException |
|
617 | - * @throws EE_Error |
|
618 | - */ |
|
619 | - protected function _extend_page_config_for_cpt() |
|
620 | - { |
|
621 | - // before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug |
|
622 | - if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) { |
|
623 | - return; |
|
624 | - } |
|
625 | - // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes |
|
626 | - if (! empty($this->_cpt_object)) { |
|
627 | - $this->_page_routes = array_merge( |
|
628 | - array( |
|
629 | - 'create_new' => '_create_new_cpt_item', |
|
630 | - 'edit' => '_edit_cpt_item', |
|
631 | - ), |
|
632 | - $this->_page_routes |
|
633 | - ); |
|
634 | - $this->_page_config = array_merge( |
|
635 | - array( |
|
636 | - 'create_new' => array( |
|
637 | - 'nav' => array( |
|
638 | - 'label' => $this->_cpt_object->labels->add_new_item, |
|
639 | - 'order' => 5, |
|
640 | - ), |
|
641 | - 'require_nonce' => false, |
|
642 | - ), |
|
643 | - 'edit' => array( |
|
644 | - 'nav' => array( |
|
645 | - 'label' => $this->_cpt_object->labels->edit_item, |
|
646 | - 'order' => 5, |
|
647 | - 'persistent' => false, |
|
648 | - 'url' => '', |
|
649 | - ), |
|
650 | - 'require_nonce' => false, |
|
651 | - ), |
|
652 | - ), |
|
653 | - $this->_page_config |
|
654 | - ); |
|
655 | - } |
|
656 | - // load the next section only if this is a matching cpt route as set in the cpt routes array. |
|
657 | - if (! isset($this->_cpt_routes[ $this->_req_action ])) { |
|
658 | - return; |
|
659 | - } |
|
660 | - $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false; |
|
661 | - // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') ); |
|
662 | - if (empty($this->_cpt_object)) { |
|
663 | - $msg = sprintf( |
|
664 | - __( |
|
665 | - 'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this: 1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).', |
|
666 | - 'event_espresso' |
|
667 | - ), |
|
668 | - $this->page_slug, |
|
669 | - $this->_req_action, |
|
670 | - get_class($this) |
|
671 | - ); |
|
672 | - throw new EE_Error($msg); |
|
673 | - } |
|
674 | - if ($this->_cpt_route) { |
|
675 | - $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null; |
|
676 | - $this->_set_model_object($id); |
|
677 | - } |
|
678 | - } |
|
679 | - |
|
680 | - |
|
681 | - /** |
|
682 | - * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id. |
|
683 | - * |
|
684 | - * @access protected |
|
685 | - * @param int $id The id to retrieve the model object for. If empty we set a default object. |
|
686 | - * @param bool $ignore_route_check |
|
687 | - * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT |
|
688 | - * @throws EE_Error |
|
689 | - * @throws InvalidArgumentException |
|
690 | - * @throws InvalidDataTypeException |
|
691 | - * @throws InvalidInterfaceException |
|
692 | - * @throws ReflectionException |
|
693 | - */ |
|
694 | - protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '') |
|
695 | - { |
|
696 | - $model = null; |
|
697 | - if (empty($this->_cpt_model_names) |
|
698 | - || ( |
|
699 | - ! $ignore_route_check |
|
700 | - && ! isset($this->_cpt_routes[ $this->_req_action ]) |
|
701 | - ) || ( |
|
702 | - $this->_cpt_model_obj instanceof EE_CPT_Base |
|
703 | - && $this->_cpt_model_obj->ID() === $id |
|
704 | - ) |
|
705 | - ) { |
|
706 | - // get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent. |
|
707 | - return; |
|
708 | - } |
|
709 | - // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions |
|
710 | - if ($ignore_route_check) { |
|
711 | - $post_type = get_post_type($id); |
|
712 | - /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */ |
|
713 | - $custom_post_types = $this->loader->getShared( |
|
714 | - 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' |
|
715 | - ); |
|
716 | - $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type); |
|
717 | - if (isset($model_names[ $post_type ])) { |
|
718 | - $model = EE_Registry::instance()->load_model($model_names[ $post_type ]); |
|
719 | - } |
|
720 | - } else { |
|
721 | - $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]); |
|
722 | - } |
|
723 | - if ($model instanceof EEM_Base) { |
|
724 | - $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object(); |
|
725 | - } |
|
726 | - do_action( |
|
727 | - 'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object', |
|
728 | - $this->_cpt_model_obj, |
|
729 | - $req_type |
|
730 | - ); |
|
731 | - } |
|
732 | - |
|
733 | - |
|
734 | - /** |
|
735 | - * admin_init_global |
|
736 | - * This runs all the code that we want executed within the WP admin_init hook. |
|
737 | - * This method executes for ALL EE Admin pages. |
|
738 | - * |
|
739 | - * @access public |
|
740 | - * @return void |
|
741 | - */ |
|
742 | - public function admin_init_global() |
|
743 | - { |
|
744 | - $post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null; |
|
745 | - // its possible this is a new save so let's catch that instead |
|
746 | - $post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post; |
|
747 | - $post_type = $post ? $post->post_type : false; |
|
748 | - $current_route = isset($this->_req_data['current_route']) |
|
749 | - ? $this->_req_data['current_route'] |
|
750 | - : 'shouldneverwork'; |
|
751 | - $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ]) |
|
752 | - ? $this->_cpt_routes[ $current_route ] |
|
753 | - : ''; |
|
754 | - add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3); |
|
755 | - add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3); |
|
756 | - if ($post_type === $route_to_check) { |
|
757 | - add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2); |
|
758 | - } |
|
759 | - // now let's filter redirect if we're on a revision page and the revision is for an event CPT. |
|
760 | - $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null; |
|
761 | - if (! empty($revision)) { |
|
762 | - $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null; |
|
763 | - // doing a restore? |
|
764 | - if (! empty($action) && $action === 'restore') { |
|
765 | - // get post for revision |
|
766 | - $rev_post = get_post($revision); |
|
767 | - $rev_parent = get_post($rev_post->post_parent); |
|
768 | - // only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts. |
|
769 | - if ($rev_parent && $rev_parent->post_type === $this->page_slug) { |
|
770 | - add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2); |
|
771 | - // restores of revisions |
|
772 | - add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2); |
|
773 | - } |
|
774 | - } |
|
775 | - } |
|
776 | - // NOTE we ONLY want to run these hooks if we're on the right class for the given post type. Otherwise we could see some really freaky things happen! |
|
777 | - if ($post_type && $post_type === $route_to_check) { |
|
778 | - // $post_id, $post |
|
779 | - add_action('save_post', array($this, 'insert_update'), 10, 3); |
|
780 | - // $post_id |
|
781 | - add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10); |
|
782 | - add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10); |
|
783 | - add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10); |
|
784 | - add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10); |
|
785 | - } |
|
786 | - } |
|
787 | - |
|
788 | - |
|
789 | - /** |
|
790 | - * Callback for the WordPress trashed_post hook. |
|
791 | - * Execute some basic checks before calling the trash_cpt_item declared in the child class. |
|
792 | - * |
|
793 | - * @param int $post_id |
|
794 | - * @throws EE_Error |
|
795 | - * @throws ReflectionException |
|
796 | - */ |
|
797 | - public function before_trash_cpt_item($post_id) |
|
798 | - { |
|
799 | - $this->_set_model_object($post_id, true, 'trash'); |
|
800 | - // if our cpt object isn't existent then get out immediately. |
|
801 | - if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) { |
|
802 | - return; |
|
803 | - } |
|
804 | - $this->trash_cpt_item($post_id); |
|
805 | - } |
|
806 | - |
|
807 | - |
|
808 | - /** |
|
809 | - * Callback for the WordPress untrashed_post hook. |
|
810 | - * Execute some basic checks before calling the restore_cpt_method in the child class. |
|
811 | - * |
|
812 | - * @param $post_id |
|
813 | - * @throws EE_Error |
|
814 | - * @throws ReflectionException |
|
815 | - */ |
|
816 | - public function before_restore_cpt_item($post_id) |
|
817 | - { |
|
818 | - $this->_set_model_object($post_id, true, 'restore'); |
|
819 | - // if our cpt object isn't existent then get out immediately. |
|
820 | - if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) { |
|
821 | - return; |
|
822 | - } |
|
823 | - $this->restore_cpt_item($post_id); |
|
824 | - } |
|
825 | - |
|
826 | - |
|
827 | - /** |
|
828 | - * Callback for the WordPress after_delete_post hook. |
|
829 | - * Execute some basic checks before calling the delete_cpt_item method in the child class. |
|
830 | - * |
|
831 | - * @param $post_id |
|
832 | - * @throws EE_Error |
|
833 | - * @throws ReflectionException |
|
834 | - */ |
|
835 | - public function before_delete_cpt_item($post_id) |
|
836 | - { |
|
837 | - $this->_set_model_object($post_id, true, 'delete'); |
|
838 | - // if our cpt object isn't existent then get out immediately. |
|
839 | - if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) { |
|
840 | - return; |
|
841 | - } |
|
842 | - $this->delete_cpt_item($post_id); |
|
843 | - } |
|
844 | - |
|
845 | - |
|
846 | - /** |
|
847 | - * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message |
|
848 | - * accordingly. |
|
849 | - * |
|
850 | - * @return void |
|
851 | - * @throws EE_Error |
|
852 | - * @throws InvalidArgumentException |
|
853 | - * @throws InvalidDataTypeException |
|
854 | - * @throws InvalidInterfaceException |
|
855 | - * @throws ReflectionException |
|
856 | - */ |
|
857 | - public function verify_cpt_object() |
|
858 | - { |
|
859 | - $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label; |
|
860 | - // verify event object |
|
861 | - if (! $this->_cpt_model_obj instanceof EE_CPT_Base) { |
|
862 | - throw new EE_Error( |
|
863 | - sprintf( |
|
864 | - __( |
|
865 | - 'Something has gone wrong with the page load because we are unable to set up the object for the %1$s. This usually happens when the given id for the page route is NOT for the correct custom post type for this page', |
|
866 | - 'event_espresso' |
|
867 | - ), |
|
868 | - $label |
|
869 | - ) |
|
870 | - ); |
|
871 | - } |
|
872 | - // if auto-draft then throw an error |
|
873 | - if ($this->_cpt_model_obj->get('status') === 'auto-draft') { |
|
874 | - EE_Error::overwrite_errors(); |
|
875 | - EE_Error::add_error( |
|
876 | - sprintf( |
|
877 | - __( |
|
878 | - 'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly. All autodrafts will show up in the "draft" view of your event list table. You can delete them from there. Please click the "Add %1$s" button to refresh and restart.', |
|
879 | - 'event_espresso' |
|
880 | - ), |
|
881 | - $label |
|
882 | - ), |
|
883 | - __FILE__, |
|
884 | - __FUNCTION__, |
|
885 | - __LINE__ |
|
886 | - ); |
|
887 | - } |
|
888 | - } |
|
889 | - |
|
890 | - |
|
891 | - /** |
|
892 | - * admin_footer_scripts_global |
|
893 | - * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method |
|
894 | - * will apply on ALL EE_Admin pages. |
|
895 | - * |
|
896 | - * @access public |
|
897 | - * @return void |
|
898 | - */ |
|
899 | - public function admin_footer_scripts_global() |
|
900 | - { |
|
901 | - $this->_add_admin_page_ajax_loading_img(); |
|
902 | - $this->_add_admin_page_overlay(); |
|
903 | - } |
|
904 | - |
|
905 | - |
|
906 | - /** |
|
907 | - * add in any global scripts for cpt routes |
|
908 | - * |
|
909 | - * @return void |
|
910 | - * @throws EE_Error |
|
911 | - */ |
|
912 | - public function load_global_scripts_styles() |
|
913 | - { |
|
914 | - parent::load_global_scripts_styles(); |
|
915 | - if ($this->_cpt_model_obj instanceof EE_CPT_Base) { |
|
916 | - // setup custom post status object for localize script but only if we've got a cpt object |
|
917 | - $statuses = $this->_cpt_model_obj->get_custom_post_statuses(); |
|
918 | - if (! empty($statuses)) { |
|
919 | - // get ALL statuses! |
|
920 | - $statuses = $this->_cpt_model_obj->get_all_post_statuses(); |
|
921 | - // setup object |
|
922 | - $ee_cpt_statuses = array(); |
|
923 | - foreach ($statuses as $status => $label) { |
|
924 | - $ee_cpt_statuses[ $status ] = array( |
|
925 | - 'label' => $label, |
|
926 | - 'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label), |
|
927 | - ); |
|
928 | - } |
|
929 | - wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses); |
|
930 | - } |
|
931 | - } |
|
932 | - } |
|
933 | - |
|
934 | - |
|
935 | - /** |
|
936 | - * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL |
|
937 | - * insert/updates |
|
938 | - * |
|
939 | - * @param int $post_id ID of post being updated |
|
940 | - * @param WP_Post $post Post object from WP |
|
941 | - * @param bool $update Whether this is an update or a new save. |
|
942 | - * @return void |
|
943 | - * @throws EE_Error |
|
944 | - * @throws ReflectionException |
|
945 | - */ |
|
946 | - public function insert_update($post_id, $post, $update) |
|
947 | - { |
|
948 | - // make sure that if this is a revision OR trash action that we don't do any updates! |
|
949 | - if (isset($this->_req_data['action']) |
|
950 | - && ( |
|
951 | - $this->_req_data['action'] === 'restore' |
|
952 | - || $this->_req_data['action'] === 'trash' |
|
953 | - ) |
|
954 | - ) { |
|
955 | - return; |
|
956 | - } |
|
957 | - $this->_set_model_object($post_id, true, 'insert_update'); |
|
958 | - // if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit. |
|
959 | - if ($update |
|
960 | - && ( |
|
961 | - ! $this->_cpt_model_obj instanceof EE_CPT_Base |
|
962 | - || $this->_cpt_model_obj->ID() !== $post_id |
|
963 | - ) |
|
964 | - ) { |
|
965 | - return; |
|
966 | - } |
|
967 | - // check for autosave and update our req_data property accordingly. |
|
968 | - /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) { |
|
497 | + } |
|
498 | + |
|
499 | + |
|
500 | + /** |
|
501 | + * if this post is a draft or scheduled post then we provide a preview button for user to click |
|
502 | + * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter. |
|
503 | + * |
|
504 | + * @param string $return the current html |
|
505 | + * @param int $id the post id for the page |
|
506 | + * @param string $new_title What the title is |
|
507 | + * @param string $new_slug what the slug is |
|
508 | + * @return string The new html string for the permalink area |
|
509 | + */ |
|
510 | + public function preview_button_html($return, $id, $new_title, $new_slug) |
|
511 | + { |
|
512 | + $post = get_post($id); |
|
513 | + if ('publish' !== get_post_status($post)) { |
|
514 | + $return .= '<span_id="view-post-btn"><a target="_blank" href="' |
|
515 | + . get_preview_post_link($id) |
|
516 | + . '" class="button button-small">' |
|
517 | + . __('Preview', 'event_espresso') |
|
518 | + . '</a></span>' |
|
519 | + . "\n"; |
|
520 | + } |
|
521 | + return $return; |
|
522 | + } |
|
523 | + |
|
524 | + |
|
525 | + /** |
|
526 | + * add our custom post stati dropdown on the wp post page for this cpt |
|
527 | + * |
|
528 | + * @return void |
|
529 | + */ |
|
530 | + public function custom_post_stati_dropdown() |
|
531 | + { |
|
532 | + |
|
533 | + $statuses = $this->_cpt_model_obj->get_custom_post_statuses(); |
|
534 | + $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses) |
|
535 | + ? $statuses[ $this->_cpt_model_obj->status() ] |
|
536 | + : ''; |
|
537 | + $template_args = array( |
|
538 | + 'cur_status' => $this->_cpt_model_obj->status(), |
|
539 | + 'statuses' => $statuses, |
|
540 | + 'cur_status_label' => $cur_status_label, |
|
541 | + 'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label), |
|
542 | + ); |
|
543 | + // we'll add a trash post status (WP doesn't add one for some reason) |
|
544 | + if ($this->_cpt_model_obj->status() === 'trash') { |
|
545 | + $template_args['cur_status_label'] = __('Trashed', 'event_espresso'); |
|
546 | + $statuses['trash'] = __('Trashed', 'event_espresso'); |
|
547 | + $template_args['statuses'] = $statuses; |
|
548 | + } |
|
549 | + |
|
550 | + $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php'; |
|
551 | + EEH_Template::display_template($template, $template_args); |
|
552 | + } |
|
553 | + |
|
554 | + |
|
555 | + public function setup_autosave_hooks() |
|
556 | + { |
|
557 | + $this->_set_autosave_containers(); |
|
558 | + $this->_load_autosave_scripts_styles(); |
|
559 | + } |
|
560 | + |
|
561 | + |
|
562 | + /** |
|
563 | + * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available |
|
564 | + * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check |
|
565 | + * for the nonce in here, but then this method looks for two things: |
|
566 | + * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR |
|
567 | + * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an |
|
568 | + * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the |
|
569 | + * $_template_args property should be used to hold the $data array. We're expecting the following things set in |
|
570 | + * template args. |
|
571 | + * 1. $template_args['error'] = IF there is an error you can add the message in here. |
|
572 | + * 2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go' |
|
573 | + * => 'values_to_add'. In other words, for the datetime metabox we'll have something like |
|
574 | + * $this->_template_args['data']['items'] = array( |
|
575 | + * 'event-datetime-ids' => '1,2,3'; |
|
576 | + * ); |
|
577 | + * Keep in mind the following things: |
|
578 | + * - "where" index is for the input with the id as that string. |
|
579 | + * - "what" index is what will be used for the value of that input. |
|
580 | + * |
|
581 | + * @return void |
|
582 | + * @throws EE_Error |
|
583 | + */ |
|
584 | + public function do_extra_autosave_stuff() |
|
585 | + { |
|
586 | + // next let's check for the autosave nonce (we'll use _verify_nonce ) |
|
587 | + $nonce = isset($this->_req_data['autosavenonce']) |
|
588 | + ? $this->_req_data['autosavenonce'] |
|
589 | + : null; |
|
590 | + $this->_verify_nonce($nonce, 'autosave'); |
|
591 | + // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it) |
|
592 | + if (! defined('DOING_AUTOSAVE')) { |
|
593 | + define('DOING_AUTOSAVE', true); |
|
594 | + } |
|
595 | + // if we made it here then the nonce checked out. Let's run our methods and actions |
|
596 | + $autosave = "_ee_autosave_{$this->_current_view}"; |
|
597 | + if (method_exists($this, $autosave)) { |
|
598 | + $this->$autosave(); |
|
599 | + } else { |
|
600 | + $this->_template_args['success'] = true; |
|
601 | + } |
|
602 | + do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this); |
|
603 | + do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this); |
|
604 | + // now let's return json |
|
605 | + $this->_return_json(); |
|
606 | + } |
|
607 | + |
|
608 | + |
|
609 | + /** |
|
610 | + * This takes care of setting up default routes and pages that utilize the core WP admin pages. |
|
611 | + * Child classes can override the defaults (in cases for adding metaboxes etc.) |
|
612 | + * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work! |
|
613 | + * |
|
614 | + * @access protected |
|
615 | + * @return void |
|
616 | + * @throws ReflectionException |
|
617 | + * @throws EE_Error |
|
618 | + */ |
|
619 | + protected function _extend_page_config_for_cpt() |
|
620 | + { |
|
621 | + // before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug |
|
622 | + if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) { |
|
623 | + return; |
|
624 | + } |
|
625 | + // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes |
|
626 | + if (! empty($this->_cpt_object)) { |
|
627 | + $this->_page_routes = array_merge( |
|
628 | + array( |
|
629 | + 'create_new' => '_create_new_cpt_item', |
|
630 | + 'edit' => '_edit_cpt_item', |
|
631 | + ), |
|
632 | + $this->_page_routes |
|
633 | + ); |
|
634 | + $this->_page_config = array_merge( |
|
635 | + array( |
|
636 | + 'create_new' => array( |
|
637 | + 'nav' => array( |
|
638 | + 'label' => $this->_cpt_object->labels->add_new_item, |
|
639 | + 'order' => 5, |
|
640 | + ), |
|
641 | + 'require_nonce' => false, |
|
642 | + ), |
|
643 | + 'edit' => array( |
|
644 | + 'nav' => array( |
|
645 | + 'label' => $this->_cpt_object->labels->edit_item, |
|
646 | + 'order' => 5, |
|
647 | + 'persistent' => false, |
|
648 | + 'url' => '', |
|
649 | + ), |
|
650 | + 'require_nonce' => false, |
|
651 | + ), |
|
652 | + ), |
|
653 | + $this->_page_config |
|
654 | + ); |
|
655 | + } |
|
656 | + // load the next section only if this is a matching cpt route as set in the cpt routes array. |
|
657 | + if (! isset($this->_cpt_routes[ $this->_req_action ])) { |
|
658 | + return; |
|
659 | + } |
|
660 | + $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false; |
|
661 | + // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') ); |
|
662 | + if (empty($this->_cpt_object)) { |
|
663 | + $msg = sprintf( |
|
664 | + __( |
|
665 | + 'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this: 1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).', |
|
666 | + 'event_espresso' |
|
667 | + ), |
|
668 | + $this->page_slug, |
|
669 | + $this->_req_action, |
|
670 | + get_class($this) |
|
671 | + ); |
|
672 | + throw new EE_Error($msg); |
|
673 | + } |
|
674 | + if ($this->_cpt_route) { |
|
675 | + $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null; |
|
676 | + $this->_set_model_object($id); |
|
677 | + } |
|
678 | + } |
|
679 | + |
|
680 | + |
|
681 | + /** |
|
682 | + * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id. |
|
683 | + * |
|
684 | + * @access protected |
|
685 | + * @param int $id The id to retrieve the model object for. If empty we set a default object. |
|
686 | + * @param bool $ignore_route_check |
|
687 | + * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT |
|
688 | + * @throws EE_Error |
|
689 | + * @throws InvalidArgumentException |
|
690 | + * @throws InvalidDataTypeException |
|
691 | + * @throws InvalidInterfaceException |
|
692 | + * @throws ReflectionException |
|
693 | + */ |
|
694 | + protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '') |
|
695 | + { |
|
696 | + $model = null; |
|
697 | + if (empty($this->_cpt_model_names) |
|
698 | + || ( |
|
699 | + ! $ignore_route_check |
|
700 | + && ! isset($this->_cpt_routes[ $this->_req_action ]) |
|
701 | + ) || ( |
|
702 | + $this->_cpt_model_obj instanceof EE_CPT_Base |
|
703 | + && $this->_cpt_model_obj->ID() === $id |
|
704 | + ) |
|
705 | + ) { |
|
706 | + // get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent. |
|
707 | + return; |
|
708 | + } |
|
709 | + // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions |
|
710 | + if ($ignore_route_check) { |
|
711 | + $post_type = get_post_type($id); |
|
712 | + /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */ |
|
713 | + $custom_post_types = $this->loader->getShared( |
|
714 | + 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' |
|
715 | + ); |
|
716 | + $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type); |
|
717 | + if (isset($model_names[ $post_type ])) { |
|
718 | + $model = EE_Registry::instance()->load_model($model_names[ $post_type ]); |
|
719 | + } |
|
720 | + } else { |
|
721 | + $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]); |
|
722 | + } |
|
723 | + if ($model instanceof EEM_Base) { |
|
724 | + $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object(); |
|
725 | + } |
|
726 | + do_action( |
|
727 | + 'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object', |
|
728 | + $this->_cpt_model_obj, |
|
729 | + $req_type |
|
730 | + ); |
|
731 | + } |
|
732 | + |
|
733 | + |
|
734 | + /** |
|
735 | + * admin_init_global |
|
736 | + * This runs all the code that we want executed within the WP admin_init hook. |
|
737 | + * This method executes for ALL EE Admin pages. |
|
738 | + * |
|
739 | + * @access public |
|
740 | + * @return void |
|
741 | + */ |
|
742 | + public function admin_init_global() |
|
743 | + { |
|
744 | + $post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null; |
|
745 | + // its possible this is a new save so let's catch that instead |
|
746 | + $post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post; |
|
747 | + $post_type = $post ? $post->post_type : false; |
|
748 | + $current_route = isset($this->_req_data['current_route']) |
|
749 | + ? $this->_req_data['current_route'] |
|
750 | + : 'shouldneverwork'; |
|
751 | + $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ]) |
|
752 | + ? $this->_cpt_routes[ $current_route ] |
|
753 | + : ''; |
|
754 | + add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3); |
|
755 | + add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3); |
|
756 | + if ($post_type === $route_to_check) { |
|
757 | + add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2); |
|
758 | + } |
|
759 | + // now let's filter redirect if we're on a revision page and the revision is for an event CPT. |
|
760 | + $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null; |
|
761 | + if (! empty($revision)) { |
|
762 | + $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null; |
|
763 | + // doing a restore? |
|
764 | + if (! empty($action) && $action === 'restore') { |
|
765 | + // get post for revision |
|
766 | + $rev_post = get_post($revision); |
|
767 | + $rev_parent = get_post($rev_post->post_parent); |
|
768 | + // only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts. |
|
769 | + if ($rev_parent && $rev_parent->post_type === $this->page_slug) { |
|
770 | + add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2); |
|
771 | + // restores of revisions |
|
772 | + add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2); |
|
773 | + } |
|
774 | + } |
|
775 | + } |
|
776 | + // NOTE we ONLY want to run these hooks if we're on the right class for the given post type. Otherwise we could see some really freaky things happen! |
|
777 | + if ($post_type && $post_type === $route_to_check) { |
|
778 | + // $post_id, $post |
|
779 | + add_action('save_post', array($this, 'insert_update'), 10, 3); |
|
780 | + // $post_id |
|
781 | + add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10); |
|
782 | + add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10); |
|
783 | + add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10); |
|
784 | + add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10); |
|
785 | + } |
|
786 | + } |
|
787 | + |
|
788 | + |
|
789 | + /** |
|
790 | + * Callback for the WordPress trashed_post hook. |
|
791 | + * Execute some basic checks before calling the trash_cpt_item declared in the child class. |
|
792 | + * |
|
793 | + * @param int $post_id |
|
794 | + * @throws EE_Error |
|
795 | + * @throws ReflectionException |
|
796 | + */ |
|
797 | + public function before_trash_cpt_item($post_id) |
|
798 | + { |
|
799 | + $this->_set_model_object($post_id, true, 'trash'); |
|
800 | + // if our cpt object isn't existent then get out immediately. |
|
801 | + if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) { |
|
802 | + return; |
|
803 | + } |
|
804 | + $this->trash_cpt_item($post_id); |
|
805 | + } |
|
806 | + |
|
807 | + |
|
808 | + /** |
|
809 | + * Callback for the WordPress untrashed_post hook. |
|
810 | + * Execute some basic checks before calling the restore_cpt_method in the child class. |
|
811 | + * |
|
812 | + * @param $post_id |
|
813 | + * @throws EE_Error |
|
814 | + * @throws ReflectionException |
|
815 | + */ |
|
816 | + public function before_restore_cpt_item($post_id) |
|
817 | + { |
|
818 | + $this->_set_model_object($post_id, true, 'restore'); |
|
819 | + // if our cpt object isn't existent then get out immediately. |
|
820 | + if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) { |
|
821 | + return; |
|
822 | + } |
|
823 | + $this->restore_cpt_item($post_id); |
|
824 | + } |
|
825 | + |
|
826 | + |
|
827 | + /** |
|
828 | + * Callback for the WordPress after_delete_post hook. |
|
829 | + * Execute some basic checks before calling the delete_cpt_item method in the child class. |
|
830 | + * |
|
831 | + * @param $post_id |
|
832 | + * @throws EE_Error |
|
833 | + * @throws ReflectionException |
|
834 | + */ |
|
835 | + public function before_delete_cpt_item($post_id) |
|
836 | + { |
|
837 | + $this->_set_model_object($post_id, true, 'delete'); |
|
838 | + // if our cpt object isn't existent then get out immediately. |
|
839 | + if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) { |
|
840 | + return; |
|
841 | + } |
|
842 | + $this->delete_cpt_item($post_id); |
|
843 | + } |
|
844 | + |
|
845 | + |
|
846 | + /** |
|
847 | + * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message |
|
848 | + * accordingly. |
|
849 | + * |
|
850 | + * @return void |
|
851 | + * @throws EE_Error |
|
852 | + * @throws InvalidArgumentException |
|
853 | + * @throws InvalidDataTypeException |
|
854 | + * @throws InvalidInterfaceException |
|
855 | + * @throws ReflectionException |
|
856 | + */ |
|
857 | + public function verify_cpt_object() |
|
858 | + { |
|
859 | + $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label; |
|
860 | + // verify event object |
|
861 | + if (! $this->_cpt_model_obj instanceof EE_CPT_Base) { |
|
862 | + throw new EE_Error( |
|
863 | + sprintf( |
|
864 | + __( |
|
865 | + 'Something has gone wrong with the page load because we are unable to set up the object for the %1$s. This usually happens when the given id for the page route is NOT for the correct custom post type for this page', |
|
866 | + 'event_espresso' |
|
867 | + ), |
|
868 | + $label |
|
869 | + ) |
|
870 | + ); |
|
871 | + } |
|
872 | + // if auto-draft then throw an error |
|
873 | + if ($this->_cpt_model_obj->get('status') === 'auto-draft') { |
|
874 | + EE_Error::overwrite_errors(); |
|
875 | + EE_Error::add_error( |
|
876 | + sprintf( |
|
877 | + __( |
|
878 | + 'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly. All autodrafts will show up in the "draft" view of your event list table. You can delete them from there. Please click the "Add %1$s" button to refresh and restart.', |
|
879 | + 'event_espresso' |
|
880 | + ), |
|
881 | + $label |
|
882 | + ), |
|
883 | + __FILE__, |
|
884 | + __FUNCTION__, |
|
885 | + __LINE__ |
|
886 | + ); |
|
887 | + } |
|
888 | + } |
|
889 | + |
|
890 | + |
|
891 | + /** |
|
892 | + * admin_footer_scripts_global |
|
893 | + * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method |
|
894 | + * will apply on ALL EE_Admin pages. |
|
895 | + * |
|
896 | + * @access public |
|
897 | + * @return void |
|
898 | + */ |
|
899 | + public function admin_footer_scripts_global() |
|
900 | + { |
|
901 | + $this->_add_admin_page_ajax_loading_img(); |
|
902 | + $this->_add_admin_page_overlay(); |
|
903 | + } |
|
904 | + |
|
905 | + |
|
906 | + /** |
|
907 | + * add in any global scripts for cpt routes |
|
908 | + * |
|
909 | + * @return void |
|
910 | + * @throws EE_Error |
|
911 | + */ |
|
912 | + public function load_global_scripts_styles() |
|
913 | + { |
|
914 | + parent::load_global_scripts_styles(); |
|
915 | + if ($this->_cpt_model_obj instanceof EE_CPT_Base) { |
|
916 | + // setup custom post status object for localize script but only if we've got a cpt object |
|
917 | + $statuses = $this->_cpt_model_obj->get_custom_post_statuses(); |
|
918 | + if (! empty($statuses)) { |
|
919 | + // get ALL statuses! |
|
920 | + $statuses = $this->_cpt_model_obj->get_all_post_statuses(); |
|
921 | + // setup object |
|
922 | + $ee_cpt_statuses = array(); |
|
923 | + foreach ($statuses as $status => $label) { |
|
924 | + $ee_cpt_statuses[ $status ] = array( |
|
925 | + 'label' => $label, |
|
926 | + 'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label), |
|
927 | + ); |
|
928 | + } |
|
929 | + wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses); |
|
930 | + } |
|
931 | + } |
|
932 | + } |
|
933 | + |
|
934 | + |
|
935 | + /** |
|
936 | + * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL |
|
937 | + * insert/updates |
|
938 | + * |
|
939 | + * @param int $post_id ID of post being updated |
|
940 | + * @param WP_Post $post Post object from WP |
|
941 | + * @param bool $update Whether this is an update or a new save. |
|
942 | + * @return void |
|
943 | + * @throws EE_Error |
|
944 | + * @throws ReflectionException |
|
945 | + */ |
|
946 | + public function insert_update($post_id, $post, $update) |
|
947 | + { |
|
948 | + // make sure that if this is a revision OR trash action that we don't do any updates! |
|
949 | + if (isset($this->_req_data['action']) |
|
950 | + && ( |
|
951 | + $this->_req_data['action'] === 'restore' |
|
952 | + || $this->_req_data['action'] === 'trash' |
|
953 | + ) |
|
954 | + ) { |
|
955 | + return; |
|
956 | + } |
|
957 | + $this->_set_model_object($post_id, true, 'insert_update'); |
|
958 | + // if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit. |
|
959 | + if ($update |
|
960 | + && ( |
|
961 | + ! $this->_cpt_model_obj instanceof EE_CPT_Base |
|
962 | + || $this->_cpt_model_obj->ID() !== $post_id |
|
963 | + ) |
|
964 | + ) { |
|
965 | + return; |
|
966 | + } |
|
967 | + // check for autosave and update our req_data property accordingly. |
|
968 | + /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) { |
|
969 | 969 | foreach( (array) $this->_req_data['ee_autosave_data'] as $id => $values ) { |
970 | 970 | |
971 | 971 | foreach ( (array) $values as $key => $value ) { |
@@ -975,537 +975,537 @@ discard block |
||
975 | 975 | |
976 | 976 | }/**/ // TODO reactivate after autosave is implemented in 4.2 |
977 | 977 | |
978 | - // take care of updating any selected page_template IF this cpt supports it. |
|
979 | - if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) { |
|
980 | - // wp version aware. |
|
981 | - if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) { |
|
982 | - $page_templates = wp_get_theme()->get_page_templates(); |
|
983 | - } else { |
|
984 | - $post->page_template = $this->_req_data['page_template']; |
|
985 | - $page_templates = wp_get_theme()->get_page_templates($post); |
|
986 | - } |
|
987 | - if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) { |
|
988 | - EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
989 | - } else { |
|
990 | - update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']); |
|
991 | - } |
|
992 | - } |
|
993 | - if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { |
|
994 | - return; |
|
995 | - } //TODO we'll remove this after reimplementing autosave in 4.2 |
|
996 | - $this->_insert_update_cpt_item($post_id, $post); |
|
997 | - } |
|
998 | - |
|
999 | - |
|
1000 | - /** |
|
1001 | - * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time` |
|
1002 | - * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes |
|
1003 | - * so we don't have to check for our CPT. |
|
1004 | - * |
|
1005 | - * @param int $post_id ID of the post |
|
1006 | - * @return void |
|
1007 | - */ |
|
1008 | - public function dont_permanently_delete_ee_cpts($post_id) |
|
1009 | - { |
|
1010 | - // only do this if we're actually processing one of our CPTs |
|
1011 | - // if our cpt object isn't existent then get out immediately. |
|
1012 | - if (! $this->_cpt_model_obj instanceof EE_CPT_Base) { |
|
1013 | - return; |
|
1014 | - } |
|
1015 | - delete_post_meta($post_id, '_wp_trash_meta_status'); |
|
1016 | - delete_post_meta($post_id, '_wp_trash_meta_time'); |
|
1017 | - // our cpts may have comments so let's take care of that too |
|
1018 | - delete_post_meta($post_id, '_wp_trash_meta_comments_status'); |
|
1019 | - } |
|
1020 | - |
|
1021 | - |
|
1022 | - /** |
|
1023 | - * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is |
|
1024 | - * triggered that we restore related items. In order to work cpt classes MUST have a restore_cpt_revision method |
|
1025 | - * in them. We also have our OWN action in here so addons can hook into the restore process easily. |
|
1026 | - * |
|
1027 | - * @param int $post_id ID of cpt item |
|
1028 | - * @param int $revision_id ID of revision being restored |
|
1029 | - * @return void |
|
1030 | - */ |
|
1031 | - public function restore_revision($post_id, $revision_id) |
|
1032 | - { |
|
1033 | - $this->_restore_cpt_item($post_id, $revision_id); |
|
1034 | - // global action |
|
1035 | - do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id); |
|
1036 | - // class specific action so you can limit hooking into a specific page. |
|
1037 | - do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id); |
|
1038 | - } |
|
1039 | - |
|
1040 | - |
|
1041 | - /** |
|
1042 | - * @see restore_revision() for details |
|
1043 | - * @param int $post_id ID of cpt item |
|
1044 | - * @param int $revision_id ID of revision for item |
|
1045 | - * @return void |
|
1046 | - */ |
|
1047 | - abstract protected function _restore_cpt_item($post_id, $revision_id); |
|
1048 | - |
|
1049 | - |
|
1050 | - /** |
|
1051 | - * Execution of this method is added to the end of the load_page_dependencies method in the parent |
|
1052 | - * so that we can fix a bug where default core metaboxes were not being called in the sidebar. |
|
1053 | - * To fix we have to reset the current_screen using the page_slug |
|
1054 | - * (which is identical - or should be - to our registered_post_type id.) |
|
1055 | - * Also, since the core WP file loads the admin_header.php for WP |
|
1056 | - * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early) |
|
1057 | - * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set). |
|
1058 | - * |
|
1059 | - * @return void |
|
1060 | - * @throws EE_Error |
|
1061 | - */ |
|
1062 | - public function modify_current_screen() |
|
1063 | - { |
|
1064 | - // ONLY do this if the current page_route IS a cpt route |
|
1065 | - if (! $this->_cpt_route) { |
|
1066 | - return; |
|
1067 | - } |
|
1068 | - // routing things REALLY early b/c this is a cpt admin page |
|
1069 | - set_current_screen($this->_cpt_routes[ $this->_req_action ]); |
|
1070 | - $this->_current_screen = get_current_screen(); |
|
1071 | - $this->_current_screen->base = 'event-espresso'; |
|
1072 | - $this->_add_help_tabs(); // we make sure we add any help tabs back in! |
|
1073 | - /*try { |
|
978 | + // take care of updating any selected page_template IF this cpt supports it. |
|
979 | + if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) { |
|
980 | + // wp version aware. |
|
981 | + if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) { |
|
982 | + $page_templates = wp_get_theme()->get_page_templates(); |
|
983 | + } else { |
|
984 | + $post->page_template = $this->_req_data['page_template']; |
|
985 | + $page_templates = wp_get_theme()->get_page_templates($post); |
|
986 | + } |
|
987 | + if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) { |
|
988 | + EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
989 | + } else { |
|
990 | + update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']); |
|
991 | + } |
|
992 | + } |
|
993 | + if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { |
|
994 | + return; |
|
995 | + } //TODO we'll remove this after reimplementing autosave in 4.2 |
|
996 | + $this->_insert_update_cpt_item($post_id, $post); |
|
997 | + } |
|
998 | + |
|
999 | + |
|
1000 | + /** |
|
1001 | + * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time` |
|
1002 | + * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes |
|
1003 | + * so we don't have to check for our CPT. |
|
1004 | + * |
|
1005 | + * @param int $post_id ID of the post |
|
1006 | + * @return void |
|
1007 | + */ |
|
1008 | + public function dont_permanently_delete_ee_cpts($post_id) |
|
1009 | + { |
|
1010 | + // only do this if we're actually processing one of our CPTs |
|
1011 | + // if our cpt object isn't existent then get out immediately. |
|
1012 | + if (! $this->_cpt_model_obj instanceof EE_CPT_Base) { |
|
1013 | + return; |
|
1014 | + } |
|
1015 | + delete_post_meta($post_id, '_wp_trash_meta_status'); |
|
1016 | + delete_post_meta($post_id, '_wp_trash_meta_time'); |
|
1017 | + // our cpts may have comments so let's take care of that too |
|
1018 | + delete_post_meta($post_id, '_wp_trash_meta_comments_status'); |
|
1019 | + } |
|
1020 | + |
|
1021 | + |
|
1022 | + /** |
|
1023 | + * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is |
|
1024 | + * triggered that we restore related items. In order to work cpt classes MUST have a restore_cpt_revision method |
|
1025 | + * in them. We also have our OWN action in here so addons can hook into the restore process easily. |
|
1026 | + * |
|
1027 | + * @param int $post_id ID of cpt item |
|
1028 | + * @param int $revision_id ID of revision being restored |
|
1029 | + * @return void |
|
1030 | + */ |
|
1031 | + public function restore_revision($post_id, $revision_id) |
|
1032 | + { |
|
1033 | + $this->_restore_cpt_item($post_id, $revision_id); |
|
1034 | + // global action |
|
1035 | + do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id); |
|
1036 | + // class specific action so you can limit hooking into a specific page. |
|
1037 | + do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id); |
|
1038 | + } |
|
1039 | + |
|
1040 | + |
|
1041 | + /** |
|
1042 | + * @see restore_revision() for details |
|
1043 | + * @param int $post_id ID of cpt item |
|
1044 | + * @param int $revision_id ID of revision for item |
|
1045 | + * @return void |
|
1046 | + */ |
|
1047 | + abstract protected function _restore_cpt_item($post_id, $revision_id); |
|
1048 | + |
|
1049 | + |
|
1050 | + /** |
|
1051 | + * Execution of this method is added to the end of the load_page_dependencies method in the parent |
|
1052 | + * so that we can fix a bug where default core metaboxes were not being called in the sidebar. |
|
1053 | + * To fix we have to reset the current_screen using the page_slug |
|
1054 | + * (which is identical - or should be - to our registered_post_type id.) |
|
1055 | + * Also, since the core WP file loads the admin_header.php for WP |
|
1056 | + * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early) |
|
1057 | + * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set). |
|
1058 | + * |
|
1059 | + * @return void |
|
1060 | + * @throws EE_Error |
|
1061 | + */ |
|
1062 | + public function modify_current_screen() |
|
1063 | + { |
|
1064 | + // ONLY do this if the current page_route IS a cpt route |
|
1065 | + if (! $this->_cpt_route) { |
|
1066 | + return; |
|
1067 | + } |
|
1068 | + // routing things REALLY early b/c this is a cpt admin page |
|
1069 | + set_current_screen($this->_cpt_routes[ $this->_req_action ]); |
|
1070 | + $this->_current_screen = get_current_screen(); |
|
1071 | + $this->_current_screen->base = 'event-espresso'; |
|
1072 | + $this->_add_help_tabs(); // we make sure we add any help tabs back in! |
|
1073 | + /*try { |
|
1074 | 1074 | $this->_route_admin_request(); |
1075 | 1075 | } catch ( EE_Error $e ) { |
1076 | 1076 | $e->get_error(); |
1077 | 1077 | }/**/ |
1078 | - } |
|
1079 | - |
|
1080 | - |
|
1081 | - /** |
|
1082 | - * This allows child classes to modify the default editor title that appears when people add a new or edit an |
|
1083 | - * existing CPT item. * This uses the _labels property set by the child class via _define_page_props. Just make |
|
1084 | - * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the |
|
1085 | - * default to be. |
|
1086 | - * |
|
1087 | - * @param string $title The new title (or existing if there is no editor_title defined) |
|
1088 | - * @return string |
|
1089 | - */ |
|
1090 | - public function add_custom_editor_default_title($title) |
|
1091 | - { |
|
1092 | - return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]) |
|
1093 | - ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ] |
|
1094 | - : $title; |
|
1095 | - } |
|
1096 | - |
|
1097 | - |
|
1098 | - /** |
|
1099 | - * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated |
|
1100 | - * |
|
1101 | - * @param string $shortlink The already generated shortlink |
|
1102 | - * @param int $id Post ID for this item |
|
1103 | - * @param string $context The context for the link |
|
1104 | - * @param bool $allow_slugs Whether to allow post slugs in the shortlink. |
|
1105 | - * @return string |
|
1106 | - */ |
|
1107 | - public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs) |
|
1108 | - { |
|
1109 | - if (! empty($id) && get_option('permalink_structure') !== '') { |
|
1110 | - $post = get_post($id); |
|
1111 | - if (isset($post->post_type) && $this->page_slug === $post->post_type) { |
|
1112 | - $shortlink = home_url('?p=' . $post->ID); |
|
1113 | - } |
|
1114 | - } |
|
1115 | - return $shortlink; |
|
1116 | - } |
|
1117 | - |
|
1118 | - |
|
1119 | - /** |
|
1120 | - * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's |
|
1121 | - * already run in modify_current_screen()) |
|
1122 | - * |
|
1123 | - * @return void |
|
1124 | - * @throws EE_Error |
|
1125 | - * @throws ReflectionException |
|
1126 | - */ |
|
1127 | - public function route_admin_request() |
|
1128 | - { |
|
1129 | - if ($this->_cpt_route) { |
|
1130 | - return; |
|
1131 | - } |
|
1132 | - try { |
|
1133 | - $this->_route_admin_request(); |
|
1134 | - } catch (EE_Error $e) { |
|
1135 | - $e->get_error(); |
|
1136 | - } |
|
1137 | - } |
|
1138 | - |
|
1139 | - |
|
1140 | - /** |
|
1141 | - * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves |
|
1142 | - * |
|
1143 | - * @return void |
|
1144 | - */ |
|
1145 | - public function cpt_post_form_hidden_input() |
|
1146 | - { |
|
1147 | - echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />'; |
|
1148 | - // we're also going to add the route value and the current page so we can direct autosave parsing correctly |
|
1149 | - echo '<div id="ee-cpt-hidden-inputs">'; |
|
1150 | - echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />'; |
|
1151 | - echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />'; |
|
1152 | - echo '</div>'; |
|
1153 | - } |
|
1154 | - |
|
1155 | - |
|
1156 | - /** |
|
1157 | - * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes. |
|
1158 | - * |
|
1159 | - * @param string $location Original location url |
|
1160 | - * @param int $status Status for http header |
|
1161 | - * @return string new (or original) url to redirect to. |
|
1162 | - * @throws EE_Error |
|
1163 | - */ |
|
1164 | - public function revision_redirect($location, $status) |
|
1165 | - { |
|
1166 | - // get revision |
|
1167 | - $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null; |
|
1168 | - // can't do anything without revision so let's get out if not present |
|
1169 | - if (empty($rev_id)) { |
|
1170 | - return $location; |
|
1171 | - } |
|
1172 | - // get rev_post_data |
|
1173 | - $rev = get_post($rev_id); |
|
1174 | - $admin_url = $this->_admin_base_url; |
|
1175 | - $query_args = array( |
|
1176 | - 'action' => 'edit', |
|
1177 | - 'post' => $rev->post_parent, |
|
1178 | - 'revision' => $rev_id, |
|
1179 | - 'message' => 5, |
|
1180 | - ); |
|
1181 | - $this->_process_notices($query_args, true); |
|
1182 | - return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url); |
|
1183 | - } |
|
1184 | - |
|
1185 | - |
|
1186 | - /** |
|
1187 | - * Modify the edit post link generated by wp core function so that EE CPTs get setup differently. |
|
1188 | - * |
|
1189 | - * @param string $link the original generated link |
|
1190 | - * @param int $id post id |
|
1191 | - * @param string $context optional, defaults to display. How to write the '&' |
|
1192 | - * @return string the link |
|
1193 | - */ |
|
1194 | - public function modify_edit_post_link($link, $id, $context) |
|
1195 | - { |
|
1196 | - $post = get_post($id); |
|
1197 | - if (! isset($this->_req_data['action']) |
|
1198 | - || ! isset($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
1199 | - || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ] |
|
1200 | - ) { |
|
1201 | - return $link; |
|
1202 | - } |
|
1203 | - $query_args = array( |
|
1204 | - 'action' => isset($this->_cpt_edit_routes[ $post->post_type ]) |
|
1205 | - ? $this->_cpt_edit_routes[ $post->post_type ] |
|
1206 | - : 'edit', |
|
1207 | - 'post' => $id, |
|
1208 | - ); |
|
1209 | - return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $this->_admin_base_url); |
|
1210 | - } |
|
1211 | - |
|
1212 | - |
|
1213 | - /** |
|
1214 | - * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on |
|
1215 | - * our routes. |
|
1216 | - * |
|
1217 | - * @param string $delete_link original delete link |
|
1218 | - * @param int $post_id id of cpt object |
|
1219 | - * @param bool $force_delete whether this is forcing a hard delete instead of trash |
|
1220 | - * @return string new delete link |
|
1221 | - * @throws EE_Error |
|
1222 | - * @throws ReflectionException |
|
1223 | - */ |
|
1224 | - public function modify_delete_post_link($delete_link, $post_id, $force_delete) |
|
1225 | - { |
|
1226 | - $post = get_post($post_id); |
|
1227 | - |
|
1228 | - if (empty($this->_req_data['action']) |
|
1229 | - || ! isset($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
1230 | - || ! $post instanceof WP_Post |
|
1231 | - || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ] |
|
1232 | - ) { |
|
1233 | - return $delete_link; |
|
1234 | - } |
|
1235 | - $this->_set_model_object($post->ID, true); |
|
1236 | - |
|
1237 | - // returns something like `trash_event` or `trash_attendee` or `trash_venue` |
|
1238 | - $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj))); |
|
1239 | - |
|
1240 | - return EE_Admin_Page::add_query_args_and_nonce( |
|
1241 | - array( |
|
1242 | - 'page' => $this->_req_data['page'], |
|
1243 | - 'action' => $action, |
|
1244 | - $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name() |
|
1245 | - => $post->ID, |
|
1246 | - ), |
|
1247 | - admin_url() |
|
1248 | - ); |
|
1249 | - } |
|
1250 | - |
|
1251 | - |
|
1252 | - /** |
|
1253 | - * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php |
|
1254 | - * so that we can hijack the default redirect locations for wp custom post types |
|
1255 | - * that WE'RE using and send back to OUR routes. This should only be hooked in on the right route. |
|
1256 | - * |
|
1257 | - * @param string $location This is the incoming currently set redirect location |
|
1258 | - * @param string $post_id This is the 'ID' value of the wp_posts table |
|
1259 | - * @return string the new location to redirect to |
|
1260 | - * @throws EE_Error |
|
1261 | - */ |
|
1262 | - public function cpt_post_location_redirect($location, $post_id) |
|
1263 | - { |
|
1264 | - // we DO have a match so let's setup the url |
|
1265 | - // we have to get the post to determine our route |
|
1266 | - $post = get_post($post_id); |
|
1267 | - $edit_route = $this->_cpt_edit_routes[ $post->post_type ]; |
|
1268 | - // shared query_args |
|
1269 | - $query_args = array('action' => $edit_route, 'post' => $post_id); |
|
1270 | - $admin_url = $this->_admin_base_url; |
|
1271 | - if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) { |
|
1272 | - $status = get_post_status($post_id); |
|
1273 | - if (isset($this->_req_data['publish'])) { |
|
1274 | - switch ($status) { |
|
1275 | - case 'pending': |
|
1276 | - $message = 8; |
|
1277 | - break; |
|
1278 | - case 'future': |
|
1279 | - $message = 9; |
|
1280 | - break; |
|
1281 | - default: |
|
1282 | - $message = 6; |
|
1283 | - } |
|
1284 | - } else { |
|
1285 | - $message = 'draft' === $status ? 10 : 1; |
|
1286 | - } |
|
1287 | - } elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) { |
|
1288 | - $message = 2; |
|
1289 | - } elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) { |
|
1290 | - $message = 3; |
|
1291 | - } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') { |
|
1292 | - $message = 7; |
|
1293 | - } else { |
|
1294 | - $message = 4; |
|
1295 | - } |
|
1296 | - // change the message if the post type is not viewable on the frontend |
|
1297 | - $this->_cpt_object = get_post_type_object($post->post_type); |
|
1298 | - $message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message; |
|
1299 | - $query_args = array_merge(array('message' => $message), $query_args); |
|
1300 | - $this->_process_notices($query_args, true); |
|
1301 | - return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url); |
|
1302 | - } |
|
1303 | - |
|
1304 | - |
|
1305 | - /** |
|
1306 | - * This method is called to inject nav tabs on core WP cpt pages |
|
1307 | - * |
|
1308 | - * @access public |
|
1309 | - * @return void |
|
1310 | - * @throws EE_Error |
|
1311 | - */ |
|
1312 | - public function inject_nav_tabs() |
|
1313 | - { |
|
1314 | - // can we hijack and insert the nav_tabs? |
|
1315 | - $nav_tabs = $this->_get_main_nav_tabs(); |
|
1316 | - // first close off existing form tag |
|
1317 | - $html = '>'; |
|
1318 | - $html .= $nav_tabs; |
|
1319 | - // now let's handle the remaining tag ( missing ">" is CORRECT ) |
|
1320 | - $html .= '<span></span'; |
|
1321 | - echo $html; |
|
1322 | - } |
|
1323 | - |
|
1324 | - |
|
1325 | - /** |
|
1326 | - * This just sets up the post update messages when an update form is loaded |
|
1327 | - * |
|
1328 | - * @access public |
|
1329 | - * @param array $messages the original messages array |
|
1330 | - * @return array the new messages array |
|
1331 | - */ |
|
1332 | - public function post_update_messages($messages) |
|
1333 | - { |
|
1334 | - global $post; |
|
1335 | - $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null; |
|
1336 | - $id = empty($id) && is_object($post) ? $post->ID : null; |
|
1337 | - /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork'; |
|
1078 | + } |
|
1079 | + |
|
1080 | + |
|
1081 | + /** |
|
1082 | + * This allows child classes to modify the default editor title that appears when people add a new or edit an |
|
1083 | + * existing CPT item. * This uses the _labels property set by the child class via _define_page_props. Just make |
|
1084 | + * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the |
|
1085 | + * default to be. |
|
1086 | + * |
|
1087 | + * @param string $title The new title (or existing if there is no editor_title defined) |
|
1088 | + * @return string |
|
1089 | + */ |
|
1090 | + public function add_custom_editor_default_title($title) |
|
1091 | + { |
|
1092 | + return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]) |
|
1093 | + ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ] |
|
1094 | + : $title; |
|
1095 | + } |
|
1096 | + |
|
1097 | + |
|
1098 | + /** |
|
1099 | + * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated |
|
1100 | + * |
|
1101 | + * @param string $shortlink The already generated shortlink |
|
1102 | + * @param int $id Post ID for this item |
|
1103 | + * @param string $context The context for the link |
|
1104 | + * @param bool $allow_slugs Whether to allow post slugs in the shortlink. |
|
1105 | + * @return string |
|
1106 | + */ |
|
1107 | + public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs) |
|
1108 | + { |
|
1109 | + if (! empty($id) && get_option('permalink_structure') !== '') { |
|
1110 | + $post = get_post($id); |
|
1111 | + if (isset($post->post_type) && $this->page_slug === $post->post_type) { |
|
1112 | + $shortlink = home_url('?p=' . $post->ID); |
|
1113 | + } |
|
1114 | + } |
|
1115 | + return $shortlink; |
|
1116 | + } |
|
1117 | + |
|
1118 | + |
|
1119 | + /** |
|
1120 | + * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's |
|
1121 | + * already run in modify_current_screen()) |
|
1122 | + * |
|
1123 | + * @return void |
|
1124 | + * @throws EE_Error |
|
1125 | + * @throws ReflectionException |
|
1126 | + */ |
|
1127 | + public function route_admin_request() |
|
1128 | + { |
|
1129 | + if ($this->_cpt_route) { |
|
1130 | + return; |
|
1131 | + } |
|
1132 | + try { |
|
1133 | + $this->_route_admin_request(); |
|
1134 | + } catch (EE_Error $e) { |
|
1135 | + $e->get_error(); |
|
1136 | + } |
|
1137 | + } |
|
1138 | + |
|
1139 | + |
|
1140 | + /** |
|
1141 | + * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves |
|
1142 | + * |
|
1143 | + * @return void |
|
1144 | + */ |
|
1145 | + public function cpt_post_form_hidden_input() |
|
1146 | + { |
|
1147 | + echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />'; |
|
1148 | + // we're also going to add the route value and the current page so we can direct autosave parsing correctly |
|
1149 | + echo '<div id="ee-cpt-hidden-inputs">'; |
|
1150 | + echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />'; |
|
1151 | + echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />'; |
|
1152 | + echo '</div>'; |
|
1153 | + } |
|
1154 | + |
|
1155 | + |
|
1156 | + /** |
|
1157 | + * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes. |
|
1158 | + * |
|
1159 | + * @param string $location Original location url |
|
1160 | + * @param int $status Status for http header |
|
1161 | + * @return string new (or original) url to redirect to. |
|
1162 | + * @throws EE_Error |
|
1163 | + */ |
|
1164 | + public function revision_redirect($location, $status) |
|
1165 | + { |
|
1166 | + // get revision |
|
1167 | + $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null; |
|
1168 | + // can't do anything without revision so let's get out if not present |
|
1169 | + if (empty($rev_id)) { |
|
1170 | + return $location; |
|
1171 | + } |
|
1172 | + // get rev_post_data |
|
1173 | + $rev = get_post($rev_id); |
|
1174 | + $admin_url = $this->_admin_base_url; |
|
1175 | + $query_args = array( |
|
1176 | + 'action' => 'edit', |
|
1177 | + 'post' => $rev->post_parent, |
|
1178 | + 'revision' => $rev_id, |
|
1179 | + 'message' => 5, |
|
1180 | + ); |
|
1181 | + $this->_process_notices($query_args, true); |
|
1182 | + return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url); |
|
1183 | + } |
|
1184 | + |
|
1185 | + |
|
1186 | + /** |
|
1187 | + * Modify the edit post link generated by wp core function so that EE CPTs get setup differently. |
|
1188 | + * |
|
1189 | + * @param string $link the original generated link |
|
1190 | + * @param int $id post id |
|
1191 | + * @param string $context optional, defaults to display. How to write the '&' |
|
1192 | + * @return string the link |
|
1193 | + */ |
|
1194 | + public function modify_edit_post_link($link, $id, $context) |
|
1195 | + { |
|
1196 | + $post = get_post($id); |
|
1197 | + if (! isset($this->_req_data['action']) |
|
1198 | + || ! isset($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
1199 | + || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ] |
|
1200 | + ) { |
|
1201 | + return $link; |
|
1202 | + } |
|
1203 | + $query_args = array( |
|
1204 | + 'action' => isset($this->_cpt_edit_routes[ $post->post_type ]) |
|
1205 | + ? $this->_cpt_edit_routes[ $post->post_type ] |
|
1206 | + : 'edit', |
|
1207 | + 'post' => $id, |
|
1208 | + ); |
|
1209 | + return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $this->_admin_base_url); |
|
1210 | + } |
|
1211 | + |
|
1212 | + |
|
1213 | + /** |
|
1214 | + * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on |
|
1215 | + * our routes. |
|
1216 | + * |
|
1217 | + * @param string $delete_link original delete link |
|
1218 | + * @param int $post_id id of cpt object |
|
1219 | + * @param bool $force_delete whether this is forcing a hard delete instead of trash |
|
1220 | + * @return string new delete link |
|
1221 | + * @throws EE_Error |
|
1222 | + * @throws ReflectionException |
|
1223 | + */ |
|
1224 | + public function modify_delete_post_link($delete_link, $post_id, $force_delete) |
|
1225 | + { |
|
1226 | + $post = get_post($post_id); |
|
1227 | + |
|
1228 | + if (empty($this->_req_data['action']) |
|
1229 | + || ! isset($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
1230 | + || ! $post instanceof WP_Post |
|
1231 | + || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ] |
|
1232 | + ) { |
|
1233 | + return $delete_link; |
|
1234 | + } |
|
1235 | + $this->_set_model_object($post->ID, true); |
|
1236 | + |
|
1237 | + // returns something like `trash_event` or `trash_attendee` or `trash_venue` |
|
1238 | + $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj))); |
|
1239 | + |
|
1240 | + return EE_Admin_Page::add_query_args_and_nonce( |
|
1241 | + array( |
|
1242 | + 'page' => $this->_req_data['page'], |
|
1243 | + 'action' => $action, |
|
1244 | + $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name() |
|
1245 | + => $post->ID, |
|
1246 | + ), |
|
1247 | + admin_url() |
|
1248 | + ); |
|
1249 | + } |
|
1250 | + |
|
1251 | + |
|
1252 | + /** |
|
1253 | + * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php |
|
1254 | + * so that we can hijack the default redirect locations for wp custom post types |
|
1255 | + * that WE'RE using and send back to OUR routes. This should only be hooked in on the right route. |
|
1256 | + * |
|
1257 | + * @param string $location This is the incoming currently set redirect location |
|
1258 | + * @param string $post_id This is the 'ID' value of the wp_posts table |
|
1259 | + * @return string the new location to redirect to |
|
1260 | + * @throws EE_Error |
|
1261 | + */ |
|
1262 | + public function cpt_post_location_redirect($location, $post_id) |
|
1263 | + { |
|
1264 | + // we DO have a match so let's setup the url |
|
1265 | + // we have to get the post to determine our route |
|
1266 | + $post = get_post($post_id); |
|
1267 | + $edit_route = $this->_cpt_edit_routes[ $post->post_type ]; |
|
1268 | + // shared query_args |
|
1269 | + $query_args = array('action' => $edit_route, 'post' => $post_id); |
|
1270 | + $admin_url = $this->_admin_base_url; |
|
1271 | + if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) { |
|
1272 | + $status = get_post_status($post_id); |
|
1273 | + if (isset($this->_req_data['publish'])) { |
|
1274 | + switch ($status) { |
|
1275 | + case 'pending': |
|
1276 | + $message = 8; |
|
1277 | + break; |
|
1278 | + case 'future': |
|
1279 | + $message = 9; |
|
1280 | + break; |
|
1281 | + default: |
|
1282 | + $message = 6; |
|
1283 | + } |
|
1284 | + } else { |
|
1285 | + $message = 'draft' === $status ? 10 : 1; |
|
1286 | + } |
|
1287 | + } elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) { |
|
1288 | + $message = 2; |
|
1289 | + } elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) { |
|
1290 | + $message = 3; |
|
1291 | + } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') { |
|
1292 | + $message = 7; |
|
1293 | + } else { |
|
1294 | + $message = 4; |
|
1295 | + } |
|
1296 | + // change the message if the post type is not viewable on the frontend |
|
1297 | + $this->_cpt_object = get_post_type_object($post->post_type); |
|
1298 | + $message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message; |
|
1299 | + $query_args = array_merge(array('message' => $message), $query_args); |
|
1300 | + $this->_process_notices($query_args, true); |
|
1301 | + return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url); |
|
1302 | + } |
|
1303 | + |
|
1304 | + |
|
1305 | + /** |
|
1306 | + * This method is called to inject nav tabs on core WP cpt pages |
|
1307 | + * |
|
1308 | + * @access public |
|
1309 | + * @return void |
|
1310 | + * @throws EE_Error |
|
1311 | + */ |
|
1312 | + public function inject_nav_tabs() |
|
1313 | + { |
|
1314 | + // can we hijack and insert the nav_tabs? |
|
1315 | + $nav_tabs = $this->_get_main_nav_tabs(); |
|
1316 | + // first close off existing form tag |
|
1317 | + $html = '>'; |
|
1318 | + $html .= $nav_tabs; |
|
1319 | + // now let's handle the remaining tag ( missing ">" is CORRECT ) |
|
1320 | + $html .= '<span></span'; |
|
1321 | + echo $html; |
|
1322 | + } |
|
1323 | + |
|
1324 | + |
|
1325 | + /** |
|
1326 | + * This just sets up the post update messages when an update form is loaded |
|
1327 | + * |
|
1328 | + * @access public |
|
1329 | + * @param array $messages the original messages array |
|
1330 | + * @return array the new messages array |
|
1331 | + */ |
|
1332 | + public function post_update_messages($messages) |
|
1333 | + { |
|
1334 | + global $post; |
|
1335 | + $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null; |
|
1336 | + $id = empty($id) && is_object($post) ? $post->ID : null; |
|
1337 | + /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork'; |
|
1338 | 1338 | |
1339 | 1339 | $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/ |
1340 | - $messages[ $post->post_type ] = array( |
|
1341 | - 0 => '', // Unused. Messages start at index 1. |
|
1342 | - 1 => sprintf( |
|
1343 | - __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'), |
|
1344 | - $this->_cpt_object->labels->singular_name, |
|
1345 | - '<a href="' . esc_url(get_permalink($id)) . '">', |
|
1346 | - '</a>' |
|
1347 | - ), |
|
1348 | - 2 => __('Custom field updated', 'event_espresso'), |
|
1349 | - 3 => __('Custom field deleted.', 'event_espresso'), |
|
1350 | - 4 => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name), |
|
1351 | - 5 => isset($_GET['revision']) ? sprintf( |
|
1352 | - __('%s restored to revision from %s', 'event_espresso'), |
|
1353 | - $this->_cpt_object->labels->singular_name, |
|
1354 | - wp_post_revision_title((int) $_GET['revision'], false) |
|
1355 | - ) |
|
1356 | - : false, |
|
1357 | - 6 => sprintf( |
|
1358 | - __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'), |
|
1359 | - $this->_cpt_object->labels->singular_name, |
|
1360 | - '<a href="' . esc_url(get_permalink($id)) . '">', |
|
1361 | - '</a>' |
|
1362 | - ), |
|
1363 | - 7 => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name), |
|
1364 | - 8 => sprintf( |
|
1365 | - __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'), |
|
1366 | - $this->_cpt_object->labels->singular_name, |
|
1367 | - '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">', |
|
1368 | - '</a>' |
|
1369 | - ), |
|
1370 | - 9 => sprintf( |
|
1371 | - __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'), |
|
1372 | - $this->_cpt_object->labels->singular_name, |
|
1373 | - '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>', |
|
1374 | - '<a target="_blank" href="' . esc_url(get_permalink($id)), |
|
1375 | - '</a>' |
|
1376 | - ), |
|
1377 | - 10 => sprintf( |
|
1378 | - __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'), |
|
1379 | - $this->_cpt_object->labels->singular_name, |
|
1380 | - '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))), |
|
1381 | - '</a>' |
|
1382 | - ), |
|
1383 | - ); |
|
1384 | - return $messages; |
|
1385 | - } |
|
1386 | - |
|
1387 | - |
|
1388 | - /** |
|
1389 | - * default method for the 'create_new' route for cpt admin pages. |
|
1390 | - * For reference what to include in here, see wp-admin/post-new.php |
|
1391 | - * |
|
1392 | - * @access protected |
|
1393 | - * @return void |
|
1394 | - */ |
|
1395 | - protected function _create_new_cpt_item() |
|
1396 | - { |
|
1397 | - // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php' |
|
1398 | - global $post, $title, $is_IE, $post_type, $post_type_object; |
|
1399 | - $post_type = $this->_cpt_routes[ $this->_req_action ]; |
|
1400 | - $post_type_object = $this->_cpt_object; |
|
1401 | - $title = $post_type_object->labels->add_new_item; |
|
1402 | - $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true); |
|
1403 | - add_action('admin_print_styles', array($this, 'add_new_admin_page_global')); |
|
1404 | - // modify the default editor title field with default title. |
|
1405 | - add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10); |
|
1406 | - $this->loadEditorTemplate(true); |
|
1407 | - } |
|
1408 | - |
|
1409 | - |
|
1410 | - /** |
|
1411 | - * Enqueues auto-save and loads the editor template |
|
1412 | - * |
|
1413 | - * @param bool $creating |
|
1414 | - */ |
|
1415 | - private function loadEditorTemplate($creating = true) |
|
1416 | - { |
|
1417 | - global $post, $title, $is_IE, $post_type, $post_type_object; |
|
1418 | - // these vars are used by the template |
|
1419 | - $editing = true; |
|
1420 | - $post_ID = $post->ID; |
|
1421 | - if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) { |
|
1422 | - // only enqueue autosave when creating event (necessary to get permalink/url generated) |
|
1423 | - // otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context. |
|
1424 | - if ($creating) { |
|
1425 | - wp_enqueue_script('autosave'); |
|
1426 | - } elseif (isset($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
1427 | - && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ]) |
|
1428 | - ) { |
|
1429 | - $create_new_action = apply_filters( |
|
1430 | - 'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action', |
|
1431 | - 'create_new', |
|
1432 | - $this |
|
1433 | - ); |
|
1434 | - $post_new_file = EE_Admin_Page::add_query_args_and_nonce( |
|
1435 | - array( |
|
1436 | - 'action' => $create_new_action, |
|
1437 | - 'page' => $this->page_slug, |
|
1438 | - ), |
|
1439 | - 'admin.php' |
|
1440 | - ); |
|
1441 | - } |
|
1442 | - include_once WP_ADMIN_PATH . 'edit-form-advanced.php'; |
|
1443 | - } |
|
1444 | - } |
|
1445 | - |
|
1446 | - |
|
1447 | - public function add_new_admin_page_global() |
|
1448 | - { |
|
1449 | - $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php'; |
|
1450 | - ?> |
|
1340 | + $messages[ $post->post_type ] = array( |
|
1341 | + 0 => '', // Unused. Messages start at index 1. |
|
1342 | + 1 => sprintf( |
|
1343 | + __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'), |
|
1344 | + $this->_cpt_object->labels->singular_name, |
|
1345 | + '<a href="' . esc_url(get_permalink($id)) . '">', |
|
1346 | + '</a>' |
|
1347 | + ), |
|
1348 | + 2 => __('Custom field updated', 'event_espresso'), |
|
1349 | + 3 => __('Custom field deleted.', 'event_espresso'), |
|
1350 | + 4 => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name), |
|
1351 | + 5 => isset($_GET['revision']) ? sprintf( |
|
1352 | + __('%s restored to revision from %s', 'event_espresso'), |
|
1353 | + $this->_cpt_object->labels->singular_name, |
|
1354 | + wp_post_revision_title((int) $_GET['revision'], false) |
|
1355 | + ) |
|
1356 | + : false, |
|
1357 | + 6 => sprintf( |
|
1358 | + __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'), |
|
1359 | + $this->_cpt_object->labels->singular_name, |
|
1360 | + '<a href="' . esc_url(get_permalink($id)) . '">', |
|
1361 | + '</a>' |
|
1362 | + ), |
|
1363 | + 7 => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name), |
|
1364 | + 8 => sprintf( |
|
1365 | + __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'), |
|
1366 | + $this->_cpt_object->labels->singular_name, |
|
1367 | + '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">', |
|
1368 | + '</a>' |
|
1369 | + ), |
|
1370 | + 9 => sprintf( |
|
1371 | + __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'), |
|
1372 | + $this->_cpt_object->labels->singular_name, |
|
1373 | + '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>', |
|
1374 | + '<a target="_blank" href="' . esc_url(get_permalink($id)), |
|
1375 | + '</a>' |
|
1376 | + ), |
|
1377 | + 10 => sprintf( |
|
1378 | + __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'), |
|
1379 | + $this->_cpt_object->labels->singular_name, |
|
1380 | + '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))), |
|
1381 | + '</a>' |
|
1382 | + ), |
|
1383 | + ); |
|
1384 | + return $messages; |
|
1385 | + } |
|
1386 | + |
|
1387 | + |
|
1388 | + /** |
|
1389 | + * default method for the 'create_new' route for cpt admin pages. |
|
1390 | + * For reference what to include in here, see wp-admin/post-new.php |
|
1391 | + * |
|
1392 | + * @access protected |
|
1393 | + * @return void |
|
1394 | + */ |
|
1395 | + protected function _create_new_cpt_item() |
|
1396 | + { |
|
1397 | + // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php' |
|
1398 | + global $post, $title, $is_IE, $post_type, $post_type_object; |
|
1399 | + $post_type = $this->_cpt_routes[ $this->_req_action ]; |
|
1400 | + $post_type_object = $this->_cpt_object; |
|
1401 | + $title = $post_type_object->labels->add_new_item; |
|
1402 | + $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true); |
|
1403 | + add_action('admin_print_styles', array($this, 'add_new_admin_page_global')); |
|
1404 | + // modify the default editor title field with default title. |
|
1405 | + add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10); |
|
1406 | + $this->loadEditorTemplate(true); |
|
1407 | + } |
|
1408 | + |
|
1409 | + |
|
1410 | + /** |
|
1411 | + * Enqueues auto-save and loads the editor template |
|
1412 | + * |
|
1413 | + * @param bool $creating |
|
1414 | + */ |
|
1415 | + private function loadEditorTemplate($creating = true) |
|
1416 | + { |
|
1417 | + global $post, $title, $is_IE, $post_type, $post_type_object; |
|
1418 | + // these vars are used by the template |
|
1419 | + $editing = true; |
|
1420 | + $post_ID = $post->ID; |
|
1421 | + if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) { |
|
1422 | + // only enqueue autosave when creating event (necessary to get permalink/url generated) |
|
1423 | + // otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context. |
|
1424 | + if ($creating) { |
|
1425 | + wp_enqueue_script('autosave'); |
|
1426 | + } elseif (isset($this->_cpt_routes[ $this->_req_data['action'] ]) |
|
1427 | + && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ]) |
|
1428 | + ) { |
|
1429 | + $create_new_action = apply_filters( |
|
1430 | + 'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action', |
|
1431 | + 'create_new', |
|
1432 | + $this |
|
1433 | + ); |
|
1434 | + $post_new_file = EE_Admin_Page::add_query_args_and_nonce( |
|
1435 | + array( |
|
1436 | + 'action' => $create_new_action, |
|
1437 | + 'page' => $this->page_slug, |
|
1438 | + ), |
|
1439 | + 'admin.php' |
|
1440 | + ); |
|
1441 | + } |
|
1442 | + include_once WP_ADMIN_PATH . 'edit-form-advanced.php'; |
|
1443 | + } |
|
1444 | + } |
|
1445 | + |
|
1446 | + |
|
1447 | + public function add_new_admin_page_global() |
|
1448 | + { |
|
1449 | + $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php'; |
|
1450 | + ?> |
|
1451 | 1451 | <script type="text/javascript"> |
1452 | 1452 | adminpage = '<?php echo $admin_page; ?>'; |
1453 | 1453 | </script> |
1454 | 1454 | <?php |
1455 | - } |
|
1456 | - |
|
1457 | - |
|
1458 | - /** |
|
1459 | - * default method for the 'edit' route for cpt admin pages |
|
1460 | - * For reference on what to put in here, refer to wp-admin/post.php |
|
1461 | - * |
|
1462 | - * @access protected |
|
1463 | - * @return string template for edit cpt form |
|
1464 | - */ |
|
1465 | - protected function _edit_cpt_item() |
|
1466 | - { |
|
1467 | - global $post, $title, $is_IE, $post_type, $post_type_object; |
|
1468 | - $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null; |
|
1469 | - $post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null; |
|
1470 | - if (empty($post)) { |
|
1471 | - wp_die(__('You attempted to edit an item that doesn’t exist. Perhaps it was deleted?', 'event_espresso')); |
|
1472 | - } |
|
1473 | - if (! empty($_GET['get-post-lock'])) { |
|
1474 | - wp_set_post_lock($post_id); |
|
1475 | - wp_redirect(get_edit_post_link($post_id, 'url')); |
|
1476 | - exit(); |
|
1477 | - } |
|
1478 | - |
|
1479 | - // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php' |
|
1480 | - $post_type = $this->_cpt_routes[ $this->_req_action ]; |
|
1481 | - $post_type_object = $this->_cpt_object; |
|
1482 | - |
|
1483 | - if (! wp_check_post_lock($post->ID)) { |
|
1484 | - wp_set_post_lock($post->ID); |
|
1485 | - } |
|
1486 | - add_action('admin_footer', '_admin_notice_post_locked'); |
|
1487 | - if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) { |
|
1488 | - wp_enqueue_script('admin-comments'); |
|
1489 | - enqueue_comment_hotkeys_js(); |
|
1490 | - } |
|
1491 | - add_action('admin_print_styles', array($this, 'add_new_admin_page_global')); |
|
1492 | - // modify the default editor title field with default title. |
|
1493 | - add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10); |
|
1494 | - $this->loadEditorTemplate(false); |
|
1495 | - } |
|
1496 | - |
|
1497 | - |
|
1498 | - |
|
1499 | - /** |
|
1500 | - * some getters |
|
1501 | - */ |
|
1502 | - /** |
|
1503 | - * This returns the protected _cpt_model_obj property |
|
1504 | - * |
|
1505 | - * @return EE_CPT_Base |
|
1506 | - */ |
|
1507 | - public function get_cpt_model_obj() |
|
1508 | - { |
|
1509 | - return $this->_cpt_model_obj; |
|
1510 | - } |
|
1455 | + } |
|
1456 | + |
|
1457 | + |
|
1458 | + /** |
|
1459 | + * default method for the 'edit' route for cpt admin pages |
|
1460 | + * For reference on what to put in here, refer to wp-admin/post.php |
|
1461 | + * |
|
1462 | + * @access protected |
|
1463 | + * @return string template for edit cpt form |
|
1464 | + */ |
|
1465 | + protected function _edit_cpt_item() |
|
1466 | + { |
|
1467 | + global $post, $title, $is_IE, $post_type, $post_type_object; |
|
1468 | + $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null; |
|
1469 | + $post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null; |
|
1470 | + if (empty($post)) { |
|
1471 | + wp_die(__('You attempted to edit an item that doesn’t exist. Perhaps it was deleted?', 'event_espresso')); |
|
1472 | + } |
|
1473 | + if (! empty($_GET['get-post-lock'])) { |
|
1474 | + wp_set_post_lock($post_id); |
|
1475 | + wp_redirect(get_edit_post_link($post_id, 'url')); |
|
1476 | + exit(); |
|
1477 | + } |
|
1478 | + |
|
1479 | + // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php' |
|
1480 | + $post_type = $this->_cpt_routes[ $this->_req_action ]; |
|
1481 | + $post_type_object = $this->_cpt_object; |
|
1482 | + |
|
1483 | + if (! wp_check_post_lock($post->ID)) { |
|
1484 | + wp_set_post_lock($post->ID); |
|
1485 | + } |
|
1486 | + add_action('admin_footer', '_admin_notice_post_locked'); |
|
1487 | + if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) { |
|
1488 | + wp_enqueue_script('admin-comments'); |
|
1489 | + enqueue_comment_hotkeys_js(); |
|
1490 | + } |
|
1491 | + add_action('admin_print_styles', array($this, 'add_new_admin_page_global')); |
|
1492 | + // modify the default editor title field with default title. |
|
1493 | + add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10); |
|
1494 | + $this->loadEditorTemplate(false); |
|
1495 | + } |
|
1496 | + |
|
1497 | + |
|
1498 | + |
|
1499 | + /** |
|
1500 | + * some getters |
|
1501 | + */ |
|
1502 | + /** |
|
1503 | + * This returns the protected _cpt_model_obj property |
|
1504 | + * |
|
1505 | + * @return EE_CPT_Base |
|
1506 | + */ |
|
1507 | + public function get_cpt_model_obj() |
|
1508 | + { |
|
1509 | + return $this->_cpt_model_obj; |
|
1510 | + } |
|
1511 | 1511 | } |
@@ -24,113 +24,113 @@ |
||
24 | 24 | class LegacyAccountingAssetManager extends AssetManager |
25 | 25 | { |
26 | 26 | |
27 | - const JS_HANDLE_UNDERSCORE = 'underscore'; |
|
28 | - |
|
29 | - const JS_HANDLE_ACCOUNTING_CORE = 'ee-accounting-core'; |
|
30 | - |
|
31 | - const JS_HANDLE_ACCOUNTING = 'ee-accounting'; |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * @var EE_Currency_Config $currency_config |
|
36 | - */ |
|
37 | - protected $currency_config; |
|
38 | - |
|
39 | - /** |
|
40 | - * CoreAssetRegister constructor. |
|
41 | - * |
|
42 | - * @param AssetCollection $assets |
|
43 | - * @param DomainInterface $domain |
|
44 | - * @param Registry $registry |
|
45 | - * @param EE_Currency_Config $currency_config |
|
46 | - */ |
|
47 | - public function __construct( |
|
48 | - AssetCollection $assets, |
|
49 | - DomainInterface $domain, |
|
50 | - Registry $registry, |
|
51 | - EE_Currency_Config $currency_config |
|
52 | - ) { |
|
53 | - $this->currency_config = $currency_config; |
|
54 | - parent::__construct($domain, $assets, $registry); |
|
55 | - } |
|
56 | - |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * @throws InvalidDataTypeException |
|
61 | - * @throws InvalidEntityException |
|
62 | - * @throws DuplicateCollectionIdentifierException |
|
63 | - * @throws DomainException |
|
64 | - */ |
|
65 | - public function addAssets() |
|
66 | - { |
|
67 | - $this->loadAccountingJs(); |
|
68 | - } |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * accounting.js for performing client-side calculations |
|
73 | - * |
|
74 | - * @throws DomainException |
|
75 | - * @throws DuplicateCollectionIdentifierException |
|
76 | - * @throws InvalidDataTypeException |
|
77 | - * @throws InvalidEntityException |
|
78 | - * @since $VID:$ |
|
79 | - */ |
|
80 | - private function loadAccountingJs() |
|
81 | - { |
|
82 | - //accounting.js library |
|
83 | - // @link http://josscrowcroft.github.io/accounting.js/ |
|
84 | - $this->addJavascript( |
|
85 | - LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING_CORE, |
|
86 | - EE_THIRD_PARTY_URL . 'accounting/accounting.js', |
|
87 | - [LegacyAccountingAssetManager::JS_HANDLE_UNDERSCORE], |
|
88 | - true, |
|
89 | - '0.3.2' |
|
90 | - ); |
|
91 | - |
|
92 | - $this->addJavascript( |
|
93 | - LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING, |
|
94 | - EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js', |
|
95 | - [LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING_CORE] |
|
96 | - ) |
|
97 | - ->setInlineDataCallback( |
|
98 | - function () { |
|
99 | - wp_localize_script( |
|
100 | - LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING, |
|
101 | - 'EE_ACCOUNTING_CFG', |
|
102 | - $this->getAccountingSettings() |
|
103 | - ); |
|
104 | - } |
|
105 | - ); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * Returns configuration data for the accounting-js library. |
|
111 | - * |
|
112 | - * @return array |
|
113 | - * @since $VID:$ |
|
114 | - */ |
|
115 | - private function getAccountingSettings() |
|
116 | - { |
|
117 | - return [ |
|
118 | - 'currency' => [ |
|
119 | - 'symbol' => $this->currency_config->sign, |
|
120 | - 'format' => [ |
|
121 | - 'pos' => $this->currency_config->sign_b4 ? '%s%v' : '%v%s', |
|
122 | - 'neg' => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s', |
|
123 | - 'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s', |
|
124 | - ], |
|
125 | - 'decimal' => $this->currency_config->dec_mrk, |
|
126 | - 'thousand' => $this->currency_config->thsnds, |
|
127 | - 'precision' => $this->currency_config->dec_plc, |
|
128 | - ], |
|
129 | - 'number' => [ |
|
130 | - 'precision' => $this->currency_config->dec_plc, |
|
131 | - 'thousand' => $this->currency_config->thsnds, |
|
132 | - 'decimal' => $this->currency_config->dec_mrk, |
|
133 | - ], |
|
134 | - ]; |
|
135 | - } |
|
27 | + const JS_HANDLE_UNDERSCORE = 'underscore'; |
|
28 | + |
|
29 | + const JS_HANDLE_ACCOUNTING_CORE = 'ee-accounting-core'; |
|
30 | + |
|
31 | + const JS_HANDLE_ACCOUNTING = 'ee-accounting'; |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * @var EE_Currency_Config $currency_config |
|
36 | + */ |
|
37 | + protected $currency_config; |
|
38 | + |
|
39 | + /** |
|
40 | + * CoreAssetRegister constructor. |
|
41 | + * |
|
42 | + * @param AssetCollection $assets |
|
43 | + * @param DomainInterface $domain |
|
44 | + * @param Registry $registry |
|
45 | + * @param EE_Currency_Config $currency_config |
|
46 | + */ |
|
47 | + public function __construct( |
|
48 | + AssetCollection $assets, |
|
49 | + DomainInterface $domain, |
|
50 | + Registry $registry, |
|
51 | + EE_Currency_Config $currency_config |
|
52 | + ) { |
|
53 | + $this->currency_config = $currency_config; |
|
54 | + parent::__construct($domain, $assets, $registry); |
|
55 | + } |
|
56 | + |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * @throws InvalidDataTypeException |
|
61 | + * @throws InvalidEntityException |
|
62 | + * @throws DuplicateCollectionIdentifierException |
|
63 | + * @throws DomainException |
|
64 | + */ |
|
65 | + public function addAssets() |
|
66 | + { |
|
67 | + $this->loadAccountingJs(); |
|
68 | + } |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * accounting.js for performing client-side calculations |
|
73 | + * |
|
74 | + * @throws DomainException |
|
75 | + * @throws DuplicateCollectionIdentifierException |
|
76 | + * @throws InvalidDataTypeException |
|
77 | + * @throws InvalidEntityException |
|
78 | + * @since $VID:$ |
|
79 | + */ |
|
80 | + private function loadAccountingJs() |
|
81 | + { |
|
82 | + //accounting.js library |
|
83 | + // @link http://josscrowcroft.github.io/accounting.js/ |
|
84 | + $this->addJavascript( |
|
85 | + LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING_CORE, |
|
86 | + EE_THIRD_PARTY_URL . 'accounting/accounting.js', |
|
87 | + [LegacyAccountingAssetManager::JS_HANDLE_UNDERSCORE], |
|
88 | + true, |
|
89 | + '0.3.2' |
|
90 | + ); |
|
91 | + |
|
92 | + $this->addJavascript( |
|
93 | + LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING, |
|
94 | + EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js', |
|
95 | + [LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING_CORE] |
|
96 | + ) |
|
97 | + ->setInlineDataCallback( |
|
98 | + function () { |
|
99 | + wp_localize_script( |
|
100 | + LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING, |
|
101 | + 'EE_ACCOUNTING_CFG', |
|
102 | + $this->getAccountingSettings() |
|
103 | + ); |
|
104 | + } |
|
105 | + ); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * Returns configuration data for the accounting-js library. |
|
111 | + * |
|
112 | + * @return array |
|
113 | + * @since $VID:$ |
|
114 | + */ |
|
115 | + private function getAccountingSettings() |
|
116 | + { |
|
117 | + return [ |
|
118 | + 'currency' => [ |
|
119 | + 'symbol' => $this->currency_config->sign, |
|
120 | + 'format' => [ |
|
121 | + 'pos' => $this->currency_config->sign_b4 ? '%s%v' : '%v%s', |
|
122 | + 'neg' => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s', |
|
123 | + 'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s', |
|
124 | + ], |
|
125 | + 'decimal' => $this->currency_config->dec_mrk, |
|
126 | + 'thousand' => $this->currency_config->thsnds, |
|
127 | + 'precision' => $this->currency_config->dec_plc, |
|
128 | + ], |
|
129 | + 'number' => [ |
|
130 | + 'precision' => $this->currency_config->dec_plc, |
|
131 | + 'thousand' => $this->currency_config->thsnds, |
|
132 | + 'decimal' => $this->currency_config->dec_mrk, |
|
133 | + ], |
|
134 | + ]; |
|
135 | + } |
|
136 | 136 | } |
@@ -83,7 +83,7 @@ discard block |
||
83 | 83 | // @link http://josscrowcroft.github.io/accounting.js/ |
84 | 84 | $this->addJavascript( |
85 | 85 | LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING_CORE, |
86 | - EE_THIRD_PARTY_URL . 'accounting/accounting.js', |
|
86 | + EE_THIRD_PARTY_URL.'accounting/accounting.js', |
|
87 | 87 | [LegacyAccountingAssetManager::JS_HANDLE_UNDERSCORE], |
88 | 88 | true, |
89 | 89 | '0.3.2' |
@@ -91,11 +91,11 @@ discard block |
||
91 | 91 | |
92 | 92 | $this->addJavascript( |
93 | 93 | LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING, |
94 | - EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js', |
|
94 | + EE_GLOBAL_ASSETS_URL.'scripts/ee-accounting-config.js', |
|
95 | 95 | [LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING_CORE] |
96 | 96 | ) |
97 | 97 | ->setInlineDataCallback( |
98 | - function () { |
|
98 | + function() { |
|
99 | 99 | wp_localize_script( |
100 | 100 | LegacyAccountingAssetManager::JS_HANDLE_ACCOUNTING, |
101 | 101 | 'EE_ACCOUNTING_CFG', |
@@ -15,42 +15,42 @@ |
||
15 | 15 | class EspressoEventsAdmin extends AdminRoute |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * returns true if the current request matches this route |
|
20 | - * |
|
21 | - * @return bool |
|
22 | - * @since $VID:$ |
|
23 | - */ |
|
24 | - public function matchesCurrentRequest() |
|
25 | - { |
|
26 | - global $pagenow; |
|
27 | - return $pagenow |
|
28 | - && $pagenow === 'admin.php' |
|
29 | - && $this->request->isAdmin() |
|
30 | - && $this->request->getRequestParam('page') === 'espresso_events'; |
|
31 | - } |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * @since $VID:$ |
|
36 | - */ |
|
37 | - protected function registerDependencies() |
|
38 | - { |
|
39 | - $this->dependency_map->registerDependencies( |
|
40 | - 'EventEspresso\core\domain\services\admin\events\default_settings\AdvancedEditorAdminFormSection', |
|
41 | - ['EE_Admin_Config' => EE_Dependency_Map::load_from_cache] |
|
42 | - ); |
|
43 | - } |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * implements logic required to run during request |
|
48 | - * |
|
49 | - * @return bool |
|
50 | - * @since $VID:$ |
|
51 | - */ |
|
52 | - protected function requestHandler() |
|
53 | - { |
|
54 | - return false; |
|
55 | - } |
|
18 | + /** |
|
19 | + * returns true if the current request matches this route |
|
20 | + * |
|
21 | + * @return bool |
|
22 | + * @since $VID:$ |
|
23 | + */ |
|
24 | + public function matchesCurrentRequest() |
|
25 | + { |
|
26 | + global $pagenow; |
|
27 | + return $pagenow |
|
28 | + && $pagenow === 'admin.php' |
|
29 | + && $this->request->isAdmin() |
|
30 | + && $this->request->getRequestParam('page') === 'espresso_events'; |
|
31 | + } |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * @since $VID:$ |
|
36 | + */ |
|
37 | + protected function registerDependencies() |
|
38 | + { |
|
39 | + $this->dependency_map->registerDependencies( |
|
40 | + 'EventEspresso\core\domain\services\admin\events\default_settings\AdvancedEditorAdminFormSection', |
|
41 | + ['EE_Admin_Config' => EE_Dependency_Map::load_from_cache] |
|
42 | + ); |
|
43 | + } |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * implements logic required to run during request |
|
48 | + * |
|
49 | + * @return bool |
|
50 | + * @since $VID:$ |
|
51 | + */ |
|
52 | + protected function requestHandler() |
|
53 | + { |
|
54 | + return false; |
|
55 | + } |
|
56 | 56 | } |