Completed
Branch FET-10766-extract-activation-d... (a650cc)
by
unknown
138:26 queued 126:47
created
modules/core_rest_api/EED_Core_Rest_Api.module.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -421,7 +421,7 @@
 block discarded – undo
421 421
     /**
422 422
      * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
423 423
      * in this versioned namespace of EE4
424
-     * @param $version
424
+     * @param string $version
425 425
      * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426 426
      */
427 427
     public static function model_names_with_plural_routes($version){
Please login to merge, or discard this patch.
Indentation   +1221 added lines, -1221 removed lines patch added patch discarded remove patch
@@ -23,1228 +23,1228 @@
 block discarded – undo
23 23
 class EED_Core_Rest_Api extends \EED_Module
24 24
 {
25 25
 
26
-    const ee_api_namespace           = 'ee/v';
26
+	const ee_api_namespace           = 'ee/v';
27 27
 
28
-    const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
29
-
30
-    const saved_routes_option_names  = 'ee_core_routes';
31
-
32
-    /**
33
-     * string used in _links response bodies to make them globally unique.
34
-     *
35
-     * @see http://v2.wp-api.org/extending/linking/
36
-     */
37
-    const ee_api_link_namespace = 'https://api.eventespresso.com/';
38
-
39
-    /**
40
-     * @var CalculatedModelFields
41
-     */
42
-    protected static $_field_calculator;
43
-
44
-
45
-
46
-    /**
47
-     * @return EED_Core_Rest_Api|EED_Module
48
-     */
49
-    public static function instance()
50
-    {
51
-        self::$_field_calculator = new CalculatedModelFields();
52
-        return parent::get_instance(__CLASS__);
53
-    }
54
-
55
-
56
-
57
-    /**
58
-     *    set_hooks - for hooking into EE Core, other modules, etc
59
-     *
60
-     * @access    public
61
-     * @return    void
62
-     */
63
-    public static function set_hooks()
64
-    {
65
-        self::set_hooks_both();
66
-    }
67
-
68
-
69
-
70
-    /**
71
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
72
-     *
73
-     * @access    public
74
-     * @return    void
75
-     */
76
-    public static function set_hooks_admin()
77
-    {
78
-        self::set_hooks_both();
79
-    }
80
-
81
-
82
-
83
-    public static function set_hooks_both()
84
-    {
85
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
86
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
87
-        add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
88
-        add_filter('rest_index',
89
-            array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'));
90
-        EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
91
-    }
92
-
93
-
94
-
95
-    /**
96
-     * sets up hooks which only need to be included as part of REST API requests;
97
-     * other requests like to the frontend or admin etc don't need them
98
-     *
99
-     * @throws \EE_Error
100
-     */
101
-    public static function set_hooks_rest_api()
102
-    {
103
-        //set hooks which account for changes made to the API
104
-        EED_Core_Rest_Api::_set_hooks_for_changes();
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * public wrapper of _set_hooks_for_changes.
111
-     * Loads all the hooks which make requests to old versions of the API
112
-     * appear the same as they always did
113
-     *
114
-     * @throws EE_Error
115
-     */
116
-    public static function set_hooks_for_changes()
117
-    {
118
-        self::_set_hooks_for_changes();
119
-    }
120
-
121
-
122
-
123
-    /**
124
-     * Loads all the hooks which make requests to old versions of the API
125
-     * appear the same as they always did
126
-     *
127
-     * @throws EE_Error
128
-     */
129
-    protected static function _set_hooks_for_changes()
130
-    {
131
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
132
-        foreach ($folder_contents as $classname_in_namespace => $filepath) {
133
-            //ignore the base parent class
134
-            //and legacy named classes
135
-            if ($classname_in_namespace === 'ChangesInBase'
136
-                || strpos($classname_in_namespace, 'Changes_In_') === 0
137
-            ) {
138
-                continue;
139
-            }
140
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
141
-            if (class_exists($full_classname)) {
142
-                $instance_of_class = new $full_classname;
143
-                if ($instance_of_class instanceof ChangesInBase) {
144
-                    $instance_of_class->setHooks();
145
-                }
146
-            }
147
-        }
148
-    }
149
-
150
-
151
-
152
-    /**
153
-     * Filters the WP routes to add our EE-related ones. This takes a bit of time
154
-     * so we actually prefer to only do it when an EE plugin is activated or upgraded
155
-     *
156
-     * @throws \EE_Error
157
-     */
158
-    public static function register_routes()
159
-    {
160
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
161
-            foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
162
-                /**
163
-                 * @var array $data_for_multiple_endpoints numerically indexed array
164
-                 *                                         but can also contain route options like {
165
-                 * @type array    $schema                      {
166
-                 * @type callable $schema_callback
167
-                 * @type array    $callback_args               arguments that will be passed to the callback, after the
168
-                 * WP_REST_Request of course
169
-                 * }
170
-                 * }
171
-                 */
172
-                //when registering routes, register all the endpoints' data at the same time
173
-                $multiple_endpoint_args = array();
174
-                foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
175
-                    /**
176
-                     * @var array     $data_for_single_endpoint {
177
-                     * @type callable $callback
178
-                     * @type string methods
179
-                     * @type array args
180
-                     * @type array _links
181
-                     * @type array    $callback_args            arguments that will be passed to the callback, after the
182
-                     * WP_REST_Request of course
183
-                     * }
184
-                     */
185
-                    //skip route options
186
-                    if (! is_numeric($endpoint_key)) {
187
-                        continue;
188
-                    }
189
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
190
-                        throw new EE_Error(
191
-                            esc_html__(
192
-                                // @codingStandardsIgnoreStart
193
-                                'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
194
-                                // @codingStandardsIgnoreEnd
195
-                                'event_espresso')
196
-                        );
197
-                    }
198
-                    $callback = $data_for_single_endpoint['callback'];
199
-                    $single_endpoint_args = array(
200
-                        'methods' => $data_for_single_endpoint['methods'],
201
-                        'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
202
-                            : array(),
203
-                    );
204
-                    if (isset($data_for_single_endpoint['_links'])) {
205
-                        $single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
206
-                    }
207
-                    if (isset($data_for_single_endpoint['callback_args'])) {
208
-                        $callback_args = $data_for_single_endpoint['callback_args'];
209
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
210
-                            $callback,
211
-                            $callback_args
212
-                        ) {
213
-                            array_unshift($callback_args, $request);
214
-                            return call_user_func_array(
215
-                                $callback,
216
-                                $callback_args
217
-                            );
218
-                        };
219
-                    } else {
220
-                        $single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
221
-                    }
222
-                    $multiple_endpoint_args[] = $single_endpoint_args;
223
-                }
224
-                if (isset($data_for_multiple_endpoints['schema'])) {
225
-                    $schema_route_data = $data_for_multiple_endpoints['schema'];
226
-                    $schema_callback = $schema_route_data['schema_callback'];
227
-                    $callback_args = $schema_route_data['callback_args'];
228
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
229
-                        return call_user_func_array(
230
-                            $schema_callback,
231
-                            $callback_args
232
-                        );
233
-                    };
234
-                }
235
-                register_rest_route(
236
-                    $namespace,
237
-                    $relative_route,
238
-                    $multiple_endpoint_args
239
-                );
240
-            }
241
-        }
242
-    }
243
-
244
-
245
-
246
-    /**
247
-     * Checks if there was a version change or something that merits invalidating the cached
248
-     * route data. If so, invalidates the cached route data so that it gets refreshed
249
-     * next time the WP API is used
250
-     */
251
-    public static function invalidate_cached_route_data_on_version_change()
252
-    {
253
-        if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
254
-            EED_Core_Rest_Api::invalidate_cached_route_data();
255
-        }
256
-        foreach (EE_Registry::instance()->addons as $addon) {
257
-            if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
258
-                EED_Core_Rest_Api::invalidate_cached_route_data();
259
-            }
260
-        }
261
-    }
262
-
263
-
264
-
265
-    /**
266
-     * Removes the cached route data so it will get refreshed next time the WP API is used
267
-     */
268
-    public static function invalidate_cached_route_data()
269
-    {
270
-        //delete the saved EE REST API routes
271
-        foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
272
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
273
-        }
274
-    }
275
-
276
-
277
-
278
-    /**
279
-     * Gets the EE route data
280
-     *
281
-     * @return array top-level key is the namespace, next-level key is the route and its value is array{
282
-     * @throws \EE_Error
283
-     * @type string|array $callback
284
-     * @type string       $methods
285
-     * @type boolean      $hidden_endpoint
286
-     * }
287
-     */
288
-    public static function get_ee_route_data()
289
-    {
290
-        $ee_routes = array();
291
-        foreach (self::versions_served() as $version => $hidden_endpoints) {
292
-            $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
293
-                $version,
294
-                $hidden_endpoints
295
-            );
296
-        }
297
-        return $ee_routes;
298
-    }
299
-
300
-
301
-
302
-    /**
303
-     * Gets the EE route data from the wp options if it exists already,
304
-     * otherwise re-generates it and saves it to the option
305
-     *
306
-     * @param string  $version
307
-     * @param boolean $hidden_endpoints
308
-     * @return array
309
-     * @throws \EE_Error
310
-     */
311
-    protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
312
-    {
313
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
314
-        if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
315
-            $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
316
-        }
317
-        return $ee_routes;
318
-    }
319
-
320
-
321
-
322
-    /**
323
-     * Saves the EE REST API route data to a wp option and returns it
324
-     *
325
-     * @param string  $version
326
-     * @param boolean $hidden_endpoints
327
-     * @return mixed|null
328
-     * @throws \EE_Error
329
-     */
330
-    protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
331
-    {
332
-        $instance = self::instance();
333
-        $routes = apply_filters(
334
-            'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
335
-            array_replace_recursive(
336
-                $instance->_get_config_route_data_for_version($version, $hidden_endpoints),
337
-                $instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
338
-                $instance->_get_model_route_data_for_version($version, $hidden_endpoints),
339
-                $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
340
-            )
341
-        );
342
-        $option_name = self::saved_routes_option_names . $version;
343
-        if (get_option($option_name)) {
344
-            update_option($option_name, $routes, true);
345
-        } else {
346
-            add_option($option_name, $routes, null, 'no');
347
-        }
348
-        return $routes;
349
-    }
350
-
351
-
352
-
353
-    /**
354
-     * Calculates all the EE routes and saves it to a WordPress option so we don't
355
-     * need to calculate it on every request
356
-     *
357
-     * @deprecated since version 4.9.1
358
-     * @return void
359
-     */
360
-    public static function save_ee_routes()
361
-    {
362
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
363
-            $instance = self::instance();
364
-            $routes = apply_filters(
365
-                'EED_Core_Rest_Api__save_ee_routes__routes',
366
-                array_replace_recursive(
367
-                    $instance->_register_config_routes(),
368
-                    $instance->_register_meta_routes(),
369
-                    $instance->_register_model_routes(),
370
-                    $instance->_register_rpc_routes()
371
-                )
372
-            );
373
-            update_option(self::saved_routes_option_names, $routes, true);
374
-        }
375
-    }
376
-
377
-
378
-
379
-    /**
380
-     * Gets all the route information relating to EE models
381
-     *
382
-     * @return array @see get_ee_route_data
383
-     * @deprecated since version 4.9.1
384
-     */
385
-    protected function _register_model_routes()
386
-    {
387
-        $model_routes = array();
388
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
389
-            $model_routes[EED_Core_Rest_Api::ee_api_namespace
390
-                          . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
391
-        }
392
-        return $model_routes;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     * Decides whether or not to add write endpoints for this model.
399
-     *
400
-     * Currently, this defaults to exclude all global tables and models
401
-     * which would allow inserting WP core data (we don't want to duplicate
402
-     * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
403
-     * @param EEM_Base $model
404
-     * @return bool
405
-     */
406
-    public static function should_have_write_endpoints(EEM_Base $model)
407
-    {
408
-        if ($model->is_wp_core_model()){
409
-            return false;
410
-        }
411
-        foreach($model->get_tables() as $table){
412
-            if( $table->is_global()){
413
-                return false;
414
-            }
415
-        }
416
-        return true;
417
-    }
418
-
419
-
420
-
421
-    /**
422
-     * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
423
-     * in this versioned namespace of EE4
424
-     * @param $version
425
-     * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426
-     */
427
-    public static function model_names_with_plural_routes($version){
428
-        $model_version_info = new ModelVersionInfo($version);
429
-        $models_to_register = $model_version_info->modelsForRequestedVersion();
430
-        //let's not bother having endpoints for extra metas
431
-        unset(
432
-            $models_to_register['Extra_Meta'],
433
-            $models_to_register['Extra_Join'],
434
-            $models_to_register['Post_Meta']
435
-        );
436
-        return apply_filters(
437
-            'FHEE__EED_Core_REST_API___register_model_routes',
438
-            $models_to_register
439
-        );
440
-    }
441
-
442
-
443
-
444
-    /**
445
-     * Gets the route data for EE models in the specified version
446
-     *
447
-     * @param string  $version
448
-     * @param boolean $hidden_endpoint
449
-     * @return array
450
-     * @throws EE_Error
451
-     */
452
-    protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
453
-    {
454
-        $model_routes = array();
455
-        $model_version_info = new ModelVersionInfo($version);
456
-        foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
457
-            $model = \EE_Registry::instance()->load_model($model_name);
458
-            //if this isn't a valid model then let's skip iterate to the next item in the loop.
459
-            if (! $model instanceof EEM_Base) {
460
-                continue;
461
-            }
462
-            //yes we could just register one route for ALL models, but then they wouldn't show up in the index
463
-            $plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
464
-            $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
465
-            $model_routes[$plural_model_route] = array(
466
-                array(
467
-                    'callback'        => array(
468
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
469
-                        'handleRequestGetAll',
470
-                    ),
471
-                    'callback_args'   => array($version, $model_name),
472
-                    'methods'         => WP_REST_Server::READABLE,
473
-                    'hidden_endpoint' => $hidden_endpoint,
474
-                    'args'            => $this->_get_read_query_params($model, $version),
475
-                    '_links'          => array(
476
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
477
-                    ),
478
-                ),
479
-                'schema' => array(
480
-                    'schema_callback' => array(
481
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
482
-                        'handleSchemaRequest',
483
-                    ),
484
-                    'callback_args'   => array($version, $model_name),
485
-                ),
486
-            );
487
-            $model_routes[$singular_model_route] = array(
488
-                array(
489
-                    'callback'        => array(
490
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
491
-                        'handleRequestGetOne',
492
-                    ),
493
-                    'callback_args'   => array($version, $model_name),
494
-                    'methods'         => WP_REST_Server::READABLE,
495
-                    'hidden_endpoint' => $hidden_endpoint,
496
-                    'args'            => $this->_get_response_selection_query_params($model, $version),
497
-                ),
498
-            );
499
-            if( apply_filters(
500
-                'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
501
-                EED_Core_Rest_Api::should_have_write_endpoints($model),
502
-                $model
503
-            )){
504
-                $model_routes[$plural_model_route][] = array(
505
-                    'callback'        => array(
506
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Write',
507
-                        'handleRequestInsert',
508
-                    ),
509
-                    'callback_args'   => array($version, $model_name),
510
-                    'methods'         => WP_REST_Server::CREATABLE,
511
-                    'hidden_endpoint' => $hidden_endpoint,
512
-                    'args'            => $this->_get_write_params($model_name, $model_version_info, true),
513
-                );
514
-                $model_routes[$singular_model_route] = array_merge(
515
-                    $model_routes[$singular_model_route],
516
-                    array(
517
-                        array(
518
-                            'callback'        => array(
519
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
520
-                                'handleRequestUpdate',
521
-                            ),
522
-                            'callback_args'   => array($version, $model_name),
523
-                            'methods'         => WP_REST_Server::EDITABLE,
524
-                            'hidden_endpoint' => $hidden_endpoint,
525
-                            'args'            => $this->_get_write_params($model_name, $model_version_info),
526
-                        ),
527
-                        array(
528
-                            'callback'        => array(
529
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
530
-                                'handleRequestDelete',
531
-                            ),
532
-                            'callback_args'   => array($version, $model_name),
533
-                            'methods'         => WP_REST_Server::DELETABLE,
534
-                            'hidden_endpoint' => $hidden_endpoint,
535
-                            'args'            => $this->_get_delete_query_params($model, $version),
536
-                        )
537
-                    )
538
-                );
539
-            }
540
-            foreach ($model->relation_settings() as $relation_name => $relation_obj) {
541
-
542
-                $related_route = EED_Core_Rest_Api::get_relation_route_via(
543
-                    $model,
544
-                    '(?P<id>[^\/]+)',
545
-                    $relation_obj
546
-                );
547
-                $endpoints = array(
548
-                    array(
549
-                        'callback'        => array(
550
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Read',
551
-                            'handleRequestGetRelated',
552
-                        ),
553
-                        'callback_args'   => array($version, $model_name, $relation_name),
554
-                        'methods'         => WP_REST_Server::READABLE,
555
-                        'hidden_endpoint' => $hidden_endpoint,
556
-                        'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
557
-                    ),
558
-                );
559
-                $model_routes[$related_route] = $endpoints;
560
-            }
561
-        }
562
-        return $model_routes;
563
-    }
564
-
565
-
566
-
567
-    /**
568
-     * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
569
-     * excluding the preceding slash.
570
-     * Eg you pass get_plural_route_to('Event') = 'events'
571
-     *
572
-     * @param EEM_Base $model
573
-     * @return string
574
-     */
575
-    public static function get_collection_route(EEM_Base $model)
576
-    {
577
-        return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
578
-    }
579
-
580
-
581
-
582
-    /**
583
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
584
-     * excluding the preceding slash.
585
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
586
-     *
587
-     * @param EEM_Base $model eg Event or Venue
588
-     * @param string $id
589
-     * @return string
590
-     */
591
-    public static function get_entity_route($model, $id)
592
-    {
593
-        return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
594
-    }
595
-
596
-
597
-    /**
598
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
599
-     * excluding the preceding slash.
600
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
601
-     *
602
-     * @param EEM_Base                 $model eg Event or Venue
603
-     * @param string                 $id
604
-     * @param EE_Model_Relation_Base $relation_obj
605
-     * @return string
606
-     */
607
-    public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
608
-    {
609
-        $related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
610
-            $relation_obj->get_other_model()->get_this_model_name(),
611
-            $relation_obj
612
-        );
613
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
614
-    }
615
-
616
-
617
-
618
-    /**
619
-     * Adds onto the $relative_route the EE4 REST API versioned namespace.
620
-     * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
621
-     * @param string $relative_route
622
-     * @param string $version
623
-     * @return string
624
-     */
625
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
626
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
627
-    }
628
-
629
-
630
-
631
-    /**
632
-     * Adds all the RPC-style routes (remote procedure call-like routes, ie
633
-     * routes that don't conform to the traditional REST CRUD-style).
634
-     *
635
-     * @deprecated since 4.9.1
636
-     */
637
-    protected function _register_rpc_routes()
638
-    {
639
-        $routes = array();
640
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
641
-            $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
642
-                $version,
643
-                $hidden_endpoint
644
-            );
645
-        }
646
-        return $routes;
647
-    }
648
-
649
-
650
-
651
-    /**
652
-     * @param string  $version
653
-     * @param boolean $hidden_endpoint
654
-     * @return array
655
-     */
656
-    protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
657
-    {
658
-        $this_versions_routes = array();
659
-        //checkin endpoint
660
-        $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
661
-            array(
662
-                'callback'        => array(
663
-                    'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
664
-                    'handleRequestToggleCheckin',
665
-                ),
666
-                'methods'         => WP_REST_Server::CREATABLE,
667
-                'hidden_endpoint' => $hidden_endpoint,
668
-                'args'            => array(
669
-                    'force' => array(
670
-                        'required'    => false,
671
-                        'default'     => false,
672
-                        'description' => __(
673
-                            // @codingStandardsIgnoreStart
674
-                            'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
675
-                            // @codingStandardsIgnoreEnd
676
-                            'event_espresso'
677
-                        ),
678
-                    ),
679
-                ),
680
-                'callback_args'   => array($version),
681
-            ),
682
-        );
683
-        return apply_filters(
684
-            'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
685
-            $this_versions_routes,
686
-            $version,
687
-            $hidden_endpoint
688
-        );
689
-    }
690
-
691
-
692
-
693
-    /**
694
-     * Gets the query params that can be used when request one or many
695
-     *
696
-     * @param EEM_Base $model
697
-     * @param string   $version
698
-     * @return array
699
-     */
700
-    protected function _get_response_selection_query_params(\EEM_Base $model, $version)
701
-    {
702
-        return apply_filters(
703
-            'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
704
-            array(
705
-                'include'   => array(
706
-                    'required' => false,
707
-                    'default'  => '*',
708
-                    'type'     => 'string',
709
-                ),
710
-                'calculate' => array(
711
-                    'required'          => false,
712
-                    'default'           => '',
713
-                    'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
714
-                    'type'              => 'string',
715
-                    //because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
716
-                    //freaks out. We'll just validate this argument while handling the request
717
-                    'validate_callback' => null,
718
-                    'sanitize_callback' => null,
719
-                ),
720
-            ),
721
-            $model,
722
-            $version
723
-        );
724
-    }
725
-
726
-
727
-
728
-    /**
729
-     * Gets the parameters acceptable for delete requests
730
-     *
731
-     * @param \EEM_Base $model
732
-     * @param string    $version
733
-     * @return array
734
-     */
735
-    protected function _get_delete_query_params(\EEM_Base $model, $version)
736
-    {
737
-        $params_for_delete = array(
738
-            'allow_blocking' => array(
739
-                'required' => false,
740
-                'default'  => true,
741
-                'type'     => 'boolean',
742
-            ),
743
-        );
744
-        $params_for_delete['force'] = array(
745
-            'required' => false,
746
-            'default'  => false,
747
-            'type'     => 'boolean',
748
-        );
749
-        return apply_filters(
750
-            'FHEE__EED_Core_Rest_Api___get_delete_query_params',
751
-            $params_for_delete,
752
-            $model,
753
-            $version
754
-        );
755
-    }
756
-
757
-
758
-
759
-    /**
760
-     * Gets info about reading query params that are acceptable
761
-     *
762
-     * @param \EEM_Base $model eg 'Event' or 'Venue'
763
-     * @param  string   $version
764
-     * @return array    describing the args acceptable when querying this model
765
-     * @throws EE_Error
766
-     */
767
-    protected function _get_read_query_params(\EEM_Base $model, $version)
768
-    {
769
-        $default_orderby = array();
770
-        foreach ($model->get_combined_primary_key_fields() as $key_field) {
771
-            $default_orderby[$key_field->get_name()] = 'ASC';
772
-        }
773
-        return array_merge(
774
-            $this->_get_response_selection_query_params($model, $version),
775
-            array(
776
-                'where'    => array(
777
-                    'required' => false,
778
-                    'default'  => array(),
779
-                    'type'     => 'object',
780
-                ),
781
-                'limit'    => array(
782
-                    'required' => false,
783
-                    'default'  => EED_Core_Rest_Api::get_default_query_limit(),
784
-                    'type'     => array(
785
-                        'object',
786
-                        'string',
787
-                        'integer',
788
-                    ),
789
-                ),
790
-                'order_by' => array(
791
-                    'required' => false,
792
-                    'default'  => $default_orderby,
793
-                    'type'     => array(
794
-                        'object',
795
-                        'string',
796
-                    ),
797
-                ),
798
-                'group_by' => array(
799
-                    'required' => false,
800
-                    'default'  => null,
801
-                    'type'     => array(
802
-                        'object',
803
-                        'string',
804
-                    ),
805
-                ),
806
-                'having'   => array(
807
-                    'required' => false,
808
-                    'default'  => null,
809
-                    'type'     => 'object',
810
-                ),
811
-                'caps'     => array(
812
-                    'required' => false,
813
-                    'default'  => EEM_Base::caps_read,
814
-                    'type'     => 'string',
815
-                ),
816
-            )
817
-        );
818
-    }
819
-
820
-
821
-
822
-    /**
823
-     * Gets parameter information for a model regarding writing data
824
-     *
825
-     * @param string           $model_name
826
-     * @param ModelVersionInfo $model_version_info
827
-     * @param boolean          $create                                       whether this is for request to create (in which case we need
828
-     *                                                                       all required params) or just to update (in which case we don't need those on every request)
829
-     * @return array
830
-     */
831
-    protected function _get_write_params(
832
-        $model_name,
833
-        ModelVersionInfo $model_version_info,
834
-        $create = false
835
-    ) {
836
-        $model = EE_Registry::instance()->load_model($model_name);
837
-        $fields = $model_version_info->fieldsOnModelInThisVersion($model);
838
-        $args_info = array();
839
-        foreach ($fields as $field_name => $field_obj) {
840
-            if ($field_obj->is_auto_increment()) {
841
-                //totally ignore auto increment IDs
842
-                continue;
843
-            }
844
-            $arg_info = $field_obj->getSchema();
845
-            $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
846
-            $arg_info['required'] = $required;
847
-            //remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
848
-            unset($arg_info['readonly']);
849
-            $schema_properties = $field_obj->getSchemaProperties();
850
-            if (
851
-                isset($schema_properties['raw'])
852
-                && $field_obj->getSchemaType() === 'object'
853
-            ) {
854
-                //if there's a "raw" form of this argument, use those properties instead
855
-                $arg_info = array_replace(
856
-                    $arg_info,
857
-                    $schema_properties['raw']
858
-                );
859
-            }
860
-            $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
861
-                $field_obj,
862
-                $field_obj->get_default_value(),
863
-                $model_version_info->requestedVersion()
864
-            );
865
-            //we do our own validation and sanitization within the controller
866
-            $arg_info['sanitize_callback'] =
867
-                array(
868
-                    'EED_Core_Rest_Api',
869
-                    'default_sanitize_callback',
870
-                );
871
-            $args_info[$field_name] = $arg_info;
872
-            if ($field_obj instanceof EE_Datetime_Field) {
873
-                $gmt_arg_info = $arg_info;
874
-                $gmt_arg_info['description'] = sprintf(
875
-                    esc_html__(
876
-                        '%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
877
-                        'event_espresso'
878
-                    ),
879
-                    $field_obj->get_nicename(),
880
-                    $field_name
881
-                );
882
-                $args_info[$field_name . '_gmt'] = $gmt_arg_info;
883
-            }
884
-        }
885
-        return $args_info;
886
-    }
887
-
888
-
889
-
890
-    /**
891
-     * Replacement for WP API's 'rest_parse_request_arg'.
892
-     * If the value is blank but not required, don't bother validating it.
893
-     * Also, it uses our email validation instead of WP API's default.
894
-     *
895
-     * @param                 $value
896
-     * @param WP_REST_Request $request
897
-     * @param                 $param
898
-     * @return bool|true|WP_Error
899
-     * @throws InvalidArgumentException
900
-     * @throws InvalidInterfaceException
901
-     * @throws InvalidDataTypeException
902
-     */
903
-    public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
904
-    {
905
-        $attributes = $request->get_attributes();
906
-        if (! isset($attributes['args'][$param])
907
-            || ! is_array($attributes['args'][$param])) {
908
-            $validation_result = true;
909
-        } else {
910
-            $args = $attributes['args'][$param];
911
-            if ((
912
-                    $value === ''
913
-                    || $value === null
914
-                )
915
-                && (! isset($args['required'])
916
-                    || $args['required'] === false
917
-                )
918
-            ) {
919
-                //not required and not provided? that's cool
920
-                $validation_result = true;
921
-            } elseif (isset($args['format'])
922
-                && $args['format'] === 'email'
923
-            ) {
924
-                $validation_result = true;
925
-                if (! self::_validate_email($value)) {
926
-                    $validation_result = new WP_Error(
927
-                        'rest_invalid_param',
928
-                        esc_html__(
929
-                            'The email address is not valid or does not exist.',
930
-                            'event_espresso'
931
-                        )
932
-                    );
933
-                }
934
-            } else {
935
-                $validation_result = rest_validate_value_from_schema($value, $args, $param);
936
-            }
937
-        }
938
-        if (is_wp_error($validation_result)) {
939
-            return $validation_result;
940
-        }
941
-        return rest_sanitize_request_arg($value, $request, $param);
942
-    }
943
-
944
-
945
-
946
-    /**
947
-     * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
948
-     *
949
-     * @param $email
950
-     * @return bool
951
-     * @throws InvalidArgumentException
952
-     * @throws InvalidInterfaceException
953
-     * @throws InvalidDataTypeException
954
-     */
955
-    protected static function _validate_email($email){
956
-        try {
957
-            EmailAddressFactory::create($email);
958
-            return true;
959
-        } catch (EmailValidationException $e) {
960
-            return false;
961
-        }
962
-    }
963
-
964
-
965
-
966
-    /**
967
-     * Gets routes for the config
968
-     *
969
-     * @return array @see _register_model_routes
970
-     * @deprecated since version 4.9.1
971
-     */
972
-    protected function _register_config_routes()
973
-    {
974
-        $config_routes = array();
975
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
976
-            $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
977
-                $version,
978
-                $hidden_endpoint
979
-            );
980
-        }
981
-        return $config_routes;
982
-    }
983
-
984
-
985
-
986
-    /**
987
-     * Gets routes for the config for the specified version
988
-     *
989
-     * @param string  $version
990
-     * @param boolean $hidden_endpoint
991
-     * @return array
992
-     */
993
-    protected function _get_config_route_data_for_version($version, $hidden_endpoint)
994
-    {
995
-        return array(
996
-            'config'    => array(
997
-                array(
998
-                    'callback'        => array(
999
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1000
-                        'handleRequest',
1001
-                    ),
1002
-                    'methods'         => WP_REST_Server::READABLE,
1003
-                    'hidden_endpoint' => $hidden_endpoint,
1004
-                    'callback_args'   => array($version),
1005
-                ),
1006
-            ),
1007
-            'site_info' => array(
1008
-                array(
1009
-                    'callback'        => array(
1010
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1011
-                        'handleRequestSiteInfo',
1012
-                    ),
1013
-                    'methods'         => WP_REST_Server::READABLE,
1014
-                    'hidden_endpoint' => $hidden_endpoint,
1015
-                    'callback_args'   => array($version),
1016
-                ),
1017
-            ),
1018
-        );
1019
-    }
1020
-
1021
-
1022
-
1023
-    /**
1024
-     * Gets the meta info routes
1025
-     *
1026
-     * @return array @see _register_model_routes
1027
-     * @deprecated since version 4.9.1
1028
-     */
1029
-    protected function _register_meta_routes()
1030
-    {
1031
-        $meta_routes = array();
1032
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1033
-            $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1034
-                $version,
1035
-                $hidden_endpoint
1036
-            );
1037
-        }
1038
-        return $meta_routes;
1039
-    }
1040
-
1041
-
1042
-
1043
-    /**
1044
-     * @param string  $version
1045
-     * @param boolean $hidden_endpoint
1046
-     * @return array
1047
-     */
1048
-    protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1049
-    {
1050
-        return array(
1051
-            'resources' => array(
1052
-                array(
1053
-                    'callback'        => array(
1054
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1055
-                        'handleRequestModelsMeta',
1056
-                    ),
1057
-                    'methods'         => WP_REST_Server::READABLE,
1058
-                    'hidden_endpoint' => $hidden_endpoint,
1059
-                    'callback_args'   => array($version),
1060
-                ),
1061
-            ),
1062
-        );
1063
-    }
1064
-
1065
-
1066
-
1067
-    /**
1068
-     * Tries to hide old 4.6 endpoints from the
1069
-     *
1070
-     * @param array $route_data
1071
-     * @return array
1072
-     * @throws \EE_Error
1073
-     */
1074
-    public static function hide_old_endpoints($route_data)
1075
-    {
1076
-        //allow API clients to override which endpoints get hidden, in case
1077
-        //they want to discover particular endpoints
1078
-        //also, we don't have access to the request so we have to just grab it from the superglobal
1079
-        $force_show_ee_namespace = ltrim(
1080
-            EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1081
-            '/'
1082
-        );
1083
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1084
-            foreach ($relative_urls as $resource_name => $endpoints) {
1085
-                foreach ($endpoints as $key => $endpoint) {
1086
-                    //skip schema and other route options
1087
-                    if (! is_numeric($key)) {
1088
-                        continue;
1089
-                    }
1090
-                    //by default, hide "hidden_endpoint"s, unless the request indicates
1091
-                    //to $force_show_ee_namespace, in which case only show that one
1092
-                    //namespace's endpoints (and hide all others)
1093
-                    if (
1094
-                        ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1095
-                        || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1096
-                    ) {
1097
-                        $full_route = '/' . ltrim($namespace, '/');
1098
-                        $full_route .= '/' . ltrim($resource_name, '/');
1099
-                        unset($route_data[$full_route]);
1100
-                    }
1101
-                }
1102
-            }
1103
-        }
1104
-        return $route_data;
1105
-    }
1106
-
1107
-
1108
-
1109
-    /**
1110
-     * Returns an array describing which versions of core support serving requests for.
1111
-     * Keys are core versions' major and minor version, and values are the
1112
-     * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1113
-     * data by just removing a few models and fields from the responses. However, 4.15 might remove
1114
-     * the answers table entirely, in which case it would be very difficult for
1115
-     * it to serve 4.6-style responses.
1116
-     * Versions of core that are missing from this array are unknowns.
1117
-     * previous ver
1118
-     *
1119
-     * @return array
1120
-     */
1121
-    public static function version_compatibilities()
1122
-    {
1123
-        return apply_filters(
1124
-            'FHEE__EED_Core_REST_API__version_compatibilities',
1125
-            array(
1126
-                '4.8.29' => '4.8.29',
1127
-                '4.8.33' => '4.8.29',
1128
-                '4.8.34' => '4.8.29',
1129
-                '4.8.36' => '4.8.29',
1130
-            )
1131
-        );
1132
-    }
1133
-
1134
-
1135
-
1136
-    /**
1137
-     * Gets the latest API version served. Eg if there
1138
-     * are two versions served of the API, 4.8.29 and 4.8.32, and
1139
-     * we are on core version 4.8.34, it will return the string "4.8.32"
1140
-     *
1141
-     * @return string
1142
-     */
1143
-    public static function latest_rest_api_version()
1144
-    {
1145
-        $versions_served = \EED_Core_Rest_Api::versions_served();
1146
-        $versions_served_keys = array_keys($versions_served);
1147
-        return end($versions_served_keys);
1148
-    }
1149
-
1150
-
1151
-
1152
-    /**
1153
-     * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1154
-     * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1155
-     * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1156
-     * We also indicate whether or not this version should be put in the index or not
1157
-     *
1158
-     * @return array keys are API version numbers (just major and minor numbers), and values
1159
-     * are whether or not they should be hidden
1160
-     */
1161
-    public static function versions_served()
1162
-    {
1163
-        $versions_served = array();
1164
-        $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1165
-        $lowest_compatible_version = end($possibly_served_versions);
1166
-        reset($possibly_served_versions);
1167
-        $versions_served_historically = array_keys($possibly_served_versions);
1168
-        $latest_version = end($versions_served_historically);
1169
-        reset($versions_served_historically);
1170
-        //for each version of core we have ever served:
1171
-        foreach ($versions_served_historically as $key_versioned_endpoint) {
1172
-            //if it's not above the current core version, and it's compatible with the current version of core
1173
-            if ($key_versioned_endpoint === $latest_version) {
1174
-                //don't hide the latest version in the index
1175
-                $versions_served[$key_versioned_endpoint] = false;
1176
-            } elseif (
1177
-                $key_versioned_endpoint >= $lowest_compatible_version
1178
-                && $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1179
-            ) {
1180
-                //include, but hide, previous versions which are still supported
1181
-                $versions_served[$key_versioned_endpoint] = true;
1182
-            } elseif (apply_filters(
1183
-                'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1184
-                false,
1185
-                $possibly_served_versions
1186
-            )) {
1187
-                //if a version is no longer supported, don't include it in index or list of versions served
1188
-                $versions_served[$key_versioned_endpoint] = true;
1189
-            }
1190
-        }
1191
-        return $versions_served;
1192
-    }
1193
-
1194
-
1195
-
1196
-    /**
1197
-     * Gets the major and minor version of EE core's version string
1198
-     *
1199
-     * @return string
1200
-     */
1201
-    public static function core_version()
1202
-    {
1203
-        return apply_filters(
1204
-            'FHEE__EED_Core_REST_API__core_version',
1205
-            implode(
1206
-                '.',
1207
-                array_slice(
1208
-                    explode(
1209
-                        '.',
1210
-                        espresso_version()
1211
-                    ),
1212
-                0,
1213
-                3
1214
-                )
1215
-            )
1216
-        );
1217
-    }
1218
-
1219
-
1220
-
1221
-    /**
1222
-     * Gets the default limit that should be used when querying for resources
1223
-     *
1224
-     * @return int
1225
-     */
1226
-    public static function get_default_query_limit()
1227
-    {
1228
-        //we actually don't use a const because we want folks to always use
1229
-        //this method, not the const directly
1230
-        return apply_filters(
1231
-            'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1232
-            50
1233
-        );
1234
-    }
1235
-
1236
-
1237
-
1238
-    /**
1239
-     *    run - initial module setup
1240
-     *
1241
-     * @access    public
1242
-     * @param  WP $WP
1243
-     * @return    void
1244
-     */
1245
-    public function run($WP)
1246
-    {
1247
-    }
28
+	const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
29
+
30
+	const saved_routes_option_names  = 'ee_core_routes';
31
+
32
+	/**
33
+	 * string used in _links response bodies to make them globally unique.
34
+	 *
35
+	 * @see http://v2.wp-api.org/extending/linking/
36
+	 */
37
+	const ee_api_link_namespace = 'https://api.eventespresso.com/';
38
+
39
+	/**
40
+	 * @var CalculatedModelFields
41
+	 */
42
+	protected static $_field_calculator;
43
+
44
+
45
+
46
+	/**
47
+	 * @return EED_Core_Rest_Api|EED_Module
48
+	 */
49
+	public static function instance()
50
+	{
51
+		self::$_field_calculator = new CalculatedModelFields();
52
+		return parent::get_instance(__CLASS__);
53
+	}
54
+
55
+
56
+
57
+	/**
58
+	 *    set_hooks - for hooking into EE Core, other modules, etc
59
+	 *
60
+	 * @access    public
61
+	 * @return    void
62
+	 */
63
+	public static function set_hooks()
64
+	{
65
+		self::set_hooks_both();
66
+	}
67
+
68
+
69
+
70
+	/**
71
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
72
+	 *
73
+	 * @access    public
74
+	 * @return    void
75
+	 */
76
+	public static function set_hooks_admin()
77
+	{
78
+		self::set_hooks_both();
79
+	}
80
+
81
+
82
+
83
+	public static function set_hooks_both()
84
+	{
85
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
86
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
87
+		add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
88
+		add_filter('rest_index',
89
+			array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'));
90
+		EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
91
+	}
92
+
93
+
94
+
95
+	/**
96
+	 * sets up hooks which only need to be included as part of REST API requests;
97
+	 * other requests like to the frontend or admin etc don't need them
98
+	 *
99
+	 * @throws \EE_Error
100
+	 */
101
+	public static function set_hooks_rest_api()
102
+	{
103
+		//set hooks which account for changes made to the API
104
+		EED_Core_Rest_Api::_set_hooks_for_changes();
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * public wrapper of _set_hooks_for_changes.
111
+	 * Loads all the hooks which make requests to old versions of the API
112
+	 * appear the same as they always did
113
+	 *
114
+	 * @throws EE_Error
115
+	 */
116
+	public static function set_hooks_for_changes()
117
+	{
118
+		self::_set_hooks_for_changes();
119
+	}
120
+
121
+
122
+
123
+	/**
124
+	 * Loads all the hooks which make requests to old versions of the API
125
+	 * appear the same as they always did
126
+	 *
127
+	 * @throws EE_Error
128
+	 */
129
+	protected static function _set_hooks_for_changes()
130
+	{
131
+		$folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
132
+		foreach ($folder_contents as $classname_in_namespace => $filepath) {
133
+			//ignore the base parent class
134
+			//and legacy named classes
135
+			if ($classname_in_namespace === 'ChangesInBase'
136
+				|| strpos($classname_in_namespace, 'Changes_In_') === 0
137
+			) {
138
+				continue;
139
+			}
140
+			$full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
141
+			if (class_exists($full_classname)) {
142
+				$instance_of_class = new $full_classname;
143
+				if ($instance_of_class instanceof ChangesInBase) {
144
+					$instance_of_class->setHooks();
145
+				}
146
+			}
147
+		}
148
+	}
149
+
150
+
151
+
152
+	/**
153
+	 * Filters the WP routes to add our EE-related ones. This takes a bit of time
154
+	 * so we actually prefer to only do it when an EE plugin is activated or upgraded
155
+	 *
156
+	 * @throws \EE_Error
157
+	 */
158
+	public static function register_routes()
159
+	{
160
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
161
+			foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
162
+				/**
163
+				 * @var array $data_for_multiple_endpoints numerically indexed array
164
+				 *                                         but can also contain route options like {
165
+				 * @type array    $schema                      {
166
+				 * @type callable $schema_callback
167
+				 * @type array    $callback_args               arguments that will be passed to the callback, after the
168
+				 * WP_REST_Request of course
169
+				 * }
170
+				 * }
171
+				 */
172
+				//when registering routes, register all the endpoints' data at the same time
173
+				$multiple_endpoint_args = array();
174
+				foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
175
+					/**
176
+					 * @var array     $data_for_single_endpoint {
177
+					 * @type callable $callback
178
+					 * @type string methods
179
+					 * @type array args
180
+					 * @type array _links
181
+					 * @type array    $callback_args            arguments that will be passed to the callback, after the
182
+					 * WP_REST_Request of course
183
+					 * }
184
+					 */
185
+					//skip route options
186
+					if (! is_numeric($endpoint_key)) {
187
+						continue;
188
+					}
189
+					if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
190
+						throw new EE_Error(
191
+							esc_html__(
192
+								// @codingStandardsIgnoreStart
193
+								'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
194
+								// @codingStandardsIgnoreEnd
195
+								'event_espresso')
196
+						);
197
+					}
198
+					$callback = $data_for_single_endpoint['callback'];
199
+					$single_endpoint_args = array(
200
+						'methods' => $data_for_single_endpoint['methods'],
201
+						'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
202
+							: array(),
203
+					);
204
+					if (isset($data_for_single_endpoint['_links'])) {
205
+						$single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
206
+					}
207
+					if (isset($data_for_single_endpoint['callback_args'])) {
208
+						$callback_args = $data_for_single_endpoint['callback_args'];
209
+						$single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
210
+							$callback,
211
+							$callback_args
212
+						) {
213
+							array_unshift($callback_args, $request);
214
+							return call_user_func_array(
215
+								$callback,
216
+								$callback_args
217
+							);
218
+						};
219
+					} else {
220
+						$single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
221
+					}
222
+					$multiple_endpoint_args[] = $single_endpoint_args;
223
+				}
224
+				if (isset($data_for_multiple_endpoints['schema'])) {
225
+					$schema_route_data = $data_for_multiple_endpoints['schema'];
226
+					$schema_callback = $schema_route_data['schema_callback'];
227
+					$callback_args = $schema_route_data['callback_args'];
228
+					$multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
229
+						return call_user_func_array(
230
+							$schema_callback,
231
+							$callback_args
232
+						);
233
+					};
234
+				}
235
+				register_rest_route(
236
+					$namespace,
237
+					$relative_route,
238
+					$multiple_endpoint_args
239
+				);
240
+			}
241
+		}
242
+	}
243
+
244
+
245
+
246
+	/**
247
+	 * Checks if there was a version change or something that merits invalidating the cached
248
+	 * route data. If so, invalidates the cached route data so that it gets refreshed
249
+	 * next time the WP API is used
250
+	 */
251
+	public static function invalidate_cached_route_data_on_version_change()
252
+	{
253
+		if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
254
+			EED_Core_Rest_Api::invalidate_cached_route_data();
255
+		}
256
+		foreach (EE_Registry::instance()->addons as $addon) {
257
+			if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
258
+				EED_Core_Rest_Api::invalidate_cached_route_data();
259
+			}
260
+		}
261
+	}
262
+
263
+
264
+
265
+	/**
266
+	 * Removes the cached route data so it will get refreshed next time the WP API is used
267
+	 */
268
+	public static function invalidate_cached_route_data()
269
+	{
270
+		//delete the saved EE REST API routes
271
+		foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
272
+			delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
273
+		}
274
+	}
275
+
276
+
277
+
278
+	/**
279
+	 * Gets the EE route data
280
+	 *
281
+	 * @return array top-level key is the namespace, next-level key is the route and its value is array{
282
+	 * @throws \EE_Error
283
+	 * @type string|array $callback
284
+	 * @type string       $methods
285
+	 * @type boolean      $hidden_endpoint
286
+	 * }
287
+	 */
288
+	public static function get_ee_route_data()
289
+	{
290
+		$ee_routes = array();
291
+		foreach (self::versions_served() as $version => $hidden_endpoints) {
292
+			$ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
293
+				$version,
294
+				$hidden_endpoints
295
+			);
296
+		}
297
+		return $ee_routes;
298
+	}
299
+
300
+
301
+
302
+	/**
303
+	 * Gets the EE route data from the wp options if it exists already,
304
+	 * otherwise re-generates it and saves it to the option
305
+	 *
306
+	 * @param string  $version
307
+	 * @param boolean $hidden_endpoints
308
+	 * @return array
309
+	 * @throws \EE_Error
310
+	 */
311
+	protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
312
+	{
313
+		$ee_routes = get_option(self::saved_routes_option_names . $version, null);
314
+		if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
315
+			$ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
316
+		}
317
+		return $ee_routes;
318
+	}
319
+
320
+
321
+
322
+	/**
323
+	 * Saves the EE REST API route data to a wp option and returns it
324
+	 *
325
+	 * @param string  $version
326
+	 * @param boolean $hidden_endpoints
327
+	 * @return mixed|null
328
+	 * @throws \EE_Error
329
+	 */
330
+	protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
331
+	{
332
+		$instance = self::instance();
333
+		$routes = apply_filters(
334
+			'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
335
+			array_replace_recursive(
336
+				$instance->_get_config_route_data_for_version($version, $hidden_endpoints),
337
+				$instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
338
+				$instance->_get_model_route_data_for_version($version, $hidden_endpoints),
339
+				$instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
340
+			)
341
+		);
342
+		$option_name = self::saved_routes_option_names . $version;
343
+		if (get_option($option_name)) {
344
+			update_option($option_name, $routes, true);
345
+		} else {
346
+			add_option($option_name, $routes, null, 'no');
347
+		}
348
+		return $routes;
349
+	}
350
+
351
+
352
+
353
+	/**
354
+	 * Calculates all the EE routes and saves it to a WordPress option so we don't
355
+	 * need to calculate it on every request
356
+	 *
357
+	 * @deprecated since version 4.9.1
358
+	 * @return void
359
+	 */
360
+	public static function save_ee_routes()
361
+	{
362
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
363
+			$instance = self::instance();
364
+			$routes = apply_filters(
365
+				'EED_Core_Rest_Api__save_ee_routes__routes',
366
+				array_replace_recursive(
367
+					$instance->_register_config_routes(),
368
+					$instance->_register_meta_routes(),
369
+					$instance->_register_model_routes(),
370
+					$instance->_register_rpc_routes()
371
+				)
372
+			);
373
+			update_option(self::saved_routes_option_names, $routes, true);
374
+		}
375
+	}
376
+
377
+
378
+
379
+	/**
380
+	 * Gets all the route information relating to EE models
381
+	 *
382
+	 * @return array @see get_ee_route_data
383
+	 * @deprecated since version 4.9.1
384
+	 */
385
+	protected function _register_model_routes()
386
+	{
387
+		$model_routes = array();
388
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
389
+			$model_routes[EED_Core_Rest_Api::ee_api_namespace
390
+						  . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
391
+		}
392
+		return $model_routes;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 * Decides whether or not to add write endpoints for this model.
399
+	 *
400
+	 * Currently, this defaults to exclude all global tables and models
401
+	 * which would allow inserting WP core data (we don't want to duplicate
402
+	 * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
403
+	 * @param EEM_Base $model
404
+	 * @return bool
405
+	 */
406
+	public static function should_have_write_endpoints(EEM_Base $model)
407
+	{
408
+		if ($model->is_wp_core_model()){
409
+			return false;
410
+		}
411
+		foreach($model->get_tables() as $table){
412
+			if( $table->is_global()){
413
+				return false;
414
+			}
415
+		}
416
+		return true;
417
+	}
418
+
419
+
420
+
421
+	/**
422
+	 * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
423
+	 * in this versioned namespace of EE4
424
+	 * @param $version
425
+	 * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426
+	 */
427
+	public static function model_names_with_plural_routes($version){
428
+		$model_version_info = new ModelVersionInfo($version);
429
+		$models_to_register = $model_version_info->modelsForRequestedVersion();
430
+		//let's not bother having endpoints for extra metas
431
+		unset(
432
+			$models_to_register['Extra_Meta'],
433
+			$models_to_register['Extra_Join'],
434
+			$models_to_register['Post_Meta']
435
+		);
436
+		return apply_filters(
437
+			'FHEE__EED_Core_REST_API___register_model_routes',
438
+			$models_to_register
439
+		);
440
+	}
441
+
442
+
443
+
444
+	/**
445
+	 * Gets the route data for EE models in the specified version
446
+	 *
447
+	 * @param string  $version
448
+	 * @param boolean $hidden_endpoint
449
+	 * @return array
450
+	 * @throws EE_Error
451
+	 */
452
+	protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
453
+	{
454
+		$model_routes = array();
455
+		$model_version_info = new ModelVersionInfo($version);
456
+		foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
457
+			$model = \EE_Registry::instance()->load_model($model_name);
458
+			//if this isn't a valid model then let's skip iterate to the next item in the loop.
459
+			if (! $model instanceof EEM_Base) {
460
+				continue;
461
+			}
462
+			//yes we could just register one route for ALL models, but then they wouldn't show up in the index
463
+			$plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
464
+			$singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
465
+			$model_routes[$plural_model_route] = array(
466
+				array(
467
+					'callback'        => array(
468
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
469
+						'handleRequestGetAll',
470
+					),
471
+					'callback_args'   => array($version, $model_name),
472
+					'methods'         => WP_REST_Server::READABLE,
473
+					'hidden_endpoint' => $hidden_endpoint,
474
+					'args'            => $this->_get_read_query_params($model, $version),
475
+					'_links'          => array(
476
+						'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
477
+					),
478
+				),
479
+				'schema' => array(
480
+					'schema_callback' => array(
481
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
482
+						'handleSchemaRequest',
483
+					),
484
+					'callback_args'   => array($version, $model_name),
485
+				),
486
+			);
487
+			$model_routes[$singular_model_route] = array(
488
+				array(
489
+					'callback'        => array(
490
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
491
+						'handleRequestGetOne',
492
+					),
493
+					'callback_args'   => array($version, $model_name),
494
+					'methods'         => WP_REST_Server::READABLE,
495
+					'hidden_endpoint' => $hidden_endpoint,
496
+					'args'            => $this->_get_response_selection_query_params($model, $version),
497
+				),
498
+			);
499
+			if( apply_filters(
500
+				'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
501
+				EED_Core_Rest_Api::should_have_write_endpoints($model),
502
+				$model
503
+			)){
504
+				$model_routes[$plural_model_route][] = array(
505
+					'callback'        => array(
506
+						'EventEspresso\core\libraries\rest_api\controllers\model\Write',
507
+						'handleRequestInsert',
508
+					),
509
+					'callback_args'   => array($version, $model_name),
510
+					'methods'         => WP_REST_Server::CREATABLE,
511
+					'hidden_endpoint' => $hidden_endpoint,
512
+					'args'            => $this->_get_write_params($model_name, $model_version_info, true),
513
+				);
514
+				$model_routes[$singular_model_route] = array_merge(
515
+					$model_routes[$singular_model_route],
516
+					array(
517
+						array(
518
+							'callback'        => array(
519
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
520
+								'handleRequestUpdate',
521
+							),
522
+							'callback_args'   => array($version, $model_name),
523
+							'methods'         => WP_REST_Server::EDITABLE,
524
+							'hidden_endpoint' => $hidden_endpoint,
525
+							'args'            => $this->_get_write_params($model_name, $model_version_info),
526
+						),
527
+						array(
528
+							'callback'        => array(
529
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
530
+								'handleRequestDelete',
531
+							),
532
+							'callback_args'   => array($version, $model_name),
533
+							'methods'         => WP_REST_Server::DELETABLE,
534
+							'hidden_endpoint' => $hidden_endpoint,
535
+							'args'            => $this->_get_delete_query_params($model, $version),
536
+						)
537
+					)
538
+				);
539
+			}
540
+			foreach ($model->relation_settings() as $relation_name => $relation_obj) {
541
+
542
+				$related_route = EED_Core_Rest_Api::get_relation_route_via(
543
+					$model,
544
+					'(?P<id>[^\/]+)',
545
+					$relation_obj
546
+				);
547
+				$endpoints = array(
548
+					array(
549
+						'callback'        => array(
550
+							'EventEspresso\core\libraries\rest_api\controllers\model\Read',
551
+							'handleRequestGetRelated',
552
+						),
553
+						'callback_args'   => array($version, $model_name, $relation_name),
554
+						'methods'         => WP_REST_Server::READABLE,
555
+						'hidden_endpoint' => $hidden_endpoint,
556
+						'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
557
+					),
558
+				);
559
+				$model_routes[$related_route] = $endpoints;
560
+			}
561
+		}
562
+		return $model_routes;
563
+	}
564
+
565
+
566
+
567
+	/**
568
+	 * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
569
+	 * excluding the preceding slash.
570
+	 * Eg you pass get_plural_route_to('Event') = 'events'
571
+	 *
572
+	 * @param EEM_Base $model
573
+	 * @return string
574
+	 */
575
+	public static function get_collection_route(EEM_Base $model)
576
+	{
577
+		return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
578
+	}
579
+
580
+
581
+
582
+	/**
583
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
584
+	 * excluding the preceding slash.
585
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
586
+	 *
587
+	 * @param EEM_Base $model eg Event or Venue
588
+	 * @param string $id
589
+	 * @return string
590
+	 */
591
+	public static function get_entity_route($model, $id)
592
+	{
593
+		return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
594
+	}
595
+
596
+
597
+	/**
598
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
599
+	 * excluding the preceding slash.
600
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
601
+	 *
602
+	 * @param EEM_Base                 $model eg Event or Venue
603
+	 * @param string                 $id
604
+	 * @param EE_Model_Relation_Base $relation_obj
605
+	 * @return string
606
+	 */
607
+	public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
608
+	{
609
+		$related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
610
+			$relation_obj->get_other_model()->get_this_model_name(),
611
+			$relation_obj
612
+		);
613
+		return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
614
+	}
615
+
616
+
617
+
618
+	/**
619
+	 * Adds onto the $relative_route the EE4 REST API versioned namespace.
620
+	 * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
621
+	 * @param string $relative_route
622
+	 * @param string $version
623
+	 * @return string
624
+	 */
625
+	public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
626
+		return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
627
+	}
628
+
629
+
630
+
631
+	/**
632
+	 * Adds all the RPC-style routes (remote procedure call-like routes, ie
633
+	 * routes that don't conform to the traditional REST CRUD-style).
634
+	 *
635
+	 * @deprecated since 4.9.1
636
+	 */
637
+	protected function _register_rpc_routes()
638
+	{
639
+		$routes = array();
640
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
641
+			$routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
642
+				$version,
643
+				$hidden_endpoint
644
+			);
645
+		}
646
+		return $routes;
647
+	}
648
+
649
+
650
+
651
+	/**
652
+	 * @param string  $version
653
+	 * @param boolean $hidden_endpoint
654
+	 * @return array
655
+	 */
656
+	protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
657
+	{
658
+		$this_versions_routes = array();
659
+		//checkin endpoint
660
+		$this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
661
+			array(
662
+				'callback'        => array(
663
+					'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
664
+					'handleRequestToggleCheckin',
665
+				),
666
+				'methods'         => WP_REST_Server::CREATABLE,
667
+				'hidden_endpoint' => $hidden_endpoint,
668
+				'args'            => array(
669
+					'force' => array(
670
+						'required'    => false,
671
+						'default'     => false,
672
+						'description' => __(
673
+							// @codingStandardsIgnoreStart
674
+							'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
675
+							// @codingStandardsIgnoreEnd
676
+							'event_espresso'
677
+						),
678
+					),
679
+				),
680
+				'callback_args'   => array($version),
681
+			),
682
+		);
683
+		return apply_filters(
684
+			'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
685
+			$this_versions_routes,
686
+			$version,
687
+			$hidden_endpoint
688
+		);
689
+	}
690
+
691
+
692
+
693
+	/**
694
+	 * Gets the query params that can be used when request one or many
695
+	 *
696
+	 * @param EEM_Base $model
697
+	 * @param string   $version
698
+	 * @return array
699
+	 */
700
+	protected function _get_response_selection_query_params(\EEM_Base $model, $version)
701
+	{
702
+		return apply_filters(
703
+			'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
704
+			array(
705
+				'include'   => array(
706
+					'required' => false,
707
+					'default'  => '*',
708
+					'type'     => 'string',
709
+				),
710
+				'calculate' => array(
711
+					'required'          => false,
712
+					'default'           => '',
713
+					'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
714
+					'type'              => 'string',
715
+					//because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
716
+					//freaks out. We'll just validate this argument while handling the request
717
+					'validate_callback' => null,
718
+					'sanitize_callback' => null,
719
+				),
720
+			),
721
+			$model,
722
+			$version
723
+		);
724
+	}
725
+
726
+
727
+
728
+	/**
729
+	 * Gets the parameters acceptable for delete requests
730
+	 *
731
+	 * @param \EEM_Base $model
732
+	 * @param string    $version
733
+	 * @return array
734
+	 */
735
+	protected function _get_delete_query_params(\EEM_Base $model, $version)
736
+	{
737
+		$params_for_delete = array(
738
+			'allow_blocking' => array(
739
+				'required' => false,
740
+				'default'  => true,
741
+				'type'     => 'boolean',
742
+			),
743
+		);
744
+		$params_for_delete['force'] = array(
745
+			'required' => false,
746
+			'default'  => false,
747
+			'type'     => 'boolean',
748
+		);
749
+		return apply_filters(
750
+			'FHEE__EED_Core_Rest_Api___get_delete_query_params',
751
+			$params_for_delete,
752
+			$model,
753
+			$version
754
+		);
755
+	}
756
+
757
+
758
+
759
+	/**
760
+	 * Gets info about reading query params that are acceptable
761
+	 *
762
+	 * @param \EEM_Base $model eg 'Event' or 'Venue'
763
+	 * @param  string   $version
764
+	 * @return array    describing the args acceptable when querying this model
765
+	 * @throws EE_Error
766
+	 */
767
+	protected function _get_read_query_params(\EEM_Base $model, $version)
768
+	{
769
+		$default_orderby = array();
770
+		foreach ($model->get_combined_primary_key_fields() as $key_field) {
771
+			$default_orderby[$key_field->get_name()] = 'ASC';
772
+		}
773
+		return array_merge(
774
+			$this->_get_response_selection_query_params($model, $version),
775
+			array(
776
+				'where'    => array(
777
+					'required' => false,
778
+					'default'  => array(),
779
+					'type'     => 'object',
780
+				),
781
+				'limit'    => array(
782
+					'required' => false,
783
+					'default'  => EED_Core_Rest_Api::get_default_query_limit(),
784
+					'type'     => array(
785
+						'object',
786
+						'string',
787
+						'integer',
788
+					),
789
+				),
790
+				'order_by' => array(
791
+					'required' => false,
792
+					'default'  => $default_orderby,
793
+					'type'     => array(
794
+						'object',
795
+						'string',
796
+					),
797
+				),
798
+				'group_by' => array(
799
+					'required' => false,
800
+					'default'  => null,
801
+					'type'     => array(
802
+						'object',
803
+						'string',
804
+					),
805
+				),
806
+				'having'   => array(
807
+					'required' => false,
808
+					'default'  => null,
809
+					'type'     => 'object',
810
+				),
811
+				'caps'     => array(
812
+					'required' => false,
813
+					'default'  => EEM_Base::caps_read,
814
+					'type'     => 'string',
815
+				),
816
+			)
817
+		);
818
+	}
819
+
820
+
821
+
822
+	/**
823
+	 * Gets parameter information for a model regarding writing data
824
+	 *
825
+	 * @param string           $model_name
826
+	 * @param ModelVersionInfo $model_version_info
827
+	 * @param boolean          $create                                       whether this is for request to create (in which case we need
828
+	 *                                                                       all required params) or just to update (in which case we don't need those on every request)
829
+	 * @return array
830
+	 */
831
+	protected function _get_write_params(
832
+		$model_name,
833
+		ModelVersionInfo $model_version_info,
834
+		$create = false
835
+	) {
836
+		$model = EE_Registry::instance()->load_model($model_name);
837
+		$fields = $model_version_info->fieldsOnModelInThisVersion($model);
838
+		$args_info = array();
839
+		foreach ($fields as $field_name => $field_obj) {
840
+			if ($field_obj->is_auto_increment()) {
841
+				//totally ignore auto increment IDs
842
+				continue;
843
+			}
844
+			$arg_info = $field_obj->getSchema();
845
+			$required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
846
+			$arg_info['required'] = $required;
847
+			//remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
848
+			unset($arg_info['readonly']);
849
+			$schema_properties = $field_obj->getSchemaProperties();
850
+			if (
851
+				isset($schema_properties['raw'])
852
+				&& $field_obj->getSchemaType() === 'object'
853
+			) {
854
+				//if there's a "raw" form of this argument, use those properties instead
855
+				$arg_info = array_replace(
856
+					$arg_info,
857
+					$schema_properties['raw']
858
+				);
859
+			}
860
+			$arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
861
+				$field_obj,
862
+				$field_obj->get_default_value(),
863
+				$model_version_info->requestedVersion()
864
+			);
865
+			//we do our own validation and sanitization within the controller
866
+			$arg_info['sanitize_callback'] =
867
+				array(
868
+					'EED_Core_Rest_Api',
869
+					'default_sanitize_callback',
870
+				);
871
+			$args_info[$field_name] = $arg_info;
872
+			if ($field_obj instanceof EE_Datetime_Field) {
873
+				$gmt_arg_info = $arg_info;
874
+				$gmt_arg_info['description'] = sprintf(
875
+					esc_html__(
876
+						'%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
877
+						'event_espresso'
878
+					),
879
+					$field_obj->get_nicename(),
880
+					$field_name
881
+				);
882
+				$args_info[$field_name . '_gmt'] = $gmt_arg_info;
883
+			}
884
+		}
885
+		return $args_info;
886
+	}
887
+
888
+
889
+
890
+	/**
891
+	 * Replacement for WP API's 'rest_parse_request_arg'.
892
+	 * If the value is blank but not required, don't bother validating it.
893
+	 * Also, it uses our email validation instead of WP API's default.
894
+	 *
895
+	 * @param                 $value
896
+	 * @param WP_REST_Request $request
897
+	 * @param                 $param
898
+	 * @return bool|true|WP_Error
899
+	 * @throws InvalidArgumentException
900
+	 * @throws InvalidInterfaceException
901
+	 * @throws InvalidDataTypeException
902
+	 */
903
+	public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
904
+	{
905
+		$attributes = $request->get_attributes();
906
+		if (! isset($attributes['args'][$param])
907
+			|| ! is_array($attributes['args'][$param])) {
908
+			$validation_result = true;
909
+		} else {
910
+			$args = $attributes['args'][$param];
911
+			if ((
912
+					$value === ''
913
+					|| $value === null
914
+				)
915
+				&& (! isset($args['required'])
916
+					|| $args['required'] === false
917
+				)
918
+			) {
919
+				//not required and not provided? that's cool
920
+				$validation_result = true;
921
+			} elseif (isset($args['format'])
922
+				&& $args['format'] === 'email'
923
+			) {
924
+				$validation_result = true;
925
+				if (! self::_validate_email($value)) {
926
+					$validation_result = new WP_Error(
927
+						'rest_invalid_param',
928
+						esc_html__(
929
+							'The email address is not valid or does not exist.',
930
+							'event_espresso'
931
+						)
932
+					);
933
+				}
934
+			} else {
935
+				$validation_result = rest_validate_value_from_schema($value, $args, $param);
936
+			}
937
+		}
938
+		if (is_wp_error($validation_result)) {
939
+			return $validation_result;
940
+		}
941
+		return rest_sanitize_request_arg($value, $request, $param);
942
+	}
943
+
944
+
945
+
946
+	/**
947
+	 * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
948
+	 *
949
+	 * @param $email
950
+	 * @return bool
951
+	 * @throws InvalidArgumentException
952
+	 * @throws InvalidInterfaceException
953
+	 * @throws InvalidDataTypeException
954
+	 */
955
+	protected static function _validate_email($email){
956
+		try {
957
+			EmailAddressFactory::create($email);
958
+			return true;
959
+		} catch (EmailValidationException $e) {
960
+			return false;
961
+		}
962
+	}
963
+
964
+
965
+
966
+	/**
967
+	 * Gets routes for the config
968
+	 *
969
+	 * @return array @see _register_model_routes
970
+	 * @deprecated since version 4.9.1
971
+	 */
972
+	protected function _register_config_routes()
973
+	{
974
+		$config_routes = array();
975
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
976
+			$config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
977
+				$version,
978
+				$hidden_endpoint
979
+			);
980
+		}
981
+		return $config_routes;
982
+	}
983
+
984
+
985
+
986
+	/**
987
+	 * Gets routes for the config for the specified version
988
+	 *
989
+	 * @param string  $version
990
+	 * @param boolean $hidden_endpoint
991
+	 * @return array
992
+	 */
993
+	protected function _get_config_route_data_for_version($version, $hidden_endpoint)
994
+	{
995
+		return array(
996
+			'config'    => array(
997
+				array(
998
+					'callback'        => array(
999
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1000
+						'handleRequest',
1001
+					),
1002
+					'methods'         => WP_REST_Server::READABLE,
1003
+					'hidden_endpoint' => $hidden_endpoint,
1004
+					'callback_args'   => array($version),
1005
+				),
1006
+			),
1007
+			'site_info' => array(
1008
+				array(
1009
+					'callback'        => array(
1010
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1011
+						'handleRequestSiteInfo',
1012
+					),
1013
+					'methods'         => WP_REST_Server::READABLE,
1014
+					'hidden_endpoint' => $hidden_endpoint,
1015
+					'callback_args'   => array($version),
1016
+				),
1017
+			),
1018
+		);
1019
+	}
1020
+
1021
+
1022
+
1023
+	/**
1024
+	 * Gets the meta info routes
1025
+	 *
1026
+	 * @return array @see _register_model_routes
1027
+	 * @deprecated since version 4.9.1
1028
+	 */
1029
+	protected function _register_meta_routes()
1030
+	{
1031
+		$meta_routes = array();
1032
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1033
+			$meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1034
+				$version,
1035
+				$hidden_endpoint
1036
+			);
1037
+		}
1038
+		return $meta_routes;
1039
+	}
1040
+
1041
+
1042
+
1043
+	/**
1044
+	 * @param string  $version
1045
+	 * @param boolean $hidden_endpoint
1046
+	 * @return array
1047
+	 */
1048
+	protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1049
+	{
1050
+		return array(
1051
+			'resources' => array(
1052
+				array(
1053
+					'callback'        => array(
1054
+						'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1055
+						'handleRequestModelsMeta',
1056
+					),
1057
+					'methods'         => WP_REST_Server::READABLE,
1058
+					'hidden_endpoint' => $hidden_endpoint,
1059
+					'callback_args'   => array($version),
1060
+				),
1061
+			),
1062
+		);
1063
+	}
1064
+
1065
+
1066
+
1067
+	/**
1068
+	 * Tries to hide old 4.6 endpoints from the
1069
+	 *
1070
+	 * @param array $route_data
1071
+	 * @return array
1072
+	 * @throws \EE_Error
1073
+	 */
1074
+	public static function hide_old_endpoints($route_data)
1075
+	{
1076
+		//allow API clients to override which endpoints get hidden, in case
1077
+		//they want to discover particular endpoints
1078
+		//also, we don't have access to the request so we have to just grab it from the superglobal
1079
+		$force_show_ee_namespace = ltrim(
1080
+			EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1081
+			'/'
1082
+		);
1083
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1084
+			foreach ($relative_urls as $resource_name => $endpoints) {
1085
+				foreach ($endpoints as $key => $endpoint) {
1086
+					//skip schema and other route options
1087
+					if (! is_numeric($key)) {
1088
+						continue;
1089
+					}
1090
+					//by default, hide "hidden_endpoint"s, unless the request indicates
1091
+					//to $force_show_ee_namespace, in which case only show that one
1092
+					//namespace's endpoints (and hide all others)
1093
+					if (
1094
+						($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1095
+						|| ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1096
+					) {
1097
+						$full_route = '/' . ltrim($namespace, '/');
1098
+						$full_route .= '/' . ltrim($resource_name, '/');
1099
+						unset($route_data[$full_route]);
1100
+					}
1101
+				}
1102
+			}
1103
+		}
1104
+		return $route_data;
1105
+	}
1106
+
1107
+
1108
+
1109
+	/**
1110
+	 * Returns an array describing which versions of core support serving requests for.
1111
+	 * Keys are core versions' major and minor version, and values are the
1112
+	 * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1113
+	 * data by just removing a few models and fields from the responses. However, 4.15 might remove
1114
+	 * the answers table entirely, in which case it would be very difficult for
1115
+	 * it to serve 4.6-style responses.
1116
+	 * Versions of core that are missing from this array are unknowns.
1117
+	 * previous ver
1118
+	 *
1119
+	 * @return array
1120
+	 */
1121
+	public static function version_compatibilities()
1122
+	{
1123
+		return apply_filters(
1124
+			'FHEE__EED_Core_REST_API__version_compatibilities',
1125
+			array(
1126
+				'4.8.29' => '4.8.29',
1127
+				'4.8.33' => '4.8.29',
1128
+				'4.8.34' => '4.8.29',
1129
+				'4.8.36' => '4.8.29',
1130
+			)
1131
+		);
1132
+	}
1133
+
1134
+
1135
+
1136
+	/**
1137
+	 * Gets the latest API version served. Eg if there
1138
+	 * are two versions served of the API, 4.8.29 and 4.8.32, and
1139
+	 * we are on core version 4.8.34, it will return the string "4.8.32"
1140
+	 *
1141
+	 * @return string
1142
+	 */
1143
+	public static function latest_rest_api_version()
1144
+	{
1145
+		$versions_served = \EED_Core_Rest_Api::versions_served();
1146
+		$versions_served_keys = array_keys($versions_served);
1147
+		return end($versions_served_keys);
1148
+	}
1149
+
1150
+
1151
+
1152
+	/**
1153
+	 * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1154
+	 * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1155
+	 * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1156
+	 * We also indicate whether or not this version should be put in the index or not
1157
+	 *
1158
+	 * @return array keys are API version numbers (just major and minor numbers), and values
1159
+	 * are whether or not they should be hidden
1160
+	 */
1161
+	public static function versions_served()
1162
+	{
1163
+		$versions_served = array();
1164
+		$possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1165
+		$lowest_compatible_version = end($possibly_served_versions);
1166
+		reset($possibly_served_versions);
1167
+		$versions_served_historically = array_keys($possibly_served_versions);
1168
+		$latest_version = end($versions_served_historically);
1169
+		reset($versions_served_historically);
1170
+		//for each version of core we have ever served:
1171
+		foreach ($versions_served_historically as $key_versioned_endpoint) {
1172
+			//if it's not above the current core version, and it's compatible with the current version of core
1173
+			if ($key_versioned_endpoint === $latest_version) {
1174
+				//don't hide the latest version in the index
1175
+				$versions_served[$key_versioned_endpoint] = false;
1176
+			} elseif (
1177
+				$key_versioned_endpoint >= $lowest_compatible_version
1178
+				&& $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1179
+			) {
1180
+				//include, but hide, previous versions which are still supported
1181
+				$versions_served[$key_versioned_endpoint] = true;
1182
+			} elseif (apply_filters(
1183
+				'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1184
+				false,
1185
+				$possibly_served_versions
1186
+			)) {
1187
+				//if a version is no longer supported, don't include it in index or list of versions served
1188
+				$versions_served[$key_versioned_endpoint] = true;
1189
+			}
1190
+		}
1191
+		return $versions_served;
1192
+	}
1193
+
1194
+
1195
+
1196
+	/**
1197
+	 * Gets the major and minor version of EE core's version string
1198
+	 *
1199
+	 * @return string
1200
+	 */
1201
+	public static function core_version()
1202
+	{
1203
+		return apply_filters(
1204
+			'FHEE__EED_Core_REST_API__core_version',
1205
+			implode(
1206
+				'.',
1207
+				array_slice(
1208
+					explode(
1209
+						'.',
1210
+						espresso_version()
1211
+					),
1212
+				0,
1213
+				3
1214
+				)
1215
+			)
1216
+		);
1217
+	}
1218
+
1219
+
1220
+
1221
+	/**
1222
+	 * Gets the default limit that should be used when querying for resources
1223
+	 *
1224
+	 * @return int
1225
+	 */
1226
+	public static function get_default_query_limit()
1227
+	{
1228
+		//we actually don't use a const because we want folks to always use
1229
+		//this method, not the const directly
1230
+		return apply_filters(
1231
+			'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1232
+			50
1233
+		);
1234
+	}
1235
+
1236
+
1237
+
1238
+	/**
1239
+	 *    run - initial module setup
1240
+	 *
1241
+	 * @access    public
1242
+	 * @param  WP $WP
1243
+	 * @return    void
1244
+	 */
1245
+	public function run($WP)
1246
+	{
1247
+	}
1248 1248
 }
