@@ -39,7 +39,6 @@ discard block |
||
39 | 39 | |
40 | 40 | /** |
41 | 41 | * Return the schema for a given model from a given model. |
42 | - * @param \EEM_Base $model |
|
43 | 42 | * @return array |
44 | 43 | */ |
45 | 44 | public function getModelSchema() |
@@ -103,7 +102,6 @@ discard block |
||
103 | 102 | |
104 | 103 | /** |
105 | 104 | * Outputs the schema header for a model. |
106 | - * @param \EEM_Base $model |
|
107 | 105 | * @return array |
108 | 106 | */ |
109 | 107 | public function getInitialSchemaStructure() |
@@ -33,7 +33,7 @@ discard block |
||
33 | 33 | * |
34 | 34 | * @param \EEM_Base $model |
35 | 35 | */ |
36 | - public function __construct(EEM_Base $model){ |
|
36 | + public function __construct(EEM_Base $model) { |
|
37 | 37 | $this->model = $model; |
38 | 38 | } |
39 | 39 | |
@@ -60,7 +60,7 @@ discard block |
||
60 | 60 | public function getModelSchemaForFields(array $model_fields, array $schema) |
61 | 61 | { |
62 | 62 | foreach ($model_fields as $field => $model_field) { |
63 | - if (! $model_field instanceof EE_Model_Field_Base) { |
|
63 | + if ( ! $model_field instanceof EE_Model_Field_Base) { |
|
64 | 64 | continue; |
65 | 65 | } |
66 | 66 | $schema['properties'][$field] = $model_field->getSchema(); |
@@ -91,7 +91,7 @@ discard block |
||
91 | 91 | public function getModelSchemaForRelations(array $relations_on_model, array $schema) |
92 | 92 | { |
93 | 93 | foreach ($relations_on_model as $model_name => $relation) { |
94 | - if (! $relation instanceof EE_Model_Relation_Base) { |
|
94 | + if ( ! $relation instanceof EE_Model_Relation_Base) { |
|
95 | 95 | continue; |
96 | 96 | } |
97 | 97 | $model_name_for_schema = EEH_Inflector::pluralize_and_lower($model_name); |
@@ -24,116 +24,116 @@ |
||
24 | 24 | class JsonModelSchema |
25 | 25 | { |
26 | 26 | |
27 | - /** |
|
28 | - * @var \EEM_Base |
|
29 | - */ |
|
30 | - protected $model; |
|
31 | - |
|
32 | - /** |
|
33 | - * JsonModelSchema constructor. |
|
34 | - * |
|
35 | - * @param \EEM_Base $model |
|
36 | - */ |
|
37 | - public function __construct(EEM_Base $model){ |
|
38 | - $this->model = $model; |
|
39 | - } |
|
40 | - |
|
41 | - /** |
|
42 | - * Return the schema for a given model from a given model. |
|
43 | - * @param \EEM_Base $model |
|
44 | - * @return array |
|
45 | - */ |
|
46 | - public function getModelSchema() |
|
47 | - { |
|
48 | - return $this->getModelSchemaForRelations( |
|
49 | - $this->model->relation_settings(), |
|
50 | - $this->getModelSchemaForFields( |
|
51 | - $this->model->field_settings(), |
|
52 | - $this->getInitialSchemaStructure() |
|
53 | - ) |
|
54 | - ); |
|
55 | - } |
|
56 | - |
|
57 | - |
|
58 | - /** |
|
59 | - * Get the schema for a given set of model fields. |
|
60 | - * @param \EE_Model_Field_Base[] $model_fields |
|
61 | - * @return array |
|
62 | - */ |
|
63 | - public function getModelSchemaForFields(array $model_fields, array $schema) |
|
64 | - { |
|
65 | - foreach ($model_fields as $field => $model_field) { |
|
66 | - if (! $model_field instanceof EE_Model_Field_Base) { |
|
67 | - continue; |
|
68 | - } |
|
69 | - $schema['properties'][$field] = $model_field->getSchema(); |
|
70 | - |
|
71 | - //if this is a primary key field add the primary key item |
|
72 | - if ($model_field instanceof EE_Primary_Key_Field_Base) { |
|
73 | - $schema['properties'][$field]['primary_key'] = true; |
|
74 | - } |
|
75 | - |
|
76 | - //if this is a foreign key field add the foreign key item |
|
77 | - if ($model_field instanceof EE_Foreign_Key_Field_Base) { |
|
78 | - $schema['properties'][$field]['foreign_key'] = array( |
|
79 | - 'description' => esc_html__('This is a foreign key the points to the given models.', 'event_espresso'), |
|
80 | - 'type' => 'array', |
|
81 | - 'enum' => $model_field->get_model_class_names_pointed_to() |
|
82 | - ); |
|
83 | - } |
|
84 | - } |
|
85 | - return $schema; |
|
86 | - } |
|
87 | - |
|
88 | - |
|
89 | - /** |
|
90 | - * Get the schema for a given set of model relations |
|
91 | - * @param EE_Model_Relation_Base[] $relations_on_model |
|
92 | - * @return array |
|
93 | - */ |
|
94 | - public function getModelSchemaForRelations(array $relations_on_model, array $schema) |
|
95 | - { |
|
96 | - foreach ($relations_on_model as $model_name => $relation) { |
|
97 | - if (! $relation instanceof EE_Model_Relation_Base) { |
|
98 | - continue; |
|
99 | - } |
|
100 | - $model_name_for_schema = $relation instanceof EE_Belongs_To_Relation |
|
101 | - ? strtolower($model_name) |
|
102 | - : EEH_Inflector::pluralize_and_lower($model_name); |
|
103 | - $schema['properties'][$model_name_for_schema] = $relation->getSchema(); |
|
104 | - $schema['properties'][$model_name_for_schema]['relation_model'] = $model_name; |
|
105 | - } |
|
106 | - return $schema; |
|
107 | - } |
|
108 | - |
|
109 | - |
|
110 | - /** |
|
111 | - * Outputs the schema header for a model. |
|
112 | - * @param \EEM_Base $model |
|
113 | - * @return array |
|
114 | - */ |
|
115 | - public function getInitialSchemaStructure() |
|
116 | - { |
|
117 | - return array( |
|
118 | - '$schema' => 'http://json-schema.org/draft-04/schema#', |
|
119 | - 'title' => $this->model->get_this_model_name(), |
|
120 | - 'type' => 'object', |
|
121 | - 'properties' => array() |
|
122 | - ); |
|
123 | - } |
|
124 | - |
|
125 | - |
|
126 | - /** |
|
127 | - * Allows one to just use the object as a string to get the json. |
|
128 | - * eg. |
|
129 | - * |
|
130 | - * $json_schema = new JsonModelSchema(EEM_Event::instance()); |
|
131 | - * echo $json_schema; //outputs the schema as a json formatted string. |
|
132 | - * |
|
133 | - * @return bool|false|mixed|string |
|
134 | - */ |
|
135 | - public function __toString() |
|
136 | - { |
|
137 | - return wp_json_encode($this->getModelSchema()); |
|
138 | - } |
|
27 | + /** |
|
28 | + * @var \EEM_Base |
|
29 | + */ |
|
30 | + protected $model; |
|
31 | + |
|
32 | + /** |
|
33 | + * JsonModelSchema constructor. |
|
34 | + * |
|
35 | + * @param \EEM_Base $model |
|
36 | + */ |
|
37 | + public function __construct(EEM_Base $model){ |
|
38 | + $this->model = $model; |
|
39 | + } |
|
40 | + |
|
41 | + /** |
|
42 | + * Return the schema for a given model from a given model. |
|
43 | + * @param \EEM_Base $model |
|
44 | + * @return array |
|
45 | + */ |
|
46 | + public function getModelSchema() |
|
47 | + { |
|
48 | + return $this->getModelSchemaForRelations( |
|
49 | + $this->model->relation_settings(), |
|
50 | + $this->getModelSchemaForFields( |
|
51 | + $this->model->field_settings(), |
|
52 | + $this->getInitialSchemaStructure() |
|
53 | + ) |
|
54 | + ); |
|
55 | + } |
|
56 | + |
|
57 | + |
|
58 | + /** |
|
59 | + * Get the schema for a given set of model fields. |
|
60 | + * @param \EE_Model_Field_Base[] $model_fields |
|
61 | + * @return array |
|
62 | + */ |
|
63 | + public function getModelSchemaForFields(array $model_fields, array $schema) |
|
64 | + { |
|
65 | + foreach ($model_fields as $field => $model_field) { |
|
66 | + if (! $model_field instanceof EE_Model_Field_Base) { |
|
67 | + continue; |
|
68 | + } |
|
69 | + $schema['properties'][$field] = $model_field->getSchema(); |
|
70 | + |
|
71 | + //if this is a primary key field add the primary key item |
|
72 | + if ($model_field instanceof EE_Primary_Key_Field_Base) { |
|
73 | + $schema['properties'][$field]['primary_key'] = true; |
|
74 | + } |
|
75 | + |
|
76 | + //if this is a foreign key field add the foreign key item |
|
77 | + if ($model_field instanceof EE_Foreign_Key_Field_Base) { |
|
78 | + $schema['properties'][$field]['foreign_key'] = array( |
|
79 | + 'description' => esc_html__('This is a foreign key the points to the given models.', 'event_espresso'), |
|
80 | + 'type' => 'array', |
|
81 | + 'enum' => $model_field->get_model_class_names_pointed_to() |
|
82 | + ); |
|
83 | + } |
|
84 | + } |
|
85 | + return $schema; |
|
86 | + } |
|
87 | + |
|
88 | + |
|
89 | + /** |
|
90 | + * Get the schema for a given set of model relations |
|
91 | + * @param EE_Model_Relation_Base[] $relations_on_model |
|
92 | + * @return array |
|
93 | + */ |
|
94 | + public function getModelSchemaForRelations(array $relations_on_model, array $schema) |
|
95 | + { |
|
96 | + foreach ($relations_on_model as $model_name => $relation) { |
|
97 | + if (! $relation instanceof EE_Model_Relation_Base) { |
|
98 | + continue; |
|
99 | + } |
|
100 | + $model_name_for_schema = $relation instanceof EE_Belongs_To_Relation |
|
101 | + ? strtolower($model_name) |
|
102 | + : EEH_Inflector::pluralize_and_lower($model_name); |
|
103 | + $schema['properties'][$model_name_for_schema] = $relation->getSchema(); |
|
104 | + $schema['properties'][$model_name_for_schema]['relation_model'] = $model_name; |
|
105 | + } |
|
106 | + return $schema; |
|
107 | + } |
|
108 | + |
|
109 | + |
|
110 | + /** |
|
111 | + * Outputs the schema header for a model. |
|
112 | + * @param \EEM_Base $model |
|
113 | + * @return array |
|
114 | + */ |
|
115 | + public function getInitialSchemaStructure() |
|
116 | + { |
|
117 | + return array( |
|
118 | + '$schema' => 'http://json-schema.org/draft-04/schema#', |
|
119 | + 'title' => $this->model->get_this_model_name(), |
|
120 | + 'type' => 'object', |
|
121 | + 'properties' => array() |
|
122 | + ); |
|
123 | + } |
|
124 | + |
|
125 | + |
|
126 | + /** |
|
127 | + * Allows one to just use the object as a string to get the json. |
|
128 | + * eg. |
|
129 | + * |
|
130 | + * $json_schema = new JsonModelSchema(EEM_Event::instance()); |
|
131 | + * echo $json_schema; //outputs the schema as a json formatted string. |
|
132 | + * |
|
133 | + * @return bool|false|mixed|string |
|
134 | + */ |
|
135 | + public function __toString() |
|
136 | + { |
|
137 | + return wp_json_encode($this->getModelSchema()); |
|
138 | + } |
|
139 | 139 | } |
@@ -157,13 +157,13 @@ discard block |
||
157 | 157 | */ |
158 | 158 | protected static function _set_hooks_for_changes() |
159 | 159 | { |
160 | - $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false); |
|
160 | + $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES.'rest_api'.DS.'changes'), false); |
|
161 | 161 | foreach ($folder_contents as $classname_in_namespace => $filepath) { |
162 | 162 | //ignore the base parent class |
163 | 163 | if ($classname_in_namespace === 'Changes_In_Base') { |
164 | 164 | continue; |
165 | 165 | } |
166 | - $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
166 | + $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\'.$classname_in_namespace; |
|
167 | 167 | if (class_exists($full_classname)) { |
168 | 168 | $instance_of_class = new $full_classname; |
169 | 169 | if ($instance_of_class instanceof EventEspresso\core\libraries\rest_api\changes\Changes_In_Base) { |
@@ -195,11 +195,11 @@ discard block |
||
195 | 195 | $model_name = isset($route['schema_callback'][0]) |
196 | 196 | ? $route['schema_callback'][0] |
197 | 197 | : ''; |
198 | - $version = isset( $route['schema_callback'][1]) |
|
198 | + $version = isset($route['schema_callback'][1]) |
|
199 | 199 | ? $route['schema_callback'][1] |
200 | 200 | : ''; |
201 | - if (! empty($model_name) && ! empty($version)) { |
|
202 | - $route_args['schema'] = function () use ($model_name, $version) { |
|
201 | + if ( ! empty($model_name) && ! empty($version)) { |
|
202 | + $route_args['schema'] = function() use ($model_name, $version) { |
|
203 | 203 | return EventEspresso\core\libraries\rest_api\controllers\model\Read::handle_schema_request( |
204 | 204 | $model_name, |
205 | 205 | $version |
@@ -245,7 +245,7 @@ discard block |
||
245 | 245 | { |
246 | 246 | //delete the saved EE REST API routes |
247 | 247 | foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
248 | - delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
248 | + delete_option(EED_Core_Rest_Api::saved_routes_option_names.$version); |
|
249 | 249 | } |
250 | 250 | } |
251 | 251 | |
@@ -264,7 +264,7 @@ discard block |
||
264 | 264 | { |
265 | 265 | $ee_routes = array(); |
266 | 266 | foreach (self::versions_served() as $version => $hidden_endpoints) { |
267 | - $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version($version, |
|
267 | + $ee_routes[self::ee_api_namespace.$version] = self::_get_ee_route_data_for_version($version, |
|
268 | 268 | $hidden_endpoints); |
269 | 269 | } |
270 | 270 | return $ee_routes; |
@@ -282,7 +282,7 @@ discard block |
||
282 | 282 | */ |
283 | 283 | protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
284 | 284 | { |
285 | - $ee_routes = get_option(self::saved_routes_option_names . $version, null); |
|
285 | + $ee_routes = get_option(self::saved_routes_option_names.$version, null); |
|
286 | 286 | if ( ! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) { |
287 | 287 | $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints); |
288 | 288 | } |
@@ -310,7 +310,7 @@ discard block |
||
310 | 310 | $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
311 | 311 | ) |
312 | 312 | ); |
313 | - $option_name = self::saved_routes_option_names . $version; |
|
313 | + $option_name = self::saved_routes_option_names.$version; |
|
314 | 314 | if (get_option($option_name)) { |
315 | 315 | update_option($option_name, $routes, true); |
316 | 316 | } else { |
@@ -387,13 +387,13 @@ discard block |
||
387 | 387 | $model = \EE_Registry::instance()->load_model($model_name); |
388 | 388 | |
389 | 389 | //if this isn't a valid model then let's skip iterate to the next item in the loop. |
390 | - if (! $model instanceof EEM_Base) { |
|
390 | + if ( ! $model instanceof EEM_Base) { |
|
391 | 391 | continue; |
392 | 392 | } |
393 | 393 | |
394 | 394 | //yes we could just register one route for ALL models, but then they wouldn't show up in the index |
395 | 395 | $plural_model_route = EEH_Inflector::pluralize_and_lower($model_name); |
396 | - $singular_model_route = $plural_model_route . '/(?P<id>\d+)'; |
|
396 | + $singular_model_route = $plural_model_route.'/(?P<id>\d+)'; |
|
397 | 397 | $model_routes[$plural_model_route] = array( |
398 | 398 | array( |
399 | 399 | 'callback' => array( |
@@ -404,7 +404,7 @@ discard block |
||
404 | 404 | 'hidden_endpoint' => $hidden_endpoint, |
405 | 405 | 'args' => $this->_get_read_query_params($model, $version), |
406 | 406 | '_links' => array( |
407 | - 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
407 | + 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace.$version.$singular_model_route), |
|
408 | 408 | ), |
409 | 409 | 'schema_callback' => array($model_name, $version) |
410 | 410 | ), |
@@ -440,7 +440,7 @@ discard block |
||
440 | 440 | $relation_name, |
441 | 441 | $relation_obj |
442 | 442 | ); |
443 | - $model_routes[$singular_model_route . '/' . $related_model_name_endpoint_part] = array( |
|
443 | + $model_routes[$singular_model_route.'/'.$related_model_name_endpoint_part] = array( |
|
444 | 444 | array( |
445 | 445 | 'callback' => array( |
446 | 446 | 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
@@ -476,7 +476,7 @@ discard block |
||
476 | 476 | { |
477 | 477 | $routes = array(); |
478 | 478 | foreach (self::versions_served() as $version => $hidden_endpoint) { |
479 | - $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version($version, |
|
479 | + $routes[self::ee_api_namespace.$version] = $this->_get_rpc_route_data_for_version($version, |
|
480 | 480 | $hidden_endpoint); |
481 | 481 | } |
482 | 482 | return $routes; |
@@ -607,7 +607,7 @@ discard block |
||
607 | 607 | { |
608 | 608 | $config_routes = array(); |
609 | 609 | foreach (self::versions_served() as $version => $hidden_endpoint) { |
610 | - $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version($version, |
|
610 | + $config_routes[self::ee_api_namespace.$version] = $this->_get_config_route_data_for_version($version, |
|
611 | 611 | $hidden_endpoint); |
612 | 612 | } |
613 | 613 | return $config_routes; |
@@ -660,7 +660,7 @@ discard block |
||
660 | 660 | { |
661 | 661 | $meta_routes = array(); |
662 | 662 | foreach (self::versions_served() as $version => $hidden_endpoint) { |
663 | - $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version($version, |
|
663 | + $meta_routes[self::ee_api_namespace.$version] = $this->_get_meta_route_data_for_version($version, |
|
664 | 664 | $hidden_endpoint); |
665 | 665 | } |
666 | 666 | return $meta_routes; |
@@ -715,7 +715,7 @@ discard block |
||
715 | 715 | if (($route['hidden_endpoint'] && $force_show_ee_namespace === '') |
716 | 716 | || ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
717 | 717 | ) { |
718 | - $full_route = '/' . ltrim($namespace, '/') . '/' . ltrim($endpoint, '/'); |
|
718 | + $full_route = '/'.ltrim($namespace, '/').'/'.ltrim($endpoint, '/'); |
|
719 | 719 | unset($route_data[$full_route]); |
720 | 720 | } |
721 | 721 | } |
@@ -18,844 +18,844 @@ |
||
18 | 18 | class EED_Core_Rest_Api extends \EED_Module |
19 | 19 | { |
20 | 20 | |
21 | - const ee_api_namespace = 'ee/v'; |
|
21 | + const ee_api_namespace = 'ee/v'; |
|
22 | 22 | |
23 | - const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
24 | - |
|
25 | - const saved_routes_option_names = 'ee_core_routes'; |
|
26 | - |
|
27 | - /** |
|
28 | - * string used in _links response bodies to make them globally unique. |
|
29 | - * |
|
30 | - * @see http://v2.wp-api.org/extending/linking/ |
|
31 | - */ |
|
32 | - const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
33 | - |
|
34 | - /** |
|
35 | - * @var Calculated_Model_Fields |
|
36 | - */ |
|
37 | - protected static $_field_calculator = null; |
|
38 | - |
|
39 | - |
|
40 | - |
|
41 | - /** |
|
42 | - * @return EED_Core_Rest_Api |
|
43 | - */ |
|
44 | - public static function instance() |
|
45 | - { |
|
46 | - self::$_field_calculator = new Calculated_Model_Fields(); |
|
47 | - return parent::get_instance(__CLASS__); |
|
48 | - } |
|
49 | - |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
54 | - * |
|
55 | - * @access public |
|
56 | - * @return void |
|
57 | - */ |
|
58 | - public static function set_hooks() |
|
59 | - { |
|
60 | - self::set_hooks_both(); |
|
61 | - } |
|
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 | - self::set_hooks_both(); |
|
74 | - } |
|
75 | - |
|
76 | - |
|
77 | - |
|
78 | - public static function set_hooks_both() |
|
79 | - { |
|
80 | - add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10); |
|
81 | - add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5); |
|
82 | - add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2); |
|
83 | - add_filter('rest_index', |
|
84 | - array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filter_ee_metadata_into_index')); |
|
85 | - EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
86 | - } |
|
87 | - |
|
88 | - |
|
89 | - |
|
90 | - /** |
|
91 | - * sets up hooks which only need to be included as part of REST API requests; |
|
92 | - * other requests like to the frontend or admin etc don't need them |
|
93 | - */ |
|
94 | - public static function set_hooks_rest_api() |
|
95 | - { |
|
96 | - //set hooks which account for changes made to the API |
|
97 | - EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
98 | - EED_Core_Rest_Api::maybe_notify_of_basic_auth_removal(); |
|
99 | - } |
|
100 | - |
|
101 | - |
|
102 | - |
|
103 | - /** |
|
104 | - * public wrapper of _set_hooks_for_changes. |
|
105 | - * Loads all the hooks which make requests to old versions of the API |
|
106 | - * appear the same as they always did |
|
107 | - */ |
|
108 | - public static function set_hooks_for_changes() |
|
109 | - { |
|
110 | - self::_set_hooks_for_changes(); |
|
111 | - } |
|
112 | - |
|
113 | - |
|
114 | - |
|
115 | - /** |
|
116 | - * If the user appears to be using WP API basic auth, tell them (via a persistent |
|
117 | - * admin notice and an email) that we're going to remove it soon, so they should |
|
118 | - * replace it with application passwords. |
|
119 | - */ |
|
120 | - public static function maybe_notify_of_basic_auth_removal() |
|
121 | - { |
|
122 | - if ( |
|
123 | - apply_filters( |
|
124 | - 'FHEE__EED_Core_Rest_Api__maybe_notify_of_basic_auth_removal__override', |
|
125 | - ! isset($_SERVER['PHP_AUTH_USER']) |
|
126 | - && ! isset($_SERVER['HTTP_AUTHORIZATION']) |
|
127 | - ) |
|
128 | - ) { |
|
129 | - //sure it's a WP API request, but they aren't using basic auth, so don't bother them |
|
130 | - return; |
|
131 | - } |
|
132 | - //ok they're using the WP API with Basic Auth |
|
133 | - $message = sprintf( |
|
134 | - __('We noticed you\'re using the WP API, which is used by the Event Espresso 4 mobile apps. Because of security and compatibility concerns, we will soon be removing our default authentication mechanism, WP API Basic Auth, from Event Espresso. It is recommended you instead install the %1$sWP Application Passwords plugin%2$s and use it with the EE4 Mobile apps. See %3$sour mobile app documentation%2$s for more information. %4$sIf you have installed the WP API Basic Auth plugin separately, or are not using the Event Espresso 4 mobile apps, you can disregard this message.%4$sThe Event Espresso Team', |
|
135 | - 'event_espresso'), |
|
136 | - '<a href="https://wordpress.org/plugins/application-passwords/">', |
|
137 | - '</a>', |
|
138 | - '<a href="https://eventespresso.com/wiki/ee4-event-apps/#authentication">', |
|
139 | - '<br/>' |
|
140 | - ); |
|
141 | - EE_Error::add_persistent_admin_notice('using_basic_auth', $message); |
|
142 | - if ( ! get_option('ee_notified_admin_on_basic_auth_removal', false)) { |
|
143 | - add_option('ee_notified_admin_on_basic_auth_removal', true); |
|
144 | - //piggy back off EE_Error::set_content_type, which sets the content type to HTML |
|
145 | - add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type')); |
|
146 | - //and send the message to the site admin too |
|
147 | - wp_mail(get_option('admin_email'), |
|
148 | - __('Notice of Removal of WP API Basic Auth From Event Espresso 4', 'event_espresso'), $message); |
|
149 | - remove_filter('wp_mail_content_type', array('EE_Error', 'set_content_type')); |
|
150 | - } |
|
151 | - } |
|
152 | - |
|
153 | - |
|
154 | - |
|
155 | - /** |
|
156 | - * Loads all the hooks which make requests to old versions of the API |
|
157 | - * appear the same as they always did |
|
158 | - */ |
|
159 | - protected static function _set_hooks_for_changes() |
|
160 | - { |
|
161 | - $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false); |
|
162 | - foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
163 | - //ignore the base parent class |
|
164 | - if ($classname_in_namespace === 'Changes_In_Base') { |
|
165 | - continue; |
|
166 | - } |
|
167 | - $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
168 | - if (class_exists($full_classname)) { |
|
169 | - $instance_of_class = new $full_classname; |
|
170 | - if ($instance_of_class instanceof Changes_In_Base) { |
|
171 | - $instance_of_class->set_hooks(); |
|
172 | - } |
|
173 | - } |
|
174 | - } |
|
175 | - } |
|
176 | - |
|
177 | - |
|
178 | - |
|
179 | - /** |
|
180 | - * Filters the WP routes to add our EE-related ones. This takes a bit of time |
|
181 | - * so we actually prefer to only do it when an EE plugin is activated or upgraded |
|
182 | - */ |
|
183 | - public static function register_routes() |
|
184 | - { |
|
185 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
186 | - foreach ($relative_urls as $endpoint => $routes) { |
|
187 | - foreach ($routes as $route) { |
|
188 | - $route_args = array( |
|
189 | - array( |
|
190 | - 'callback' => $route['callback'], |
|
191 | - 'methods' => $route['methods'], |
|
192 | - 'args' => isset($route['args']) ? $route['args'] : array(), |
|
193 | - ) |
|
194 | - ); |
|
195 | - if (isset($route['schema_callback'])) { |
|
196 | - $model_name = isset($route['schema_callback'][0]) |
|
197 | - ? $route['schema_callback'][0] |
|
198 | - : ''; |
|
199 | - $version = isset( $route['schema_callback'][1]) |
|
200 | - ? $route['schema_callback'][1] |
|
201 | - : ''; |
|
202 | - if (! empty($model_name) && ! empty($version)) { |
|
203 | - $route_args['schema'] = function () use ($model_name, $version) { |
|
204 | - return ModelRead::handle_schema_request( |
|
205 | - $model_name, |
|
206 | - $version |
|
207 | - ); |
|
208 | - }; |
|
209 | - } |
|
210 | - } |
|
211 | - register_rest_route( |
|
212 | - $namespace, |
|
213 | - $endpoint, |
|
214 | - $route_args |
|
215 | - ); |
|
216 | - } |
|
217 | - } |
|
218 | - } |
|
219 | - } |
|
220 | - |
|
221 | - |
|
222 | - |
|
223 | - /** |
|
224 | - * Checks if there was a version change or something that merits invalidating the cached |
|
225 | - * route data. If so, invalidates the cached route data so that it gets refreshed |
|
226 | - * next time the WP API is used |
|
227 | - */ |
|
228 | - public static function invalidate_cached_route_data_on_version_change() |
|
229 | - { |
|
230 | - if (EE_System::instance()->detect_req_type() != EE_System::req_type_normal) { |
|
231 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
232 | - } |
|
233 | - foreach (EE_Registry::instance()->addons as $addon) { |
|
234 | - if ($addon instanceof EE_Addon && $addon->detect_req_type() != EE_System::req_type_normal) { |
|
235 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
236 | - } |
|
237 | - } |
|
238 | - } |
|
239 | - |
|
240 | - |
|
241 | - |
|
242 | - /** |
|
243 | - * Removes the cached route data so it will get refreshed next time the WP API is used |
|
244 | - */ |
|
245 | - public static function invalidate_cached_route_data() |
|
246 | - { |
|
247 | - //delete the saved EE REST API routes |
|
248 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
|
249 | - delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
250 | - } |
|
251 | - } |
|
252 | - |
|
253 | - |
|
254 | - |
|
255 | - /** |
|
256 | - * Gets the EE route data |
|
257 | - * |
|
258 | - * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
259 | - * @type string|array $callback |
|
260 | - * @type string $methods |
|
261 | - * @type boolean $hidden_endpoint |
|
262 | - * } |
|
263 | - */ |
|
264 | - public static function get_ee_route_data() |
|
265 | - { |
|
266 | - $ee_routes = array(); |
|
267 | - foreach (self::versions_served() as $version => $hidden_endpoints) { |
|
268 | - $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version($version, |
|
269 | - $hidden_endpoints); |
|
270 | - } |
|
271 | - return $ee_routes; |
|
272 | - } |
|
273 | - |
|
274 | - |
|
275 | - |
|
276 | - /** |
|
277 | - * Gets the EE route data from the wp options if it exists already, |
|
278 | - * otherwise re-generates it and saves it to the option |
|
279 | - * |
|
280 | - * @param string $version |
|
281 | - * @param boolean $hidden_endpoints |
|
282 | - * @return array |
|
283 | - */ |
|
284 | - protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
285 | - { |
|
286 | - $ee_routes = get_option(self::saved_routes_option_names . $version, null); |
|
287 | - if ( ! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) { |
|
288 | - $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
289 | - } |
|
290 | - return $ee_routes; |
|
291 | - } |
|
292 | - |
|
293 | - |
|
294 | - |
|
295 | - /** |
|
296 | - * Saves the EE REST API route data to a wp option and returns it |
|
297 | - * |
|
298 | - * @param string $version |
|
299 | - * @param boolean $hidden_endpoints |
|
300 | - * @return mixed|null|void |
|
301 | - */ |
|
302 | - protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
303 | - { |
|
304 | - $instance = self::instance(); |
|
305 | - $routes = apply_filters( |
|
306 | - 'EED_Core_Rest_Api__save_ee_route_data_for_version__routes', |
|
307 | - array_replace_recursive( |
|
308 | - $instance->_get_config_route_data_for_version($version, $hidden_endpoints), |
|
309 | - $instance->_get_meta_route_data_for_version($version, $hidden_endpoints), |
|
310 | - $instance->_get_model_route_data_for_version($version, $hidden_endpoints), |
|
311 | - $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
|
312 | - ) |
|
313 | - ); |
|
314 | - $option_name = self::saved_routes_option_names . $version; |
|
315 | - if (get_option($option_name)) { |
|
316 | - update_option($option_name, $routes, true); |
|
317 | - } else { |
|
318 | - add_option($option_name, $routes, null, 'no'); |
|
319 | - } |
|
320 | - return $routes; |
|
321 | - } |
|
322 | - |
|
323 | - |
|
324 | - |
|
325 | - /** |
|
326 | - * Calculates all the EE routes and saves it to a wordpress option so we don't |
|
327 | - * need to calculate it on every request |
|
328 | - * |
|
329 | - * @deprecated since version 4.9.1 |
|
330 | - * @return void |
|
331 | - */ |
|
332 | - public static function save_ee_routes() |
|
333 | - { |
|
334 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
335 | - $instance = self::instance(); |
|
336 | - $routes = apply_filters( |
|
337 | - 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
338 | - array_replace_recursive( |
|
339 | - $instance->_register_config_routes(), |
|
340 | - $instance->_register_meta_routes(), |
|
341 | - $instance->_register_model_routes(), |
|
342 | - $instance->_register_rpc_routes() |
|
343 | - ) |
|
344 | - ); |
|
345 | - update_option(self::saved_routes_option_names, $routes, true); |
|
346 | - } |
|
347 | - } |
|
348 | - |
|
349 | - |
|
350 | - |
|
351 | - /** |
|
352 | - * Gets all the route information relating to EE models |
|
353 | - * |
|
354 | - * @return array @see get_ee_route_data |
|
355 | - * @deprecated since version 4.9.1 |
|
356 | - */ |
|
357 | - protected function _register_model_routes() |
|
358 | - { |
|
359 | - $model_routes = array(); |
|
360 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
361 | - $model_routes[EED_Core_Rest_Api::ee_api_namespace |
|
362 | - . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
363 | - } |
|
364 | - return $model_routes; |
|
365 | - } |
|
366 | - |
|
367 | - |
|
368 | - |
|
369 | - /** |
|
370 | - * Gets the route data for EE models in the specified version |
|
371 | - * |
|
372 | - * @param string $version |
|
373 | - * @param boolean $hidden_endpoint |
|
374 | - * @return array |
|
375 | - */ |
|
376 | - protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
377 | - { |
|
378 | - $model_version_info = new Model_Version_Info($version); |
|
379 | - $models_to_register = apply_filters( |
|
380 | - 'FHEE__EED_Core_REST_API___register_model_routes', |
|
381 | - $model_version_info->models_for_requested_version() |
|
382 | - ); |
|
383 | - //let's not bother having endpoints for extra metas |
|
384 | - unset($models_to_register['Extra_Meta']); |
|
385 | - unset($models_to_register['Extra_Join']); |
|
386 | - $model_routes = array(); |
|
387 | - foreach ($models_to_register as $model_name => $model_classname) { |
|
388 | - $model = \EE_Registry::instance()->load_model($model_name); |
|
389 | - |
|
390 | - //if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
391 | - if (! $model instanceof EEM_Base) { |
|
392 | - continue; |
|
393 | - } |
|
394 | - |
|
395 | - //yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
396 | - $plural_model_route = EEH_Inflector::pluralize_and_lower($model_name); |
|
397 | - $singular_model_route = $plural_model_route . '/(?P<id>\d+)'; |
|
398 | - $model_routes[$plural_model_route] = array( |
|
399 | - array( |
|
400 | - 'callback' => array( |
|
401 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
402 | - 'handle_request_get_all', |
|
403 | - ), |
|
404 | - 'methods' => WP_REST_Server::READABLE, |
|
405 | - 'hidden_endpoint' => $hidden_endpoint, |
|
406 | - 'args' => $this->_get_read_query_params($model, $version), |
|
407 | - '_links' => array( |
|
408 | - 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
409 | - ), |
|
410 | - 'schema_callback' => array($model_name, $version) |
|
411 | - ), |
|
412 | - // array( |
|
413 | - // 'callback' => array( |
|
414 | - // 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
415 | - // 'handle_request_create_one' ), |
|
416 | - // 'methods' => WP_REST_Server::CREATABLE, |
|
417 | - // 'hidden_endpoint' => $hidden_endpoint |
|
418 | - // ) |
|
419 | - ); |
|
420 | - $model_routes[$singular_model_route] = array( |
|
421 | - array( |
|
422 | - 'callback' => array( |
|
423 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
424 | - 'handle_request_get_one', |
|
425 | - ), |
|
426 | - 'methods' => WP_REST_Server::READABLE, |
|
427 | - 'hidden_endpoint' => $hidden_endpoint, |
|
428 | - 'args' => $this->_get_response_selection_query_params($model, $version), |
|
429 | - ), |
|
430 | - // array( |
|
431 | - // 'callback' => array( |
|
432 | - // 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
433 | - // 'handle_request_edit_one' ), |
|
434 | - // 'methods' => WP_REST_Server::EDITABLE, |
|
435 | - // 'hidden_endpoint' => $hidden_endpoint |
|
436 | - // ), |
|
437 | - ); |
|
438 | - //@todo: also handle DELETE for a single item |
|
439 | - foreach ($model_version_info->relation_settings($model) as $relation_name => $relation_obj) { |
|
440 | - $related_model_name_endpoint_part = ModelRead::get_related_entity_name( |
|
441 | - $relation_name, |
|
442 | - $relation_obj |
|
443 | - ); |
|
444 | - $model_routes[$singular_model_route . '/' . $related_model_name_endpoint_part] = array( |
|
445 | - array( |
|
446 | - 'callback' => array( |
|
447 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
448 | - 'handle_request_get_related', |
|
449 | - ), |
|
450 | - 'methods' => WP_REST_Server::READABLE, |
|
451 | - 'hidden_endpoint' => $hidden_endpoint, |
|
452 | - 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
453 | - ), |
|
454 | - // array( |
|
455 | - // 'callback' => array( |
|
456 | - // 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
457 | - // 'handle_request_create_or_update_related' ), |
|
458 | - // 'methods' => WP_REST_Server::EDITABLE, |
|
459 | - // 'hidden_endpoint' => $hidden_endpoint |
|
460 | - // ) |
|
461 | - ); |
|
462 | - //@todo: handle delete related and possibly remove relation (not sure hwo to distinguish) |
|
463 | - } |
|
464 | - } |
|
465 | - return $model_routes; |
|
466 | - } |
|
467 | - |
|
468 | - |
|
469 | - |
|
470 | - /** |
|
471 | - * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
472 | - * routes that don't conform to the traditional REST CRUD-style). |
|
473 | - * |
|
474 | - * @deprecated since 4.9.1 |
|
475 | - */ |
|
476 | - protected function _register_rpc_routes() |
|
477 | - { |
|
478 | - $routes = array(); |
|
479 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
480 | - $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version($version, |
|
481 | - $hidden_endpoint); |
|
482 | - } |
|
483 | - return $routes; |
|
484 | - } |
|
485 | - |
|
486 | - |
|
487 | - |
|
488 | - /** |
|
489 | - * @param string $version |
|
490 | - * @param boolean $hidden_endpoint |
|
491 | - * @return array |
|
492 | - */ |
|
493 | - protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
494 | - { |
|
495 | - $this_versions_routes = array(); |
|
496 | - //checkin endpoint |
|
497 | - $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array( |
|
498 | - array( |
|
499 | - 'callback' => array( |
|
500 | - 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
501 | - 'handle_request_toggle_checkin', |
|
502 | - ), |
|
503 | - 'methods' => WP_REST_Server::CREATABLE, |
|
504 | - 'hidden_endpoint' => $hidden_endpoint, |
|
505 | - 'args' => array( |
|
506 | - 'force' => array( |
|
507 | - 'required' => false, |
|
508 | - 'default' => false, |
|
509 | - 'description' => __('Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
510 | - 'event_espresso'), |
|
511 | - ), |
|
512 | - ), |
|
513 | - ), |
|
514 | - ); |
|
515 | - return apply_filters( |
|
516 | - 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
517 | - $this_versions_routes, |
|
518 | - $version, |
|
519 | - $hidden_endpoint |
|
520 | - ); |
|
521 | - } |
|
522 | - |
|
523 | - |
|
524 | - |
|
525 | - /** |
|
526 | - * Gets the query params that can be used when request one or many |
|
527 | - * |
|
528 | - * @param EEM_Base $model |
|
529 | - * @param string $version |
|
530 | - * @return array |
|
531 | - */ |
|
532 | - protected function _get_response_selection_query_params(\EEM_Base $model, $version) |
|
533 | - { |
|
534 | - return apply_filters( |
|
535 | - 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
536 | - array( |
|
537 | - 'include' => array( |
|
538 | - 'required' => false, |
|
539 | - 'default' => '*', |
|
540 | - ), |
|
541 | - 'calculate' => array( |
|
542 | - 'required' => false, |
|
543 | - 'default' => '', |
|
544 | - 'enum' => self::$_field_calculator->retrieve_calculated_fields_for_model($model), |
|
545 | - ), |
|
546 | - ), |
|
547 | - $model, |
|
548 | - $version |
|
549 | - ); |
|
550 | - } |
|
551 | - |
|
552 | - |
|
553 | - |
|
554 | - /** |
|
555 | - * Gets info about reading query params that are acceptable |
|
556 | - * |
|
557 | - * @param \EEM_Base $model eg 'Event' or 'Venue' |
|
558 | - * @param string $version |
|
559 | - * @return array describing the args acceptable when querying this model |
|
560 | - * @throws \EE_Error |
|
561 | - */ |
|
562 | - protected function _get_read_query_params(\EEM_Base $model, $version) |
|
563 | - { |
|
564 | - $default_orderby = array(); |
|
565 | - foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
566 | - $default_orderby[$key_field->get_name()] = 'ASC'; |
|
567 | - } |
|
568 | - return array_merge( |
|
569 | - $this->_get_response_selection_query_params($model, $version), |
|
570 | - array( |
|
571 | - 'where' => array( |
|
572 | - 'required' => false, |
|
573 | - 'default' => array(), |
|
574 | - ), |
|
575 | - 'limit' => array( |
|
576 | - 'required' => false, |
|
577 | - 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
578 | - ), |
|
579 | - 'order_by' => array( |
|
580 | - 'required' => false, |
|
581 | - 'default' => $default_orderby, |
|
582 | - ), |
|
583 | - 'group_by' => array( |
|
584 | - 'required' => false, |
|
585 | - 'default' => null, |
|
586 | - ), |
|
587 | - 'having' => array( |
|
588 | - 'required' => false, |
|
589 | - 'default' => null, |
|
590 | - ), |
|
591 | - 'caps' => array( |
|
592 | - 'required' => false, |
|
593 | - 'default' => EEM_Base::caps_read, |
|
594 | - ), |
|
595 | - ) |
|
596 | - ); |
|
597 | - } |
|
598 | - |
|
599 | - |
|
600 | - |
|
601 | - /** |
|
602 | - * Gets routes for the config |
|
603 | - * |
|
604 | - * @return array @see _register_model_routes |
|
605 | - * @deprecated since version 4.9.1 |
|
606 | - */ |
|
607 | - protected function _register_config_routes() |
|
608 | - { |
|
609 | - $config_routes = array(); |
|
610 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
611 | - $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version($version, |
|
612 | - $hidden_endpoint); |
|
613 | - } |
|
614 | - return $config_routes; |
|
615 | - } |
|
616 | - |
|
617 | - |
|
618 | - |
|
619 | - /** |
|
620 | - * Gets routes for the config for the specified version |
|
621 | - * |
|
622 | - * @param string $version |
|
623 | - * @param boolean $hidden_endpoint |
|
624 | - * @return array |
|
625 | - */ |
|
626 | - protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
627 | - { |
|
628 | - return array( |
|
629 | - 'config' => array( |
|
630 | - array( |
|
631 | - 'callback' => array( |
|
632 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
633 | - 'handle_request', |
|
634 | - ), |
|
635 | - 'methods' => WP_REST_Server::READABLE, |
|
636 | - 'hidden_endpoint' => $hidden_endpoint, |
|
637 | - ), |
|
638 | - ), |
|
639 | - 'site_info' => array( |
|
640 | - array( |
|
641 | - 'callback' => array( |
|
642 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
643 | - 'handle_request_site_info', |
|
644 | - ), |
|
645 | - 'methods' => WP_REST_Server::READABLE, |
|
646 | - 'hidden_endpoint' => $hidden_endpoint, |
|
647 | - ), |
|
648 | - ), |
|
649 | - ); |
|
650 | - } |
|
651 | - |
|
652 | - |
|
653 | - |
|
654 | - /** |
|
655 | - * Gets the meta info routes |
|
656 | - * |
|
657 | - * @return array @see _register_model_routes |
|
658 | - * @deprecated since version 4.9.1 |
|
659 | - */ |
|
660 | - protected function _register_meta_routes() |
|
661 | - { |
|
662 | - $meta_routes = array(); |
|
663 | - foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
664 | - $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version($version, |
|
665 | - $hidden_endpoint); |
|
666 | - } |
|
667 | - return $meta_routes; |
|
668 | - } |
|
669 | - |
|
670 | - |
|
671 | - |
|
672 | - /** |
|
673 | - * @param string $version |
|
674 | - * @param boolean $hidden_endpoint |
|
675 | - * @return array |
|
676 | - */ |
|
677 | - protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
678 | - { |
|
679 | - return array( |
|
680 | - 'resources' => array( |
|
681 | - array( |
|
682 | - 'callback' => array( |
|
683 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
684 | - 'handle_request_models_meta', |
|
685 | - ), |
|
686 | - 'methods' => WP_REST_Server::READABLE, |
|
687 | - 'hidden_endpoint' => $hidden_endpoint, |
|
688 | - ), |
|
689 | - ), |
|
690 | - ); |
|
691 | - } |
|
692 | - |
|
693 | - |
|
694 | - |
|
695 | - /** |
|
696 | - * Tries to hide old 4.6 endpoints from the |
|
697 | - * |
|
698 | - * @param array $route_data |
|
699 | - * @return array |
|
700 | - */ |
|
701 | - public static function hide_old_endpoints($route_data) |
|
702 | - { |
|
703 | - //allow API clients to override which endpoints get hidden, in case |
|
704 | - //they want to discover particular endpoints |
|
705 | - //also, we don't have access to the request so we have to just grab it from the superglobal |
|
706 | - $force_show_ee_namespace = ltrim( |
|
707 | - EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''), |
|
708 | - '/' |
|
709 | - ); |
|
710 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
711 | - foreach ($relative_urls as $endpoint => $routes) { |
|
712 | - foreach ($routes as $route) { |
|
713 | - //by default, hide "hidden_endpoint"s, unless the request indicates |
|
714 | - //to $force_show_ee_namespace, in which case only show that one |
|
715 | - //namespace's endpoints (and hide all others) |
|
716 | - if (($route['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
717 | - || ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
718 | - ) { |
|
719 | - $full_route = '/' . ltrim($namespace, '/') . '/' . ltrim($endpoint, '/'); |
|
720 | - unset($route_data[$full_route]); |
|
721 | - } |
|
722 | - } |
|
723 | - } |
|
724 | - } |
|
725 | - return $route_data; |
|
726 | - } |
|
727 | - |
|
728 | - |
|
729 | - |
|
730 | - /** |
|
731 | - * Returns an array describing which versions of core support serving requests for. |
|
732 | - * Keys are core versions' major and minor version, and values are the |
|
733 | - * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
734 | - * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
735 | - * the answers table entirely, in which case it would be very difficult for |
|
736 | - * it to serve 4.6-style responses. |
|
737 | - * Versions of core that are missing from this array are unknowns. |
|
738 | - * previous ver |
|
739 | - * |
|
740 | - * @return array |
|
741 | - */ |
|
742 | - public static function version_compatibilities() |
|
743 | - { |
|
744 | - return apply_filters( |
|
745 | - 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
746 | - array( |
|
747 | - '4.8.29' => '4.8.29', |
|
748 | - '4.8.33' => '4.8.29', |
|
749 | - '4.8.34' => '4.8.29', |
|
750 | - '4.8.36' => '4.8.29', |
|
751 | - ) |
|
752 | - ); |
|
753 | - } |
|
754 | - |
|
755 | - |
|
756 | - |
|
757 | - /** |
|
758 | - * Gets the latest API version served. Eg if there |
|
759 | - * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
760 | - * we are on core version 4.8.34, it will return the string "4.8.32" |
|
761 | - * |
|
762 | - * @return string |
|
763 | - */ |
|
764 | - public static function latest_rest_api_version() |
|
765 | - { |
|
766 | - $versions_served = \EED_Core_Rest_Api::versions_served(); |
|
767 | - $versions_served_keys = array_keys($versions_served); |
|
768 | - return end($versions_served_keys); |
|
769 | - } |
|
770 | - |
|
771 | - |
|
772 | - |
|
773 | - /** |
|
774 | - * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
775 | - * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
776 | - * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
777 | - * We also indicate whether or not this version should be put in the index or not |
|
778 | - * |
|
779 | - * @return array keys are API version numbers (just major and minor numbers), and values |
|
780 | - * are whether or not they should be hidden |
|
781 | - */ |
|
782 | - public static function versions_served() |
|
783 | - { |
|
784 | - $versions_served = array(); |
|
785 | - $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
786 | - $lowest_compatible_version = end($possibly_served_versions); |
|
787 | - reset($possibly_served_versions); |
|
788 | - $versions_served_historically = array_keys($possibly_served_versions); |
|
789 | - $latest_version = end($versions_served_historically); |
|
790 | - reset($versions_served_historically); |
|
791 | - //for each version of core we have ever served: |
|
792 | - foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
793 | - //if it's not above the current core version, and it's compatible with the current version of core |
|
794 | - if ($key_versioned_endpoint == $latest_version) { |
|
795 | - //don't hide the latest version in the index |
|
796 | - $versions_served[$key_versioned_endpoint] = false; |
|
797 | - } else if ( |
|
798 | - $key_versioned_endpoint < EED_Core_Rest_Api::core_version() |
|
799 | - && $key_versioned_endpoint >= $lowest_compatible_version |
|
800 | - ) { |
|
801 | - //include, but hide, previous versions which are still supported |
|
802 | - $versions_served[$key_versioned_endpoint] = true; |
|
803 | - } elseif ( |
|
804 | - apply_filters( |
|
805 | - 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
806 | - false, |
|
807 | - $possibly_served_versions |
|
808 | - ) |
|
809 | - ) { |
|
810 | - //if a version is no longer supported, don't include it in index or list of versions served |
|
811 | - $versions_served[$key_versioned_endpoint] = true; |
|
812 | - } |
|
813 | - } |
|
814 | - return $versions_served; |
|
815 | - } |
|
816 | - |
|
817 | - |
|
818 | - |
|
819 | - /** |
|
820 | - * Gets the major and minor version of EE core's version string |
|
821 | - * |
|
822 | - * @return string |
|
823 | - */ |
|
824 | - public static function core_version() |
|
825 | - { |
|
826 | - return apply_filters('FHEE__EED_Core_REST_API__core_version', |
|
827 | - implode('.', array_slice(explode('.', espresso_version()), 0, 3))); |
|
828 | - } |
|
829 | - |
|
830 | - |
|
831 | - |
|
832 | - /** |
|
833 | - * Gets the default limit that should be used when querying for resources |
|
834 | - * |
|
835 | - * @return int |
|
836 | - */ |
|
837 | - public static function get_default_query_limit() |
|
838 | - { |
|
839 | - //we actually don't use a const because we want folks to always use |
|
840 | - //this method, not the const directly |
|
841 | - return apply_filters( |
|
842 | - 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
843 | - 50 |
|
844 | - ); |
|
845 | - } |
|
846 | - |
|
847 | - |
|
848 | - |
|
849 | - /** |
|
850 | - * run - initial module setup |
|
851 | - * |
|
852 | - * @access public |
|
853 | - * @param WP $WP |
|
854 | - * @return void |
|
855 | - */ |
|
856 | - public function run($WP) |
|
857 | - { |
|
858 | - } |
|
23 | + const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
24 | + |
|
25 | + const saved_routes_option_names = 'ee_core_routes'; |
|
26 | + |
|
27 | + /** |
|
28 | + * string used in _links response bodies to make them globally unique. |
|
29 | + * |
|
30 | + * @see http://v2.wp-api.org/extending/linking/ |
|
31 | + */ |
|
32 | + const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
33 | + |
|
34 | + /** |
|
35 | + * @var Calculated_Model_Fields |
|
36 | + */ |
|
37 | + protected static $_field_calculator = null; |
|
38 | + |
|
39 | + |
|
40 | + |
|
41 | + /** |
|
42 | + * @return EED_Core_Rest_Api |
|
43 | + */ |
|
44 | + public static function instance() |
|
45 | + { |
|
46 | + self::$_field_calculator = new Calculated_Model_Fields(); |
|
47 | + return parent::get_instance(__CLASS__); |
|
48 | + } |
|
49 | + |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
54 | + * |
|
55 | + * @access public |
|
56 | + * @return void |
|
57 | + */ |
|
58 | + public static function set_hooks() |
|
59 | + { |
|
60 | + self::set_hooks_both(); |
|
61 | + } |
|
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 | + self::set_hooks_both(); |
|
74 | + } |
|
75 | + |
|
76 | + |
|
77 | + |
|
78 | + public static function set_hooks_both() |
|
79 | + { |
|
80 | + add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10); |
|
81 | + add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5); |
|
82 | + add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2); |
|
83 | + add_filter('rest_index', |
|
84 | + array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filter_ee_metadata_into_index')); |
|
85 | + EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
86 | + } |
|
87 | + |
|
88 | + |
|
89 | + |
|
90 | + /** |
|
91 | + * sets up hooks which only need to be included as part of REST API requests; |
|
92 | + * other requests like to the frontend or admin etc don't need them |
|
93 | + */ |
|
94 | + public static function set_hooks_rest_api() |
|
95 | + { |
|
96 | + //set hooks which account for changes made to the API |
|
97 | + EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
98 | + EED_Core_Rest_Api::maybe_notify_of_basic_auth_removal(); |
|
99 | + } |
|
100 | + |
|
101 | + |
|
102 | + |
|
103 | + /** |
|
104 | + * public wrapper of _set_hooks_for_changes. |
|
105 | + * Loads all the hooks which make requests to old versions of the API |
|
106 | + * appear the same as they always did |
|
107 | + */ |
|
108 | + public static function set_hooks_for_changes() |
|
109 | + { |
|
110 | + self::_set_hooks_for_changes(); |
|
111 | + } |
|
112 | + |
|
113 | + |
|
114 | + |
|
115 | + /** |
|
116 | + * If the user appears to be using WP API basic auth, tell them (via a persistent |
|
117 | + * admin notice and an email) that we're going to remove it soon, so they should |
|
118 | + * replace it with application passwords. |
|
119 | + */ |
|
120 | + public static function maybe_notify_of_basic_auth_removal() |
|
121 | + { |
|
122 | + if ( |
|
123 | + apply_filters( |
|
124 | + 'FHEE__EED_Core_Rest_Api__maybe_notify_of_basic_auth_removal__override', |
|
125 | + ! isset($_SERVER['PHP_AUTH_USER']) |
|
126 | + && ! isset($_SERVER['HTTP_AUTHORIZATION']) |
|
127 | + ) |
|
128 | + ) { |
|
129 | + //sure it's a WP API request, but they aren't using basic auth, so don't bother them |
|
130 | + return; |
|
131 | + } |
|
132 | + //ok they're using the WP API with Basic Auth |
|
133 | + $message = sprintf( |
|
134 | + __('We noticed you\'re using the WP API, which is used by the Event Espresso 4 mobile apps. Because of security and compatibility concerns, we will soon be removing our default authentication mechanism, WP API Basic Auth, from Event Espresso. It is recommended you instead install the %1$sWP Application Passwords plugin%2$s and use it with the EE4 Mobile apps. See %3$sour mobile app documentation%2$s for more information. %4$sIf you have installed the WP API Basic Auth plugin separately, or are not using the Event Espresso 4 mobile apps, you can disregard this message.%4$sThe Event Espresso Team', |
|
135 | + 'event_espresso'), |
|
136 | + '<a href="https://wordpress.org/plugins/application-passwords/">', |
|
137 | + '</a>', |
|
138 | + '<a href="https://eventespresso.com/wiki/ee4-event-apps/#authentication">', |
|
139 | + '<br/>' |
|
140 | + ); |
|
141 | + EE_Error::add_persistent_admin_notice('using_basic_auth', $message); |
|
142 | + if ( ! get_option('ee_notified_admin_on_basic_auth_removal', false)) { |
|
143 | + add_option('ee_notified_admin_on_basic_auth_removal', true); |
|
144 | + //piggy back off EE_Error::set_content_type, which sets the content type to HTML |
|
145 | + add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type')); |
|
146 | + //and send the message to the site admin too |
|
147 | + wp_mail(get_option('admin_email'), |
|
148 | + __('Notice of Removal of WP API Basic Auth From Event Espresso 4', 'event_espresso'), $message); |
|
149 | + remove_filter('wp_mail_content_type', array('EE_Error', 'set_content_type')); |
|
150 | + } |
|
151 | + } |
|
152 | + |
|
153 | + |
|
154 | + |
|
155 | + /** |
|
156 | + * Loads all the hooks which make requests to old versions of the API |
|
157 | + * appear the same as they always did |
|
158 | + */ |
|
159 | + protected static function _set_hooks_for_changes() |
|
160 | + { |
|
161 | + $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false); |
|
162 | + foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
163 | + //ignore the base parent class |
|
164 | + if ($classname_in_namespace === 'Changes_In_Base') { |
|
165 | + continue; |
|
166 | + } |
|
167 | + $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
168 | + if (class_exists($full_classname)) { |
|
169 | + $instance_of_class = new $full_classname; |
|
170 | + if ($instance_of_class instanceof Changes_In_Base) { |
|
171 | + $instance_of_class->set_hooks(); |
|
172 | + } |
|
173 | + } |
|
174 | + } |
|
175 | + } |
|
176 | + |
|
177 | + |
|
178 | + |
|
179 | + /** |
|
180 | + * Filters the WP routes to add our EE-related ones. This takes a bit of time |
|
181 | + * so we actually prefer to only do it when an EE plugin is activated or upgraded |
|
182 | + */ |
|
183 | + public static function register_routes() |
|
184 | + { |
|
185 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
186 | + foreach ($relative_urls as $endpoint => $routes) { |
|
187 | + foreach ($routes as $route) { |
|
188 | + $route_args = array( |
|
189 | + array( |
|
190 | + 'callback' => $route['callback'], |
|
191 | + 'methods' => $route['methods'], |
|
192 | + 'args' => isset($route['args']) ? $route['args'] : array(), |
|
193 | + ) |
|
194 | + ); |
|
195 | + if (isset($route['schema_callback'])) { |
|
196 | + $model_name = isset($route['schema_callback'][0]) |
|
197 | + ? $route['schema_callback'][0] |
|
198 | + : ''; |
|
199 | + $version = isset( $route['schema_callback'][1]) |
|
200 | + ? $route['schema_callback'][1] |
|
201 | + : ''; |
|
202 | + if (! empty($model_name) && ! empty($version)) { |
|
203 | + $route_args['schema'] = function () use ($model_name, $version) { |
|
204 | + return ModelRead::handle_schema_request( |
|
205 | + $model_name, |
|
206 | + $version |
|
207 | + ); |
|
208 | + }; |
|
209 | + } |
|
210 | + } |
|
211 | + register_rest_route( |
|
212 | + $namespace, |
|
213 | + $endpoint, |
|
214 | + $route_args |
|
215 | + ); |
|
216 | + } |
|
217 | + } |
|
218 | + } |
|
219 | + } |
|
220 | + |
|
221 | + |
|
222 | + |
|
223 | + /** |
|
224 | + * Checks if there was a version change or something that merits invalidating the cached |
|
225 | + * route data. If so, invalidates the cached route data so that it gets refreshed |
|
226 | + * next time the WP API is used |
|
227 | + */ |
|
228 | + public static function invalidate_cached_route_data_on_version_change() |
|
229 | + { |
|
230 | + if (EE_System::instance()->detect_req_type() != EE_System::req_type_normal) { |
|
231 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
232 | + } |
|
233 | + foreach (EE_Registry::instance()->addons as $addon) { |
|
234 | + if ($addon instanceof EE_Addon && $addon->detect_req_type() != EE_System::req_type_normal) { |
|
235 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
236 | + } |
|
237 | + } |
|
238 | + } |
|
239 | + |
|
240 | + |
|
241 | + |
|
242 | + /** |
|
243 | + * Removes the cached route data so it will get refreshed next time the WP API is used |
|
244 | + */ |
|
245 | + public static function invalidate_cached_route_data() |
|
246 | + { |
|
247 | + //delete the saved EE REST API routes |
|
248 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
|
249 | + delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
250 | + } |
|
251 | + } |
|
252 | + |
|
253 | + |
|
254 | + |
|
255 | + /** |
|
256 | + * Gets the EE route data |
|
257 | + * |
|
258 | + * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
259 | + * @type string|array $callback |
|
260 | + * @type string $methods |
|
261 | + * @type boolean $hidden_endpoint |
|
262 | + * } |
|
263 | + */ |
|
264 | + public static function get_ee_route_data() |
|
265 | + { |
|
266 | + $ee_routes = array(); |
|
267 | + foreach (self::versions_served() as $version => $hidden_endpoints) { |
|
268 | + $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version($version, |
|
269 | + $hidden_endpoints); |
|
270 | + } |
|
271 | + return $ee_routes; |
|
272 | + } |
|
273 | + |
|
274 | + |
|
275 | + |
|
276 | + /** |
|
277 | + * Gets the EE route data from the wp options if it exists already, |
|
278 | + * otherwise re-generates it and saves it to the option |
|
279 | + * |
|
280 | + * @param string $version |
|
281 | + * @param boolean $hidden_endpoints |
|
282 | + * @return array |
|
283 | + */ |
|
284 | + protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
285 | + { |
|
286 | + $ee_routes = get_option(self::saved_routes_option_names . $version, null); |
|
287 | + if ( ! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) { |
|
288 | + $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
289 | + } |
|
290 | + return $ee_routes; |
|
291 | + } |
|
292 | + |
|
293 | + |
|
294 | + |
|
295 | + /** |
|
296 | + * Saves the EE REST API route data to a wp option and returns it |
|
297 | + * |
|
298 | + * @param string $version |
|
299 | + * @param boolean $hidden_endpoints |
|
300 | + * @return mixed|null|void |
|
301 | + */ |
|
302 | + protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
303 | + { |
|
304 | + $instance = self::instance(); |
|
305 | + $routes = apply_filters( |
|
306 | + 'EED_Core_Rest_Api__save_ee_route_data_for_version__routes', |
|
307 | + array_replace_recursive( |
|
308 | + $instance->_get_config_route_data_for_version($version, $hidden_endpoints), |
|
309 | + $instance->_get_meta_route_data_for_version($version, $hidden_endpoints), |
|
310 | + $instance->_get_model_route_data_for_version($version, $hidden_endpoints), |
|
311 | + $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
|
312 | + ) |
|
313 | + ); |
|
314 | + $option_name = self::saved_routes_option_names . $version; |
|
315 | + if (get_option($option_name)) { |
|
316 | + update_option($option_name, $routes, true); |
|
317 | + } else { |
|
318 | + add_option($option_name, $routes, null, 'no'); |
|
319 | + } |
|
320 | + return $routes; |
|
321 | + } |
|
322 | + |
|
323 | + |
|
324 | + |
|
325 | + /** |
|
326 | + * Calculates all the EE routes and saves it to a wordpress option so we don't |
|
327 | + * need to calculate it on every request |
|
328 | + * |
|
329 | + * @deprecated since version 4.9.1 |
|
330 | + * @return void |
|
331 | + */ |
|
332 | + public static function save_ee_routes() |
|
333 | + { |
|
334 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
335 | + $instance = self::instance(); |
|
336 | + $routes = apply_filters( |
|
337 | + 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
338 | + array_replace_recursive( |
|
339 | + $instance->_register_config_routes(), |
|
340 | + $instance->_register_meta_routes(), |
|
341 | + $instance->_register_model_routes(), |
|
342 | + $instance->_register_rpc_routes() |
|
343 | + ) |
|
344 | + ); |
|
345 | + update_option(self::saved_routes_option_names, $routes, true); |
|
346 | + } |
|
347 | + } |
|
348 | + |
|
349 | + |
|
350 | + |
|
351 | + /** |
|
352 | + * Gets all the route information relating to EE models |
|
353 | + * |
|
354 | + * @return array @see get_ee_route_data |
|
355 | + * @deprecated since version 4.9.1 |
|
356 | + */ |
|
357 | + protected function _register_model_routes() |
|
358 | + { |
|
359 | + $model_routes = array(); |
|
360 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
361 | + $model_routes[EED_Core_Rest_Api::ee_api_namespace |
|
362 | + . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
363 | + } |
|
364 | + return $model_routes; |
|
365 | + } |
|
366 | + |
|
367 | + |
|
368 | + |
|
369 | + /** |
|
370 | + * Gets the route data for EE models in the specified version |
|
371 | + * |
|
372 | + * @param string $version |
|
373 | + * @param boolean $hidden_endpoint |
|
374 | + * @return array |
|
375 | + */ |
|
376 | + protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
377 | + { |
|
378 | + $model_version_info = new Model_Version_Info($version); |
|
379 | + $models_to_register = apply_filters( |
|
380 | + 'FHEE__EED_Core_REST_API___register_model_routes', |
|
381 | + $model_version_info->models_for_requested_version() |
|
382 | + ); |
|
383 | + //let's not bother having endpoints for extra metas |
|
384 | + unset($models_to_register['Extra_Meta']); |
|
385 | + unset($models_to_register['Extra_Join']); |
|
386 | + $model_routes = array(); |
|
387 | + foreach ($models_to_register as $model_name => $model_classname) { |
|
388 | + $model = \EE_Registry::instance()->load_model($model_name); |
|
389 | + |
|
390 | + //if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
391 | + if (! $model instanceof EEM_Base) { |
|
392 | + continue; |
|
393 | + } |
|
394 | + |
|
395 | + //yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
396 | + $plural_model_route = EEH_Inflector::pluralize_and_lower($model_name); |
|
397 | + $singular_model_route = $plural_model_route . '/(?P<id>\d+)'; |
|
398 | + $model_routes[$plural_model_route] = array( |
|
399 | + array( |
|
400 | + 'callback' => array( |
|
401 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
402 | + 'handle_request_get_all', |
|
403 | + ), |
|
404 | + 'methods' => WP_REST_Server::READABLE, |
|
405 | + 'hidden_endpoint' => $hidden_endpoint, |
|
406 | + 'args' => $this->_get_read_query_params($model, $version), |
|
407 | + '_links' => array( |
|
408 | + 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
409 | + ), |
|
410 | + 'schema_callback' => array($model_name, $version) |
|
411 | + ), |
|
412 | + // array( |
|
413 | + // 'callback' => array( |
|
414 | + // 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
415 | + // 'handle_request_create_one' ), |
|
416 | + // 'methods' => WP_REST_Server::CREATABLE, |
|
417 | + // 'hidden_endpoint' => $hidden_endpoint |
|
418 | + // ) |
|
419 | + ); |
|
420 | + $model_routes[$singular_model_route] = array( |
|
421 | + array( |
|
422 | + 'callback' => array( |
|
423 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
424 | + 'handle_request_get_one', |
|
425 | + ), |
|
426 | + 'methods' => WP_REST_Server::READABLE, |
|
427 | + 'hidden_endpoint' => $hidden_endpoint, |
|
428 | + 'args' => $this->_get_response_selection_query_params($model, $version), |
|
429 | + ), |
|
430 | + // array( |
|
431 | + // 'callback' => array( |
|
432 | + // 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
433 | + // 'handle_request_edit_one' ), |
|
434 | + // 'methods' => WP_REST_Server::EDITABLE, |
|
435 | + // 'hidden_endpoint' => $hidden_endpoint |
|
436 | + // ), |
|
437 | + ); |
|
438 | + //@todo: also handle DELETE for a single item |
|
439 | + foreach ($model_version_info->relation_settings($model) as $relation_name => $relation_obj) { |
|
440 | + $related_model_name_endpoint_part = ModelRead::get_related_entity_name( |
|
441 | + $relation_name, |
|
442 | + $relation_obj |
|
443 | + ); |
|
444 | + $model_routes[$singular_model_route . '/' . $related_model_name_endpoint_part] = array( |
|
445 | + array( |
|
446 | + 'callback' => array( |
|
447 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
448 | + 'handle_request_get_related', |
|
449 | + ), |
|
450 | + 'methods' => WP_REST_Server::READABLE, |
|
451 | + 'hidden_endpoint' => $hidden_endpoint, |
|
452 | + 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
453 | + ), |
|
454 | + // array( |
|
455 | + // 'callback' => array( |
|
456 | + // 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
457 | + // 'handle_request_create_or_update_related' ), |
|
458 | + // 'methods' => WP_REST_Server::EDITABLE, |
|
459 | + // 'hidden_endpoint' => $hidden_endpoint |
|
460 | + // ) |
|
461 | + ); |
|
462 | + //@todo: handle delete related and possibly remove relation (not sure hwo to distinguish) |
|
463 | + } |
|
464 | + } |
|
465 | + return $model_routes; |
|
466 | + } |
|
467 | + |
|
468 | + |
|
469 | + |
|
470 | + /** |
|
471 | + * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
472 | + * routes that don't conform to the traditional REST CRUD-style). |
|
473 | + * |
|
474 | + * @deprecated since 4.9.1 |
|
475 | + */ |
|
476 | + protected function _register_rpc_routes() |
|
477 | + { |
|
478 | + $routes = array(); |
|
479 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
480 | + $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version($version, |
|
481 | + $hidden_endpoint); |
|
482 | + } |
|
483 | + return $routes; |
|
484 | + } |
|
485 | + |
|
486 | + |
|
487 | + |
|
488 | + /** |
|
489 | + * @param string $version |
|
490 | + * @param boolean $hidden_endpoint |
|
491 | + * @return array |
|
492 | + */ |
|
493 | + protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
494 | + { |
|
495 | + $this_versions_routes = array(); |
|
496 | + //checkin endpoint |
|
497 | + $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array( |
|
498 | + array( |
|
499 | + 'callback' => array( |
|
500 | + 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
501 | + 'handle_request_toggle_checkin', |
|
502 | + ), |
|
503 | + 'methods' => WP_REST_Server::CREATABLE, |
|
504 | + 'hidden_endpoint' => $hidden_endpoint, |
|
505 | + 'args' => array( |
|
506 | + 'force' => array( |
|
507 | + 'required' => false, |
|
508 | + 'default' => false, |
|
509 | + 'description' => __('Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
510 | + 'event_espresso'), |
|
511 | + ), |
|
512 | + ), |
|
513 | + ), |
|
514 | + ); |
|
515 | + return apply_filters( |
|
516 | + 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
517 | + $this_versions_routes, |
|
518 | + $version, |
|
519 | + $hidden_endpoint |
|
520 | + ); |
|
521 | + } |
|
522 | + |
|
523 | + |
|
524 | + |
|
525 | + /** |
|
526 | + * Gets the query params that can be used when request one or many |
|
527 | + * |
|
528 | + * @param EEM_Base $model |
|
529 | + * @param string $version |
|
530 | + * @return array |
|
531 | + */ |
|
532 | + protected function _get_response_selection_query_params(\EEM_Base $model, $version) |
|
533 | + { |
|
534 | + return apply_filters( |
|
535 | + 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
536 | + array( |
|
537 | + 'include' => array( |
|
538 | + 'required' => false, |
|
539 | + 'default' => '*', |
|
540 | + ), |
|
541 | + 'calculate' => array( |
|
542 | + 'required' => false, |
|
543 | + 'default' => '', |
|
544 | + 'enum' => self::$_field_calculator->retrieve_calculated_fields_for_model($model), |
|
545 | + ), |
|
546 | + ), |
|
547 | + $model, |
|
548 | + $version |
|
549 | + ); |
|
550 | + } |
|
551 | + |
|
552 | + |
|
553 | + |
|
554 | + /** |
|
555 | + * Gets info about reading query params that are acceptable |
|
556 | + * |
|
557 | + * @param \EEM_Base $model eg 'Event' or 'Venue' |
|
558 | + * @param string $version |
|
559 | + * @return array describing the args acceptable when querying this model |
|
560 | + * @throws \EE_Error |
|
561 | + */ |
|
562 | + protected function _get_read_query_params(\EEM_Base $model, $version) |
|
563 | + { |
|
564 | + $default_orderby = array(); |
|
565 | + foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
566 | + $default_orderby[$key_field->get_name()] = 'ASC'; |
|
567 | + } |
|
568 | + return array_merge( |
|
569 | + $this->_get_response_selection_query_params($model, $version), |
|
570 | + array( |
|
571 | + 'where' => array( |
|
572 | + 'required' => false, |
|
573 | + 'default' => array(), |
|
574 | + ), |
|
575 | + 'limit' => array( |
|
576 | + 'required' => false, |
|
577 | + 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
578 | + ), |
|
579 | + 'order_by' => array( |
|
580 | + 'required' => false, |
|
581 | + 'default' => $default_orderby, |
|
582 | + ), |
|
583 | + 'group_by' => array( |
|
584 | + 'required' => false, |
|
585 | + 'default' => null, |
|
586 | + ), |
|
587 | + 'having' => array( |
|
588 | + 'required' => false, |
|
589 | + 'default' => null, |
|
590 | + ), |
|
591 | + 'caps' => array( |
|
592 | + 'required' => false, |
|
593 | + 'default' => EEM_Base::caps_read, |
|
594 | + ), |
|
595 | + ) |
|
596 | + ); |
|
597 | + } |
|
598 | + |
|
599 | + |
|
600 | + |
|
601 | + /** |
|
602 | + * Gets routes for the config |
|
603 | + * |
|
604 | + * @return array @see _register_model_routes |
|
605 | + * @deprecated since version 4.9.1 |
|
606 | + */ |
|
607 | + protected function _register_config_routes() |
|
608 | + { |
|
609 | + $config_routes = array(); |
|
610 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
611 | + $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version($version, |
|
612 | + $hidden_endpoint); |
|
613 | + } |
|
614 | + return $config_routes; |
|
615 | + } |
|
616 | + |
|
617 | + |
|
618 | + |
|
619 | + /** |
|
620 | + * Gets routes for the config for the specified version |
|
621 | + * |
|
622 | + * @param string $version |
|
623 | + * @param boolean $hidden_endpoint |
|
624 | + * @return array |
|
625 | + */ |
|
626 | + protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
627 | + { |
|
628 | + return array( |
|
629 | + 'config' => array( |
|
630 | + array( |
|
631 | + 'callback' => array( |
|
632 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
633 | + 'handle_request', |
|
634 | + ), |
|
635 | + 'methods' => WP_REST_Server::READABLE, |
|
636 | + 'hidden_endpoint' => $hidden_endpoint, |
|
637 | + ), |
|
638 | + ), |
|
639 | + 'site_info' => array( |
|
640 | + array( |
|
641 | + 'callback' => array( |
|
642 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
643 | + 'handle_request_site_info', |
|
644 | + ), |
|
645 | + 'methods' => WP_REST_Server::READABLE, |
|
646 | + 'hidden_endpoint' => $hidden_endpoint, |
|
647 | + ), |
|
648 | + ), |
|
649 | + ); |
|
650 | + } |
|
651 | + |
|
652 | + |
|
653 | + |
|
654 | + /** |
|
655 | + * Gets the meta info routes |
|
656 | + * |
|
657 | + * @return array @see _register_model_routes |
|
658 | + * @deprecated since version 4.9.1 |
|
659 | + */ |
|
660 | + protected function _register_meta_routes() |
|
661 | + { |
|
662 | + $meta_routes = array(); |
|
663 | + foreach (self::versions_served() as $version => $hidden_endpoint) { |
|
664 | + $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version($version, |
|
665 | + $hidden_endpoint); |
|
666 | + } |
|
667 | + return $meta_routes; |
|
668 | + } |
|
669 | + |
|
670 | + |
|
671 | + |
|
672 | + /** |
|
673 | + * @param string $version |
|
674 | + * @param boolean $hidden_endpoint |
|
675 | + * @return array |
|
676 | + */ |
|
677 | + protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
678 | + { |
|
679 | + return array( |
|
680 | + 'resources' => array( |
|
681 | + array( |
|
682 | + 'callback' => array( |
|
683 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
684 | + 'handle_request_models_meta', |
|
685 | + ), |
|
686 | + 'methods' => WP_REST_Server::READABLE, |
|
687 | + 'hidden_endpoint' => $hidden_endpoint, |
|
688 | + ), |
|
689 | + ), |
|
690 | + ); |
|
691 | + } |
|
692 | + |
|
693 | + |
|
694 | + |
|
695 | + /** |
|
696 | + * Tries to hide old 4.6 endpoints from the |
|
697 | + * |
|
698 | + * @param array $route_data |
|
699 | + * @return array |
|
700 | + */ |
|
701 | + public static function hide_old_endpoints($route_data) |
|
702 | + { |
|
703 | + //allow API clients to override which endpoints get hidden, in case |
|
704 | + //they want to discover particular endpoints |
|
705 | + //also, we don't have access to the request so we have to just grab it from the superglobal |
|
706 | + $force_show_ee_namespace = ltrim( |
|
707 | + EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''), |
|
708 | + '/' |
|
709 | + ); |
|
710 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
711 | + foreach ($relative_urls as $endpoint => $routes) { |
|
712 | + foreach ($routes as $route) { |
|
713 | + //by default, hide "hidden_endpoint"s, unless the request indicates |
|
714 | + //to $force_show_ee_namespace, in which case only show that one |
|
715 | + //namespace's endpoints (and hide all others) |
|
716 | + if (($route['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
717 | + || ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
718 | + ) { |
|
719 | + $full_route = '/' . ltrim($namespace, '/') . '/' . ltrim($endpoint, '/'); |
|
720 | + unset($route_data[$full_route]); |
|
721 | + } |
|
722 | + } |
|
723 | + } |
|
724 | + } |
|
725 | + return $route_data; |
|
726 | + } |
|
727 | + |
|
728 | + |
|
729 | + |
|
730 | + /** |
|
731 | + * Returns an array describing which versions of core support serving requests for. |
|
732 | + * Keys are core versions' major and minor version, and values are the |
|
733 | + * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
734 | + * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
735 | + * the answers table entirely, in which case it would be very difficult for |
|
736 | + * it to serve 4.6-style responses. |
|
737 | + * Versions of core that are missing from this array are unknowns. |
|
738 | + * previous ver |
|
739 | + * |
|
740 | + * @return array |
|
741 | + */ |
|
742 | + public static function version_compatibilities() |
|
743 | + { |
|
744 | + return apply_filters( |
|
745 | + 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
746 | + array( |
|
747 | + '4.8.29' => '4.8.29', |
|
748 | + '4.8.33' => '4.8.29', |
|
749 | + '4.8.34' => '4.8.29', |
|
750 | + '4.8.36' => '4.8.29', |
|
751 | + ) |
|
752 | + ); |
|
753 | + } |
|
754 | + |
|
755 | + |
|
756 | + |
|
757 | + /** |
|
758 | + * Gets the latest API version served. Eg if there |
|
759 | + * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
760 | + * we are on core version 4.8.34, it will return the string "4.8.32" |
|
761 | + * |
|
762 | + * @return string |
|
763 | + */ |
|
764 | + public static function latest_rest_api_version() |
|
765 | + { |
|
766 | + $versions_served = \EED_Core_Rest_Api::versions_served(); |
|
767 | + $versions_served_keys = array_keys($versions_served); |
|
768 | + return end($versions_served_keys); |
|
769 | + } |
|
770 | + |
|
771 | + |
|
772 | + |
|
773 | + /** |
|
774 | + * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
775 | + * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
776 | + * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
777 | + * We also indicate whether or not this version should be put in the index or not |
|
778 | + * |
|
779 | + * @return array keys are API version numbers (just major and minor numbers), and values |
|
780 | + * are whether or not they should be hidden |
|
781 | + */ |
|
782 | + public static function versions_served() |
|
783 | + { |
|
784 | + $versions_served = array(); |
|
785 | + $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
786 | + $lowest_compatible_version = end($possibly_served_versions); |
|
787 | + reset($possibly_served_versions); |
|
788 | + $versions_served_historically = array_keys($possibly_served_versions); |
|
789 | + $latest_version = end($versions_served_historically); |
|
790 | + reset($versions_served_historically); |
|
791 | + //for each version of core we have ever served: |
|
792 | + foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
793 | + //if it's not above the current core version, and it's compatible with the current version of core |
|
794 | + if ($key_versioned_endpoint == $latest_version) { |
|
795 | + //don't hide the latest version in the index |
|
796 | + $versions_served[$key_versioned_endpoint] = false; |
|
797 | + } else if ( |
|
798 | + $key_versioned_endpoint < EED_Core_Rest_Api::core_version() |
|
799 | + && $key_versioned_endpoint >= $lowest_compatible_version |
|
800 | + ) { |
|
801 | + //include, but hide, previous versions which are still supported |
|
802 | + $versions_served[$key_versioned_endpoint] = true; |
|
803 | + } elseif ( |
|
804 | + apply_filters( |
|
805 | + 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
806 | + false, |
|
807 | + $possibly_served_versions |
|
808 | + ) |
|
809 | + ) { |
|
810 | + //if a version is no longer supported, don't include it in index or list of versions served |
|
811 | + $versions_served[$key_versioned_endpoint] = true; |
|
812 | + } |
|
813 | + } |
|
814 | + return $versions_served; |
|
815 | + } |
|
816 | + |
|
817 | + |
|
818 | + |
|
819 | + /** |
|
820 | + * Gets the major and minor version of EE core's version string |
|
821 | + * |
|
822 | + * @return string |
|
823 | + */ |
|
824 | + public static function core_version() |
|
825 | + { |
|
826 | + return apply_filters('FHEE__EED_Core_REST_API__core_version', |
|
827 | + implode('.', array_slice(explode('.', espresso_version()), 0, 3))); |
|
828 | + } |
|
829 | + |
|
830 | + |
|
831 | + |
|
832 | + /** |
|
833 | + * Gets the default limit that should be used when querying for resources |
|
834 | + * |
|
835 | + * @return int |
|
836 | + */ |
|
837 | + public static function get_default_query_limit() |
|
838 | + { |
|
839 | + //we actually don't use a const because we want folks to always use |
|
840 | + //this method, not the const directly |
|
841 | + return apply_filters( |
|
842 | + 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
843 | + 50 |
|
844 | + ); |
|
845 | + } |
|
846 | + |
|
847 | + |
|
848 | + |
|
849 | + /** |
|
850 | + * run - initial module setup |
|
851 | + * |
|
852 | + * @access public |
|
853 | + * @param WP $WP |
|
854 | + * @return void |
|
855 | + */ |
|
856 | + public function run($WP) |
|
857 | + { |
|
858 | + } |
|
859 | 859 | |
860 | 860 | |
861 | 861 |
@@ -5,63 +5,63 @@ |
||
5 | 5 | |
6 | 6 | interface HasSchemaInterface |
7 | 7 | { |
8 | - /** |
|
9 | - * Returns whatever is set as the nicename for the object. |
|
10 | - * |
|
11 | - * @return string |
|
12 | - */ |
|
13 | - public function getSchemaDescription(); |
|
8 | + /** |
|
9 | + * Returns whatever is set as the nicename for the object. |
|
10 | + * |
|
11 | + * @return string |
|
12 | + */ |
|
13 | + public function getSchemaDescription(); |
|
14 | 14 | |
15 | 15 | |
16 | - /** |
|
17 | - * Returns whatever is set as the $_schema_type property for the object. |
|
18 | - * Note: this will automatically add 'null' to the schema if the object is_nullable() |
|
19 | - * |
|
20 | - * @return string|array |
|
21 | - */ |
|
22 | - public function getSchemaType(); |
|
16 | + /** |
|
17 | + * Returns whatever is set as the $_schema_type property for the object. |
|
18 | + * Note: this will automatically add 'null' to the schema if the object is_nullable() |
|
19 | + * |
|
20 | + * @return string|array |
|
21 | + */ |
|
22 | + public function getSchemaType(); |
|
23 | 23 | |
24 | 24 | |
25 | - /** |
|
26 | - * This is usually present when the $_schema_type property is 'object'. Any child classes will need to override |
|
27 | - * this method and return the properties for the schema. |
|
28 | - * The reason this is not a property on the class is because there may be filters set on the values for the property |
|
29 | - * that won't be exposed on construct. For example enum type schemas may have the enum values filtered. |
|
30 | - * |
|
31 | - * @return array |
|
32 | - */ |
|
33 | - public function getSchemaProperties(); |
|
25 | + /** |
|
26 | + * This is usually present when the $_schema_type property is 'object'. Any child classes will need to override |
|
27 | + * this method and return the properties for the schema. |
|
28 | + * The reason this is not a property on the class is because there may be filters set on the values for the property |
|
29 | + * that won't be exposed on construct. For example enum type schemas may have the enum values filtered. |
|
30 | + * |
|
31 | + * @return array |
|
32 | + */ |
|
33 | + public function getSchemaProperties(); |
|
34 | 34 | |
35 | - /** |
|
36 | - * If a child class has enum values, they should override this method and provide a simple array |
|
37 | - * of the enum values. |
|
38 | - * The reason this is not a property on the class is because there may be filterable enum values that |
|
39 | - * are set on the instantiated object that could be filtered after construct. |
|
40 | - * |
|
41 | - * @return array |
|
42 | - */ |
|
43 | - public function getSchemaEnum(); |
|
35 | + /** |
|
36 | + * If a child class has enum values, they should override this method and provide a simple array |
|
37 | + * of the enum values. |
|
38 | + * The reason this is not a property on the class is because there may be filterable enum values that |
|
39 | + * are set on the instantiated object that could be filtered after construct. |
|
40 | + * |
|
41 | + * @return array |
|
42 | + */ |
|
43 | + public function getSchemaEnum(); |
|
44 | 44 | |
45 | - /** |
|
46 | - * This returns the value of the $_schema_format property on the object. |
|
47 | - * |
|
48 | - * @return string |
|
49 | - */ |
|
50 | - public function getSchemaFormat(); |
|
45 | + /** |
|
46 | + * This returns the value of the $_schema_format property on the object. |
|
47 | + * |
|
48 | + * @return string |
|
49 | + */ |
|
50 | + public function getSchemaFormat(); |
|
51 | 51 | |
52 | - /** |
|
53 | - * This returns the value of the $_schema_readonly property on the object. |
|
54 | - * |
|
55 | - * @return bool |
|
56 | - */ |
|
57 | - public function getSchemaReadonly(); |
|
52 | + /** |
|
53 | + * This returns the value of the $_schema_readonly property on the object. |
|
54 | + * |
|
55 | + * @return bool |
|
56 | + */ |
|
57 | + public function getSchemaReadonly(); |
|
58 | 58 | |
59 | 59 | |
60 | - /** |
|
61 | - * This returns elements used to represent this field in the json schema. |
|
62 | - * |
|
63 | - * @link http://json-schema.org/ |
|
64 | - * @return array |
|
65 | - */ |
|
66 | - public function getSchema(); |
|
60 | + /** |
|
61 | + * This returns elements used to represent this field in the json schema. |
|
62 | + * |
|
63 | + * @link http://json-schema.org/ |
|
64 | + * @return array |
|
65 | + */ |
|
66 | + public function getSchema(); |
|
67 | 67 | } |
68 | 68 | \ No newline at end of file |
@@ -7,36 +7,36 @@ |
||
7 | 7 | abstract class EE_Text_Field_Base extends EE_Model_Field_Base |
8 | 8 | { |
9 | 9 | |
10 | - function prepare_for_get($value_of_field_on_model_object) |
|
11 | - { |
|
12 | - return is_string($value_of_field_on_model_object) ? stripslashes($value_of_field_on_model_object) : $value_of_field_on_model_object; |
|
13 | - } |
|
10 | + function prepare_for_get($value_of_field_on_model_object) |
|
11 | + { |
|
12 | + return is_string($value_of_field_on_model_object) ? stripslashes($value_of_field_on_model_object) : $value_of_field_on_model_object; |
|
13 | + } |
|
14 | 14 | |
15 | - /** |
|
16 | - * Accepts schema of 'form_input' which formats the string for echoing in form input's value. |
|
17 | - * |
|
18 | - * @param string $value_on_field_to_be_outputted |
|
19 | - * @param string $schema |
|
20 | - * @return string |
|
21 | - */ |
|
22 | - function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null) |
|
23 | - { |
|
24 | - if ($schema == 'form_input') { |
|
25 | - $value_on_field_to_be_outputted = htmlentities($value_on_field_to_be_outputted, ENT_QUOTES, 'UTF-8'); |
|
26 | - } |
|
27 | - return parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema); |
|
28 | - } |
|
15 | + /** |
|
16 | + * Accepts schema of 'form_input' which formats the string for echoing in form input's value. |
|
17 | + * |
|
18 | + * @param string $value_on_field_to_be_outputted |
|
19 | + * @param string $schema |
|
20 | + * @return string |
|
21 | + */ |
|
22 | + function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null) |
|
23 | + { |
|
24 | + if ($schema == 'form_input') { |
|
25 | + $value_on_field_to_be_outputted = htmlentities($value_on_field_to_be_outputted, ENT_QUOTES, 'UTF-8'); |
|
26 | + } |
|
27 | + return parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema); |
|
28 | + } |
|
29 | 29 | |
30 | - /** |
|
31 | - * In form inputs, we should have called htmlentities and addslashes on form inputs, |
|
32 | - * so we need to undo that on setting of these fields |
|
33 | - * |
|
34 | - * @param string $value_inputted_for_field_on_model_object |
|
35 | - * @return string |
|
36 | - */ |
|
37 | - function prepare_for_set($value_inputted_for_field_on_model_object) |
|
38 | - { |
|
39 | - return stripslashes(html_entity_decode(parent::prepare_for_set($value_inputted_for_field_on_model_object), |
|
40 | - ENT_QUOTES, 'UTF-8')); |
|
41 | - } |
|
30 | + /** |
|
31 | + * In form inputs, we should have called htmlentities and addslashes on form inputs, |
|
32 | + * so we need to undo that on setting of these fields |
|
33 | + * |
|
34 | + * @param string $value_inputted_for_field_on_model_object |
|
35 | + * @return string |
|
36 | + */ |
|
37 | + function prepare_for_set($value_inputted_for_field_on_model_object) |
|
38 | + { |
|
39 | + return stripslashes(html_entity_decode(parent::prepare_for_set($value_inputted_for_field_on_model_object), |
|
40 | + ENT_QUOTES, 'UTF-8')); |
|
41 | + } |
|
42 | 42 | } |
43 | 43 | \ No newline at end of file |
@@ -4,22 +4,22 @@ |
||
4 | 4 | class EE_Primary_Key_String_Field extends EE_Primary_Key_Field_Base |
5 | 5 | { |
6 | 6 | |
7 | - public function __construct($table_column, $nicename) |
|
8 | - { |
|
9 | - parent::__construct($table_column, $nicename, null); |
|
10 | - } |
|
7 | + public function __construct($table_column, $nicename) |
|
8 | + { |
|
9 | + parent::__construct($table_column, $nicename, null); |
|
10 | + } |
|
11 | 11 | |
12 | - /** |
|
13 | - * removes all tags when setting |
|
14 | - * |
|
15 | - * @param string $value_inputted_for_field_on_model_object |
|
16 | - * @return string |
|
17 | - */ |
|
18 | - function prepare_for_set($value_inputted_for_field_on_model_object) |
|
19 | - { |
|
20 | - if ($this->is_model_obj_of_type_pointed_to($value_inputted_for_field_on_model_object)) { |
|
21 | - $value_inputted_for_field_on_model_object = $value_inputted_for_field_on_model_object->ID(); |
|
22 | - } |
|
23 | - return wp_strip_all_tags($value_inputted_for_field_on_model_object); |
|
24 | - } |
|
12 | + /** |
|
13 | + * removes all tags when setting |
|
14 | + * |
|
15 | + * @param string $value_inputted_for_field_on_model_object |
|
16 | + * @return string |
|
17 | + */ |
|
18 | + function prepare_for_set($value_inputted_for_field_on_model_object) |
|
19 | + { |
|
20 | + if ($this->is_model_obj_of_type_pointed_to($value_inputted_for_field_on_model_object)) { |
|
21 | + $value_inputted_for_field_on_model_object = $value_inputted_for_field_on_model_object->ID(); |
|
22 | + } |
|
23 | + return wp_strip_all_tags($value_inputted_for_field_on_model_object); |
|
24 | + } |
|
25 | 25 | } |
26 | 26 | \ No newline at end of file |
@@ -4,17 +4,17 @@ |
||
4 | 4 | class EE_Foreign_Key_String_Field extends EE_Foreign_Key_Field_Base |
5 | 5 | { |
6 | 6 | |
7 | - /** |
|
8 | - * removes all tags when setting |
|
9 | - * |
|
10 | - * @param string $value_inputted_for_field_on_model_object |
|
11 | - * @return string |
|
12 | - */ |
|
13 | - function prepare_for_set($value_inputted_for_field_on_model_object) |
|
14 | - { |
|
15 | - if ($this->is_model_obj_of_type_pointed_to($value_inputted_for_field_on_model_object)) { |
|
16 | - $value_inputted_for_field_on_model_object = $value_inputted_for_field_on_model_object->ID(); |
|
17 | - } |
|
18 | - return strtoupper(wp_strip_all_tags($value_inputted_for_field_on_model_object)); |
|
19 | - } |
|
7 | + /** |
|
8 | + * removes all tags when setting |
|
9 | + * |
|
10 | + * @param string $value_inputted_for_field_on_model_object |
|
11 | + * @return string |
|
12 | + */ |
|
13 | + function prepare_for_set($value_inputted_for_field_on_model_object) |
|
14 | + { |
|
15 | + if ($this->is_model_obj_of_type_pointed_to($value_inputted_for_field_on_model_object)) { |
|
16 | + $value_inputted_for_field_on_model_object = $value_inputted_for_field_on_model_object->ID(); |
|
17 | + } |
|
18 | + return strtoupper(wp_strip_all_tags($value_inputted_for_field_on_model_object)); |
|
19 | + } |
|
20 | 20 | } |
21 | 21 | \ No newline at end of file |
@@ -6,14 +6,14 @@ |
||
6 | 6 | */ |
7 | 7 | class EE_All_Caps_Text_Field extends EE_Text_Field_Base |
8 | 8 | { |
9 | - /** |
|
10 | - * makes it all upper case, and key-like |
|
11 | - * |
|
12 | - * @param string $value_inputted_for_field_on_model_object |
|
13 | - * @return string |
|
14 | - */ |
|
15 | - function prepare_for_set($value_inputted_for_field_on_model_object) |
|
16 | - { |
|
17 | - return strtoupper(sanitize_key($value_inputted_for_field_on_model_object)); |
|
18 | - } |
|
9 | + /** |
|
10 | + * makes it all upper case, and key-like |
|
11 | + * |
|
12 | + * @param string $value_inputted_for_field_on_model_object |
|
13 | + * @return string |
|
14 | + */ |
|
15 | + function prepare_for_set($value_inputted_for_field_on_model_object) |
|
16 | + { |
|
17 | + return strtoupper(sanitize_key($value_inputted_for_field_on_model_object)); |
|
18 | + } |
|
19 | 19 | } |
20 | 20 | \ No newline at end of file |
@@ -15,7 +15,7 @@ |
||
15 | 15 | * @param string $table_column |
16 | 16 | * @param string $nicename |
17 | 17 | * @param bool $nullable |
18 | - * @param null $default_value |
|
18 | + * @param string|null $default_value |
|
19 | 19 | */ |
20 | 20 | public function __construct($table_column, $nicename, $nullable, $default_value = null) |
21 | 21 | { |
@@ -11,28 +11,28 @@ |
||
11 | 11 | abstract class EE_DB_Only_Field_Base extends EE_Model_Field_Base |
12 | 12 | { |
13 | 13 | |
14 | - /** |
|
15 | - * @param string $table_column |
|
16 | - * @param string $nicename |
|
17 | - * @param bool $nullable |
|
18 | - * @param null $default_value |
|
19 | - */ |
|
20 | - public function __construct($table_column, $nicename, $nullable, $default_value = null) |
|
21 | - { |
|
22 | - parent::__construct($table_column, $nicename, $nullable, $default_value); |
|
23 | - $this->setSchemaReadOnly(true); |
|
24 | - } |
|
14 | + /** |
|
15 | + * @param string $table_column |
|
16 | + * @param string $nicename |
|
17 | + * @param bool $nullable |
|
18 | + * @param null $default_value |
|
19 | + */ |
|
20 | + public function __construct($table_column, $nicename, $nullable, $default_value = null) |
|
21 | + { |
|
22 | + parent::__construct($table_column, $nicename, $nullable, $default_value); |
|
23 | + $this->setSchemaReadOnly(true); |
|
24 | + } |
|
25 | 25 | |
26 | 26 | |
27 | - /** |
|
28 | - * All these children classes are for the db-only (meaning, we should select them |
|
29 | - * on get_all queries, update, delete, and will still want to set their default value |
|
30 | - * on inserts, but the model object won't have reference to these fields) |
|
31 | - * |
|
32 | - * @return boolean |
|
33 | - */ |
|
34 | - function is_db_only_field() |
|
35 | - { |
|
36 | - return true; |
|
37 | - } |
|
27 | + /** |
|
28 | + * All these children classes are for the db-only (meaning, we should select them |
|
29 | + * on get_all queries, update, delete, and will still want to set their default value |
|
30 | + * on inserts, but the model object won't have reference to these fields) |
|
31 | + * |
|
32 | + * @return boolean |
|
33 | + */ |
|
34 | + function is_db_only_field() |
|
35 | + { |
|
36 | + return true; |
|
37 | + } |
|
38 | 38 | } |
39 | 39 | \ No newline at end of file |
@@ -12,7 +12,7 @@ discard block |
||
12 | 12 | * @param string $table_column |
13 | 13 | * @param string $nicename |
14 | 14 | * @param bool $nullable |
15 | - * @param null $default_value |
|
15 | + * @param integer|null $default_value |
|
16 | 16 | */ |
17 | 17 | public function __construct($table_column, $nicename, $nullable, $default_value = null) |
18 | 18 | { |
@@ -27,7 +27,7 @@ discard block |
||
27 | 27 | * So if you want to pass in a string that NEEDS to interpret periods as decimal marks, call floatval() on it first. |
28 | 28 | * Returns a float |
29 | 29 | * |
30 | - * @param type $value_inputted_for_field_on_model_object |
|
30 | + * @param string $value_inputted_for_field_on_model_object |
|
31 | 31 | * @return float |
32 | 32 | */ |
33 | 33 | function prepare_for_set($value_inputted_for_field_on_model_object) |
@@ -8,64 +8,64 @@ |
||
8 | 8 | class EE_Float_Field extends EE_Model_Field_Base |
9 | 9 | { |
10 | 10 | |
11 | - /** |
|
12 | - * @param string $table_column |
|
13 | - * @param string $nicename |
|
14 | - * @param bool $nullable |
|
15 | - * @param null $default_value |
|
16 | - */ |
|
17 | - public function __construct($table_column, $nicename, $nullable, $default_value = null) |
|
18 | - { |
|
19 | - parent::__construct($table_column, $nicename, $nullable, $default_value); |
|
20 | - $this->setSchemaType('number'); |
|
21 | - } |
|
11 | + /** |
|
12 | + * @param string $table_column |
|
13 | + * @param string $nicename |
|
14 | + * @param bool $nullable |
|
15 | + * @param null $default_value |
|
16 | + */ |
|
17 | + public function __construct($table_column, $nicename, $nullable, $default_value = null) |
|
18 | + { |
|
19 | + parent::__construct($table_column, $nicename, $nullable, $default_value); |
|
20 | + $this->setSchemaType('number'); |
|
21 | + } |
|
22 | 22 | |
23 | 23 | |
24 | - /** |
|
25 | - * If provided a string, strips out number-related formatting, like commas, periods, spaces, other junk, etc. |
|
26 | - * However, treats commas and periods as thousand-separators ro decimal marks, as indicate by the config's currency. |
|
27 | - * So if you want to pass in a string that NEEDS to interpret periods as decimal marks, call floatval() on it first. |
|
28 | - * Returns a float |
|
29 | - * |
|
30 | - * @param type $value_inputted_for_field_on_model_object |
|
31 | - * @return float |
|
32 | - */ |
|
33 | - function prepare_for_set($value_inputted_for_field_on_model_object) |
|
34 | - { |
|
24 | + /** |
|
25 | + * If provided a string, strips out number-related formatting, like commas, periods, spaces, other junk, etc. |
|
26 | + * However, treats commas and periods as thousand-separators ro decimal marks, as indicate by the config's currency. |
|
27 | + * So if you want to pass in a string that NEEDS to interpret periods as decimal marks, call floatval() on it first. |
|
28 | + * Returns a float |
|
29 | + * |
|
30 | + * @param type $value_inputted_for_field_on_model_object |
|
31 | + * @return float |
|
32 | + */ |
|
33 | + function prepare_for_set($value_inputted_for_field_on_model_object) |
|
34 | + { |
|
35 | 35 | // echo __LINE__."$value_inputted_for_field_on_model_object<br>"; |
36 | - //remove whitespaces and thousands separators |
|
37 | - if (is_string($value_inputted_for_field_on_model_object)) { |
|
38 | - $value_inputted_for_field_on_model_object = str_replace(array(" ", EE_Config::instance()->currency->thsnds), |
|
39 | - "", $value_inputted_for_field_on_model_object); |
|
36 | + //remove whitespaces and thousands separators |
|
37 | + if (is_string($value_inputted_for_field_on_model_object)) { |
|
38 | + $value_inputted_for_field_on_model_object = str_replace(array(" ", EE_Config::instance()->currency->thsnds), |
|
39 | + "", $value_inputted_for_field_on_model_object); |
|
40 | 40 | //echo __LINE__."$value_inputted_for_field_on_model_object<br>"; |
41 | 41 | //normalize it so periods are decimal marks (we don't care where you're from: we're talking PHP now) |
42 | - $value_inputted_for_field_on_model_object = str_replace(EE_Config::instance()->currency->dec_mrk, ".", |
|
43 | - $value_inputted_for_field_on_model_object); |
|
42 | + $value_inputted_for_field_on_model_object = str_replace(EE_Config::instance()->currency->dec_mrk, ".", |
|
43 | + $value_inputted_for_field_on_model_object); |
|
44 | 44 | //echo __LINE__."$value_inputted_for_field_on_model_object<br>"; |
45 | 45 | //double-check there's absolutely nothing left on this string besides numbers |
46 | - $value_inputted_for_field_on_model_object = preg_replace("/[^0-9,.]/", "", |
|
47 | - $value_inputted_for_field_on_model_object); |
|
48 | - } |
|
46 | + $value_inputted_for_field_on_model_object = preg_replace("/[^0-9,.]/", "", |
|
47 | + $value_inputted_for_field_on_model_object); |
|
48 | + } |
|
49 | 49 | // echo __LINE__."$value_inputted_for_field_on_model_object<br>"; |
50 | - return floatval($value_inputted_for_field_on_model_object); |
|
51 | - } |
|
50 | + return floatval($value_inputted_for_field_on_model_object); |
|
51 | + } |
|
52 | 52 | |
53 | - /** |
|
54 | - * Returns the number formatted according to local custom (set by the country of the blog). |
|
55 | - * |
|
56 | - * @param float $value_on_field_to_be_outputted |
|
57 | - * @return string |
|
58 | - */ |
|
59 | - function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null) |
|
60 | - { |
|
61 | - $EE = EE_Registry::instance(); |
|
62 | - return number_format($value_on_field_to_be_outputted, $EE->CFG->currency->dec_plc, $EE->CFG->currency->dec_mrk, |
|
63 | - $EE->CFG->currency->thsnds); |
|
64 | - } |
|
53 | + /** |
|
54 | + * Returns the number formatted according to local custom (set by the country of the blog). |
|
55 | + * |
|
56 | + * @param float $value_on_field_to_be_outputted |
|
57 | + * @return string |
|
58 | + */ |
|
59 | + function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null) |
|
60 | + { |
|
61 | + $EE = EE_Registry::instance(); |
|
62 | + return number_format($value_on_field_to_be_outputted, $EE->CFG->currency->dec_plc, $EE->CFG->currency->dec_mrk, |
|
63 | + $EE->CFG->currency->thsnds); |
|
64 | + } |
|
65 | 65 | |
66 | - function prepare_for_set_from_db($value_found_in_db_for_model_object) |
|
67 | - { |
|
66 | + function prepare_for_set_from_db($value_found_in_db_for_model_object) |
|
67 | + { |
|
68 | 68 | // echo "prepare for set from db of ";d($value_found_in_db_for_model_object); |
69 | - return floatval($value_found_in_db_for_model_object); |
|
70 | - } |
|
69 | + return floatval($value_found_in_db_for_model_object); |
|
70 | + } |
|
71 | 71 | } |
72 | 72 | \ No newline at end of file |