1249 1249
 
1250 1250
 // End of file EED_Core_Rest_Api.module.php
Please login to merge, or discard this patch.
Spacing   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
      */
129 129
     protected static function _set_hooks_for_changes()
130 130
     {
131
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
131
+        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES.'rest_api'.DS.'changes'), false);
132 132
         foreach ($folder_contents as $classname_in_namespace => $filepath) {
133 133
             //ignore the base parent class
134 134
             //and legacy named classes
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
             ) {
138 138
                 continue;
139 139
             }
140
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
140
+            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\'.$classname_in_namespace;
141 141
             if (class_exists($full_classname)) {
142 142
                 $instance_of_class = new $full_classname;
143 143
                 if ($instance_of_class instanceof ChangesInBase) {
@@ -183,10 +183,10 @@  discard block
 block discarded – undo
183 183
                      * }
184 184
                      */
185 185
                     //skip route options
186
-                    if (! is_numeric($endpoint_key)) {
186
+                    if ( ! is_numeric($endpoint_key)) {
187 187
                         continue;
188 188
                     }
189
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
189
+                    if ( ! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
190 190
                         throw new EE_Error(
191 191
                             esc_html__(
192 192
                                 // @codingStandardsIgnoreStart
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
                     }
207 207
                     if (isset($data_for_single_endpoint['callback_args'])) {
208 208
                         $callback_args = $data_for_single_endpoint['callback_args'];
209
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
209
+                        $single_endpoint_args['callback'] = function(\WP_REST_Request $request) use (
210 210
                             $callback,
211 211
                             $callback_args
212 212
                         ) {
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
                     $schema_route_data = $data_for_multiple_endpoints['schema'];
226 226
                     $schema_callback = $schema_route_data['schema_callback'];
227 227
                     $callback_args = $schema_route_data['callback_args'];
228
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
228
+                    $multiple_endpoint_args['schema'] = function() use ($schema_callback, $callback_args) {
229 229
                         return call_user_func_array(
230 230
                             $schema_callback,
231 231
                             $callback_args
@@ -269,7 +269,7 @@  discard block
 block discarded – undo
269 269
     {
270 270
         //delete the saved EE REST API routes
271 271
         foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
272
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
272
+            delete_option(EED_Core_Rest_Api::saved_routes_option_names.$version);
273 273
         }
274 274
     }
275 275
 
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
     {
290 290
         $ee_routes = array();
291 291
         foreach (self::versions_served() as $version => $hidden_endpoints) {
292
-            $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
292
+            $ee_routes[self::ee_api_namespace.$version] = self::_get_ee_route_data_for_version(
293 293
                 $version,
294 294
                 $hidden_endpoints
295 295
             );
@@ -310,8 +310,8 @@  discard block
 block discarded – undo
310 310
      */
311 311
     protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
312 312
     {
313
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
314
-        if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
313
+        $ee_routes = get_option(self::saved_routes_option_names.$version, null);
314
+        if ( ! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
315 315
             $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
316 316
         }
317 317
         return $ee_routes;
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
                 $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
340 340
             )
341 341
         );
342
-        $option_name = self::saved_routes_option_names . $version;
342
+        $option_name = self::saved_routes_option_names.$version;
343 343
         if (get_option($option_name)) {
344 344
             update_option($option_name, $routes, true);
345 345
         } else {
@@ -405,11 +405,11 @@  discard block
 block discarded – undo
405 405
      */
406 406
     public static function should_have_write_endpoints(EEM_Base $model)
407 407
     {
408
-        if ($model->is_wp_core_model()){
408
+        if ($model->is_wp_core_model()) {
409 409
             return false;
410 410
         }
411
-        foreach($model->get_tables() as $table){
412
-            if( $table->is_global()){
411
+        foreach ($model->get_tables() as $table) {
412
+            if ($table->is_global()) {
413 413
                 return false;
414 414
             }
415 415
         }
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
      * @param $version
425 425
      * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426 426
      */
427
-    public static function model_names_with_plural_routes($version){
427
+    public static function model_names_with_plural_routes($version) {
428 428
         $model_version_info = new ModelVersionInfo($version);
429 429
         $models_to_register = $model_version_info->modelsForRequestedVersion();
430 430
         //let's not bother having endpoints for extra metas
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
         foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
457 457
             $model = \EE_Registry::instance()->load_model($model_name);
458 458
             //if this isn't a valid model then let's skip iterate to the next item in the loop.
459
-            if (! $model instanceof EEM_Base) {
459
+            if ( ! $model instanceof EEM_Base) {
460 460
                 continue;
461 461
             }
462 462
             //yes we could just register one route for ALL models, but then they wouldn't show up in the index
@@ -473,7 +473,7 @@  discard block
 block discarded – undo
473 473
                     'hidden_endpoint' => $hidden_endpoint,
474 474
                     'args'            => $this->_get_read_query_params($model, $version),
475 475
                     '_links'          => array(
476
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
476
+                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace.$version.$singular_model_route),
477 477
                     ),
478 478
                 ),
479 479
                 'schema' => array(
@@ -496,11 +496,11 @@  discard block
 block discarded – undo
496 496
                     'args'            => $this->_get_response_selection_query_params($model, $version),
497 497
                 ),
498 498
             );
499
-            if( apply_filters(
499
+            if (apply_filters(
500 500
                 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
501 501
                 EED_Core_Rest_Api::should_have_write_endpoints($model),
502 502
                 $model
503
-            )){
503
+            )) {
504 504
                 $model_routes[$plural_model_route][] = array(
505 505
                     'callback'        => array(
506 506
                         'EventEspresso\core\libraries\rest_api\controllers\model\Write',
@@ -590,7 +590,7 @@  discard block
 block discarded – undo
590 590
      */
591 591
     public static function get_entity_route($model, $id)
592 592
     {
593
-        return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
593
+        return EED_Core_Rest_Api::get_collection_route($model).'/'.$id;
594 594
     }
595 595
 
596 596
 
@@ -610,7 +610,7 @@  discard block
 block discarded – undo
610 610
             $relation_obj->get_other_model()->get_this_model_name(),
611 611
             $relation_obj
612 612
         );
613
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
613
+        return EED_Core_Rest_Api::get_entity_route($model, $id).'/'.$related_model_name_endpoint_part;
614 614
     }
615 615
 
616 616
 
@@ -622,8 +622,8 @@  discard block
 block discarded – undo
622 622
      * @param string $version
623 623
      * @return string
624 624
      */
625
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
626
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
625
+    public static function get_versioned_route_to($relative_route, $version = '4.8.36') {
626
+        return '/'.EED_Core_Rest_Api::ee_api_namespace.$version.'/'.$relative_route;
627 627
     }
628 628
 
629 629
 
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
     {
639 639
         $routes = array();
640 640
         foreach (self::versions_served() as $version => $hidden_endpoint) {
641
-            $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
641
+            $routes[self::ee_api_namespace.$version] = $this->_get_rpc_route_data_for_version(
642 642
                 $version,
643 643
                 $hidden_endpoint
644 644
             );
@@ -879,7 +879,7 @@  discard block
 block discarded – undo
879 879
                     $field_obj->get_nicename(),
880 880
                     $field_name
881 881
                 );
882
-                $args_info[$field_name . '_gmt'] = $gmt_arg_info;
882
+                $args_info[$field_name.'_gmt'] = $gmt_arg_info;
883 883
             }
884 884
         }
885 885
         return $args_info;
@@ -900,10 +900,10 @@  discard block
 block discarded – undo
900 900
      * @throws InvalidInterfaceException
901 901
      * @throws InvalidDataTypeException
902 902
      */
903
-    public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
903
+    public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
904 904
     {
905 905
         $attributes = $request->get_attributes();
906
-        if (! isset($attributes['args'][$param])
906
+        if ( ! isset($attributes['args'][$param])
907 907
             || ! is_array($attributes['args'][$param])) {
908 908
             $validation_result = true;
909 909
         } else {
@@ -912,7 +912,7 @@  discard block
 block discarded – undo
912 912
                     $value === ''
913 913
                     || $value === null
914 914
                 )
915
-                && (! isset($args['required'])
915
+                && ( ! isset($args['required'])
916 916
                     || $args['required'] === false
917 917
                 )
918 918
             ) {
@@ -922,7 +922,7 @@  discard block
 block discarded – undo
922 922
                 && $args['format'] === 'email'
923 923
             ) {
924 924
                 $validation_result = true;
925
-                if (! self::_validate_email($value)) {
925
+                if ( ! self::_validate_email($value)) {
926 926
                     $validation_result = new WP_Error(
927 927
                         'rest_invalid_param',
928 928
                         esc_html__(
@@ -952,7 +952,7 @@  discard block
 block discarded – undo
952 952
      * @throws InvalidInterfaceException
953 953
      * @throws InvalidDataTypeException
954 954
      */
955
-    protected static function _validate_email($email){
955
+    protected static function _validate_email($email) {
956 956
         try {
957 957
             EmailAddressFactory::create($email);
958 958
             return true;
@@ -973,7 +973,7 @@  discard block
 block discarded – undo
973 973
     {
974 974
         $config_routes = array();
975 975
         foreach (self::versions_served() as $version => $hidden_endpoint) {
976
-            $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
976
+            $config_routes[self::ee_api_namespace.$version] = $this->_get_config_route_data_for_version(
977 977
                 $version,
978 978
                 $hidden_endpoint
979 979
             );
@@ -1030,7 +1030,7 @@  discard block
 block discarded – undo
1030 1030
     {
1031 1031
         $meta_routes = array();
1032 1032
         foreach (self::versions_served() as $version => $hidden_endpoint) {
1033
-            $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1033
+            $meta_routes[self::ee_api_namespace.$version] = $this->_get_meta_route_data_for_version(
1034 1034
                 $version,
1035 1035
                 $hidden_endpoint
1036 1036
             );
@@ -1084,7 +1084,7 @@  discard block
 block discarded – undo
1084 1084
             foreach ($relative_urls as $resource_name => $endpoints) {
1085 1085
                 foreach ($endpoints as $key => $endpoint) {
1086 1086
                     //skip schema and other route options
1087
-                    if (! is_numeric($key)) {
1087
+                    if ( ! is_numeric($key)) {
1088 1088
                         continue;
1089 1089
                     }
1090 1090
                     //by default, hide "hidden_endpoint"s, unless the request indicates
@@ -1094,8 +1094,8 @@  discard block
 block discarded – undo
1094 1094
                         ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1095 1095
                         || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1096 1096
                     ) {
1097
-                        $full_route = '/' . ltrim($namespace, '/');
1098
-                        $full_route .= '/' . ltrim($resource_name, '/');
1097
+                        $full_route = '/'.ltrim($namespace, '/');
1098
+                        $full_route .= '/'.ltrim($resource_name, '/');
1099 1099
                         unset($route_data[$full_route]);
1100 1100
                     }
1101 1101
                 }
Please login to merge, or discard this patch.
core/db_models/fields/EE_Email_Field.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -16,38 +16,38 @@
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * @param string $table_column
21
-     * @param string $nice_name
22
-     * @param bool   $nullable
23
-     * @param null   $default_value
24
-     * @throws InvalidArgumentException
25
-     */
26
-    public function __construct($table_column, $nice_name, $nullable, $default_value = null)
27
-    {
28
-        parent::__construct($table_column, $nice_name, $nullable, $default_value);
29
-        $this->setSchemaFormat('email');
30
-    }
19
+	/**
20
+	 * @param string $table_column
21
+	 * @param string $nice_name
22
+	 * @param bool   $nullable
23
+	 * @param null   $default_value
24
+	 * @throws InvalidArgumentException
25
+	 */
26
+	public function __construct($table_column, $nice_name, $nullable, $default_value = null)
27
+	{
28
+		parent::__construct($table_column, $nice_name, $nullable, $default_value);
29
+		$this->setSchemaFormat('email');
30
+	}
31 31
 
32 32
 
33 33
 
34
-    /**
35
-     * In form inputs, we should have called htmlentities and addslashes() on form inputs,
36
-     * so we need to undo that on setting of these fields
37
-     *
38
-     * @param string $email_address
39
-     * @return string
40
-     * @throws InvalidArgumentException
41
-     * @throws InvalidInterfaceException
42
-     * @throws InvalidDataTypeException
43
-     */
44
-    public function prepare_for_set($email_address)
45
-    {
46
-        try {
47
-            $email_address = EmailAddressFactory::create($email_address);
48
-            return $email_address->get();
49
-        } catch (EmailValidationException $e) {
50
-            return '';
51
-        }
52
-    }
34
+	/**
35
+	 * In form inputs, we should have called htmlentities and addslashes() on form inputs,
36
+	 * so we need to undo that on setting of these fields
37
+	 *
38
+	 * @param string $email_address
39
+	 * @return string
40
+	 * @throws InvalidArgumentException
41
+	 * @throws InvalidInterfaceException
42
+	 * @throws InvalidDataTypeException
43
+	 */
44
+	public function prepare_for_set($email_address)
45
+	{
46
+		try {
47
+			$email_address = EmailAddressFactory::create($email_address);
48
+			return $email_address->get();
49
+		} catch (EmailValidationException $e) {
50
+			return '';
51
+		}
52
+	}
53 53
 }
Please login to merge, or discard this patch.
core/domain/services/factories/FactoryInterface.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -15,11 +15,11 @@
 block discarded – undo
15 15
 interface FactoryInterface
16 16
 {
17 17
 
18
-    /**
19
-     * @param mixed $arguments
20
-     * @return mixed
21
-     */
22
-    public static function create($arguments);
18
+	/**
19
+	 * @param mixed $arguments
20
+	 * @return mixed
21
+	 */
22
+	public static function create($arguments);
23 23
 
24 24
 
25 25
 }
Please login to merge, or discard this patch.
core/domain/services/validation/email/strategies/InternationalDNS.php 2 patches
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -20,44 +20,44 @@
 block discarded – undo
20 20
 class InternationalDNS extends International
21 21
 {
22 22
 
23
-    /**
24
-     * Validates the email in teh same way as the parent, but also
25
-     * verifies the domain exists.
26
-     * @param string $email_address
27
-     * @return bool
28
-     * @throws EmailValidationException
29
-     */
30
-    public function validate($email_address)
31
-    {
32
-        parent::validate($email_address);
33
-        $domain = $this->getDomainPartOfEmail(
34
-            $email_address,
35
-            $this->getAtIndex($email_address)
36
-        );
37
-        if (! checkdnsrr($domain, 'MX')) {
38
-            // domain not found in MX records
39
-            throw new EmailValidationException(
40
-                __(
41
-                    // @codingStandardsIgnoreStart
42
-                    'Although the email address provided is formatted correctly, a valid "MX record" could not be located for that address and domain. Please enter a valid email address.',
43
-                    // @codingStandardsIgnoreEnd
44
-                    'event_espresso'
45
-                )
46
-            );
47
-        }
48
-        if (! checkdnsrr($domain, 'A')) {
49
-            // domain not found in A records
50
-            throw new EmailValidationException(
51
-                __(
52
-                    // @codingStandardsIgnoreStart
53
-                    'Although the email address provided is formatted correctly, a valid "A record" could not be located for that address and domain. Please enter a valid email address.',
54
-                    // @codingStandardsIgnoreEnd
55
-                    'event_espresso'
56
-                )
57
-            );
58
-        }
59
-        return true;
60
-    }
23
+	/**
24
+	 * Validates the email in teh same way as the parent, but also
25
+	 * verifies the domain exists.
26
+	 * @param string $email_address
27
+	 * @return bool
28
+	 * @throws EmailValidationException
29
+	 */
30
+	public function validate($email_address)
31
+	{
32
+		parent::validate($email_address);
33
+		$domain = $this->getDomainPartOfEmail(
34
+			$email_address,
35
+			$this->getAtIndex($email_address)
36
+		);
37
+		if (! checkdnsrr($domain, 'MX')) {
38
+			// domain not found in MX records
39
+			throw new EmailValidationException(
40
+				__(
41
+					// @codingStandardsIgnoreStart
42
+					'Although the email address provided is formatted correctly, a valid "MX record" could not be located for that address and domain. Please enter a valid email address.',
43
+					// @codingStandardsIgnoreEnd
44
+					'event_espresso'
45
+				)
46
+			);
47
+		}
48
+		if (! checkdnsrr($domain, 'A')) {
49
+			// domain not found in A records
50
+			throw new EmailValidationException(
51
+				__(
52
+					// @codingStandardsIgnoreStart
53
+					'Although the email address provided is formatted correctly, a valid "A record" could not be located for that address and domain. Please enter a valid email address.',
54
+					// @codingStandardsIgnoreEnd
55
+					'event_espresso'
56
+				)
57
+			);
58
+		}
59
+		return true;
60
+	}
61 61
 
62 62
 
63 63
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
             $email_address,
35 35
             $this->getAtIndex($email_address)
36 36
         );
37
-        if (! checkdnsrr($domain, 'MX')) {
37
+        if ( ! checkdnsrr($domain, 'MX')) {
38 38
             // domain not found in MX records
39 39
             throw new EmailValidationException(
40 40
                 __(
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
                 )
46 46
             );
47 47
         }
48
-        if (! checkdnsrr($domain, 'A')) {
48
+        if ( ! checkdnsrr($domain, 'A')) {
49 49
             // domain not found in A records
50 50
             throw new EmailValidationException(
51 51
                 __(
Please login to merge, or discard this patch.
core/domain/services/validation/email/strategies/International.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -20,28 +20,28 @@
 block discarded – undo
20 20
 class International extends Basic
21 21
 {
22 22
 
23
-    /**
24
-     * @param string $email_address
25
-     * @return bool
26
-     * @throws \EventEspresso\core\domain\services\validation\email\EmailValidationException
27
-     */
28
-    public function validate($email_address)
29
-    {
30
-        parent::validate($email_address);
31
-        if (// plz see http://stackoverflow.com/a/24817336 re: the following regex
32
-            ! preg_match(
33
-                // @codingStandardsIgnoreStart
34
-                '/^(?!\.)((?!.*\.{2})[a-zA-Z0-9\x{0080}-\x{00FF}\x{0100}-\x{017F}\x{0180}-\x{024F}\x{0250}-\x{02AF}\x{0300}-\x{036F}\x{0370}-\x{03FF}\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{0530}-\x{058F}\x{0590}-\x{05FF}\x{0600}-\x{06FF}\x{0700}-\x{074F}\x{0750}-\x{077F}\x{0780}-\x{07BF}\x{07C0}-\x{07FF}\x{0900}-\x{097F}\x{0980}-\x{09FF}\x{0A00}-\x{0A7F}\x{0A80}-\x{0AFF}\x{0B00}-\x{0B7F}\x{0B80}-\x{0BFF}\x{0C00}-\x{0C7F}\x{0C80}-\x{0CFF}\x{0D00}-\x{0D7F}\x{0D80}-\x{0DFF}\x{0E00}-\x{0E7F}\x{0E80}-\x{0EFF}\x{0F00}-\x{0FFF}\x{1000}-\x{109F}\x{10A0}-\x{10FF}\x{1100}-\x{11FF}\x{1200}-\x{137F}\x{1380}-\x{139F}\x{13A0}-\x{13FF}\x{1400}-\x{167F}\x{1680}-\x{169F}\x{16A0}-\x{16FF}\x{1700}-\x{171F}\x{1720}-\x{173F}\x{1740}-\x{175F}\x{1760}-\x{177F}\x{1780}-\x{17FF}\x{1800}-\x{18AF}\x{1900}-\x{194F}\x{1950}-\x{197F}\x{1980}-\x{19DF}\x{19E0}-\x{19FF}\x{1A00}-\x{1A1F}\x{1B00}-\x{1B7F}\x{1D00}-\x{1D7F}\x{1D80}-\x{1DBF}\x{1DC0}-\x{1DFF}\x{1E00}-\x{1EFF}\x{1F00}-\x{1FFF}\x{20D0}-\x{20FF}\x{2100}-\x{214F}\x{2C00}-\x{2C5F}\x{2C60}-\x{2C7F}\x{2C80}-\x{2CFF}\x{2D00}-\x{2D2F}\x{2D30}-\x{2D7F}\x{2D80}-\x{2DDF}\x{2F00}-\x{2FDF}\x{2FF0}-\x{2FFF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{3100}-\x{312F}\x{3130}-\x{318F}\x{3190}-\x{319F}\x{31C0}-\x{31EF}\x{31F0}-\x{31FF}\x{3200}-\x{32FF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4DC0}-\x{4DFF}\x{4E00}-\x{9FFF}\x{A000}-\x{A48F}\x{A490}-\x{A4CF}\x{A700}-\x{A71F}\x{A800}-\x{A82F}\x{A840}-\x{A87F}\x{AC00}-\x{D7AF}\x{F900}-\x{FAFF}\.!#$%&\'*+-\/=?^_`{|}~\-\d]+)@(?!\.)([a-zA-Z0-9\x{0080}-\x{00FF}\x{0100}-\x{017F}\x{0180}-\x{024F}\x{0250}-\x{02AF}\x{0300}-\x{036F}\x{0370}-\x{03FF}\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{0530}-\x{058F}\x{0590}-\x{05FF}\x{0600}-\x{06FF}\x{0700}-\x{074F}\x{0750}-\x{077F}\x{0780}-\x{07BF}\x{07C0}-\x{07FF}\x{0900}-\x{097F}\x{0980}-\x{09FF}\x{0A00}-\x{0A7F}\x{0A80}-\x{0AFF}\x{0B00}-\x{0B7F}\x{0B80}-\x{0BFF}\x{0C00}-\x{0C7F}\x{0C80}-\x{0CFF}\x{0D00}-\x{0D7F}\x{0D80}-\x{0DFF}\x{0E00}-\x{0E7F}\x{0E80}-\x{0EFF}\x{0F00}-\x{0FFF}\x{1000}-\x{109F}\x{10A0}-\x{10FF}\x{1100}-\x{11FF}\x{1200}-\x{137F}\x{1380}-\x{139F}\x{13A0}-\x{13FF}\x{1400}-\x{167F}\x{1680}-\x{169F}\x{16A0}-\x{16FF}\x{1700}-\x{171F}\x{1720}-\x{173F}\x{1740}-\x{175F}\x{1760}-\x{177F}\x{1780}-\x{17FF}\x{1800}-\x{18AF}\x{1900}-\x{194F}\x{1950}-\x{197F}\x{1980}-\x{19DF}\x{19E0}-\x{19FF}\x{1A00}-\x{1A1F}\x{1B00}-\x{1B7F}\x{1D00}-\x{1D7F}\x{1D80}-\x{1DBF}\x{1DC0}-\x{1DFF}\x{1E00}-\x{1EFF}\x{1F00}-\x{1FFF}\x{20D0}-\x{20FF}\x{2100}-\x{214F}\x{2C00}-\x{2C5F}\x{2C60}-\x{2C7F}\x{2C80}-\x{2CFF}\x{2D00}-\x{2D2F}\x{2D30}-\x{2D7F}\x{2D80}-\x{2DDF}\x{2F00}-\x{2FDF}\x{2FF0}-\x{2FFF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{3100}-\x{312F}\x{3130}-\x{318F}\x{3190}-\x{319F}\x{31C0}-\x{31EF}\x{31F0}-\x{31FF}\x{3200}-\x{32FF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4DC0}-\x{4DFF}\x{4E00}-\x{9FFF}\x{A000}-\x{A48F}\x{A490}-\x{A4CF}\x{A700}-\x{A71F}\x{A800}-\x{A82F}\x{A840}-\x{A87F}\x{AC00}-\x{D7AF}\x{F900}-\x{FAFF}\-\.\d]+)((\.([a-zA-Z\x{0080}-\x{00FF}\x{0100}-\x{017F}\x{0180}-\x{024F}\x{0250}-\x{02AF}\x{0300}-\x{036F}\x{0370}-\x{03FF}\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{0530}-\x{058F}\x{0590}-\x{05FF}\x{0600}-\x{06FF}\x{0700}-\x{074F}\x{0750}-\x{077F}\x{0780}-\x{07BF}\x{07C0}-\x{07FF}\x{0900}-\x{097F}\x{0980}-\x{09FF}\x{0A00}-\x{0A7F}\x{0A80}-\x{0AFF}\x{0B00}-\x{0B7F}\x{0B80}-\x{0BFF}\x{0C00}-\x{0C7F}\x{0C80}-\x{0CFF}\x{0D00}-\x{0D7F}\x{0D80}-\x{0DFF}\x{0E00}-\x{0E7F}\x{0E80}-\x{0EFF}\x{0F00}-\x{0FFF}\x{1000}-\x{109F}\x{10A0}-\x{10FF}\x{1100}-\x{11FF}\x{1200}-\x{137F}\x{1380}-\x{139F}\x{13A0}-\x{13FF}\x{1400}-\x{167F}\x{1680}-\x{169F}\x{16A0}-\x{16FF}\x{1700}-\x{171F}\x{1720}-\x{173F}\x{1740}-\x{175F}\x{1760}-\x{177F}\x{1780}-\x{17FF}\x{1800}-\x{18AF}\x{1900}-\x{194F}\x{1950}-\x{197F}\x{1980}-\x{19DF}\x{19E0}-\x{19FF}\x{1A00}-\x{1A1F}\x{1B00}-\x{1B7F}\x{1D00}-\x{1D7F}\x{1D80}-\x{1DBF}\x{1DC0}-\x{1DFF}\x{1E00}-\x{1EFF}\x{1F00}-\x{1FFF}\x{20D0}-\x{20FF}\x{2100}-\x{214F}\x{2C00}-\x{2C5F}\x{2C60}-\x{2C7F}\x{2C80}-\x{2CFF}\x{2D00}-\x{2D2F}\x{2D30}-\x{2D7F}\x{2D80}-\x{2DDF}\x{2F00}-\x{2FDF}\x{2FF0}-\x{2FFF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{3100}-\x{312F}\x{3130}-\x{318F}\x{3190}-\x{319F}\x{31C0}-\x{31EF}\x{31F0}-\x{31FF}\x{3200}-\x{32FF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4DC0}-\x{4DFF}\x{4E00}-\x{9FFF}\x{A000}-\x{A48F}\x{A490}-\x{A4CF}\x{A700}-\x{A71F}\x{A800}-\x{A82F}\x{A840}-\x{A87F}\x{AC00}-\x{D7AF}\x{F900}-\x{FAFF}]){2,63})+)$/u',
35
-                // @codingStandardsIgnoreEnd
36
-                $email_address
37
-            )
38
-        ) {
39
-            throw new EmailValidationException(
40
-                esc_html__('Email address is invalid.', 'event_espresso')
41
-            );
42
-        }
43
-        return true;
44
-    }
23
+	/**
24
+	 * @param string $email_address
25
+	 * @return bool
26
+	 * @throws \EventEspresso\core\domain\services\validation\email\EmailValidationException
27
+	 */
28
+	public function validate($email_address)
29
+	{
30
+		parent::validate($email_address);
31
+		if (// plz see http://stackoverflow.com/a/24817336 re: the following regex
32
+			! preg_match(
33
+				// @codingStandardsIgnoreStart
34
+				'/^(?!\.)((?!.*\.{2})[a-zA-Z0-9\x{0080}-\x{00FF}\x{0100}-\x{017F}\x{0180}-\x{024F}\x{0250}-\x{02AF}\x{0300}-\x{036F}\x{0370}-\x{03FF}\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{0530}-\x{058F}\x{0590}-\x{05FF}\x{0600}-\x{06FF}\x{0700}-\x{074F}\x{0750}-\x{077F}\x{0780}-\x{07BF}\x{07C0}-\x{07FF}\x{0900}-\x{097F}\x{0980}-\x{09FF}\x{0A00}-\x{0A7F}\x{0A80}-\x{0AFF}\x{0B00}-\x{0B7F}\x{0B80}-\x{0BFF}\x{0C00}-\x{0C7F}\x{0C80}-\x{0CFF}\x{0D00}-\x{0D7F}\x{0D80}-\x{0DFF}\x{0E00}-\x{0E7F}\x{0E80}-\x{0EFF}\x{0F00}-\x{0FFF}\x{1000}-\x{109F}\x{10A0}-\x{10FF}\x{1100}-\x{11FF}\x{1200}-\x{137F}\x{1380}-\x{139F}\x{13A0}-\x{13FF}\x{1400}-\x{167F}\x{1680}-\x{169F}\x{16A0}-\x{16FF}\x{1700}-\x{171F}\x{1720}-\x{173F}\x{1740}-\x{175F}\x{1760}-\x{177F}\x{1780}-\x{17FF}\x{1800}-\x{18AF}\x{1900}-\x{194F}\x{1950}-\x{197F}\x{1980}-\x{19DF}\x{19E0}-\x{19FF}\x{1A00}-\x{1A1F}\x{1B00}-\x{1B7F}\x{1D00}-\x{1D7F}\x{1D80}-\x{1DBF}\x{1DC0}-\x{1DFF}\x{1E00}-\x{1EFF}\x{1F00}-\x{1FFF}\x{20D0}-\x{20FF}\x{2100}-\x{214F}\x{2C00}-\x{2C5F}\x{2C60}-\x{2C7F}\x{2C80}-\x{2CFF}\x{2D00}-\x{2D2F}\x{2D30}-\x{2D7F}\x{2D80}-\x{2DDF}\x{2F00}-\x{2FDF}\x{2FF0}-\x{2FFF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{3100}-\x{312F}\x{3130}-\x{318F}\x{3190}-\x{319F}\x{31C0}-\x{31EF}\x{31F0}-\x{31FF}\x{3200}-\x{32FF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4DC0}-\x{4DFF}\x{4E00}-\x{9FFF}\x{A000}-\x{A48F}\x{A490}-\x{A4CF}\x{A700}-\x{A71F}\x{A800}-\x{A82F}\x{A840}-\x{A87F}\x{AC00}-\x{D7AF}\x{F900}-\x{FAFF}\.!#$%&\'*+-\/=?^_`{|}~\-\d]+)@(?!\.)([a-zA-Z0-9\x{0080}-\x{00FF}\x{0100}-\x{017F}\x{0180}-\x{024F}\x{0250}-\x{02AF}\x{0300}-\x{036F}\x{0370}-\x{03FF}\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{0530}-\x{058F}\x{0590}-\x{05FF}\x{0600}-\x{06FF}\x{0700}-\x{074F}\x{0750}-\x{077F}\x{0780}-\x{07BF}\x{07C0}-\x{07FF}\x{0900}-\x{097F}\x{0980}-\x{09FF}\x{0A00}-\x{0A7F}\x{0A80}-\x{0AFF}\x{0B00}-\x{0B7F}\x{0B80}-\x{0BFF}\x{0C00}-\x{0C7F}\x{0C80}-\x{0CFF}\x{0D00}-\x{0D7F}\x{0D80}-\x{0DFF}\x{0E00}-\x{0E7F}\x{0E80}-\x{0EFF}\x{0F00}-\x{0FFF}\x{1000}-\x{109F}\x{10A0}-\x{10FF}\x{1100}-\x{11FF}\x{1200}-\x{137F}\x{1380}-\x{139F}\x{13A0}-\x{13FF}\x{1400}-\x{167F}\x{1680}-\x{169F}\x{16A0}-\x{16FF}\x{1700}-\x{171F}\x{1720}-\x{173F}\x{1740}-\x{175F}\x{1760}-\x{177F}\x{1780}-\x{17FF}\x{1800}-\x{18AF}\x{1900}-\x{194F}\x{1950}-\x{197F}\x{1980}-\x{19DF}\x{19E0}-\x{19FF}\x{1A00}-\x{1A1F}\x{1B00}-\x{1B7F}\x{1D00}-\x{1D7F}\x{1D80}-\x{1DBF}\x{1DC0}-\x{1DFF}\x{1E00}-\x{1EFF}\x{1F00}-\x{1FFF}\x{20D0}-\x{20FF}\x{2100}-\x{214F}\x{2C00}-\x{2C5F}\x{2C60}-\x{2C7F}\x{2C80}-\x{2CFF}\x{2D00}-\x{2D2F}\x{2D30}-\x{2D7F}\x{2D80}-\x{2DDF}\x{2F00}-\x{2FDF}\x{2FF0}-\x{2FFF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{3100}-\x{312F}\x{3130}-\x{318F}\x{3190}-\x{319F}\x{31C0}-\x{31EF}\x{31F0}-\x{31FF}\x{3200}-\x{32FF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4DC0}-\x{4DFF}\x{4E00}-\x{9FFF}\x{A000}-\x{A48F}\x{A490}-\x{A4CF}\x{A700}-\x{A71F}\x{A800}-\x{A82F}\x{A840}-\x{A87F}\x{AC00}-\x{D7AF}\x{F900}-\x{FAFF}\-\.\d]+)((\.([a-zA-Z\x{0080}-\x{00FF}\x{0100}-\x{017F}\x{0180}-\x{024F}\x{0250}-\x{02AF}\x{0300}-\x{036F}\x{0370}-\x{03FF}\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{0530}-\x{058F}\x{0590}-\x{05FF}\x{0600}-\x{06FF}\x{0700}-\x{074F}\x{0750}-\x{077F}\x{0780}-\x{07BF}\x{07C0}-\x{07FF}\x{0900}-\x{097F}\x{0980}-\x{09FF}\x{0A00}-\x{0A7F}\x{0A80}-\x{0AFF}\x{0B00}-\x{0B7F}\x{0B80}-\x{0BFF}\x{0C00}-\x{0C7F}\x{0C80}-\x{0CFF}\x{0D00}-\x{0D7F}\x{0D80}-\x{0DFF}\x{0E00}-\x{0E7F}\x{0E80}-\x{0EFF}\x{0F00}-\x{0FFF}\x{1000}-\x{109F}\x{10A0}-\x{10FF}\x{1100}-\x{11FF}\x{1200}-\x{137F}\x{1380}-\x{139F}\x{13A0}-\x{13FF}\x{1400}-\x{167F}\x{1680}-\x{169F}\x{16A0}-\x{16FF}\x{1700}-\x{171F}\x{1720}-\x{173F}\x{1740}-\x{175F}\x{1760}-\x{177F}\x{1780}-\x{17FF}\x{1800}-\x{18AF}\x{1900}-\x{194F}\x{1950}-\x{197F}\x{1980}-\x{19DF}\x{19E0}-\x{19FF}\x{1A00}-\x{1A1F}\x{1B00}-\x{1B7F}\x{1D00}-\x{1D7F}\x{1D80}-\x{1DBF}\x{1DC0}-\x{1DFF}\x{1E00}-\x{1EFF}\x{1F00}-\x{1FFF}\x{20D0}-\x{20FF}\x{2100}-\x{214F}\x{2C00}-\x{2C5F}\x{2C60}-\x{2C7F}\x{2C80}-\x{2CFF}\x{2D00}-\x{2D2F}\x{2D30}-\x{2D7F}\x{2D80}-\x{2DDF}\x{2F00}-\x{2FDF}\x{2FF0}-\x{2FFF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{3100}-\x{312F}\x{3130}-\x{318F}\x{3190}-\x{319F}\x{31C0}-\x{31EF}\x{31F0}-\x{31FF}\x{3200}-\x{32FF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4DC0}-\x{4DFF}\x{4E00}-\x{9FFF}\x{A000}-\x{A48F}\x{A490}-\x{A4CF}\x{A700}-\x{A71F}\x{A800}-\x{A82F}\x{A840}-\x{A87F}\x{AC00}-\x{D7AF}\x{F900}-\x{FAFF}]){2,63})+)$/u',
35
+				// @codingStandardsIgnoreEnd
36
+				$email_address
37
+			)
38
+		) {
39
+			throw new EmailValidationException(
40
+				esc_html__('Email address is invalid.', 'event_espresso')
41
+			);
42
+		}
43
+		return true;
44
+	}
45 45
 }
46 46
 // End of file International.php
47 47
 // Location: core\services\validation/International.php
Please login to merge, or discard this patch.
core/domain/services/validation/email/strategies/Basic.php 2 patches
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -20,117 +20,117 @@
 block discarded – undo
20 20
 class Basic implements EmailValidatorInterface
21 21
 {
22 22
 
23
-    /**
24
-     * @param string $email_address
25
-     * @return bool
26
-     * @throws EmailValidationException
27
-     */
28
-    public function validate($email_address)
29
-    {
30
-        if (! preg_match('/^.+\@\S+$/', $email_address)) {
31
-            // email not in correct {string}@{string} format
32
-            throw new EmailValidationException(
33
-                esc_html__('Email does not have the required @ sign.', 'event_espresso')
34
-            );
35
-        }
36
-        $atIndex = $this->getAtIndex($email_address);
37
-        $local = $this->getLocalPartOfEmail($email_address, $atIndex);
38
-        $localLen = strlen($local);
39
-        if ($localLen < 1) {
40
-            //no local part
41
-            throw new EmailValidationException(
42
-                esc_html__('Email local-part (before the @) is required.', 'event_espresso')
43
-            );
44
-        }
45
-        if ($localLen > 64) {
46
-            // local part length exceeded
47
-            throw new EmailValidationException(
48
-                esc_html__('Email local-part (before the @) is too long.', 'event_espresso')
49
-            );
50
-        }
51
-        if ($local[0] === '.') {
52
-            // local part starts with '.'
53
-            throw new EmailValidationException(
54
-                esc_html__('Email local-part (before the @) must not begin with a period.', 'event_espresso')
55
-            );
56
-        }
57
-        if ($local[$localLen - 1] === '.') {
58
-            // local part starts or ends with '.'
59
-            throw new EmailValidationException(
60
-                esc_html__('Email local-part (before the @) must not end with a period.', 'event_espresso')
61
-            );
62
-        }
63
-        if (preg_match('/\\.\\./', $local)) {
64
-            // local part has two consecutive dots
65
-            throw new EmailValidationException(
66
-                esc_html__(
67
-                    'Email local-part (before the @) must not have two consecutive periods.',
68
-                    'event_espresso'
69
-                )
70
-            );
71
-        }
72
-        $domain = $this->getDomainPartOfEmail($email_address, $atIndex);
73
-        $domainLen = strlen($domain);
74
-        if ($domainLen < 1) {
75
-            throw new EmailValidationException(
76
-                esc_html__('Email domain (after the @) is required.', 'event_espresso')
77
-            );
78
-        }
79
-        if ($domainLen > 255) {
80
-            // domain part length exceeded
81
-            throw new EmailValidationException(
82
-                esc_html__('Email domain (after the @) is too long.', 'event_espresso')
83
-            );
84
-        }
85
-        if (preg_match('/\\.\\./', $domain)) {
86
-            // domain part has two consecutive dots
87
-            throw new EmailValidationException(
88
-                esc_html__('Email domain (after the @) must not have two consecutive periods.', 'event_espresso')
89
-            );
90
-        }
91
-        return true;
92
-    }
93
-
94
-
95
-
96
-    /**
97
-     * returns the location of the @ symbol
98
-     *
99
-     * @param string $email_address
100
-     * @return bool|string
101
-     */
102
-    protected function getAtIndex($email_address)
103
-    {
104
-        return strrpos($email_address, '@');
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * Gets the local part of the email
111
-     *
112
-     * @param string $email_address
113
-     * @param bool|int $atIndex
114
-     * @return bool|string
115
-     */
116
-    protected function getLocalPartOfEmail($email_address, $atIndex)
117
-    {
118
-        return substr($email_address, 0, $atIndex);
119
-    }
120
-
121
-
122
-
123
-    /**
124
-     * Gets the domain part of the email
125
-     *
126
-     * @param string   $email_address
127
-     * @param bool|int $atIndex
128
-     * @return bool|string
129
-     */
130
-    protected function getDomainPartOfEmail($email_address, $atIndex)
131
-    {
132
-        return substr($email_address, $atIndex + 1);
133
-    }
23
+	/**
24
+	 * @param string $email_address
25
+	 * @return bool
26
+	 * @throws EmailValidationException
27
+	 */
28
+	public function validate($email_address)
29
+	{
30
+		if (! preg_match('/^.+\@\S+$/', $email_address)) {
31
+			// email not in correct {string}@{string} format
32
+			throw new EmailValidationException(
33
+				esc_html__('Email does not have the required @ sign.', 'event_espresso')
34
+			);
35
+		}
36
+		$atIndex = $this->getAtIndex($email_address);
37
+		$local = $this->getLocalPartOfEmail($email_address, $atIndex);
38
+		$localLen = strlen($local);
39
+		if ($localLen < 1) {
40
+			//no local part
41
+			throw new EmailValidationException(
42
+				esc_html__('Email local-part (before the @) is required.', 'event_espresso')
43
+			);
44
+		}
45
+		if ($localLen > 64) {
46
+			// local part length exceeded
47
+			throw new EmailValidationException(
48
+				esc_html__('Email local-part (before the @) is too long.', 'event_espresso')
49
+			);
50
+		}
51
+		if ($local[0] === '.') {
52
+			// local part starts with '.'
53
+			throw new EmailValidationException(
54
+				esc_html__('Email local-part (before the @) must not begin with a period.', 'event_espresso')
55
+			);
56
+		}
57
+		if ($local[$localLen - 1] === '.') {
58
+			// local part starts or ends with '.'
59
+			throw new EmailValidationException(
60
+				esc_html__('Email local-part (before the @) must not end with a period.', 'event_espresso')
61
+			);
62
+		}
63
+		if (preg_match('/\\.\\./', $local)) {
64
+			// local part has two consecutive dots
65
+			throw new EmailValidationException(
66
+				esc_html__(
67
+					'Email local-part (before the @) must not have two consecutive periods.',
68
+					'event_espresso'
69
+				)
70
+			);
71
+		}
72
+		$domain = $this->getDomainPartOfEmail($email_address, $atIndex);
73
+		$domainLen = strlen($domain);
74
+		if ($domainLen < 1) {
75
+			throw new EmailValidationException(
76
+				esc_html__('Email domain (after the @) is required.', 'event_espresso')
77
+			);
78
+		}
79
+		if ($domainLen > 255) {
80
+			// domain part length exceeded
81
+			throw new EmailValidationException(
82
+				esc_html__('Email domain (after the @) is too long.', 'event_espresso')
83
+			);
84
+		}
85
+		if (preg_match('/\\.\\./', $domain)) {
86
+			// domain part has two consecutive dots
87
+			throw new EmailValidationException(
88
+				esc_html__('Email domain (after the @) must not have two consecutive periods.', 'event_espresso')
89
+			);
90
+		}
91
+		return true;
92
+	}
93
+
94
+
95
+
96
+	/**
97
+	 * returns the location of the @ symbol
98
+	 *
99
+	 * @param string $email_address
100
+	 * @return bool|string
101
+	 */
102
+	protected function getAtIndex($email_address)
103
+	{
104
+		return strrpos($email_address, '@');
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * Gets the local part of the email
111
+	 *
112
+	 * @param string $email_address
113
+	 * @param bool|int $atIndex
114
+	 * @return bool|string
115
+	 */
116
+	protected function getLocalPartOfEmail($email_address, $atIndex)
117
+	{
118
+		return substr($email_address, 0, $atIndex);
119
+	}
120
+
121
+
122
+
123
+	/**
124
+	 * Gets the domain part of the email
125
+	 *
126
+	 * @param string   $email_address
127
+	 * @param bool|int $atIndex
128
+	 * @return bool|string
129
+	 */
130
+	protected function getDomainPartOfEmail($email_address, $atIndex)
131
+	{
132
+		return substr($email_address, $atIndex + 1);
133
+	}
134 134
 }
135 135
 // End of file Basic.php
136 136
 // Location: core\services\validation/Basic.php
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@
 block discarded – undo
27 27
      */
28 28
     public function validate($email_address)
29 29
     {
30
-        if (! preg_match('/^.+\@\S+$/', $email_address)) {
30
+        if ( ! preg_match('/^.+\@\S+$/', $email_address)) {
31 31
             // email not in correct {string}@{string} format
32 32
             throw new EmailValidationException(
33 33
                 esc_html__('Email does not have the required @ sign.', 'event_espresso')
Please login to merge, or discard this patch.
core/domain/services/validation/email/strategies/WordPress.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -20,22 +20,22 @@
 block discarded – undo
20 20
 class WordPress extends Basic
21 21
 {
22 22
 
23
-    /**
24
-     *
25
-     * @param string $email_address
26
-     * @return boolean
27
-     * @throws EmailValidationException
28
-     */
29
-    public function validate($email_address)
30
-    {
31
-        parent::validate($email_address);
32
-        if( ! is_email($email_address)){
33
-            throw new EmailValidationException(
34
-                esc_html__('The email address provided is not valid.', 'event_espresso')
35
-            );
36
-        }
37
-        return true;
38
-    }
23
+	/**
24
+	 *
25
+	 * @param string $email_address
26
+	 * @return boolean
27
+	 * @throws EmailValidationException
28
+	 */
29
+	public function validate($email_address)
30
+	{
31
+		parent::validate($email_address);
32
+		if( ! is_email($email_address)){
33
+			throw new EmailValidationException(
34
+				esc_html__('The email address provided is not valid.', 'event_espresso')
35
+			);
36
+		}
37
+		return true;
38
+	}
39 39
 
40 40
 
41 41
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@
 block discarded – undo
29 29
     public function validate($email_address)
30 30
     {
31 31
         parent::validate($email_address);
32
-        if( ! is_email($email_address)){
32
+        if ( ! is_email($email_address)) {
33 33
             throw new EmailValidationException(
34 34
                 esc_html__('The email address provided is not valid.', 'event_espresso')
35 35
             );
Please login to merge, or discard this patch.
core/domain/services/validation/email/EmailValidationService.php 2 patches
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -21,69 +21,69 @@
 block discarded – undo
21 21
 class EmailValidationService implements EmailValidatorInterface
22 22
 {
23 23
 
24
-    /**
25
-     * @var EE_Registration_Config $registration_config
26
-     */
27
-    protected $registration_config;
28
-
29
-    /**
30
-     * @var Loader $loader
31
-     */
32
-    protected $loader;
33
-
34
-
35
-
36
-    /**
37
-     * EmailValidationService constructor.
38
-     * Accepts an \EE_Config as an argument.
39
-     *
40
-     * @param EE_Registration_Config $config
41
-     * @param Loader    $loader
42
-     */
43
-    public function __construct(EE_Registration_Config $config, Loader $loader)
44
-    {
45
-        $this->registration_config = $config;
46
-        $this->loader = $loader;
47
-    }
48
-
49
-
50
-
51
-    /**
52
-     * Validates the email address. If it's invalid, an EmailValidationException
53
-     * is thrown that describes why its invalid.
54
-     *
55
-     * @param string $email_address
56
-     * @return boolean
57
-     * @throws EmailValidationException
58
-     */
59
-    public function validate($email_address)
60
-    {
61
-        //pick the correct validator according to the config
62
-        switch ($this->registration_config->email_validation_level) {
63
-            case 'basic':
64
-                $validator = $this->loader->getShared(
65
-                    'EventEspresso\core\domain\services\validation\email\strategies\Basic'
66
-                );
67
-                break;
68
-            case 'i18n':
69
-                $validator = $this->loader->getShared(
70
-                    'EventEspresso\core\domain\services\validation\email\strategies\International'
71
-                ) ;
72
-                break;
73
-            case 'i18n_dns':
74
-                $validator = $this->loader->getShared(
75
-                    'EventEspresso\core\domain\services\validation\email\strategies\InternationalDNS'
76
-                ) ;
77
-                break;
78
-            case 'wp_default':
79
-            default:
80
-                $validator = $this->loader->getShared(
81
-                    'EventEspresso\core\domain\services\validation\email\strategies\WordPress'
82
-                ) ;
83
-                break;
84
-        }
85
-        return $validator->validate($email_address);
86
-    }
24
+	/**
25
+	 * @var EE_Registration_Config $registration_config
26
+	 */
27
+	protected $registration_config;
28
+
29
+	/**
30
+	 * @var Loader $loader
31
+	 */
32
+	protected $loader;
33
+
34
+
35
+
36
+	/**
37
+	 * EmailValidationService constructor.
38
+	 * Accepts an \EE_Config as an argument.
39
+	 *
40
+	 * @param EE_Registration_Config $config
41
+	 * @param Loader    $loader
42
+	 */
43
+	public function __construct(EE_Registration_Config $config, Loader $loader)
44
+	{
45
+		$this->registration_config = $config;
46
+		$this->loader = $loader;
47
+	}
48
+
49
+
50
+
51
+	/**
52
+	 * Validates the email address. If it's invalid, an EmailValidationException
53
+	 * is thrown that describes why its invalid.
54
+	 *
55
+	 * @param string $email_address
56
+	 * @return boolean
57
+	 * @throws EmailValidationException
58
+	 */
59
+	public function validate($email_address)
60
+	{
61
+		//pick the correct validator according to the config
62
+		switch ($this->registration_config->email_validation_level) {
63
+			case 'basic':
64
+				$validator = $this->loader->getShared(
65
+					'EventEspresso\core\domain\services\validation\email\strategies\Basic'
66
+				);
67
+				break;
68
+			case 'i18n':
69
+				$validator = $this->loader->getShared(
70
+					'EventEspresso\core\domain\services\validation\email\strategies\International'
71
+				) ;
72
+				break;
73
+			case 'i18n_dns':
74
+				$validator = $this->loader->getShared(
75
+					'EventEspresso\core\domain\services\validation\email\strategies\InternationalDNS'
76
+				) ;
77
+				break;
78
+			case 'wp_default':
79
+			default:
80
+				$validator = $this->loader->getShared(
81
+					'EventEspresso\core\domain\services\validation\email\strategies\WordPress'
82
+				) ;
83
+				break;
84
+		}
85
+		return $validator->validate($email_address);
86
+	}
87 87
 
88 88
 
89 89
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -68,18 +68,18 @@
 block discarded – undo
68 68
             case 'i18n':
69 69
                 $validator = $this->loader->getShared(
70 70
                     'EventEspresso\core\domain\services\validation\email\strategies\International'
71
-                ) ;
71
+                );
72 72
                 break;
73 73
             case 'i18n_dns':
74 74
                 $validator = $this->loader->getShared(
75 75
                     'EventEspresso\core\domain\services\validation\email\strategies\InternationalDNS'
76
-                ) ;
76
+                );
77 77
                 break;
78 78
             case 'wp_default':
79 79
             default:
80 80
                 $validator = $this->loader->getShared(
81 81
                     'EventEspresso\core\domain\services\validation\email\strategies\WordPress'
82
-                ) ;
82
+                );
83 83
                 break;
84 84
         }
85 85
         return $validator->validate($email_address);
Please login to merge, or discard this patch.
core/domain/services/validation/email/EmailValidatorInterface.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -18,14 +18,14 @@
 block discarded – undo
18 18
 interface EmailValidatorInterface
19 19
 {
20 20
 
21
-    /**
22
-     * Validates the supplied email address. If it is invalid, throws EmailValidationException
23
-     *
24
-     * @param string $email_address
25
-     * @return boolean
26
-     * @throws EmailValidationException
27
-     */
28
-    public function validate($email_address);
21
+	/**
22
+	 * Validates the supplied email address. If it is invalid, throws EmailValidationException
23
+	 *
24
+	 * @param string $email_address
25
+	 * @return boolean
26
+	 * @throws EmailValidationException
27
+	 */
28
+	public function validate($email_address);
29 29
 
30 30
 
31 31
 }
Please login to merge, or discard this patch.