Completed
Branch EDTR/refactor-fast-api-fetch (a894bd)
by
unknown
17:34 queued 09:16
created
core/libraries/rest_api/controllers/model/Read.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -717,7 +717,7 @@  discard block
 block discarded – undo
717 717
      *
718 718
      * @param EEM_Base $model
719 719
      * @param          $results_so_far
720
-     * @param          $protected
720
+     * @param          boolean $protected
721 721
      * @return array results
722 722
      * @throws EE_Error
723 723
      * @since 4.9.74.p
@@ -1545,7 +1545,7 @@  discard block
 block discarded – undo
1545 1545
      *
1546 1546
      * @param EEM_Base        $model
1547 1547
      * @param WP_REST_Request $request
1548
-     * @param null            $context
1548
+     * @param string            $context
1549 1549
      * @return array
1550 1550
      * @throws EE_Error
1551 1551
      * @throws InvalidArgumentException
Please login to merge, or discard this patch.
Indentation   +1590 added lines, -1590 removed lines patch added patch discarded remove patch
@@ -52,1605 +52,1605 @@
 block discarded – undo
52 52
 {
53 53
 
54 54
 
55
-    /**
56
-     * @var CalculatedModelFields
57
-     */
58
-    protected $fields_calculator;
59
-
60
-
61
-    /**
62
-     * Read constructor.
63
-     * @param CalculatedModelFields $fields_calculator
64
-     */
65
-    public function __construct(CalculatedModelFields $fields_calculator)
66
-    {
67
-        parent::__construct();
68
-        $this->fields_calculator = $fields_calculator;
69
-    }
70
-
71
-
72
-    /**
73
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
74
-     *
75
-     * @param WP_REST_Request $request
76
-     * @param string $version
77
-     * @param string $model_name
78
-     * @return WP_REST_Response|WP_Error
79
-     * @throws InvalidArgumentException
80
-     * @throws InvalidDataTypeException
81
-     * @throws InvalidInterfaceException
82
-     */
83
-    public static function handleRequestGetAll(WP_REST_Request $request, $version, $model_name)
84
-    {
85
-        /** @var Read $controller */
86
-        $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
87
-        try {
88
-            $controller->setRequestedVersion($version);
89
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
90
-                return $controller->sendResponse(
91
-                    new WP_Error(
92
-                        'endpoint_parsing_error',
93
-                        sprintf(
94
-                            __(
95
-                                'There is no model for endpoint %s. Please contact event espresso support',
96
-                                'event_espresso'
97
-                            ),
98
-                            $model_name
99
-                        )
100
-                    )
101
-                );
102
-            }
103
-            return $controller->sendResponse(
104
-                $controller->getEntitiesFromModel(
105
-                    $controller->getModelVersionInfo()->loadModel($model_name),
106
-                    $request
107
-                )
108
-            );
109
-        } catch (Exception $e) {
110
-            return $controller->sendResponse($e);
111
-        }
112
-    }
113
-
114
-
115
-    /**
116
-     * Prepares and returns schema for any OPTIONS request.
117
-     *
118
-     * @param string $version The API endpoint version being used.
119
-     * @param string $model_name Something like `Event` or `Registration`
120
-     * @return array
121
-     * @throws InvalidArgumentException
122
-     * @throws InvalidDataTypeException
123
-     * @throws InvalidInterfaceException
124
-     */
125
-    public static function handleSchemaRequest($version, $model_name)
126
-    {
127
-        /** @var Read $controller */
128
-        $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
129
-        try {
130
-            $controller->setRequestedVersion($version);
131
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
132
-                return array();
133
-            }
134
-            // get the model for this version
135
-            $model = $controller->getModelVersionInfo()->loadModel($model_name);
136
-            $model_schema = new JsonModelSchema($model, LoaderFactory::getLoader()->getShared('EventEspresso\core\libraries\rest_api\CalculatedModelFields'));
137
-            return $model_schema->getModelSchemaForRelations(
138
-                $controller->getModelVersionInfo()->relationSettings($model),
139
-                $controller->customizeSchemaForRestResponse(
140
-                    $model,
141
-                    $model_schema->getModelSchemaForFields(
142
-                        $controller->getModelVersionInfo()->fieldsOnModelInThisVersion($model),
143
-                        $model_schema->getInitialSchemaStructure()
144
-                    )
145
-                )
146
-            );
147
-        } catch (Exception $e) {
148
-            return array();
149
-        }
150
-    }
151
-
152
-
153
-    /**
154
-     * This loops through each field in the given schema for the model and does the following:
155
-     * - add any extra fields that are REST API specific and related to existing fields.
156
-     * - transform default values into the correct format for a REST API response.
157
-     *
158
-     * @param EEM_Base $model
159
-     * @param array    $schema
160
-     * @return array  The final schema.
161
-     * @throws EE_Error
162
-     */
163
-    protected function customizeSchemaForRestResponse(EEM_Base $model, array $schema)
164
-    {
165
-        foreach ($this->getModelVersionInfo()->fieldsOnModelInThisVersion($model) as $field_name => $field) {
166
-            $schema = $this->translateDefaultsForRestResponse(
167
-                $field_name,
168
-                $field,
169
-                $this->maybeAddExtraFieldsToSchema($field_name, $field, $schema)
170
-            );
171
-        }
172
-        return $schema;
173
-    }
174
-
175
-
176
-    /**
177
-     * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
178
-     * response.
179
-     *
180
-     * @param                      $field_name
181
-     * @param EE_Model_Field_Base  $field
182
-     * @param array                $schema
183
-     * @return array
184
-     * @throws EE_Error
185
-     */
186
-    protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema)
187
-    {
188
-        if (isset($schema['properties'][ $field_name ]['default'])) {
189
-            if (is_array($schema['properties'][ $field_name ]['default'])) {
190
-                foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
191
-                    if ($default_key === 'raw') {
192
-                        $schema['properties'][ $field_name ]['default'][ $default_key ] =
193
-                            ModelDataTranslator::prepareFieldValueForJson(
194
-                                $field,
195
-                                $default_value,
196
-                                $this->getModelVersionInfo()->requestedVersion()
197
-                            );
198
-                    }
199
-                }
200
-            } else {
201
-                $schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
202
-                    $field,
203
-                    $schema['properties'][ $field_name ]['default'],
204
-                    $this->getModelVersionInfo()->requestedVersion()
205
-                );
206
-            }
207
-        }
208
-        return $schema;
209
-    }
210
-
211
-
212
-    /**
213
-     * Adds additional fields to the schema
214
-     * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
215
-     * needs to be added to the schema.
216
-     *
217
-     * @param                      $field_name
218
-     * @param EE_Model_Field_Base  $field
219
-     * @param array                $schema
220
-     * @return array
221
-     */
222
-    protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema)
223
-    {
224
-        if ($field instanceof EE_Datetime_Field) {
225
-            $schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
226
-            // modify the description
227
-            $schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
228
-                esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
229
-                wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
230
-            );
231
-        }
232
-        return $schema;
233
-    }
234
-
235
-
236
-    /**
237
-     * Used to figure out the route from the request when a `WP_REST_Request` object is not available
238
-     *
239
-     * @return string
240
-     */
241
-    protected function getRouteFromRequest()
242
-    {
243
-        if (isset($GLOBALS['wp'])
244
-            && $GLOBALS['wp'] instanceof WP
245
-            && isset($GLOBALS['wp']->query_vars['rest_route'])
246
-        ) {
247
-            return $GLOBALS['wp']->query_vars['rest_route'];
248
-        } else {
249
-            return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
250
-        }
251
-    }
252
-
253
-
254
-    /**
255
-     * Gets a single entity related to the model indicated in the path and its id
256
-     *
257
-     * @param WP_REST_Request $request
258
-     * @param string $version
259
-     * @param string $model_name
260
-     * @return WP_REST_Response|WP_Error
261
-     * @throws InvalidDataTypeException
262
-     * @throws InvalidInterfaceException
263
-     * @throws InvalidArgumentException
264
-     */
265
-    public static function handleRequestGetOne(WP_REST_Request $request, $version, $model_name)
266
-    {
267
-        $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
268
-        try {
269
-            $controller->setRequestedVersion($version);
270
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
271
-                return $controller->sendResponse(
272
-                    new WP_Error(
273
-                        'endpoint_parsing_error',
274
-                        sprintf(
275
-                            __(
276
-                                'There is no model for endpoint %s. Please contact event espresso support',
277
-                                'event_espresso'
278
-                            ),
279
-                            $model_name
280
-                        )
281
-                    )
282
-                );
283
-            }
284
-            return $controller->sendResponse(
285
-                $controller->getEntityFromModel(
286
-                    $controller->getModelVersionInfo()->loadModel($model_name),
287
-                    $request
288
-                )
289
-            );
290
-        } catch (Exception $e) {
291
-            return $controller->sendResponse($e);
292
-        }
293
-    }
294
-
295
-
296
-    /**
297
-     * Gets all the related entities (or if its a belongs-to relation just the one)
298
-     * to the item with the given id
299
-     *
300
-     * @param WP_REST_Request $request
301
-     * @param string $version
302
-     * @param string $model_name
303
-     * @param string $related_model_name
304
-     * @return WP_REST_Response|WP_Error
305
-     * @throws InvalidDataTypeException
306
-     * @throws InvalidInterfaceException
307
-     * @throws InvalidArgumentException
308
-     */
309
-    public static function handleRequestGetRelated(
310
-        WP_REST_Request $request,
311
-        $version,
312
-        $model_name,
313
-        $related_model_name
314
-    ) {
315
-        $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
316
-        try {
317
-            $controller->setRequestedVersion($version);
318
-            $main_model = $controller->validateModel($model_name);
319
-            $controller->validateModel($related_model_name);
320
-            return $controller->sendResponse(
321
-                $controller->getEntitiesFromRelation(
322
-                    $request->get_param('id'),
323
-                    $main_model->related_settings_for($related_model_name),
324
-                    $request
325
-                )
326
-            );
327
-        } catch (Exception $e) {
328
-            return $controller->sendResponse($e);
329
-        }
330
-    }
331
-
332
-
333
-    /**
334
-     * Gets a collection for the given model and filters
335
-     *
336
-     * @param EEM_Base $model
337
-     * @param WP_REST_Request $request
338
-     * @return array
339
-     * @throws EE_Error
340
-     * @throws InvalidArgumentException
341
-     * @throws InvalidDataTypeException
342
-     * @throws InvalidInterfaceException
343
-     * @throws ReflectionException
344
-     * @throws RestException
345
-     */
346
-    public function getEntitiesFromModel($model, $request)
347
-    {
348
-        $query_params = $this->createModelQueryParams($model, $request->get_params());
349
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
350
-            $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
351
-            throw new RestException(
352
-                sprintf('rest_%s_cannot_list', $model_name_plural),
353
-                sprintf(
354
-                    __('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
355
-                    $model_name_plural,
356
-                    Capabilities::getMissingPermissionsString($model, $query_params['caps'])
357
-                ),
358
-                array('status' => 403)
359
-            );
360
-        }
361
-        if (! $request->get_header('no_rest_headers')) {
362
-            $this->setHeadersFromQueryParams($model, $query_params);
363
-        }
364
-        /** @type array $results */
365
-        $results = $model->get_all_wpdb_results($query_params);
366
-        $nice_results = array();
367
-        foreach ($results as $result) {
368
-            $nice_results[] =  $this->createEntityFromWpdbResult(
369
-                $model,
370
-                $result,
371
-                $request
372
-            );
373
-        }
374
-        return $nice_results;
375
-    }
376
-
377
-
378
-    /**
379
-     * Gets the collection for given relation object
380
-     * The same as Read::get_entities_from_model(), except if the relation
381
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
382
-     * the join-model-object into the results
383
-     *
384
-     * @param array $primary_model_query_params query params for finding the item from which
385
-     *                                                            relations will be based
386
-     * @param EE_Model_Relation_Base $relation
387
-     * @param WP_REST_Request $request
388
-     * @return array
389
-     * @throws EE_Error
390
-     * @throws InvalidArgumentException
391
-     * @throws InvalidDataTypeException
392
-     * @throws InvalidInterfaceException
393
-     * @throws ReflectionException
394
-     * @throws RestException
395
-     * @throws ModelConfigurationException
396
-     */
397
-    protected function getEntitiesFromRelationUsingModelQueryParams($primary_model_query_params, $relation, $request)
398
-    {
399
-        $context = $this->validateContext($request->get_param('caps'));
400
-        $model = $relation->get_this_model();
401
-        $related_model = $relation->get_other_model();
402
-        if (! isset($primary_model_query_params[0])) {
403
-            $primary_model_query_params[0] = array();
404
-        }
405
-        // check if they can access the 1st model object
406
-        $primary_model_query_params = array(
407
-            0       => $primary_model_query_params[0],
408
-            'limit' => 1,
409
-        );
410
-        if ($model instanceof EEM_Soft_Delete_Base) {
411
-            $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included(
412
-                $primary_model_query_params
413
-            );
414
-        }
415
-        $restricted_query_params = $primary_model_query_params;
416
-        $restricted_query_params['caps'] = $context;
417
-        $restricted_query_params['limit'] = 1;
418
-        $this->setDebugInfo('main model query params', $restricted_query_params);
419
-        $this->setDebugInfo('missing caps', Capabilities::getMissingPermissionsString($related_model, $context));
420
-        $primary_model_rows = $model->get_all_wpdb_results($restricted_query_params);
421
-        $primary_model_row = null;
422
-        if (is_array($primary_model_rows)) {
423
-            $primary_model_row = reset($primary_model_rows);
424
-        }
425
-        if (! (
426
-            Capabilities::currentUserHasPartialAccessTo($related_model, $context)
427
-            && $primary_model_row
428
-        )
429
-        ) {
430
-            if ($relation instanceof EE_Belongs_To_Relation) {
431
-                $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
432
-            } else {
433
-                $related_model_name_maybe_plural = EEH_Inflector::pluralize_and_lower(
434
-                    $related_model->get_this_model_name()
435
-                );
436
-            }
437
-            throw new RestException(
438
-                sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
439
-                sprintf(
440
-                    __(
441
-                        'Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
442
-                        'event_espresso'
443
-                    ),
444
-                    $related_model_name_maybe_plural,
445
-                    $relation->get_this_model()->get_this_model_name(),
446
-                    implode(
447
-                        ',',
448
-                        array_keys(
449
-                            Capabilities::getMissingPermissions($related_model, $context)
450
-                        )
451
-                    )
452
-                ),
453
-                array('status' => 403)
454
-            );
455
-        }
456
-
457
-        $this->checkPassword(
458
-            $model,
459
-            $primary_model_row,
460
-            $restricted_query_params,
461
-            $request
462
-        );
463
-        $query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
464
-        foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
465
-            $query_params[0][ $relation->get_this_model()->get_this_model_name()
466
-                              . '.'
467
-                              . $where_condition_key ] = $where_condition_value;
468
-        }
469
-        $query_params['default_where_conditions'] = 'none';
470
-        $query_params['caps'] = $context;
471
-        if (! $request->get_header('no_rest_headers')) {
472
-            $this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
473
-        }
474
-        /** @type array $results */
475
-        $results = $relation->get_other_model()->get_all_wpdb_results($query_params);
476
-        $nice_results = array();
477
-        foreach ($results as $result) {
478
-            $nice_result = $this->createEntityFromWpdbResult(
479
-                $relation->get_other_model(),
480
-                $result,
481
-                $request
482
-            );
483
-            if ($relation instanceof EE_HABTM_Relation) {
484
-                // put the unusual stuff (properties from the HABTM relation) first, and make sure
485
-                // if there are conflicts we prefer the properties from the main model
486
-                $join_model_result = $this->createEntityFromWpdbResult(
487
-                    $relation->get_join_model(),
488
-                    $result,
489
-                    $request
490
-                );
491
-                $joined_result = array_merge($join_model_result, $nice_result);
492
-                // but keep the meta stuff from the main model
493
-                if (isset($nice_result['meta'])) {
494
-                    $joined_result['meta'] = $nice_result['meta'];
495
-                }
496
-                $nice_result = $joined_result;
497
-            }
498
-            $nice_results[] = $nice_result;
499
-        }
500
-        if ($relation instanceof EE_Belongs_To_Relation) {
501
-            return array_shift($nice_results);
502
-        } else {
503
-            return $nice_results;
504
-        }
505
-    }
506
-
507
-
508
-    /**
509
-     * Gets the collection for given relation object
510
-     * The same as Read::get_entities_from_model(), except if the relation
511
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
512
-     * the join-model-object into the results
513
-     *
514
-     * @param string                  $id the ID of the thing we are fetching related stuff from
515
-     * @param EE_Model_Relation_Base $relation
516
-     * @param WP_REST_Request         $request
517
-     * @return array
518
-     * @throws EE_Error
519
-     * @throws InvalidArgumentException
520
-     * @throws InvalidDataTypeException
521
-     * @throws InvalidInterfaceException
522
-     * @throws ReflectionException
523
-     * @throws RestException
524
-     * @throws ModelConfigurationException
525
-     */
526
-    public function getEntitiesFromRelation($id, $relation, $request)
527
-    {
528
-        if (! $relation->get_this_model()->has_primary_key_field()) {
529
-            throw new EE_Error(
530
-                sprintf(
531
-                    __(
532
-                    // @codingStandardsIgnoreStart
533
-                        'Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
534
-                        // @codingStandardsIgnoreEnd
535
-                        'event_espresso'
536
-                    ),
537
-                    $relation->get_this_model()->get_this_model_name()
538
-                )
539
-            );
540
-        }
541
-        // can we edit that main item?
542
-        // if not, show nothing but an error
543
-        // otherwise, please proceed
544
-        return $this->getEntitiesFromRelationUsingModelQueryParams(
545
-            array(
546
-                array(
547
-                    $relation->get_this_model()->primary_key_name() => $id,
548
-                ),
549
-            ),
550
-            $relation,
551
-            $request
552
-        );
553
-    }
554
-
555
-
556
-    /**
557
-     * Sets the headers that are based on the model and query params,
558
-     * like the total records. This should only be called on the original request
559
-     * from the client, not on subsequent internal
560
-     *
561
-     * @param EEM_Base $model
562
-     * @param array    $query_params
563
-     * @return void
564
-     * @throws EE_Error
565
-     */
566
-    protected function setHeadersFromQueryParams($model, $query_params)
567
-    {
568
-        $this->setDebugInfo('model query params', $query_params);
569
-        $this->setDebugInfo(
570
-            'missing caps',
571
-            Capabilities::getMissingPermissionsString($model, $query_params['caps'])
572
-        );
573
-        // normally the limit to a 2-part array, where the 2nd item is the limit
574
-        if (! isset($query_params['limit'])) {
575
-            $query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
576
-        }
577
-        if (is_array($query_params['limit'])) {
578
-            $limit_parts = $query_params['limit'];
579
-        } else {
580
-            $limit_parts = explode(',', $query_params['limit']);
581
-            if (count($limit_parts) == 1) {
582
-                $limit_parts = array(0, $limit_parts[0]);
583
-            }
584
-        }
585
-        // remove the group by and having parts of the query, as those will
586
-        // make the sql query return an array of values, instead of just a single value
587
-        unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
588
-        $count = $model->count($query_params, null, true);
589
-        $pages = $count / $limit_parts[1];
590
-        $this->setResponseHeader('Total', $count, false);
591
-        $this->setResponseHeader('PageSize', $limit_parts[1], false);
592
-        $this->setResponseHeader('TotalPages', ceil($pages), false);
593
-    }
594
-
595
-
596
-    /**
597
-     * Changes database results into REST API entities
598
-     *
599
-     * @param EEM_Base        $model
600
-     * @param array           $db_row     like results from $wpdb->get_results()
601
-     * @param WP_REST_Request $rest_request
602
-     * @param string          $deprecated no longer used
603
-     * @return array ready for being converted into json for sending to client
604
-     * @throws EE_Error
605
-     * @throws InvalidArgumentException
606
-     * @throws InvalidDataTypeException
607
-     * @throws InvalidInterfaceException
608
-     * @throws ReflectionException
609
-     * @throws RestException
610
-     * @throws RestPasswordIncorrectException
611
-     * @throws RestPasswordRequiredException
612
-     * @throws ModelConfigurationException
613
-     * @throws UnexpectedEntityException
614
-     */
615
-    public function createEntityFromWpdbResult($model, $db_row, $rest_request, $deprecated = null)
616
-    {
617
-        if (! $rest_request instanceof WP_REST_Request) {
618
-            // ok so this was called in the old style, where the 3rd arg was
619
-            // $include, and the 4th arg was $context
620
-            // now setup the request just to avoid fatal errors, although we won't be able
621
-            // to truly make use of it because it's kinda devoid of info
622
-            $rest_request = new WP_REST_Request();
623
-            $rest_request->set_param('include', $rest_request);
624
-            $rest_request->set_param('caps', $deprecated);
625
-        }
626
-        if ($rest_request->get_param('caps') === null) {
627
-            $rest_request->set_param('caps', EEM_Base::caps_read);
628
-        }
629
-        $current_user_full_access_to_entity = $model->currentUserCan(
630
-            EEM_Base::caps_read_admin,
631
-            $model->deduce_fields_n_values_from_cols_n_values($db_row)
632
-        );
633
-        $entity_array = $this->createBareEntityFromWpdbResults($model, $db_row);
634
-        $entity_array = $this->addExtraFields($model, $db_row, $entity_array);
635
-        $entity_array['_links'] = $this->getEntityLinks($model, $db_row, $entity_array);
636
-        // when it's a regular read request for a model with a password and the password wasn't provided
637
-        // remove the password protected fields
638
-        $has_protected_fields = false;
639
-        try {
640
-            $this->checkPassword(
641
-                $model,
642
-                $db_row,
643
-                $model->alter_query_params_to_restrict_by_ID(
644
-                    $model->get_index_primary_key_string(
645
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
646
-                    )
647
-                ),
648
-                $rest_request
649
-            );
650
-        } catch (RestPasswordRequiredException $e) {
651
-            if ($model->hasPassword()) {
652
-                // just remove protected fields
653
-                $has_protected_fields = true;
654
-                $entity_array = Capabilities::filterOutPasswordProtectedFields(
655
-                    $entity_array,
656
-                    $model,
657
-                    $this->getModelVersionInfo()
658
-                );
659
-            } else {
660
-                // that's a problem. None of this should be accessible if no password was provided
661
-                throw $e;
662
-            }
663
-        }
664
-
665
-        $entity_array['_calculated_fields'] = $this->getEntityCalculations($model, $db_row, $rest_request, $has_protected_fields);
666
-        $entity_array = apply_filters(
667
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
668
-            $entity_array,
669
-            $model,
670
-            $rest_request->get_param('caps'),
671
-            $rest_request,
672
-            $this
673
-        );
674
-        // add an empty protected property for now. If it's still around after we remove everything the request didn't
675
-        // want, we'll populate it then. k?
676
-        $entity_array['_protected'] = array();
677
-        // remove any properties the request didn't want. This way _protected won't bother mentioning them
678
-        $entity_array = $this->includeOnlyRequestedProperties($model, $rest_request, $entity_array);
679
-        $entity_array = $this->includeRequestedModels($model, $rest_request, $entity_array, $db_row, $has_protected_fields);
680
-        // if they still wanted the _protected property, add it.
681
-        if (isset($entity_array['_protected'])) {
682
-            $entity_array = $this->addProtectedProperty($model, $entity_array, $has_protected_fields);
683
-        }
684
-        $entity_array = apply_filters(
685
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
686
-            $entity_array,
687
-            $model,
688
-            $rest_request->get_param('caps'),
689
-            $rest_request,
690
-            $this
691
-        );
692
-        if (! $current_user_full_access_to_entity) {
693
-            $result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
694
-                $entity_array,
695
-                $model,
696
-                $rest_request->get_param('caps'),
697
-                $this->getModelVersionInfo()
698
-            );
699
-        } else {
700
-            $result_without_inaccessible_fields = $entity_array;
701
-        }
702
-        $this->setDebugInfo(
703
-            'inaccessible fields',
704
-            array_keys(array_diff_key((array) $entity_array, (array) $result_without_inaccessible_fields))
705
-        );
706
-        return apply_filters(
707
-            'FHEE__Read__create_entity_from_wpdb_results__entity_return',
708
-            $result_without_inaccessible_fields,
709
-            $model,
710
-            $rest_request->get_param('caps')
711
-        );
712
-    }
713
-
714
-
715
-    /**
716
-     * Returns an array describing which fields can be protected, and which actually were removed this request
717
-     *
718
-     * @param EEM_Base $model
719
-     * @param          $results_so_far
720
-     * @param          $protected
721
-     * @return array results
722
-     * @throws EE_Error
723
-     * @since 4.9.74.p
724
-     */
725
-    protected function addProtectedProperty(EEM_Base $model, $results_so_far, $protected)
726
-    {
727
-        if (! $model->hasPassword() || ! $protected) {
728
-            return $results_so_far;
729
-        }
730
-        $password_field = $model->getPasswordField();
731
-        $all_protected = array_merge(
732
-            array($password_field->get_name()),
733
-            $password_field->protectedFields()
734
-        );
735
-        $fields_included = array_keys($results_so_far);
736
-        $fields_included = array_intersect(
737
-            $all_protected,
738
-            $fields_included
739
-        );
740
-        foreach ($fields_included as $field_name) {
741
-            $results_so_far['_protected'][] = $field_name ;
742
-        }
743
-        return $results_so_far;
744
-    }
745
-
746
-
747
-    /**
748
-     * Creates a REST entity array (JSON object we're going to return in the response, but
749
-     * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
750
-     * from $wpdb->get_row( $sql, ARRAY_A)
751
-     *
752
-     * @param EEM_Base $model
753
-     * @param array    $db_row
754
-     * @return array entity mostly ready for converting to JSON and sending in the response
755
-     * @throws EE_Error
756
-     * @throws InvalidArgumentException
757
-     * @throws InvalidDataTypeException
758
-     * @throws InvalidInterfaceException
759
-     * @throws ReflectionException
760
-     * @throws RestException
55
+	/**
56
+	 * @var CalculatedModelFields
57
+	 */
58
+	protected $fields_calculator;
59
+
60
+
61
+	/**
62
+	 * Read constructor.
63
+	 * @param CalculatedModelFields $fields_calculator
64
+	 */
65
+	public function __construct(CalculatedModelFields $fields_calculator)
66
+	{
67
+		parent::__construct();
68
+		$this->fields_calculator = $fields_calculator;
69
+	}
70
+
71
+
72
+	/**
73
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
74
+	 *
75
+	 * @param WP_REST_Request $request
76
+	 * @param string $version
77
+	 * @param string $model_name
78
+	 * @return WP_REST_Response|WP_Error
79
+	 * @throws InvalidArgumentException
80
+	 * @throws InvalidDataTypeException
81
+	 * @throws InvalidInterfaceException
82
+	 */
83
+	public static function handleRequestGetAll(WP_REST_Request $request, $version, $model_name)
84
+	{
85
+		/** @var Read $controller */
86
+		$controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
87
+		try {
88
+			$controller->setRequestedVersion($version);
89
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
90
+				return $controller->sendResponse(
91
+					new WP_Error(
92
+						'endpoint_parsing_error',
93
+						sprintf(
94
+							__(
95
+								'There is no model for endpoint %s. Please contact event espresso support',
96
+								'event_espresso'
97
+							),
98
+							$model_name
99
+						)
100
+					)
101
+				);
102
+			}
103
+			return $controller->sendResponse(
104
+				$controller->getEntitiesFromModel(
105
+					$controller->getModelVersionInfo()->loadModel($model_name),
106
+					$request
107
+				)
108
+			);
109
+		} catch (Exception $e) {
110
+			return $controller->sendResponse($e);
111
+		}
112
+	}
113
+
114
+
115
+	/**
116
+	 * Prepares and returns schema for any OPTIONS request.
117
+	 *
118
+	 * @param string $version The API endpoint version being used.
119
+	 * @param string $model_name Something like `Event` or `Registration`
120
+	 * @return array
121
+	 * @throws InvalidArgumentException
122
+	 * @throws InvalidDataTypeException
123
+	 * @throws InvalidInterfaceException
124
+	 */
125
+	public static function handleSchemaRequest($version, $model_name)
126
+	{
127
+		/** @var Read $controller */
128
+		$controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
129
+		try {
130
+			$controller->setRequestedVersion($version);
131
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
132
+				return array();
133
+			}
134
+			// get the model for this version
135
+			$model = $controller->getModelVersionInfo()->loadModel($model_name);
136
+			$model_schema = new JsonModelSchema($model, LoaderFactory::getLoader()->getShared('EventEspresso\core\libraries\rest_api\CalculatedModelFields'));
137
+			return $model_schema->getModelSchemaForRelations(
138
+				$controller->getModelVersionInfo()->relationSettings($model),
139
+				$controller->customizeSchemaForRestResponse(
140
+					$model,
141
+					$model_schema->getModelSchemaForFields(
142
+						$controller->getModelVersionInfo()->fieldsOnModelInThisVersion($model),
143
+						$model_schema->getInitialSchemaStructure()
144
+					)
145
+				)
146
+			);
147
+		} catch (Exception $e) {
148
+			return array();
149
+		}
150
+	}
151
+
152
+
153
+	/**
154
+	 * This loops through each field in the given schema for the model and does the following:
155
+	 * - add any extra fields that are REST API specific and related to existing fields.
156
+	 * - transform default values into the correct format for a REST API response.
157
+	 *
158
+	 * @param EEM_Base $model
159
+	 * @param array    $schema
160
+	 * @return array  The final schema.
161
+	 * @throws EE_Error
162
+	 */
163
+	protected function customizeSchemaForRestResponse(EEM_Base $model, array $schema)
164
+	{
165
+		foreach ($this->getModelVersionInfo()->fieldsOnModelInThisVersion($model) as $field_name => $field) {
166
+			$schema = $this->translateDefaultsForRestResponse(
167
+				$field_name,
168
+				$field,
169
+				$this->maybeAddExtraFieldsToSchema($field_name, $field, $schema)
170
+			);
171
+		}
172
+		return $schema;
173
+	}
174
+
175
+
176
+	/**
177
+	 * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
178
+	 * response.
179
+	 *
180
+	 * @param                      $field_name
181
+	 * @param EE_Model_Field_Base  $field
182
+	 * @param array                $schema
183
+	 * @return array
184
+	 * @throws EE_Error
185
+	 */
186
+	protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema)
187
+	{
188
+		if (isset($schema['properties'][ $field_name ]['default'])) {
189
+			if (is_array($schema['properties'][ $field_name ]['default'])) {
190
+				foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
191
+					if ($default_key === 'raw') {
192
+						$schema['properties'][ $field_name ]['default'][ $default_key ] =
193
+							ModelDataTranslator::prepareFieldValueForJson(
194
+								$field,
195
+								$default_value,
196
+								$this->getModelVersionInfo()->requestedVersion()
197
+							);
198
+					}
199
+				}
200
+			} else {
201
+				$schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
202
+					$field,
203
+					$schema['properties'][ $field_name ]['default'],
204
+					$this->getModelVersionInfo()->requestedVersion()
205
+				);
206
+			}
207
+		}
208
+		return $schema;
209
+	}
210
+
211
+
212
+	/**
213
+	 * Adds additional fields to the schema
214
+	 * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
215
+	 * needs to be added to the schema.
216
+	 *
217
+	 * @param                      $field_name
218
+	 * @param EE_Model_Field_Base  $field
219
+	 * @param array                $schema
220
+	 * @return array
221
+	 */
222
+	protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema)
223
+	{
224
+		if ($field instanceof EE_Datetime_Field) {
225
+			$schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
226
+			// modify the description
227
+			$schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
228
+				esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
229
+				wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
230
+			);
231
+		}
232
+		return $schema;
233
+	}
234
+
235
+
236
+	/**
237
+	 * Used to figure out the route from the request when a `WP_REST_Request` object is not available
238
+	 *
239
+	 * @return string
240
+	 */
241
+	protected function getRouteFromRequest()
242
+	{
243
+		if (isset($GLOBALS['wp'])
244
+			&& $GLOBALS['wp'] instanceof WP
245
+			&& isset($GLOBALS['wp']->query_vars['rest_route'])
246
+		) {
247
+			return $GLOBALS['wp']->query_vars['rest_route'];
248
+		} else {
249
+			return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
250
+		}
251
+	}
252
+
253
+
254
+	/**
255
+	 * Gets a single entity related to the model indicated in the path and its id
256
+	 *
257
+	 * @param WP_REST_Request $request
258
+	 * @param string $version
259
+	 * @param string $model_name
260
+	 * @return WP_REST_Response|WP_Error
261
+	 * @throws InvalidDataTypeException
262
+	 * @throws InvalidInterfaceException
263
+	 * @throws InvalidArgumentException
264
+	 */
265
+	public static function handleRequestGetOne(WP_REST_Request $request, $version, $model_name)
266
+	{
267
+		$controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
268
+		try {
269
+			$controller->setRequestedVersion($version);
270
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
271
+				return $controller->sendResponse(
272
+					new WP_Error(
273
+						'endpoint_parsing_error',
274
+						sprintf(
275
+							__(
276
+								'There is no model for endpoint %s. Please contact event espresso support',
277
+								'event_espresso'
278
+							),
279
+							$model_name
280
+						)
281
+					)
282
+				);
283
+			}
284
+			return $controller->sendResponse(
285
+				$controller->getEntityFromModel(
286
+					$controller->getModelVersionInfo()->loadModel($model_name),
287
+					$request
288
+				)
289
+			);
290
+		} catch (Exception $e) {
291
+			return $controller->sendResponse($e);
292
+		}
293
+	}
294
+
295
+
296
+	/**
297
+	 * Gets all the related entities (or if its a belongs-to relation just the one)
298
+	 * to the item with the given id
299
+	 *
300
+	 * @param WP_REST_Request $request
301
+	 * @param string $version
302
+	 * @param string $model_name
303
+	 * @param string $related_model_name
304
+	 * @return WP_REST_Response|WP_Error
305
+	 * @throws InvalidDataTypeException
306
+	 * @throws InvalidInterfaceException
307
+	 * @throws InvalidArgumentException
308
+	 */
309
+	public static function handleRequestGetRelated(
310
+		WP_REST_Request $request,
311
+		$version,
312
+		$model_name,
313
+		$related_model_name
314
+	) {
315
+		$controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
316
+		try {
317
+			$controller->setRequestedVersion($version);
318
+			$main_model = $controller->validateModel($model_name);
319
+			$controller->validateModel($related_model_name);
320
+			return $controller->sendResponse(
321
+				$controller->getEntitiesFromRelation(
322
+					$request->get_param('id'),
323
+					$main_model->related_settings_for($related_model_name),
324
+					$request
325
+				)
326
+			);
327
+		} catch (Exception $e) {
328
+			return $controller->sendResponse($e);
329
+		}
330
+	}
331
+
332
+
333
+	/**
334
+	 * Gets a collection for the given model and filters
335
+	 *
336
+	 * @param EEM_Base $model
337
+	 * @param WP_REST_Request $request
338
+	 * @return array
339
+	 * @throws EE_Error
340
+	 * @throws InvalidArgumentException
341
+	 * @throws InvalidDataTypeException
342
+	 * @throws InvalidInterfaceException
343
+	 * @throws ReflectionException
344
+	 * @throws RestException
345
+	 */
346
+	public function getEntitiesFromModel($model, $request)
347
+	{
348
+		$query_params = $this->createModelQueryParams($model, $request->get_params());
349
+		if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
350
+			$model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
351
+			throw new RestException(
352
+				sprintf('rest_%s_cannot_list', $model_name_plural),
353
+				sprintf(
354
+					__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
355
+					$model_name_plural,
356
+					Capabilities::getMissingPermissionsString($model, $query_params['caps'])
357
+				),
358
+				array('status' => 403)
359
+			);
360
+		}
361
+		if (! $request->get_header('no_rest_headers')) {
362
+			$this->setHeadersFromQueryParams($model, $query_params);
363
+		}
364
+		/** @type array $results */
365
+		$results = $model->get_all_wpdb_results($query_params);
366
+		$nice_results = array();
367
+		foreach ($results as $result) {
368
+			$nice_results[] =  $this->createEntityFromWpdbResult(
369
+				$model,
370
+				$result,
371
+				$request
372
+			);
373
+		}
374
+		return $nice_results;
375
+	}
376
+
377
+
378
+	/**
379
+	 * Gets the collection for given relation object
380
+	 * The same as Read::get_entities_from_model(), except if the relation
381
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
382
+	 * the join-model-object into the results
383
+	 *
384
+	 * @param array $primary_model_query_params query params for finding the item from which
385
+	 *                                                            relations will be based
386
+	 * @param EE_Model_Relation_Base $relation
387
+	 * @param WP_REST_Request $request
388
+	 * @return array
389
+	 * @throws EE_Error
390
+	 * @throws InvalidArgumentException
391
+	 * @throws InvalidDataTypeException
392
+	 * @throws InvalidInterfaceException
393
+	 * @throws ReflectionException
394
+	 * @throws RestException
395
+	 * @throws ModelConfigurationException
396
+	 */
397
+	protected function getEntitiesFromRelationUsingModelQueryParams($primary_model_query_params, $relation, $request)
398
+	{
399
+		$context = $this->validateContext($request->get_param('caps'));
400
+		$model = $relation->get_this_model();
401
+		$related_model = $relation->get_other_model();
402
+		if (! isset($primary_model_query_params[0])) {
403
+			$primary_model_query_params[0] = array();
404
+		}
405
+		// check if they can access the 1st model object
406
+		$primary_model_query_params = array(
407
+			0       => $primary_model_query_params[0],
408
+			'limit' => 1,
409
+		);
410
+		if ($model instanceof EEM_Soft_Delete_Base) {
411
+			$primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included(
412
+				$primary_model_query_params
413
+			);
414
+		}
415
+		$restricted_query_params = $primary_model_query_params;
416
+		$restricted_query_params['caps'] = $context;
417
+		$restricted_query_params['limit'] = 1;
418
+		$this->setDebugInfo('main model query params', $restricted_query_params);
419
+		$this->setDebugInfo('missing caps', Capabilities::getMissingPermissionsString($related_model, $context));
420
+		$primary_model_rows = $model->get_all_wpdb_results($restricted_query_params);
421
+		$primary_model_row = null;
422
+		if (is_array($primary_model_rows)) {
423
+			$primary_model_row = reset($primary_model_rows);
424
+		}
425
+		if (! (
426
+			Capabilities::currentUserHasPartialAccessTo($related_model, $context)
427
+			&& $primary_model_row
428
+		)
429
+		) {
430
+			if ($relation instanceof EE_Belongs_To_Relation) {
431
+				$related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
432
+			} else {
433
+				$related_model_name_maybe_plural = EEH_Inflector::pluralize_and_lower(
434
+					$related_model->get_this_model_name()
435
+				);
436
+			}
437
+			throw new RestException(
438
+				sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
439
+				sprintf(
440
+					__(
441
+						'Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
442
+						'event_espresso'
443
+					),
444
+					$related_model_name_maybe_plural,
445
+					$relation->get_this_model()->get_this_model_name(),
446
+					implode(
447
+						',',
448
+						array_keys(
449
+							Capabilities::getMissingPermissions($related_model, $context)
450
+						)
451
+					)
452
+				),
453
+				array('status' => 403)
454
+			);
455
+		}
456
+
457
+		$this->checkPassword(
458
+			$model,
459
+			$primary_model_row,
460
+			$restricted_query_params,
461
+			$request
462
+		);
463
+		$query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
464
+		foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
465
+			$query_params[0][ $relation->get_this_model()->get_this_model_name()
466
+							  . '.'
467
+							  . $where_condition_key ] = $where_condition_value;
468
+		}
469
+		$query_params['default_where_conditions'] = 'none';
470
+		$query_params['caps'] = $context;
471
+		if (! $request->get_header('no_rest_headers')) {
472
+			$this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
473
+		}
474
+		/** @type array $results */
475
+		$results = $relation->get_other_model()->get_all_wpdb_results($query_params);
476
+		$nice_results = array();
477
+		foreach ($results as $result) {
478
+			$nice_result = $this->createEntityFromWpdbResult(
479
+				$relation->get_other_model(),
480
+				$result,
481
+				$request
482
+			);
483
+			if ($relation instanceof EE_HABTM_Relation) {
484
+				// put the unusual stuff (properties from the HABTM relation) first, and make sure
485
+				// if there are conflicts we prefer the properties from the main model
486
+				$join_model_result = $this->createEntityFromWpdbResult(
487
+					$relation->get_join_model(),
488
+					$result,
489
+					$request
490
+				);
491
+				$joined_result = array_merge($join_model_result, $nice_result);
492
+				// but keep the meta stuff from the main model
493
+				if (isset($nice_result['meta'])) {
494
+					$joined_result['meta'] = $nice_result['meta'];
495
+				}
496
+				$nice_result = $joined_result;
497
+			}
498
+			$nice_results[] = $nice_result;
499
+		}
500
+		if ($relation instanceof EE_Belongs_To_Relation) {
501
+			return array_shift($nice_results);
502
+		} else {
503
+			return $nice_results;
504
+		}
505
+	}
506
+
507
+
508
+	/**
509
+	 * Gets the collection for given relation object
510
+	 * The same as Read::get_entities_from_model(), except if the relation
511
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
512
+	 * the join-model-object into the results
513
+	 *
514
+	 * @param string                  $id the ID of the thing we are fetching related stuff from
515
+	 * @param EE_Model_Relation_Base $relation
516
+	 * @param WP_REST_Request         $request
517
+	 * @return array
518
+	 * @throws EE_Error
519
+	 * @throws InvalidArgumentException
520
+	 * @throws InvalidDataTypeException
521
+	 * @throws InvalidInterfaceException
522
+	 * @throws ReflectionException
523
+	 * @throws RestException
524
+	 * @throws ModelConfigurationException
525
+	 */
526
+	public function getEntitiesFromRelation($id, $relation, $request)
527
+	{
528
+		if (! $relation->get_this_model()->has_primary_key_field()) {
529
+			throw new EE_Error(
530
+				sprintf(
531
+					__(
532
+					// @codingStandardsIgnoreStart
533
+						'Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
534
+						// @codingStandardsIgnoreEnd
535
+						'event_espresso'
536
+					),
537
+					$relation->get_this_model()->get_this_model_name()
538
+				)
539
+			);
540
+		}
541
+		// can we edit that main item?
542
+		// if not, show nothing but an error
543
+		// otherwise, please proceed
544
+		return $this->getEntitiesFromRelationUsingModelQueryParams(
545
+			array(
546
+				array(
547
+					$relation->get_this_model()->primary_key_name() => $id,
548
+				),
549
+			),
550
+			$relation,
551
+			$request
552
+		);
553
+	}
554
+
555
+
556
+	/**
557
+	 * Sets the headers that are based on the model and query params,
558
+	 * like the total records. This should only be called on the original request
559
+	 * from the client, not on subsequent internal
560
+	 *
561
+	 * @param EEM_Base $model
562
+	 * @param array    $query_params
563
+	 * @return void
564
+	 * @throws EE_Error
565
+	 */
566
+	protected function setHeadersFromQueryParams($model, $query_params)
567
+	{
568
+		$this->setDebugInfo('model query params', $query_params);
569
+		$this->setDebugInfo(
570
+			'missing caps',
571
+			Capabilities::getMissingPermissionsString($model, $query_params['caps'])
572
+		);
573
+		// normally the limit to a 2-part array, where the 2nd item is the limit
574
+		if (! isset($query_params['limit'])) {
575
+			$query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
576
+		}
577
+		if (is_array($query_params['limit'])) {
578
+			$limit_parts = $query_params['limit'];
579
+		} else {
580
+			$limit_parts = explode(',', $query_params['limit']);
581
+			if (count($limit_parts) == 1) {
582
+				$limit_parts = array(0, $limit_parts[0]);
583
+			}
584
+		}
585
+		// remove the group by and having parts of the query, as those will
586
+		// make the sql query return an array of values, instead of just a single value
587
+		unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
588
+		$count = $model->count($query_params, null, true);
589
+		$pages = $count / $limit_parts[1];
590
+		$this->setResponseHeader('Total', $count, false);
591
+		$this->setResponseHeader('PageSize', $limit_parts[1], false);
592
+		$this->setResponseHeader('TotalPages', ceil($pages), false);
593
+	}
594
+
595
+
596
+	/**
597
+	 * Changes database results into REST API entities
598
+	 *
599
+	 * @param EEM_Base        $model
600
+	 * @param array           $db_row     like results from $wpdb->get_results()
601
+	 * @param WP_REST_Request $rest_request
602
+	 * @param string          $deprecated no longer used
603
+	 * @return array ready for being converted into json for sending to client
604
+	 * @throws EE_Error
605
+	 * @throws InvalidArgumentException
606
+	 * @throws InvalidDataTypeException
607
+	 * @throws InvalidInterfaceException
608
+	 * @throws ReflectionException
609
+	 * @throws RestException
610
+	 * @throws RestPasswordIncorrectException
611
+	 * @throws RestPasswordRequiredException
612
+	 * @throws ModelConfigurationException
613
+	 * @throws UnexpectedEntityException
614
+	 */
615
+	public function createEntityFromWpdbResult($model, $db_row, $rest_request, $deprecated = null)
616
+	{
617
+		if (! $rest_request instanceof WP_REST_Request) {
618
+			// ok so this was called in the old style, where the 3rd arg was
619
+			// $include, and the 4th arg was $context
620
+			// now setup the request just to avoid fatal errors, although we won't be able
621
+			// to truly make use of it because it's kinda devoid of info
622
+			$rest_request = new WP_REST_Request();
623
+			$rest_request->set_param('include', $rest_request);
624
+			$rest_request->set_param('caps', $deprecated);
625
+		}
626
+		if ($rest_request->get_param('caps') === null) {
627
+			$rest_request->set_param('caps', EEM_Base::caps_read);
628
+		}
629
+		$current_user_full_access_to_entity = $model->currentUserCan(
630
+			EEM_Base::caps_read_admin,
631
+			$model->deduce_fields_n_values_from_cols_n_values($db_row)
632
+		);
633
+		$entity_array = $this->createBareEntityFromWpdbResults($model, $db_row);
634
+		$entity_array = $this->addExtraFields($model, $db_row, $entity_array);
635
+		$entity_array['_links'] = $this->getEntityLinks($model, $db_row, $entity_array);
636
+		// when it's a regular read request for a model with a password and the password wasn't provided
637
+		// remove the password protected fields
638
+		$has_protected_fields = false;
639
+		try {
640
+			$this->checkPassword(
641
+				$model,
642
+				$db_row,
643
+				$model->alter_query_params_to_restrict_by_ID(
644
+					$model->get_index_primary_key_string(
645
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
646
+					)
647
+				),
648
+				$rest_request
649
+			);
650
+		} catch (RestPasswordRequiredException $e) {
651
+			if ($model->hasPassword()) {
652
+				// just remove protected fields
653
+				$has_protected_fields = true;
654
+				$entity_array = Capabilities::filterOutPasswordProtectedFields(
655
+					$entity_array,
656
+					$model,
657
+					$this->getModelVersionInfo()
658
+				);
659
+			} else {
660
+				// that's a problem. None of this should be accessible if no password was provided
661
+				throw $e;
662
+			}
663
+		}
664
+
665
+		$entity_array['_calculated_fields'] = $this->getEntityCalculations($model, $db_row, $rest_request, $has_protected_fields);
666
+		$entity_array = apply_filters(
667
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
668
+			$entity_array,
669
+			$model,
670
+			$rest_request->get_param('caps'),
671
+			$rest_request,
672
+			$this
673
+		);
674
+		// add an empty protected property for now. If it's still around after we remove everything the request didn't
675
+		// want, we'll populate it then. k?
676
+		$entity_array['_protected'] = array();
677
+		// remove any properties the request didn't want. This way _protected won't bother mentioning them
678
+		$entity_array = $this->includeOnlyRequestedProperties($model, $rest_request, $entity_array);
679
+		$entity_array = $this->includeRequestedModels($model, $rest_request, $entity_array, $db_row, $has_protected_fields);
680
+		// if they still wanted the _protected property, add it.
681
+		if (isset($entity_array['_protected'])) {
682
+			$entity_array = $this->addProtectedProperty($model, $entity_array, $has_protected_fields);
683
+		}
684
+		$entity_array = apply_filters(
685
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
686
+			$entity_array,
687
+			$model,
688
+			$rest_request->get_param('caps'),
689
+			$rest_request,
690
+			$this
691
+		);
692
+		if (! $current_user_full_access_to_entity) {
693
+			$result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
694
+				$entity_array,
695
+				$model,
696
+				$rest_request->get_param('caps'),
697
+				$this->getModelVersionInfo()
698
+			);
699
+		} else {
700
+			$result_without_inaccessible_fields = $entity_array;
701
+		}
702
+		$this->setDebugInfo(
703
+			'inaccessible fields',
704
+			array_keys(array_diff_key((array) $entity_array, (array) $result_without_inaccessible_fields))
705
+		);
706
+		return apply_filters(
707
+			'FHEE__Read__create_entity_from_wpdb_results__entity_return',
708
+			$result_without_inaccessible_fields,
709
+			$model,
710
+			$rest_request->get_param('caps')
711
+		);
712
+	}
713
+
714
+
715
+	/**
716
+	 * Returns an array describing which fields can be protected, and which actually were removed this request
717
+	 *
718
+	 * @param EEM_Base $model
719
+	 * @param          $results_so_far
720
+	 * @param          $protected
721
+	 * @return array results
722
+	 * @throws EE_Error
723
+	 * @since 4.9.74.p
724
+	 */
725
+	protected function addProtectedProperty(EEM_Base $model, $results_so_far, $protected)
726
+	{
727
+		if (! $model->hasPassword() || ! $protected) {
728
+			return $results_so_far;
729
+		}
730
+		$password_field = $model->getPasswordField();
731
+		$all_protected = array_merge(
732
+			array($password_field->get_name()),
733
+			$password_field->protectedFields()
734
+		);
735
+		$fields_included = array_keys($results_so_far);
736
+		$fields_included = array_intersect(
737
+			$all_protected,
738
+			$fields_included
739
+		);
740
+		foreach ($fields_included as $field_name) {
741
+			$results_so_far['_protected'][] = $field_name ;
742
+		}
743
+		return $results_so_far;
744
+	}
745
+
746
+
747
+	/**
748
+	 * Creates a REST entity array (JSON object we're going to return in the response, but
749
+	 * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
750
+	 * from $wpdb->get_row( $sql, ARRAY_A)
751
+	 *
752
+	 * @param EEM_Base $model
753
+	 * @param array    $db_row
754
+	 * @return array entity mostly ready for converting to JSON and sending in the response
755
+	 * @throws EE_Error
756
+	 * @throws InvalidArgumentException
757
+	 * @throws InvalidDataTypeException
758
+	 * @throws InvalidInterfaceException
759
+	 * @throws ReflectionException
760
+	 * @throws RestException
761 761
 */
762
-    protected function createBareEntityFromWpdbResults(EEM_Base $model, $db_row)
763
-    {
764
-        $result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
765
-        $result = array_intersect_key(
766
-            $result,
767
-            $this->getModelVersionInfo()->fieldsOnModelInThisVersion($model)
768
-        );
769
-        // if this is a CPT, we need to set the global $post to it,
770
-        // otherwise shortcodes etc won't work properly while rendering it
771
-        if ($model instanceof \EEM_CPT_Base) {
772
-            $do_chevy_shuffle = true;
773
-        } else {
774
-            $do_chevy_shuffle = false;
775
-        }
776
-        if ($do_chevy_shuffle) {
777
-            global $post;
778
-            $old_post = $post;
779
-            $post = get_post($result[ $model->primary_key_name() ]);
780
-            if (! $post instanceof WP_Post) {
781
-                // well that's weird, because $result is what we JUST fetched from the database
782
-                throw new RestException(
783
-                    'error_fetching_post_from_database_results',
784
-                    esc_html__(
785
-                        'An item was retrieved from the database but it\'s not a WP_Post like it should be.',
786
-                        'event_espresso'
787
-                    )
788
-                );
789
-            }
790
-            $model_object_classname = 'EE_' . $model->get_this_model_name();
791
-            $post->{$model_object_classname} = \EE_Registry::instance()->load_class(
792
-                $model_object_classname,
793
-                $result,
794
-                false,
795
-                false
796
-            );
797
-        }
798
-        foreach ($result as $field_name => $field_value) {
799
-            $field_obj = $model->field_settings_for($field_name);
800
-            if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
801
-                unset($result[ $field_name ]);
802
-            } elseif ($this->isSubclassOfOne(
803
-                $field_obj,
804
-                $this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
805
-            )
806
-            ) {
807
-                $result[ $field_name ] = array(
808
-                    'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
809
-                    'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
810
-                );
811
-            } elseif ($this->isSubclassOfOne(
812
-                $field_obj,
813
-                $this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
814
-            )
815
-            ) {
816
-                $result[ $field_name ] = array(
817
-                    'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
818
-                    'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
819
-                );
820
-            } elseif ($field_obj instanceof \EE_Datetime_Field) {
821
-                $field_value = $field_obj->prepare_for_set_from_db($field_value);
822
-                // if the value is null, but we're not supposed to permit null, then set to the field's default
823
-                if (is_null($field_value)) {
824
-                    $field_value = $field_obj->getDefaultDateTimeObj();
825
-                }
826
-                if (is_null($field_value)) {
827
-                    $gmt_date = $local_date = ModelDataTranslator::prepareFieldValuesForJson(
828
-                        $field_obj,
829
-                        $field_value,
830
-                        $this->getModelVersionInfo()->requestedVersion()
831
-                    );
832
-                } else {
833
-                    $timezone = $field_value->getTimezone();
834
-                    EEH_DTT_Helper::setTimezone($field_value, new DateTimeZone('UTC'));
835
-                    $gmt_date = ModelDataTranslator::prepareFieldValuesForJson(
836
-                        $field_obj,
837
-                        $field_value,
838
-                        $this->getModelVersionInfo()->requestedVersion()
839
-                    );
840
-                    EEH_DTT_Helper::setTimezone($field_value, $timezone);
841
-                    $local_date = ModelDataTranslator::prepareFieldValuesForJson(
842
-                        $field_obj,
843
-                        $field_value,
844
-                        $this->getModelVersionInfo()->requestedVersion()
845
-                    );
846
-                }
847
-                $result[ $field_name . '_gmt' ] = $gmt_date;
848
-                $result[ $field_name ] = $local_date;
849
-            } else {
850
-                $result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
851
-            }
852
-        }
853
-        if ($do_chevy_shuffle) {
854
-            $post = $old_post;
855
-        }
856
-        return $result;
857
-    }
858
-
859
-
860
-    /**
861
-     * Takes a value all the way from the DB representation, to the model object's representation, to the
862
-     * user-facing PHP representation, to the REST API representation. (Assumes you've already taken from the DB
863
-     * representation using $field_obj->prepare_for_set_from_db())
864
-     *
865
-     * @param EE_Model_Field_Base $field_obj
866
-     * @param mixed               $value  as it's stored on a model object
867
-     * @param string              $format valid values are 'normal' (default), 'pretty', 'datetime_obj'
868
-     * @return mixed
869
-     * @throws EE_Error
762
+	protected function createBareEntityFromWpdbResults(EEM_Base $model, $db_row)
763
+	{
764
+		$result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
765
+		$result = array_intersect_key(
766
+			$result,
767
+			$this->getModelVersionInfo()->fieldsOnModelInThisVersion($model)
768
+		);
769
+		// if this is a CPT, we need to set the global $post to it,
770
+		// otherwise shortcodes etc won't work properly while rendering it
771
+		if ($model instanceof \EEM_CPT_Base) {
772
+			$do_chevy_shuffle = true;
773
+		} else {
774
+			$do_chevy_shuffle = false;
775
+		}
776
+		if ($do_chevy_shuffle) {
777
+			global $post;
778
+			$old_post = $post;
779
+			$post = get_post($result[ $model->primary_key_name() ]);
780
+			if (! $post instanceof WP_Post) {
781
+				// well that's weird, because $result is what we JUST fetched from the database
782
+				throw new RestException(
783
+					'error_fetching_post_from_database_results',
784
+					esc_html__(
785
+						'An item was retrieved from the database but it\'s not a WP_Post like it should be.',
786
+						'event_espresso'
787
+					)
788
+				);
789
+			}
790
+			$model_object_classname = 'EE_' . $model->get_this_model_name();
791
+			$post->{$model_object_classname} = \EE_Registry::instance()->load_class(
792
+				$model_object_classname,
793
+				$result,
794
+				false,
795
+				false
796
+			);
797
+		}
798
+		foreach ($result as $field_name => $field_value) {
799
+			$field_obj = $model->field_settings_for($field_name);
800
+			if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
801
+				unset($result[ $field_name ]);
802
+			} elseif ($this->isSubclassOfOne(
803
+				$field_obj,
804
+				$this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
805
+			)
806
+			) {
807
+				$result[ $field_name ] = array(
808
+					'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
809
+					'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
810
+				);
811
+			} elseif ($this->isSubclassOfOne(
812
+				$field_obj,
813
+				$this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
814
+			)
815
+			) {
816
+				$result[ $field_name ] = array(
817
+					'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
818
+					'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
819
+				);
820
+			} elseif ($field_obj instanceof \EE_Datetime_Field) {
821
+				$field_value = $field_obj->prepare_for_set_from_db($field_value);
822
+				// if the value is null, but we're not supposed to permit null, then set to the field's default
823
+				if (is_null($field_value)) {
824
+					$field_value = $field_obj->getDefaultDateTimeObj();
825
+				}
826
+				if (is_null($field_value)) {
827
+					$gmt_date = $local_date = ModelDataTranslator::prepareFieldValuesForJson(
828
+						$field_obj,
829
+						$field_value,
830
+						$this->getModelVersionInfo()->requestedVersion()
831
+					);
832
+				} else {
833
+					$timezone = $field_value->getTimezone();
834
+					EEH_DTT_Helper::setTimezone($field_value, new DateTimeZone('UTC'));
835
+					$gmt_date = ModelDataTranslator::prepareFieldValuesForJson(
836
+						$field_obj,
837
+						$field_value,
838
+						$this->getModelVersionInfo()->requestedVersion()
839
+					);
840
+					EEH_DTT_Helper::setTimezone($field_value, $timezone);
841
+					$local_date = ModelDataTranslator::prepareFieldValuesForJson(
842
+						$field_obj,
843
+						$field_value,
844
+						$this->getModelVersionInfo()->requestedVersion()
845
+					);
846
+				}
847
+				$result[ $field_name . '_gmt' ] = $gmt_date;
848
+				$result[ $field_name ] = $local_date;
849
+			} else {
850
+				$result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
851
+			}
852
+		}
853
+		if ($do_chevy_shuffle) {
854
+			$post = $old_post;
855
+		}
856
+		return $result;
857
+	}
858
+
859
+
860
+	/**
861
+	 * Takes a value all the way from the DB representation, to the model object's representation, to the
862
+	 * user-facing PHP representation, to the REST API representation. (Assumes you've already taken from the DB
863
+	 * representation using $field_obj->prepare_for_set_from_db())
864
+	 *
865
+	 * @param EE_Model_Field_Base $field_obj
866
+	 * @param mixed               $value  as it's stored on a model object
867
+	 * @param string              $format valid values are 'normal' (default), 'pretty', 'datetime_obj'
868
+	 * @return mixed
869
+	 * @throws EE_Error
870 870
 */
871
-    protected function prepareFieldObjValueForJson(EE_Model_Field_Base $field_obj, $value, $format = 'normal')
872
-    {
873
-        $value = $field_obj->prepare_for_set_from_db($value);
874
-        switch ($format) {
875
-            case 'pretty':
876
-                $value = $field_obj->prepare_for_pretty_echoing($value);
877
-                break;
878
-            case 'normal':
879
-            default:
880
-                $value = $field_obj->prepare_for_get($value);
881
-                break;
882
-        }
883
-        return ModelDataTranslator::prepareFieldValuesForJson(
884
-            $field_obj,
885
-            $value,
886
-            $this->getModelVersionInfo()->requestedVersion()
887
-        );
888
-    }
889
-
890
-
891
-    /**
892
-     * Adds a few extra fields to the entity response
893
-     *
894
-     * @param EEM_Base $model
895
-     * @param array    $db_row
896
-     * @param array    $entity_array
897
-     * @return array modified entity
898
-     * @throws EE_Error
871
+	protected function prepareFieldObjValueForJson(EE_Model_Field_Base $field_obj, $value, $format = 'normal')
872
+	{
873
+		$value = $field_obj->prepare_for_set_from_db($value);
874
+		switch ($format) {
875
+			case 'pretty':
876
+				$value = $field_obj->prepare_for_pretty_echoing($value);
877
+				break;
878
+			case 'normal':
879
+			default:
880
+				$value = $field_obj->prepare_for_get($value);
881
+				break;
882
+		}
883
+		return ModelDataTranslator::prepareFieldValuesForJson(
884
+			$field_obj,
885
+			$value,
886
+			$this->getModelVersionInfo()->requestedVersion()
887
+		);
888
+	}
889
+
890
+
891
+	/**
892
+	 * Adds a few extra fields to the entity response
893
+	 *
894
+	 * @param EEM_Base $model
895
+	 * @param array    $db_row
896
+	 * @param array    $entity_array
897
+	 * @return array modified entity
898
+	 * @throws EE_Error
899 899
 */
900
-    protected function addExtraFields(EEM_Base $model, $db_row, $entity_array)
901
-    {
902
-        if ($model instanceof EEM_CPT_Base) {
903
-            $entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
904
-        }
905
-        return $entity_array;
906
-    }
907
-
908
-
909
-    /**
910
-     * Gets links we want to add to the response
911
-     *
912
-     * @param EEM_Base         $model
913
-     * @param array            $db_row
914
-     * @param array            $entity_array
915
-     * @return array the _links item in the entity
916
-     * @throws EE_Error
917
-     * @global WP_REST_Server $wp_rest_server
900
+	protected function addExtraFields(EEM_Base $model, $db_row, $entity_array)
901
+	{
902
+		if ($model instanceof EEM_CPT_Base) {
903
+			$entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
904
+		}
905
+		return $entity_array;
906
+	}
907
+
908
+
909
+	/**
910
+	 * Gets links we want to add to the response
911
+	 *
912
+	 * @param EEM_Base         $model
913
+	 * @param array            $db_row
914
+	 * @param array            $entity_array
915
+	 * @return array the _links item in the entity
916
+	 * @throws EE_Error
917
+	 * @global WP_REST_Server $wp_rest_server
918 918
 */
919
-    protected function getEntityLinks($model, $db_row, $entity_array)
920
-    {
921
-        // add basic links
922
-        $links = array();
923
-        if ($model->has_primary_key_field()) {
924
-            $links['self'] = array(
925
-                array(
926
-                    'href' => $this->getVersionedLinkTo(
927
-                        EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
928
-                        . '/'
929
-                        . $entity_array[ $model->primary_key_name() ]
930
-                    ),
931
-                ),
932
-            );
933
-        }
934
-        $links['collection'] = array(
935
-            array(
936
-                'href' => $this->getVersionedLinkTo(
937
-                    EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
938
-                ),
939
-            ),
940
-        );
941
-        // add links to related models
942
-        if ($model->has_primary_key_field()) {
943
-            foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
944
-                $related_model_part = Read::getRelatedEntityName($relation_name, $relation_obj);
945
-                $links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = array(
946
-                    array(
947
-                        'href'   => $this->getVersionedLinkTo(
948
-                            EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
949
-                            . '/'
950
-                            . $entity_array[ $model->primary_key_name() ]
951
-                            . '/'
952
-                            . $related_model_part
953
-                        ),
954
-                        'single' => $relation_obj instanceof EE_Belongs_To_Relation ? true : false,
955
-                    ),
956
-                );
957
-            }
958
-        }
959
-        return $links;
960
-    }
961
-
962
-
963
-    /**
964
-     * Adds the included models indicated in the request to the entity provided
965
-     *
966
-     * @param EEM_Base        $model
967
-     * @param WP_REST_Request $rest_request
968
-     * @param array           $entity_array
969
-     * @param array           $db_row
970
-     * @param boolean         $included_items_protected if the original item is password protected, don't include any related models.
971
-     * @return array the modified entity
972
-     * @throws EE_Error
973
-     * @throws InvalidArgumentException
974
-     * @throws InvalidDataTypeException
975
-     * @throws InvalidInterfaceException
976
-     * @throws ReflectionException
977
-     * @throws ModelConfigurationException
919
+	protected function getEntityLinks($model, $db_row, $entity_array)
920
+	{
921
+		// add basic links
922
+		$links = array();
923
+		if ($model->has_primary_key_field()) {
924
+			$links['self'] = array(
925
+				array(
926
+					'href' => $this->getVersionedLinkTo(
927
+						EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
928
+						. '/'
929
+						. $entity_array[ $model->primary_key_name() ]
930
+					),
931
+				),
932
+			);
933
+		}
934
+		$links['collection'] = array(
935
+			array(
936
+				'href' => $this->getVersionedLinkTo(
937
+					EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
938
+				),
939
+			),
940
+		);
941
+		// add links to related models
942
+		if ($model->has_primary_key_field()) {
943
+			foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
944
+				$related_model_part = Read::getRelatedEntityName($relation_name, $relation_obj);
945
+				$links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = array(
946
+					array(
947
+						'href'   => $this->getVersionedLinkTo(
948
+							EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
949
+							. '/'
950
+							. $entity_array[ $model->primary_key_name() ]
951
+							. '/'
952
+							. $related_model_part
953
+						),
954
+						'single' => $relation_obj instanceof EE_Belongs_To_Relation ? true : false,
955
+					),
956
+				);
957
+			}
958
+		}
959
+		return $links;
960
+	}
961
+
962
+
963
+	/**
964
+	 * Adds the included models indicated in the request to the entity provided
965
+	 *
966
+	 * @param EEM_Base        $model
967
+	 * @param WP_REST_Request $rest_request
968
+	 * @param array           $entity_array
969
+	 * @param array           $db_row
970
+	 * @param boolean         $included_items_protected if the original item is password protected, don't include any related models.
971
+	 * @return array the modified entity
972
+	 * @throws EE_Error
973
+	 * @throws InvalidArgumentException
974
+	 * @throws InvalidDataTypeException
975
+	 * @throws InvalidInterfaceException
976
+	 * @throws ReflectionException
977
+	 * @throws ModelConfigurationException
978 978
 */
979
-    protected function includeRequestedModels(
980
-        EEM_Base $model,
981
-        WP_REST_Request $rest_request,
982
-        $entity_array,
983
-        $db_row = array(),
984
-        $included_items_protected = false
985
-    ) {
986
-        // if $db_row not included, hope the entity array has what we need
987
-        if (! $db_row) {
988
-            $db_row = $entity_array;
989
-        }
990
-        $relation_settings = $this->getModelVersionInfo()->relationSettings($model);
991
-        foreach ($relation_settings as $relation_name => $relation_obj) {
992
-            $related_fields_to_include = $this->explodeAndGetItemsPrefixedWith(
993
-                $rest_request->get_param('include'),
994
-                $relation_name
995
-            );
996
-            $related_fields_to_calculate = $this->explodeAndGetItemsPrefixedWith(
997
-                $rest_request->get_param('calculate'),
998
-                $relation_name
999
-            );
1000
-            // did they specify they wanted to include a related model, or
1001
-            // specific fields from a related model?
1002
-            // or did they specify to calculate a field from a related model?
1003
-            if ($related_fields_to_include || $related_fields_to_calculate) {
1004
-                // if so, we should include at least some part of the related model
1005
-                $pretend_related_request = new WP_REST_Request();
1006
-                $pretend_related_request->set_query_params(
1007
-                    array(
1008
-                        'caps'      => $rest_request->get_param('caps'),
1009
-                        'include'   => $related_fields_to_include,
1010
-                        'calculate' => $related_fields_to_calculate,
1011
-                        'password' => $rest_request->get_param('password')
1012
-                    )
1013
-                );
1014
-                $pretend_related_request->add_header('no_rest_headers', true);
1015
-                $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
1016
-                    $model->get_index_primary_key_string(
1017
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
1018
-                    )
1019
-                );
1020
-                if (! $included_items_protected) {
1021
-                    try {
1022
-                        $related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1023
-                            $primary_model_query_params,
1024
-                            $relation_obj,
1025
-                            $pretend_related_request
1026
-                        );
1027
-                    } catch (RestException $e) {
1028
-                        $related_results = null;
1029
-                    }
1030
-                } else {
1031
-                    // they're protected, hide them.
1032
-                    $related_results = null;
1033
-                    $entity_array['_protected'][] = Read::getRelatedEntityName($relation_name, $relation_obj);
1034
-                }
1035
-                if ($related_results instanceof WP_Error || $related_results === null) {
1036
-                    $related_results = $relation_obj instanceof EE_Belongs_To_Relation ? null : array();
1037
-                }
1038
-                $entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1039
-            }
1040
-        }
1041
-        return $entity_array;
1042
-    }
1043
-
1044
-    /**
1045
-     * If the user has requested only specific properties (including meta properties like _links or _protected)
1046
-     * remove everything else.
1047
-     * @since 4.9.74.p
1048
-     * @param EEM_Base $model
1049
-     * @param WP_REST_Request $rest_request
1050
-     * @param $entity_array
1051
-     * @return array
1052
-     * @throws EE_Error
1053
-     */
1054
-    protected function includeOnlyRequestedProperties(
1055
-        EEM_Base $model,
1056
-        WP_REST_Request $rest_request,
1057
-        $entity_array
1058
-    ) {
1059
-
1060
-        $includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1061
-        $includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1062
-        // if they passed in * or didn't specify any includes, return everything
1063
-        if (! in_array('*', $includes_for_this_model)
1064
-            && ! empty($includes_for_this_model)
1065
-        ) {
1066
-            if ($model->has_primary_key_field()) {
1067
-                // always include the primary key. ya just gotta know that at least
1068
-                $includes_for_this_model[] = $model->primary_key_name();
1069
-            }
1070
-            if ($this->explodeAndGetItemsPrefixedWith($rest_request->get_param('calculate'), '')) {
1071
-                $includes_for_this_model[] = '_calculated_fields';
1072
-            }
1073
-            $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
1074
-        }
1075
-        return $entity_array;
1076
-    }
1077
-
1078
-
1079
-    /**
1080
-     * Returns a new array with all the names of models removed. Eg
1081
-     * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
1082
-     *
1083
-     * @param array $arr
1084
-     * @return array
1085
-     */
1086
-    private function removeModelNamesFromArray($arr)
1087
-    {
1088
-        return array_diff($arr, array_keys(EE_Registry::instance()->non_abstract_db_models));
1089
-    }
1090
-
1091
-
1092
-    /**
1093
-     * Gets the calculated fields for the response
1094
-     *
1095
-     * @param EEM_Base        $model
1096
-     * @param array           $wpdb_row
1097
-     * @param WP_REST_Request $rest_request
1098
-     * @param boolean         $row_is_protected whether this row is password protected or not
1099
-     * @return \stdClass the _calculations item in the entity
1100
-     * @throws EE_Error
1101
-     * @throws UnexpectedEntityException
979
+	protected function includeRequestedModels(
980
+		EEM_Base $model,
981
+		WP_REST_Request $rest_request,
982
+		$entity_array,
983
+		$db_row = array(),
984
+		$included_items_protected = false
985
+	) {
986
+		// if $db_row not included, hope the entity array has what we need
987
+		if (! $db_row) {
988
+			$db_row = $entity_array;
989
+		}
990
+		$relation_settings = $this->getModelVersionInfo()->relationSettings($model);
991
+		foreach ($relation_settings as $relation_name => $relation_obj) {
992
+			$related_fields_to_include = $this->explodeAndGetItemsPrefixedWith(
993
+				$rest_request->get_param('include'),
994
+				$relation_name
995
+			);
996
+			$related_fields_to_calculate = $this->explodeAndGetItemsPrefixedWith(
997
+				$rest_request->get_param('calculate'),
998
+				$relation_name
999
+			);
1000
+			// did they specify they wanted to include a related model, or
1001
+			// specific fields from a related model?
1002
+			// or did they specify to calculate a field from a related model?
1003
+			if ($related_fields_to_include || $related_fields_to_calculate) {
1004
+				// if so, we should include at least some part of the related model
1005
+				$pretend_related_request = new WP_REST_Request();
1006
+				$pretend_related_request->set_query_params(
1007
+					array(
1008
+						'caps'      => $rest_request->get_param('caps'),
1009
+						'include'   => $related_fields_to_include,
1010
+						'calculate' => $related_fields_to_calculate,
1011
+						'password' => $rest_request->get_param('password')
1012
+					)
1013
+				);
1014
+				$pretend_related_request->add_header('no_rest_headers', true);
1015
+				$primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
1016
+					$model->get_index_primary_key_string(
1017
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
1018
+					)
1019
+				);
1020
+				if (! $included_items_protected) {
1021
+					try {
1022
+						$related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1023
+							$primary_model_query_params,
1024
+							$relation_obj,
1025
+							$pretend_related_request
1026
+						);
1027
+					} catch (RestException $e) {
1028
+						$related_results = null;
1029
+					}
1030
+				} else {
1031
+					// they're protected, hide them.
1032
+					$related_results = null;
1033
+					$entity_array['_protected'][] = Read::getRelatedEntityName($relation_name, $relation_obj);
1034
+				}
1035
+				if ($related_results instanceof WP_Error || $related_results === null) {
1036
+					$related_results = $relation_obj instanceof EE_Belongs_To_Relation ? null : array();
1037
+				}
1038
+				$entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1039
+			}
1040
+		}
1041
+		return $entity_array;
1042
+	}
1043
+
1044
+	/**
1045
+	 * If the user has requested only specific properties (including meta properties like _links or _protected)
1046
+	 * remove everything else.
1047
+	 * @since 4.9.74.p
1048
+	 * @param EEM_Base $model
1049
+	 * @param WP_REST_Request $rest_request
1050
+	 * @param $entity_array
1051
+	 * @return array
1052
+	 * @throws EE_Error
1053
+	 */
1054
+	protected function includeOnlyRequestedProperties(
1055
+		EEM_Base $model,
1056
+		WP_REST_Request $rest_request,
1057
+		$entity_array
1058
+	) {
1059
+
1060
+		$includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1061
+		$includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1062
+		// if they passed in * or didn't specify any includes, return everything
1063
+		if (! in_array('*', $includes_for_this_model)
1064
+			&& ! empty($includes_for_this_model)
1065
+		) {
1066
+			if ($model->has_primary_key_field()) {
1067
+				// always include the primary key. ya just gotta know that at least
1068
+				$includes_for_this_model[] = $model->primary_key_name();
1069
+			}
1070
+			if ($this->explodeAndGetItemsPrefixedWith($rest_request->get_param('calculate'), '')) {
1071
+				$includes_for_this_model[] = '_calculated_fields';
1072
+			}
1073
+			$entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
1074
+		}
1075
+		return $entity_array;
1076
+	}
1077
+
1078
+
1079
+	/**
1080
+	 * Returns a new array with all the names of models removed. Eg
1081
+	 * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
1082
+	 *
1083
+	 * @param array $arr
1084
+	 * @return array
1085
+	 */
1086
+	private function removeModelNamesFromArray($arr)
1087
+	{
1088
+		return array_diff($arr, array_keys(EE_Registry::instance()->non_abstract_db_models));
1089
+	}
1090
+
1091
+
1092
+	/**
1093
+	 * Gets the calculated fields for the response
1094
+	 *
1095
+	 * @param EEM_Base        $model
1096
+	 * @param array           $wpdb_row
1097
+	 * @param WP_REST_Request $rest_request
1098
+	 * @param boolean         $row_is_protected whether this row is password protected or not
1099
+	 * @return \stdClass the _calculations item in the entity
1100
+	 * @throws EE_Error
1101
+	 * @throws UnexpectedEntityException
1102 1102
 */
1103
-    protected function getEntityCalculations($model, $wpdb_row, $rest_request, $row_is_protected = false)
1104
-    {
1105
-        $calculated_fields = $this->explodeAndGetItemsPrefixedWith(
1106
-            $rest_request->get_param('calculate'),
1107
-            ''
1108
-        );
1109
-        // note: setting calculate=* doesn't do anything
1110
-        $calculated_fields_to_return = new \stdClass();
1111
-        $protected_fields = array();
1112
-        foreach ($calculated_fields as $field_to_calculate) {
1113
-            try {
1114
-                // it's password protected, so they shouldn't be able to read this. Remove the value
1115
-                $schema = $this->fields_calculator->getJsonSchemaForModel($model);
1116
-                if ($row_is_protected
1117
-                    && isset($schema['properties'][ $field_to_calculate ]['protected'])
1118
-                    && $schema['properties'][ $field_to_calculate ]['protected']) {
1119
-                    $calculated_value = null;
1120
-                    $protected_fields[] = $field_to_calculate;
1121
-                    if ($schema['properties'][ $field_to_calculate ]['type']) {
1122
-                        switch ($schema['properties'][ $field_to_calculate ]['type']) {
1123
-                            case 'boolean':
1124
-                                $calculated_value = false;
1125
-                                break;
1126
-                            case 'integer':
1127
-                                $calculated_value = 0;
1128
-                                break;
1129
-                            case 'string':
1130
-                                $calculated_value = '';
1131
-                                break;
1132
-                            case 'array':
1133
-                                $calculated_value = array();
1134
-                                break;
1135
-                            case 'object':
1136
-                                $calculated_value = new stdClass();
1137
-                                break;
1138
-                        }
1139
-                    }
1140
-                } else {
1141
-                    $calculated_value = ModelDataTranslator::prepareFieldValueForJson(
1142
-                        null,
1143
-                        $this->fields_calculator->retrieveCalculatedFieldValue(
1144
-                            $model,
1145
-                            $field_to_calculate,
1146
-                            $wpdb_row,
1147
-                            $rest_request,
1148
-                            $this
1149
-                        ),
1150
-                        $this->getModelVersionInfo()->requestedVersion()
1151
-                    );
1152
-                }
1153
-                $calculated_fields_to_return->{$field_to_calculate} = $calculated_value;
1154
-            } catch (RestException $e) {
1155
-                // if we don't have permission to read it, just leave it out. but let devs know about the problem
1156
-                $this->setResponseHeader(
1157
-                    'Notices-Field-Calculation-Errors['
1158
-                    . $e->getStringCode()
1159
-                    . ']['
1160
-                    . $model->get_this_model_name()
1161
-                    . ']['
1162
-                    . $field_to_calculate
1163
-                    . ']',
1164
-                    $e->getMessage(),
1165
-                    true
1166
-                );
1167
-            }
1168
-        }
1169
-        $calculated_fields_to_return->_protected = $protected_fields;
1170
-        return $calculated_fields_to_return;
1171
-    }
1172
-
1173
-
1174
-    /**
1175
-     * Gets the full URL to the resource, taking the requested version into account
1176
-     *
1177
-     * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
1178
-     * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
1179
-     * @throws EE_Error
1103
+	protected function getEntityCalculations($model, $wpdb_row, $rest_request, $row_is_protected = false)
1104
+	{
1105
+		$calculated_fields = $this->explodeAndGetItemsPrefixedWith(
1106
+			$rest_request->get_param('calculate'),
1107
+			''
1108
+		);
1109
+		// note: setting calculate=* doesn't do anything
1110
+		$calculated_fields_to_return = new \stdClass();
1111
+		$protected_fields = array();
1112
+		foreach ($calculated_fields as $field_to_calculate) {
1113
+			try {
1114
+				// it's password protected, so they shouldn't be able to read this. Remove the value
1115
+				$schema = $this->fields_calculator->getJsonSchemaForModel($model);
1116
+				if ($row_is_protected
1117
+					&& isset($schema['properties'][ $field_to_calculate ]['protected'])
1118
+					&& $schema['properties'][ $field_to_calculate ]['protected']) {
1119
+					$calculated_value = null;
1120
+					$protected_fields[] = $field_to_calculate;
1121
+					if ($schema['properties'][ $field_to_calculate ]['type']) {
1122
+						switch ($schema['properties'][ $field_to_calculate ]['type']) {
1123
+							case 'boolean':
1124
+								$calculated_value = false;
1125
+								break;
1126
+							case 'integer':
1127
+								$calculated_value = 0;
1128
+								break;
1129
+							case 'string':
1130
+								$calculated_value = '';
1131
+								break;
1132
+							case 'array':
1133
+								$calculated_value = array();
1134
+								break;
1135
+							case 'object':
1136
+								$calculated_value = new stdClass();
1137
+								break;
1138
+						}
1139
+					}
1140
+				} else {
1141
+					$calculated_value = ModelDataTranslator::prepareFieldValueForJson(
1142
+						null,
1143
+						$this->fields_calculator->retrieveCalculatedFieldValue(
1144
+							$model,
1145
+							$field_to_calculate,
1146
+							$wpdb_row,
1147
+							$rest_request,
1148
+							$this
1149
+						),
1150
+						$this->getModelVersionInfo()->requestedVersion()
1151
+					);
1152
+				}
1153
+				$calculated_fields_to_return->{$field_to_calculate} = $calculated_value;
1154
+			} catch (RestException $e) {
1155
+				// if we don't have permission to read it, just leave it out. but let devs know about the problem
1156
+				$this->setResponseHeader(
1157
+					'Notices-Field-Calculation-Errors['
1158
+					. $e->getStringCode()
1159
+					. ']['
1160
+					. $model->get_this_model_name()
1161
+					. ']['
1162
+					. $field_to_calculate
1163
+					. ']',
1164
+					$e->getMessage(),
1165
+					true
1166
+				);
1167
+			}
1168
+		}
1169
+		$calculated_fields_to_return->_protected = $protected_fields;
1170
+		return $calculated_fields_to_return;
1171
+	}
1172
+
1173
+
1174
+	/**
1175
+	 * Gets the full URL to the resource, taking the requested version into account
1176
+	 *
1177
+	 * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
1178
+	 * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
1179
+	 * @throws EE_Error
1180 1180
 */
1181
-    public function getVersionedLinkTo($link_part_after_version_and_slash)
1182
-    {
1183
-        return rest_url(
1184
-            EED_Core_Rest_Api::get_versioned_route_to(
1185
-                $link_part_after_version_and_slash,
1186
-                $this->getModelVersionInfo()->requestedVersion()
1187
-            )
1188
-        );
1189
-    }
1190
-
1191
-
1192
-    /**
1193
-     * Gets the correct lowercase name for the relation in the API according
1194
-     * to the relation's type
1195
-     *
1196
-     * @param string                  $relation_name
1197
-     * @param EE_Model_Relation_Base $relation_obj
1198
-     * @return string
1199
-     */
1200
-    public static function getRelatedEntityName($relation_name, $relation_obj)
1201
-    {
1202
-        if ($relation_obj instanceof EE_Belongs_To_Relation) {
1203
-            return strtolower($relation_name);
1204
-        } else {
1205
-            return EEH_Inflector::pluralize_and_lower($relation_name);
1206
-        }
1207
-    }
1208
-
1209
-
1210
-    /**
1211
-     * Gets the one model object with the specified id for the specified model
1212
-     *
1213
-     * @param EEM_Base        $model
1214
-     * @param WP_REST_Request $request
1215
-     * @return array
1216
-     * @throws EE_Error
1217
-     * @throws InvalidArgumentException
1218
-     * @throws InvalidDataTypeException
1219
-     * @throws InvalidInterfaceException
1220
-     * @throws ReflectionException
1221
-     * @throws RestException
1181
+	public function getVersionedLinkTo($link_part_after_version_and_slash)
1182
+	{
1183
+		return rest_url(
1184
+			EED_Core_Rest_Api::get_versioned_route_to(
1185
+				$link_part_after_version_and_slash,
1186
+				$this->getModelVersionInfo()->requestedVersion()
1187
+			)
1188
+		);
1189
+	}
1190
+
1191
+
1192
+	/**
1193
+	 * Gets the correct lowercase name for the relation in the API according
1194
+	 * to the relation's type
1195
+	 *
1196
+	 * @param string                  $relation_name
1197
+	 * @param EE_Model_Relation_Base $relation_obj
1198
+	 * @return string
1199
+	 */
1200
+	public static function getRelatedEntityName($relation_name, $relation_obj)
1201
+	{
1202
+		if ($relation_obj instanceof EE_Belongs_To_Relation) {
1203
+			return strtolower($relation_name);
1204
+		} else {
1205
+			return EEH_Inflector::pluralize_and_lower($relation_name);
1206
+		}
1207
+	}
1208
+
1209
+
1210
+	/**
1211
+	 * Gets the one model object with the specified id for the specified model
1212
+	 *
1213
+	 * @param EEM_Base        $model
1214
+	 * @param WP_REST_Request $request
1215
+	 * @return array
1216
+	 * @throws EE_Error
1217
+	 * @throws InvalidArgumentException
1218
+	 * @throws InvalidDataTypeException
1219
+	 * @throws InvalidInterfaceException
1220
+	 * @throws ReflectionException
1221
+	 * @throws RestException
1222 1222
 */
1223
-    public function getEntityFromModel($model, $request)
1224
-    {
1225
-        $context = $this->validateContext($request->get_param('caps'));
1226
-        return $this->getOneOrReportPermissionError($model, $request, $context);
1227
-    }
1228
-
1229
-
1230
-    /**
1231
-     * If a context is provided which isn't valid, maybe it was added in a future
1232
-     * version so just treat it as a default read
1233
-     *
1234
-     * @param string $context
1235
-     * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
1236
-     */
1237
-    public function validateContext($context)
1238
-    {
1239
-        if (! $context) {
1240
-            $context = EEM_Base::caps_read;
1241
-        }
1242
-        $valid_contexts = EEM_Base::valid_cap_contexts();
1243
-        if (in_array($context, $valid_contexts)) {
1244
-            return $context;
1245
-        } else {
1246
-            return EEM_Base::caps_read;
1247
-        }
1248
-    }
1249
-
1250
-
1251
-    /**
1252
-     * Verifies the passed in value is an allowable default where conditions value.
1253
-     *
1254
-     * @param $default_query_params
1255
-     * @return string
1256
-     */
1257
-    public function validateDefaultQueryParams($default_query_params)
1258
-    {
1259
-        $valid_default_where_conditions_for_api_calls = array(
1260
-            EEM_Base::default_where_conditions_all,
1261
-            EEM_Base::default_where_conditions_minimum_all,
1262
-            EEM_Base::default_where_conditions_minimum_others,
1263
-        );
1264
-        if (! $default_query_params) {
1265
-            $default_query_params = EEM_Base::default_where_conditions_all;
1266
-        }
1267
-        if (in_array(
1268
-            $default_query_params,
1269
-            $valid_default_where_conditions_for_api_calls,
1270
-            true
1271
-        )) {
1272
-            return $default_query_params;
1273
-        } else {
1274
-            return EEM_Base::default_where_conditions_all;
1275
-        }
1276
-    }
1277
-
1278
-
1279
-    /**
1280
-     * Translates API filter get parameter into model query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions.
1281
-     * Note: right now the query parameter keys for fields (and related fields)
1282
-     * can be left as-is, but it's quite possible this will change someday.
1283
-     * Also, this method's contents might be candidate for moving to Model_Data_Translator
1284
-     *
1285
-     * @param EEM_Base $model
1286
-     * @param          $query_params
1287
-     * @return array model query params (@see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions)
1288
-     *                                    or FALSE to indicate that absolutely no results should be returned
1289
-     * @throws EE_Error
1290
-     * @throws InvalidArgumentException
1291
-     * @throws InvalidDataTypeException
1292
-     * @throws InvalidInterfaceException
1293
-     * @throws RestException
1294
-     * @throws DomainException
1223
+	public function getEntityFromModel($model, $request)
1224
+	{
1225
+		$context = $this->validateContext($request->get_param('caps'));
1226
+		return $this->getOneOrReportPermissionError($model, $request, $context);
1227
+	}
1228
+
1229
+
1230
+	/**
1231
+	 * If a context is provided which isn't valid, maybe it was added in a future
1232
+	 * version so just treat it as a default read
1233
+	 *
1234
+	 * @param string $context
1235
+	 * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
1236
+	 */
1237
+	public function validateContext($context)
1238
+	{
1239
+		if (! $context) {
1240
+			$context = EEM_Base::caps_read;
1241
+		}
1242
+		$valid_contexts = EEM_Base::valid_cap_contexts();
1243
+		if (in_array($context, $valid_contexts)) {
1244
+			return $context;
1245
+		} else {
1246
+			return EEM_Base::caps_read;
1247
+		}
1248
+	}
1249
+
1250
+
1251
+	/**
1252
+	 * Verifies the passed in value is an allowable default where conditions value.
1253
+	 *
1254
+	 * @param $default_query_params
1255
+	 * @return string
1256
+	 */
1257
+	public function validateDefaultQueryParams($default_query_params)
1258
+	{
1259
+		$valid_default_where_conditions_for_api_calls = array(
1260
+			EEM_Base::default_where_conditions_all,
1261
+			EEM_Base::default_where_conditions_minimum_all,
1262
+			EEM_Base::default_where_conditions_minimum_others,
1263
+		);
1264
+		if (! $default_query_params) {
1265
+			$default_query_params = EEM_Base::default_where_conditions_all;
1266
+		}
1267
+		if (in_array(
1268
+			$default_query_params,
1269
+			$valid_default_where_conditions_for_api_calls,
1270
+			true
1271
+		)) {
1272
+			return $default_query_params;
1273
+		} else {
1274
+			return EEM_Base::default_where_conditions_all;
1275
+		}
1276
+	}
1277
+
1278
+
1279
+	/**
1280
+	 * Translates API filter get parameter into model query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions.
1281
+	 * Note: right now the query parameter keys for fields (and related fields)
1282
+	 * can be left as-is, but it's quite possible this will change someday.
1283
+	 * Also, this method's contents might be candidate for moving to Model_Data_Translator
1284
+	 *
1285
+	 * @param EEM_Base $model
1286
+	 * @param          $query_params
1287
+	 * @return array model query params (@see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions)
1288
+	 *                                    or FALSE to indicate that absolutely no results should be returned
1289
+	 * @throws EE_Error
1290
+	 * @throws InvalidArgumentException
1291
+	 * @throws InvalidDataTypeException
1292
+	 * @throws InvalidInterfaceException
1293
+	 * @throws RestException
1294
+	 * @throws DomainException
1295 1295
 */
1296
-    public function createModelQueryParams($model, $query_params)
1297
-    {
1298
-        $model_query_params = array();
1299
-        if (isset($query_params['where'])) {
1300
-            $model_query_params[0] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1301
-                $query_params['where'],
1302
-                $model,
1303
-                $this->getModelVersionInfo()->requestedVersion()
1304
-            );
1305
-        }
1306
-        if (isset($query_params['order_by'])) {
1307
-            $order_by = $query_params['order_by'];
1308
-        } elseif (isset($query_params['orderby'])) {
1309
-            $order_by = $query_params['orderby'];
1310
-        } else {
1311
-            $order_by = null;
1312
-        }
1313
-        if ($order_by !== null) {
1314
-            if (is_array($order_by)) {
1315
-                $order_by = ModelDataTranslator::prepareFieldNamesInArrayKeysFromJson($order_by);
1316
-            } else {
1317
-                // it's a single item
1318
-                $order_by = ModelDataTranslator::prepareFieldNameFromJson($order_by);
1319
-            }
1320
-            $model_query_params['order_by'] = $order_by;
1321
-        }
1322
-        if (isset($query_params['group_by'])) {
1323
-            $group_by = $query_params['group_by'];
1324
-        } elseif (isset($query_params['groupby'])) {
1325
-            $group_by = $query_params['groupby'];
1326
-        } else {
1327
-            $group_by = array_keys($model->get_combined_primary_key_fields());
1328
-        }
1329
-        // make sure they're all real names
1330
-        if (is_array($group_by)) {
1331
-            $group_by = ModelDataTranslator::prepareFieldNamesFromJson($group_by);
1332
-        }
1333
-        if ($group_by !== null) {
1334
-            $model_query_params['group_by'] = $group_by;
1335
-        }
1336
-        if (isset($query_params['having'])) {
1337
-            $model_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1338
-                $query_params['having'],
1339
-                $model,
1340
-                $this->getModelVersionInfo()->requestedVersion()
1341
-            );
1342
-        }
1343
-        if (isset($query_params['order'])) {
1344
-            $model_query_params['order'] = $query_params['order'];
1345
-        }
1346
-        if (isset($query_params['mine'])) {
1347
-            $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1348
-        }
1349
-        if (isset($query_params['limit'])) {
1350
-            // limit should be either a string like '23' or '23,43', or an array with two items in it
1351
-            if (! is_array($query_params['limit'])) {
1352
-                $limit_array = explode(',', (string) $query_params['limit']);
1353
-            } else {
1354
-                $limit_array = $query_params['limit'];
1355
-            }
1356
-            $sanitized_limit = array();
1357
-            foreach ($limit_array as $key => $limit_part) {
1358
-                if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1359
-                    throw new EE_Error(
1360
-                        sprintf(
1361
-                            __(
1362
-                            // @codingStandardsIgnoreStart
1363
-                                'An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.',
1364
-                                // @codingStandardsIgnoreEnd
1365
-                                'event_espresso'
1366
-                            ),
1367
-                            wp_json_encode($query_params['limit'])
1368
-                        )
1369
-                    );
1370
-                }
1371
-                $sanitized_limit[] = (int) $limit_part;
1372
-            }
1373
-            $model_query_params['limit'] = implode(',', $sanitized_limit);
1374
-        } else {
1375
-            $model_query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
1376
-        }
1377
-        if (isset($query_params['caps'])) {
1378
-            $model_query_params['caps'] = $this->validateContext($query_params['caps']);
1379
-        } else {
1380
-            $model_query_params['caps'] = EEM_Base::caps_read;
1381
-        }
1382
-        if (isset($query_params['default_where_conditions'])) {
1383
-            $model_query_params['default_where_conditions'] = $this->validateDefaultQueryParams(
1384
-                $query_params['default_where_conditions']
1385
-            );
1386
-        }
1387
-        // if this is a model protected by a password on another model, exclude the password protected
1388
-        // entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1389
-        // though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1390
-        if (! $model->hasPassword()
1391
-            && $model->restrictedByRelatedModelPassword()
1392
-            && $model_query_params['caps'] === EEM_Base::caps_read) {
1393
-            if (empty($query_params['password'])) {
1394
-                $model_query_params['exclude_protected'] = true;
1395
-            }
1396
-        }
1397
-
1398
-        return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_params, $model);
1399
-    }
1400
-
1401
-
1402
-    /**
1403
-     * Changes the REST-style query params for use in the models
1404
-     *
1405
-     * @deprecated
1406
-     * @param EEM_Base $model
1407
-     * @param array    $query_params sub-array from @see EEM_Base::get_all()
1408
-     * @return array
1409
-     */
1410
-    public function prepareRestQueryParamsKeyForModels($model, $query_params)
1411
-    {
1412
-        $model_ready_query_params = array();
1413
-        foreach ($query_params as $key => $value) {
1414
-            if (is_array($value)) {
1415
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsKeyForModels($model, $value);
1416
-            } else {
1417
-                $model_ready_query_params[ $key ] = $value;
1418
-            }
1419
-        }
1420
-        return $model_ready_query_params;
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * @deprecated instead use ModelDataTranslator::prepareFieldValuesFromJson()
1426
-     * @param $model
1427
-     * @param $query_params
1428
-     * @return array
1429
-     */
1430
-    public function prepareRestQueryParamsValuesForModels($model, $query_params)
1431
-    {
1432
-        $model_ready_query_params = array();
1433
-        foreach ($query_params as $key => $value) {
1434
-            if (is_array($value)) {
1435
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1436
-            } else {
1437
-                $model_ready_query_params[ $key ] = $value;
1438
-            }
1439
-        }
1440
-        return $model_ready_query_params;
1441
-    }
1442
-
1443
-
1444
-    /**
1445
-     * Explodes the string on commas, and only returns items with $prefix followed by a period.
1446
-     * If no prefix is specified, returns items with no period.
1447
-     *
1448
-     * @param string|array $string_to_explode eg "jibba,jabba, blah, blah, blah" or array('jibba', 'jabba' )
1449
-     * @param string       $prefix            "Event" or "foobar"
1450
-     * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1451
-     *                                        we only return strings starting with that and a period; if no prefix was
1452
-     *                                        specified we return all items containing NO periods
1453
-     */
1454
-    public function explodeAndGetItemsPrefixedWith($string_to_explode, $prefix)
1455
-    {
1456
-        if (is_string($string_to_explode)) {
1457
-            $exploded_contents = explode(',', $string_to_explode);
1458
-        } elseif (is_array($string_to_explode)) {
1459
-            $exploded_contents = $string_to_explode;
1460
-        } else {
1461
-            $exploded_contents = array();
1462
-        }
1463
-        // if the string was empty, we want an empty array
1464
-        $exploded_contents = array_filter($exploded_contents);
1465
-        $contents_with_prefix = array();
1466
-        foreach ($exploded_contents as $item) {
1467
-            $item = trim($item);
1468
-            // if no prefix was provided, so we look for items with no "." in them
1469
-            if (! $prefix) {
1470
-                // does this item have a period?
1471
-                if (strpos($item, '.') === false) {
1472
-                    // if not, then its what we're looking for
1473
-                    $contents_with_prefix[] = $item;
1474
-                }
1475
-            } elseif (strpos($item, $prefix . '.') === 0) {
1476
-                // this item has the prefix and a period, grab it
1477
-                $contents_with_prefix[] = substr(
1478
-                    $item,
1479
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1480
-                );
1481
-            } elseif ($item === $prefix) {
1482
-                // this item is JUST the prefix
1483
-                // so let's grab everything after, which is a blank string
1484
-                $contents_with_prefix[] = '';
1485
-            }
1486
-        }
1487
-        return $contents_with_prefix;
1488
-    }
1489
-
1490
-
1491
-    /**
1492
-     * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1493
-     * Deprecated because its return values were really quite confusing- sometimes it returned
1494
-     * an empty array (when the include string was blank or '*') or sometimes it returned
1495
-     * array('*') (when you provided a model and a model of that kind was found).
1496
-     * Parses the $include_string so we fetch all the field names relating to THIS model
1497
-     * (ie have NO period in them), or for the provided model (ie start with the model
1498
-     * name and then a period).
1499
-     * @param string $include_string @see Read:handle_request_get_all
1500
-     * @param string $model_name
1501
-     * @return array of fields for this model. If $model_name is provided, then
1502
-     *                               the fields for that model, with the model's name removed from each.
1503
-     *                               If $include_string was blank or '*' returns an empty array
1504
-     * @throws EE_Error
1296
+	public function createModelQueryParams($model, $query_params)
1297
+	{
1298
+		$model_query_params = array();
1299
+		if (isset($query_params['where'])) {
1300
+			$model_query_params[0] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1301
+				$query_params['where'],
1302
+				$model,
1303
+				$this->getModelVersionInfo()->requestedVersion()
1304
+			);
1305
+		}
1306
+		if (isset($query_params['order_by'])) {
1307
+			$order_by = $query_params['order_by'];
1308
+		} elseif (isset($query_params['orderby'])) {
1309
+			$order_by = $query_params['orderby'];
1310
+		} else {
1311
+			$order_by = null;
1312
+		}
1313
+		if ($order_by !== null) {
1314
+			if (is_array($order_by)) {
1315
+				$order_by = ModelDataTranslator::prepareFieldNamesInArrayKeysFromJson($order_by);
1316
+			} else {
1317
+				// it's a single item
1318
+				$order_by = ModelDataTranslator::prepareFieldNameFromJson($order_by);
1319
+			}
1320
+			$model_query_params['order_by'] = $order_by;
1321
+		}
1322
+		if (isset($query_params['group_by'])) {
1323
+			$group_by = $query_params['group_by'];
1324
+		} elseif (isset($query_params['groupby'])) {
1325
+			$group_by = $query_params['groupby'];
1326
+		} else {
1327
+			$group_by = array_keys($model->get_combined_primary_key_fields());
1328
+		}
1329
+		// make sure they're all real names
1330
+		if (is_array($group_by)) {
1331
+			$group_by = ModelDataTranslator::prepareFieldNamesFromJson($group_by);
1332
+		}
1333
+		if ($group_by !== null) {
1334
+			$model_query_params['group_by'] = $group_by;
1335
+		}
1336
+		if (isset($query_params['having'])) {
1337
+			$model_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1338
+				$query_params['having'],
1339
+				$model,
1340
+				$this->getModelVersionInfo()->requestedVersion()
1341
+			);
1342
+		}
1343
+		if (isset($query_params['order'])) {
1344
+			$model_query_params['order'] = $query_params['order'];
1345
+		}
1346
+		if (isset($query_params['mine'])) {
1347
+			$model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1348
+		}
1349
+		if (isset($query_params['limit'])) {
1350
+			// limit should be either a string like '23' or '23,43', or an array with two items in it
1351
+			if (! is_array($query_params['limit'])) {
1352
+				$limit_array = explode(',', (string) $query_params['limit']);
1353
+			} else {
1354
+				$limit_array = $query_params['limit'];
1355
+			}
1356
+			$sanitized_limit = array();
1357
+			foreach ($limit_array as $key => $limit_part) {
1358
+				if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1359
+					throw new EE_Error(
1360
+						sprintf(
1361
+							__(
1362
+							// @codingStandardsIgnoreStart
1363
+								'An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.',
1364
+								// @codingStandardsIgnoreEnd
1365
+								'event_espresso'
1366
+							),
1367
+							wp_json_encode($query_params['limit'])
1368
+						)
1369
+					);
1370
+				}
1371
+				$sanitized_limit[] = (int) $limit_part;
1372
+			}
1373
+			$model_query_params['limit'] = implode(',', $sanitized_limit);
1374
+		} else {
1375
+			$model_query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
1376
+		}
1377
+		if (isset($query_params['caps'])) {
1378
+			$model_query_params['caps'] = $this->validateContext($query_params['caps']);
1379
+		} else {
1380
+			$model_query_params['caps'] = EEM_Base::caps_read;
1381
+		}
1382
+		if (isset($query_params['default_where_conditions'])) {
1383
+			$model_query_params['default_where_conditions'] = $this->validateDefaultQueryParams(
1384
+				$query_params['default_where_conditions']
1385
+			);
1386
+		}
1387
+		// if this is a model protected by a password on another model, exclude the password protected
1388
+		// entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1389
+		// though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1390
+		if (! $model->hasPassword()
1391
+			&& $model->restrictedByRelatedModelPassword()
1392
+			&& $model_query_params['caps'] === EEM_Base::caps_read) {
1393
+			if (empty($query_params['password'])) {
1394
+				$model_query_params['exclude_protected'] = true;
1395
+			}
1396
+		}
1397
+
1398
+		return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_params, $model);
1399
+	}
1400
+
1401
+
1402
+	/**
1403
+	 * Changes the REST-style query params for use in the models
1404
+	 *
1405
+	 * @deprecated
1406
+	 * @param EEM_Base $model
1407
+	 * @param array    $query_params sub-array from @see EEM_Base::get_all()
1408
+	 * @return array
1409
+	 */
1410
+	public function prepareRestQueryParamsKeyForModels($model, $query_params)
1411
+	{
1412
+		$model_ready_query_params = array();
1413
+		foreach ($query_params as $key => $value) {
1414
+			if (is_array($value)) {
1415
+				$model_ready_query_params[ $key ] = $this->prepareRestQueryParamsKeyForModels($model, $value);
1416
+			} else {
1417
+				$model_ready_query_params[ $key ] = $value;
1418
+			}
1419
+		}
1420
+		return $model_ready_query_params;
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * @deprecated instead use ModelDataTranslator::prepareFieldValuesFromJson()
1426
+	 * @param $model
1427
+	 * @param $query_params
1428
+	 * @return array
1429
+	 */
1430
+	public function prepareRestQueryParamsValuesForModels($model, $query_params)
1431
+	{
1432
+		$model_ready_query_params = array();
1433
+		foreach ($query_params as $key => $value) {
1434
+			if (is_array($value)) {
1435
+				$model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1436
+			} else {
1437
+				$model_ready_query_params[ $key ] = $value;
1438
+			}
1439
+		}
1440
+		return $model_ready_query_params;
1441
+	}
1442
+
1443
+
1444
+	/**
1445
+	 * Explodes the string on commas, and only returns items with $prefix followed by a period.
1446
+	 * If no prefix is specified, returns items with no period.
1447
+	 *
1448
+	 * @param string|array $string_to_explode eg "jibba,jabba, blah, blah, blah" or array('jibba', 'jabba' )
1449
+	 * @param string       $prefix            "Event" or "foobar"
1450
+	 * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1451
+	 *                                        we only return strings starting with that and a period; if no prefix was
1452
+	 *                                        specified we return all items containing NO periods
1453
+	 */
1454
+	public function explodeAndGetItemsPrefixedWith($string_to_explode, $prefix)
1455
+	{
1456
+		if (is_string($string_to_explode)) {
1457
+			$exploded_contents = explode(',', $string_to_explode);
1458
+		} elseif (is_array($string_to_explode)) {
1459
+			$exploded_contents = $string_to_explode;
1460
+		} else {
1461
+			$exploded_contents = array();
1462
+		}
1463
+		// if the string was empty, we want an empty array
1464
+		$exploded_contents = array_filter($exploded_contents);
1465
+		$contents_with_prefix = array();
1466
+		foreach ($exploded_contents as $item) {
1467
+			$item = trim($item);
1468
+			// if no prefix was provided, so we look for items with no "." in them
1469
+			if (! $prefix) {
1470
+				// does this item have a period?
1471
+				if (strpos($item, '.') === false) {
1472
+					// if not, then its what we're looking for
1473
+					$contents_with_prefix[] = $item;
1474
+				}
1475
+			} elseif (strpos($item, $prefix . '.') === 0) {
1476
+				// this item has the prefix and a period, grab it
1477
+				$contents_with_prefix[] = substr(
1478
+					$item,
1479
+					strpos($item, $prefix . '.') + strlen($prefix . '.')
1480
+				);
1481
+			} elseif ($item === $prefix) {
1482
+				// this item is JUST the prefix
1483
+				// so let's grab everything after, which is a blank string
1484
+				$contents_with_prefix[] = '';
1485
+			}
1486
+		}
1487
+		return $contents_with_prefix;
1488
+	}
1489
+
1490
+
1491
+	/**
1492
+	 * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1493
+	 * Deprecated because its return values were really quite confusing- sometimes it returned
1494
+	 * an empty array (when the include string was blank or '*') or sometimes it returned
1495
+	 * array('*') (when you provided a model and a model of that kind was found).
1496
+	 * Parses the $include_string so we fetch all the field names relating to THIS model
1497
+	 * (ie have NO period in them), or for the provided model (ie start with the model
1498
+	 * name and then a period).
1499
+	 * @param string $include_string @see Read:handle_request_get_all
1500
+	 * @param string $model_name
1501
+	 * @return array of fields for this model. If $model_name is provided, then
1502
+	 *                               the fields for that model, with the model's name removed from each.
1503
+	 *                               If $include_string was blank or '*' returns an empty array
1504
+	 * @throws EE_Error
1505 1505
 */
1506
-    public function extractIncludesForThisModel($include_string, $model_name = null)
1507
-    {
1508
-        if (is_array($include_string)) {
1509
-            $include_string = implode(',', $include_string);
1510
-        }
1511
-        if ($include_string === '*' || $include_string === '') {
1512
-            return array();
1513
-        }
1514
-        $includes = explode(',', $include_string);
1515
-        $extracted_fields_to_include = array();
1516
-        if ($model_name) {
1517
-            foreach ($includes as $field_to_include) {
1518
-                $field_to_include = trim($field_to_include);
1519
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1520
-                    // found the model name at the exact start
1521
-                    $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1522
-                    $extracted_fields_to_include[] = $field_sans_model_name;
1523
-                } elseif ($field_to_include == $model_name) {
1524
-                    $extracted_fields_to_include[] = '*';
1525
-                }
1526
-            }
1527
-        } else {
1528
-            // look for ones with no period
1529
-            foreach ($includes as $field_to_include) {
1530
-                $field_to_include = trim($field_to_include);
1531
-                if (strpos($field_to_include, '.') === false
1532
-                    && ! $this->getModelVersionInfo()->isModelNameInThisVersion($field_to_include)
1533
-                ) {
1534
-                    $extracted_fields_to_include[] = $field_to_include;
1535
-                }
1536
-            }
1537
-        }
1538
-        return $extracted_fields_to_include;
1539
-    }
1540
-
1541
-
1542
-    /**
1543
-     * Gets the single item using the model according to the request in the context given, otherwise
1544
-     * returns that it's inaccessible to the current user
1545
-     *
1546
-     * @param EEM_Base        $model
1547
-     * @param WP_REST_Request $request
1548
-     * @param null            $context
1549
-     * @return array
1550
-     * @throws EE_Error
1551
-     * @throws InvalidArgumentException
1552
-     * @throws InvalidDataTypeException
1553
-     * @throws InvalidInterfaceException
1554
-     * @throws ReflectionException
1555
-     * @throws RestException
1506
+	public function extractIncludesForThisModel($include_string, $model_name = null)
1507
+	{
1508
+		if (is_array($include_string)) {
1509
+			$include_string = implode(',', $include_string);
1510
+		}
1511
+		if ($include_string === '*' || $include_string === '') {
1512
+			return array();
1513
+		}
1514
+		$includes = explode(',', $include_string);
1515
+		$extracted_fields_to_include = array();
1516
+		if ($model_name) {
1517
+			foreach ($includes as $field_to_include) {
1518
+				$field_to_include = trim($field_to_include);
1519
+				if (strpos($field_to_include, $model_name . '.') === 0) {
1520
+					// found the model name at the exact start
1521
+					$field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1522
+					$extracted_fields_to_include[] = $field_sans_model_name;
1523
+				} elseif ($field_to_include == $model_name) {
1524
+					$extracted_fields_to_include[] = '*';
1525
+				}
1526
+			}
1527
+		} else {
1528
+			// look for ones with no period
1529
+			foreach ($includes as $field_to_include) {
1530
+				$field_to_include = trim($field_to_include);
1531
+				if (strpos($field_to_include, '.') === false
1532
+					&& ! $this->getModelVersionInfo()->isModelNameInThisVersion($field_to_include)
1533
+				) {
1534
+					$extracted_fields_to_include[] = $field_to_include;
1535
+				}
1536
+			}
1537
+		}
1538
+		return $extracted_fields_to_include;
1539
+	}
1540
+
1541
+
1542
+	/**
1543
+	 * Gets the single item using the model according to the request in the context given, otherwise
1544
+	 * returns that it's inaccessible to the current user
1545
+	 *
1546
+	 * @param EEM_Base        $model
1547
+	 * @param WP_REST_Request $request
1548
+	 * @param null            $context
1549
+	 * @return array
1550
+	 * @throws EE_Error
1551
+	 * @throws InvalidArgumentException
1552
+	 * @throws InvalidDataTypeException
1553
+	 * @throws InvalidInterfaceException
1554
+	 * @throws ReflectionException
1555
+	 * @throws RestException
1556 1556
 */
1557
-    public function getOneOrReportPermissionError(EEM_Base $model, WP_REST_Request $request, $context = null)
1558
-    {
1559
-        $query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
1560
-        if ($model instanceof EEM_Soft_Delete_Base) {
1561
-            $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
1562
-        }
1563
-        $restricted_query_params = $query_params;
1564
-        $restricted_query_params['caps'] = $context;
1565
-        $this->setDebugInfo('model query params', $restricted_query_params);
1566
-        $model_rows = $model->get_all_wpdb_results($restricted_query_params);
1567
-        if (! empty($model_rows)) {
1568
-            return $this->createEntityFromWpdbResult(
1569
-                $model,
1570
-                reset($model_rows),
1571
-                $request
1572
-            );
1573
-        } else {
1574
-            // ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
1575
-            $lowercase_model_name = strtolower($model->get_this_model_name());
1576
-            if ($model->exists($query_params)) {
1577
-                // you got shafted- it existed but we didn't want to tell you!
1578
-                throw new RestException(
1579
-                    'rest_user_cannot_' . $context,
1580
-                    sprintf(
1581
-                        __('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1582
-                        $context,
1583
-                        $lowercase_model_name,
1584
-                        Capabilities::getMissingPermissionsString(
1585
-                            $model,
1586
-                            $context
1587
-                        )
1588
-                    ),
1589
-                    array('status' => 403)
1590
-                );
1591
-            } else {
1592
-                // it's not you. It just doesn't exist
1593
-                throw new RestException(
1594
-                    sprintf('rest_%s_invalid_id', $lowercase_model_name),
1595
-                    sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
1596
-                    array('status' => 404)
1597
-                );
1598
-            }
1599
-        }
1600
-    }
1601
-
1602
-    /**
1603
-     * Checks that if this content requires a password to be read, that it's been provided and is correct.
1604
-     * @since 4.9.74.p
1605
-     * @param EEM_Base $model
1606
-     * @param $model_row
1607
-     * @param $query_params Adds 'default_where_conditions' => 'minimum' to ensure we don't confuse trashed with
1608
-     *                      password protected.
1609
-     * @param WP_REST_Request $request
1610
-     * @throws EE_Error
1611
-     * @throws InvalidArgumentException
1612
-     * @throws InvalidDataTypeException
1613
-     * @throws InvalidInterfaceException
1614
-     * @throws RestPasswordRequiredException
1615
-     * @throws RestPasswordIncorrectException
1616
-     * @throws ModelConfigurationException
1617
-     * @throws ReflectionException
1618
-     */
1619
-    protected function checkPassword(EEM_Base $model, $model_row, $query_params, WP_REST_Request $request)
1620
-    {
1621
-        $query_params['default_where_conditions'] = 'minimum';
1622
-        // stuff is only "protected" for front-end requests. Elsewhere, you either get full permission to access the object
1623
-        // or you don't.
1624
-        $request_caps = $request->get_param('caps');
1625
-        if (isset($request_caps) && $request_caps !== EEM_Base::caps_read) {
1626
-            return;
1627
-        }
1628
-        // if this entity requires a password, they better give it and it better be right!
1629
-        if ($model->hasPassword()
1630
-            && $model_row[ $model->getPasswordField()->get_qualified_column() ] !== '') {
1631
-            if (empty($request['password'])) {
1632
-                throw new RestPasswordRequiredException();
1633
-            } elseif (!hash_equals(
1634
-                $model_row[ $model->getPasswordField()->get_qualified_column() ],
1635
-                $request['password']
1636
-            )) {
1637
-                throw new RestPasswordIncorrectException();
1638
-            }
1639
-        } // wait! maybe this content is password protected
1640
-        elseif ($model->restrictedByRelatedModelPassword()
1641
-            && $request->get_param('caps') === EEM_Base::caps_read) {
1642
-            $password_supplied = $request->get_param('password');
1643
-            if (empty($password_supplied)) {
1644
-                $query_params['exclude_protected'] = true;
1645
-                if (!$model->exists($query_params)) {
1646
-                    throw new RestPasswordRequiredException();
1647
-                }
1648
-            } else {
1649
-                $query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1650
-                if (!$model->exists($query_params)) {
1651
-                    throw new RestPasswordIncorrectException();
1652
-                }
1653
-            }
1654
-        }
1655
-    }
1557
+	public function getOneOrReportPermissionError(EEM_Base $model, WP_REST_Request $request, $context = null)
1558
+	{
1559
+		$query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
1560
+		if ($model instanceof EEM_Soft_Delete_Base) {
1561
+			$query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
1562
+		}
1563
+		$restricted_query_params = $query_params;
1564
+		$restricted_query_params['caps'] = $context;
1565
+		$this->setDebugInfo('model query params', $restricted_query_params);
1566
+		$model_rows = $model->get_all_wpdb_results($restricted_query_params);
1567
+		if (! empty($model_rows)) {
1568
+			return $this->createEntityFromWpdbResult(
1569
+				$model,
1570
+				reset($model_rows),
1571
+				$request
1572
+			);
1573
+		} else {
1574
+			// ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
1575
+			$lowercase_model_name = strtolower($model->get_this_model_name());
1576
+			if ($model->exists($query_params)) {
1577
+				// you got shafted- it existed but we didn't want to tell you!
1578
+				throw new RestException(
1579
+					'rest_user_cannot_' . $context,
1580
+					sprintf(
1581
+						__('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1582
+						$context,
1583
+						$lowercase_model_name,
1584
+						Capabilities::getMissingPermissionsString(
1585
+							$model,
1586
+							$context
1587
+						)
1588
+					),
1589
+					array('status' => 403)
1590
+				);
1591
+			} else {
1592
+				// it's not you. It just doesn't exist
1593
+				throw new RestException(
1594
+					sprintf('rest_%s_invalid_id', $lowercase_model_name),
1595
+					sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
1596
+					array('status' => 404)
1597
+				);
1598
+			}
1599
+		}
1600
+	}
1601
+
1602
+	/**
1603
+	 * Checks that if this content requires a password to be read, that it's been provided and is correct.
1604
+	 * @since 4.9.74.p
1605
+	 * @param EEM_Base $model
1606
+	 * @param $model_row
1607
+	 * @param $query_params Adds 'default_where_conditions' => 'minimum' to ensure we don't confuse trashed with
1608
+	 *                      password protected.
1609
+	 * @param WP_REST_Request $request
1610
+	 * @throws EE_Error
1611
+	 * @throws InvalidArgumentException
1612
+	 * @throws InvalidDataTypeException
1613
+	 * @throws InvalidInterfaceException
1614
+	 * @throws RestPasswordRequiredException
1615
+	 * @throws RestPasswordIncorrectException
1616
+	 * @throws ModelConfigurationException
1617
+	 * @throws ReflectionException
1618
+	 */
1619
+	protected function checkPassword(EEM_Base $model, $model_row, $query_params, WP_REST_Request $request)
1620
+	{
1621
+		$query_params['default_where_conditions'] = 'minimum';
1622
+		// stuff is only "protected" for front-end requests. Elsewhere, you either get full permission to access the object
1623
+		// or you don't.
1624
+		$request_caps = $request->get_param('caps');
1625
+		if (isset($request_caps) && $request_caps !== EEM_Base::caps_read) {
1626
+			return;
1627
+		}
1628
+		// if this entity requires a password, they better give it and it better be right!
1629
+		if ($model->hasPassword()
1630
+			&& $model_row[ $model->getPasswordField()->get_qualified_column() ] !== '') {
1631
+			if (empty($request['password'])) {
1632
+				throw new RestPasswordRequiredException();
1633
+			} elseif (!hash_equals(
1634
+				$model_row[ $model->getPasswordField()->get_qualified_column() ],
1635
+				$request['password']
1636
+			)) {
1637
+				throw new RestPasswordIncorrectException();
1638
+			}
1639
+		} // wait! maybe this content is password protected
1640
+		elseif ($model->restrictedByRelatedModelPassword()
1641
+			&& $request->get_param('caps') === EEM_Base::caps_read) {
1642
+			$password_supplied = $request->get_param('password');
1643
+			if (empty($password_supplied)) {
1644
+				$query_params['exclude_protected'] = true;
1645
+				if (!$model->exists($query_params)) {
1646
+					throw new RestPasswordRequiredException();
1647
+				}
1648
+			} else {
1649
+				$query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1650
+				if (!$model->exists($query_params)) {
1651
+					throw new RestPasswordIncorrectException();
1652
+				}
1653
+			}
1654
+		}
1655
+	}
1656 1656
 }
Please login to merge, or discard this patch.
Spacing   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
         $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
87 87
         try {
88 88
             $controller->setRequestedVersion($version);
89
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
89
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
90 90
                 return $controller->sendResponse(
91 91
                     new WP_Error(
92 92
                         'endpoint_parsing_error',
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
         $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
129 129
         try {
130 130
             $controller->setRequestedVersion($version);
131
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
131
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
132 132
                 return array();
133 133
             }
134 134
             // get the model for this version
@@ -185,11 +185,11 @@  discard block
 block discarded – undo
185 185
      */
186 186
     protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema)
187 187
     {
188
-        if (isset($schema['properties'][ $field_name ]['default'])) {
189
-            if (is_array($schema['properties'][ $field_name ]['default'])) {
190
-                foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
188
+        if (isset($schema['properties'][$field_name]['default'])) {
189
+            if (is_array($schema['properties'][$field_name]['default'])) {
190
+                foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
191 191
                     if ($default_key === 'raw') {
192
-                        $schema['properties'][ $field_name ]['default'][ $default_key ] =
192
+                        $schema['properties'][$field_name]['default'][$default_key] =
193 193
                             ModelDataTranslator::prepareFieldValueForJson(
194 194
                                 $field,
195 195
                                 $default_value,
@@ -198,9 +198,9 @@  discard block
 block discarded – undo
198 198
                     }
199 199
                 }
200 200
             } else {
201
-                $schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
201
+                $schema['properties'][$field_name]['default'] = ModelDataTranslator::prepareFieldValueForJson(
202 202
                     $field,
203
-                    $schema['properties'][ $field_name ]['default'],
203
+                    $schema['properties'][$field_name]['default'],
204 204
                     $this->getModelVersionInfo()->requestedVersion()
205 205
                 );
206 206
             }
@@ -222,9 +222,9 @@  discard block
 block discarded – undo
222 222
     protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema)
223 223
     {
224 224
         if ($field instanceof EE_Datetime_Field) {
225
-            $schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
225
+            $schema['properties'][$field_name.'_gmt'] = $field->getSchema();
226 226
             // modify the description
227
-            $schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
227
+            $schema['properties'][$field_name.'_gmt']['description'] = sprintf(
228 228
                 esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
229 229
                 wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
230 230
             );
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
         $controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
268 268
         try {
269 269
             $controller->setRequestedVersion($version);
270
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
270
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
271 271
                 return $controller->sendResponse(
272 272
                     new WP_Error(
273 273
                         'endpoint_parsing_error',
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
     public function getEntitiesFromModel($model, $request)
347 347
     {
348 348
         $query_params = $this->createModelQueryParams($model, $request->get_params());
349
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
349
+        if ( ! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
350 350
             $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
351 351
             throw new RestException(
352 352
                 sprintf('rest_%s_cannot_list', $model_name_plural),
@@ -358,14 +358,14 @@  discard block
 block discarded – undo
358 358
                 array('status' => 403)
359 359
             );
360 360
         }
361
-        if (! $request->get_header('no_rest_headers')) {
361
+        if ( ! $request->get_header('no_rest_headers')) {
362 362
             $this->setHeadersFromQueryParams($model, $query_params);
363 363
         }
364 364
         /** @type array $results */
365 365
         $results = $model->get_all_wpdb_results($query_params);
366 366
         $nice_results = array();
367 367
         foreach ($results as $result) {
368
-            $nice_results[] =  $this->createEntityFromWpdbResult(
368
+            $nice_results[] = $this->createEntityFromWpdbResult(
369 369
                 $model,
370 370
                 $result,
371 371
                 $request
@@ -399,7 +399,7 @@  discard block
 block discarded – undo
399 399
         $context = $this->validateContext($request->get_param('caps'));
400 400
         $model = $relation->get_this_model();
401 401
         $related_model = $relation->get_other_model();
402
-        if (! isset($primary_model_query_params[0])) {
402
+        if ( ! isset($primary_model_query_params[0])) {
403 403
             $primary_model_query_params[0] = array();
404 404
         }
405 405
         // check if they can access the 1st model object
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
         if (is_array($primary_model_rows)) {
423 423
             $primary_model_row = reset($primary_model_rows);
424 424
         }
425
-        if (! (
425
+        if ( ! (
426 426
             Capabilities::currentUserHasPartialAccessTo($related_model, $context)
427 427
             && $primary_model_row
428 428
         )
@@ -462,13 +462,13 @@  discard block
 block discarded – undo
462 462
         );
463 463
         $query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
464 464
         foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
465
-            $query_params[0][ $relation->get_this_model()->get_this_model_name()
465
+            $query_params[0][$relation->get_this_model()->get_this_model_name()
466 466
                               . '.'
467
-                              . $where_condition_key ] = $where_condition_value;
467
+                              . $where_condition_key] = $where_condition_value;
468 468
         }
469 469
         $query_params['default_where_conditions'] = 'none';
470 470
         $query_params['caps'] = $context;
471
-        if (! $request->get_header('no_rest_headers')) {
471
+        if ( ! $request->get_header('no_rest_headers')) {
472 472
             $this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
473 473
         }
474 474
         /** @type array $results */
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
      */
526 526
     public function getEntitiesFromRelation($id, $relation, $request)
527 527
     {
528
-        if (! $relation->get_this_model()->has_primary_key_field()) {
528
+        if ( ! $relation->get_this_model()->has_primary_key_field()) {
529 529
             throw new EE_Error(
530 530
                 sprintf(
531 531
                     __(
@@ -571,7 +571,7 @@  discard block
 block discarded – undo
571 571
             Capabilities::getMissingPermissionsString($model, $query_params['caps'])
572 572
         );
573 573
         // normally the limit to a 2-part array, where the 2nd item is the limit
574
-        if (! isset($query_params['limit'])) {
574
+        if ( ! isset($query_params['limit'])) {
575 575
             $query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
576 576
         }
577 577
         if (is_array($query_params['limit'])) {
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
      */
615 615
     public function createEntityFromWpdbResult($model, $db_row, $rest_request, $deprecated = null)
616 616
     {
617
-        if (! $rest_request instanceof WP_REST_Request) {
617
+        if ( ! $rest_request instanceof WP_REST_Request) {
618 618
             // ok so this was called in the old style, where the 3rd arg was
619 619
             // $include, and the 4th arg was $context
620 620
             // now setup the request just to avoid fatal errors, although we won't be able
@@ -689,7 +689,7 @@  discard block
 block discarded – undo
689 689
             $rest_request,
690 690
             $this
691 691
         );
692
-        if (! $current_user_full_access_to_entity) {
692
+        if ( ! $current_user_full_access_to_entity) {
693 693
             $result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
694 694
                 $entity_array,
695 695
                 $model,
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
      */
725 725
     protected function addProtectedProperty(EEM_Base $model, $results_so_far, $protected)
726 726
     {
727
-        if (! $model->hasPassword() || ! $protected) {
727
+        if ( ! $model->hasPassword() || ! $protected) {
728 728
             return $results_so_far;
729 729
         }
730 730
         $password_field = $model->getPasswordField();
@@ -738,7 +738,7 @@  discard block
 block discarded – undo
738 738
             $fields_included
739 739
         );
740 740
         foreach ($fields_included as $field_name) {
741
-            $results_so_far['_protected'][] = $field_name ;
741
+            $results_so_far['_protected'][] = $field_name;
742 742
         }
743 743
         return $results_so_far;
744 744
     }
@@ -776,8 +776,8 @@  discard block
 block discarded – undo
776 776
         if ($do_chevy_shuffle) {
777 777
             global $post;
778 778
             $old_post = $post;
779
-            $post = get_post($result[ $model->primary_key_name() ]);
780
-            if (! $post instanceof WP_Post) {
779
+            $post = get_post($result[$model->primary_key_name()]);
780
+            if ( ! $post instanceof WP_Post) {
781 781
                 // well that's weird, because $result is what we JUST fetched from the database
782 782
                 throw new RestException(
783 783
                     'error_fetching_post_from_database_results',
@@ -787,7 +787,7 @@  discard block
 block discarded – undo
787 787
                     )
788 788
                 );
789 789
             }
790
-            $model_object_classname = 'EE_' . $model->get_this_model_name();
790
+            $model_object_classname = 'EE_'.$model->get_this_model_name();
791 791
             $post->{$model_object_classname} = \EE_Registry::instance()->load_class(
792 792
                 $model_object_classname,
793 793
                 $result,
@@ -798,13 +798,13 @@  discard block
 block discarded – undo
798 798
         foreach ($result as $field_name => $field_value) {
799 799
             $field_obj = $model->field_settings_for($field_name);
800 800
             if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
801
-                unset($result[ $field_name ]);
801
+                unset($result[$field_name]);
802 802
             } elseif ($this->isSubclassOfOne(
803 803
                 $field_obj,
804 804
                 $this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
805 805
             )
806 806
             ) {
807
-                $result[ $field_name ] = array(
807
+                $result[$field_name] = array(
808 808
                     'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
809 809
                     'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
810 810
                 );
@@ -813,7 +813,7 @@  discard block
 block discarded – undo
813 813
                 $this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
814 814
             )
815 815
             ) {
816
-                $result[ $field_name ] = array(
816
+                $result[$field_name] = array(
817 817
                     'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
818 818
                     'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
819 819
                 );
@@ -844,10 +844,10 @@  discard block
 block discarded – undo
844 844
                         $this->getModelVersionInfo()->requestedVersion()
845 845
                     );
846 846
                 }
847
-                $result[ $field_name . '_gmt' ] = $gmt_date;
848
-                $result[ $field_name ] = $local_date;
847
+                $result[$field_name.'_gmt'] = $gmt_date;
848
+                $result[$field_name] = $local_date;
849 849
             } else {
850
-                $result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
850
+                $result[$field_name] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
851 851
             }
852 852
         }
853 853
         if ($do_chevy_shuffle) {
@@ -900,7 +900,7 @@  discard block
 block discarded – undo
900 900
     protected function addExtraFields(EEM_Base $model, $db_row, $entity_array)
901 901
     {
902 902
         if ($model instanceof EEM_CPT_Base) {
903
-            $entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
903
+            $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
904 904
         }
905 905
         return $entity_array;
906 906
     }
@@ -926,7 +926,7 @@  discard block
 block discarded – undo
926 926
                     'href' => $this->getVersionedLinkTo(
927 927
                         EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
928 928
                         . '/'
929
-                        . $entity_array[ $model->primary_key_name() ]
929
+                        . $entity_array[$model->primary_key_name()]
930 930
                     ),
931 931
                 ),
932 932
             );
@@ -942,12 +942,12 @@  discard block
 block discarded – undo
942 942
         if ($model->has_primary_key_field()) {
943 943
             foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
944 944
                 $related_model_part = Read::getRelatedEntityName($relation_name, $relation_obj);
945
-                $links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = array(
945
+                $links[EED_Core_Rest_Api::ee_api_link_namespace.$related_model_part] = array(
946 946
                     array(
947 947
                         'href'   => $this->getVersionedLinkTo(
948 948
                             EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
949 949
                             . '/'
950
-                            . $entity_array[ $model->primary_key_name() ]
950
+                            . $entity_array[$model->primary_key_name()]
951 951
                             . '/'
952 952
                             . $related_model_part
953 953
                         ),
@@ -984,7 +984,7 @@  discard block
 block discarded – undo
984 984
         $included_items_protected = false
985 985
     ) {
986 986
         // if $db_row not included, hope the entity array has what we need
987
-        if (! $db_row) {
987
+        if ( ! $db_row) {
988 988
             $db_row = $entity_array;
989 989
         }
990 990
         $relation_settings = $this->getModelVersionInfo()->relationSettings($model);
@@ -1017,7 +1017,7 @@  discard block
 block discarded – undo
1017 1017
                         $model->deduce_fields_n_values_from_cols_n_values($db_row)
1018 1018
                     )
1019 1019
                 );
1020
-                if (! $included_items_protected) {
1020
+                if ( ! $included_items_protected) {
1021 1021
                     try {
1022 1022
                         $related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1023 1023
                             $primary_model_query_params,
@@ -1035,7 +1035,7 @@  discard block
 block discarded – undo
1035 1035
                 if ($related_results instanceof WP_Error || $related_results === null) {
1036 1036
                     $related_results = $relation_obj instanceof EE_Belongs_To_Relation ? null : array();
1037 1037
                 }
1038
-                $entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1038
+                $entity_array[Read::getRelatedEntityName($relation_name, $relation_obj)] = $related_results;
1039 1039
             }
1040 1040
         }
1041 1041
         return $entity_array;
@@ -1060,7 +1060,7 @@  discard block
 block discarded – undo
1060 1060
         $includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1061 1061
         $includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1062 1062
         // if they passed in * or didn't specify any includes, return everything
1063
-        if (! in_array('*', $includes_for_this_model)
1063
+        if ( ! in_array('*', $includes_for_this_model)
1064 1064
             && ! empty($includes_for_this_model)
1065 1065
         ) {
1066 1066
             if ($model->has_primary_key_field()) {
@@ -1114,12 +1114,12 @@  discard block
 block discarded – undo
1114 1114
                 // it's password protected, so they shouldn't be able to read this. Remove the value
1115 1115
                 $schema = $this->fields_calculator->getJsonSchemaForModel($model);
1116 1116
                 if ($row_is_protected
1117
-                    && isset($schema['properties'][ $field_to_calculate ]['protected'])
1118
-                    && $schema['properties'][ $field_to_calculate ]['protected']) {
1117
+                    && isset($schema['properties'][$field_to_calculate]['protected'])
1118
+                    && $schema['properties'][$field_to_calculate]['protected']) {
1119 1119
                     $calculated_value = null;
1120 1120
                     $protected_fields[] = $field_to_calculate;
1121
-                    if ($schema['properties'][ $field_to_calculate ]['type']) {
1122
-                        switch ($schema['properties'][ $field_to_calculate ]['type']) {
1121
+                    if ($schema['properties'][$field_to_calculate]['type']) {
1122
+                        switch ($schema['properties'][$field_to_calculate]['type']) {
1123 1123
                             case 'boolean':
1124 1124
                                 $calculated_value = false;
1125 1125
                                 break;
@@ -1236,7 +1236,7 @@  discard block
 block discarded – undo
1236 1236
      */
1237 1237
     public function validateContext($context)
1238 1238
     {
1239
-        if (! $context) {
1239
+        if ( ! $context) {
1240 1240
             $context = EEM_Base::caps_read;
1241 1241
         }
1242 1242
         $valid_contexts = EEM_Base::valid_cap_contexts();
@@ -1261,7 +1261,7 @@  discard block
 block discarded – undo
1261 1261
             EEM_Base::default_where_conditions_minimum_all,
1262 1262
             EEM_Base::default_where_conditions_minimum_others,
1263 1263
         );
1264
-        if (! $default_query_params) {
1264
+        if ( ! $default_query_params) {
1265 1265
             $default_query_params = EEM_Base::default_where_conditions_all;
1266 1266
         }
1267 1267
         if (in_array(
@@ -1348,14 +1348,14 @@  discard block
 block discarded – undo
1348 1348
         }
1349 1349
         if (isset($query_params['limit'])) {
1350 1350
             // limit should be either a string like '23' or '23,43', or an array with two items in it
1351
-            if (! is_array($query_params['limit'])) {
1351
+            if ( ! is_array($query_params['limit'])) {
1352 1352
                 $limit_array = explode(',', (string) $query_params['limit']);
1353 1353
             } else {
1354 1354
                 $limit_array = $query_params['limit'];
1355 1355
             }
1356 1356
             $sanitized_limit = array();
1357 1357
             foreach ($limit_array as $key => $limit_part) {
1358
-                if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1358
+                if ($this->debug_mode && ( ! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1359 1359
                     throw new EE_Error(
1360 1360
                         sprintf(
1361 1361
                             __(
@@ -1387,7 +1387,7 @@  discard block
 block discarded – undo
1387 1387
         // if this is a model protected by a password on another model, exclude the password protected
1388 1388
         // entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1389 1389
         // though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1390
-        if (! $model->hasPassword()
1390
+        if ( ! $model->hasPassword()
1391 1391
             && $model->restrictedByRelatedModelPassword()
1392 1392
             && $model_query_params['caps'] === EEM_Base::caps_read) {
1393 1393
             if (empty($query_params['password'])) {
@@ -1412,9 +1412,9 @@  discard block
 block discarded – undo
1412 1412
         $model_ready_query_params = array();
1413 1413
         foreach ($query_params as $key => $value) {
1414 1414
             if (is_array($value)) {
1415
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsKeyForModels($model, $value);
1415
+                $model_ready_query_params[$key] = $this->prepareRestQueryParamsKeyForModels($model, $value);
1416 1416
             } else {
1417
-                $model_ready_query_params[ $key ] = $value;
1417
+                $model_ready_query_params[$key] = $value;
1418 1418
             }
1419 1419
         }
1420 1420
         return $model_ready_query_params;
@@ -1432,9 +1432,9 @@  discard block
 block discarded – undo
1432 1432
         $model_ready_query_params = array();
1433 1433
         foreach ($query_params as $key => $value) {
1434 1434
             if (is_array($value)) {
1435
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1435
+                $model_ready_query_params[$key] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1436 1436
             } else {
1437
-                $model_ready_query_params[ $key ] = $value;
1437
+                $model_ready_query_params[$key] = $value;
1438 1438
             }
1439 1439
         }
1440 1440
         return $model_ready_query_params;
@@ -1466,17 +1466,17 @@  discard block
 block discarded – undo
1466 1466
         foreach ($exploded_contents as $item) {
1467 1467
             $item = trim($item);
1468 1468
             // if no prefix was provided, so we look for items with no "." in them
1469
-            if (! $prefix) {
1469
+            if ( ! $prefix) {
1470 1470
                 // does this item have a period?
1471 1471
                 if (strpos($item, '.') === false) {
1472 1472
                     // if not, then its what we're looking for
1473 1473
                     $contents_with_prefix[] = $item;
1474 1474
                 }
1475
-            } elseif (strpos($item, $prefix . '.') === 0) {
1475
+            } elseif (strpos($item, $prefix.'.') === 0) {
1476 1476
                 // this item has the prefix and a period, grab it
1477 1477
                 $contents_with_prefix[] = substr(
1478 1478
                     $item,
1479
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1479
+                    strpos($item, $prefix.'.') + strlen($prefix.'.')
1480 1480
                 );
1481 1481
             } elseif ($item === $prefix) {
1482 1482
                 // this item is JUST the prefix
@@ -1516,9 +1516,9 @@  discard block
 block discarded – undo
1516 1516
         if ($model_name) {
1517 1517
             foreach ($includes as $field_to_include) {
1518 1518
                 $field_to_include = trim($field_to_include);
1519
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1519
+                if (strpos($field_to_include, $model_name.'.') === 0) {
1520 1520
                     // found the model name at the exact start
1521
-                    $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1521
+                    $field_sans_model_name = str_replace($model_name.'.', '', $field_to_include);
1522 1522
                     $extracted_fields_to_include[] = $field_sans_model_name;
1523 1523
                 } elseif ($field_to_include == $model_name) {
1524 1524
                     $extracted_fields_to_include[] = '*';
@@ -1564,7 +1564,7 @@  discard block
 block discarded – undo
1564 1564
         $restricted_query_params['caps'] = $context;
1565 1565
         $this->setDebugInfo('model query params', $restricted_query_params);
1566 1566
         $model_rows = $model->get_all_wpdb_results($restricted_query_params);
1567
-        if (! empty($model_rows)) {
1567
+        if ( ! empty($model_rows)) {
1568 1568
             return $this->createEntityFromWpdbResult(
1569 1569
                 $model,
1570 1570
                 reset($model_rows),
@@ -1576,7 +1576,7 @@  discard block
 block discarded – undo
1576 1576
             if ($model->exists($query_params)) {
1577 1577
                 // you got shafted- it existed but we didn't want to tell you!
1578 1578
                 throw new RestException(
1579
-                    'rest_user_cannot_' . $context,
1579
+                    'rest_user_cannot_'.$context,
1580 1580
                     sprintf(
1581 1581
                         __('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1582 1582
                         $context,
@@ -1627,11 +1627,11 @@  discard block
 block discarded – undo
1627 1627
         }
1628 1628
         // if this entity requires a password, they better give it and it better be right!
1629 1629
         if ($model->hasPassword()
1630
-            && $model_row[ $model->getPasswordField()->get_qualified_column() ] !== '') {
1630
+            && $model_row[$model->getPasswordField()->get_qualified_column()] !== '') {
1631 1631
             if (empty($request['password'])) {
1632 1632
                 throw new RestPasswordRequiredException();
1633
-            } elseif (!hash_equals(
1634
-                $model_row[ $model->getPasswordField()->get_qualified_column() ],
1633
+            } elseif ( ! hash_equals(
1634
+                $model_row[$model->getPasswordField()->get_qualified_column()],
1635 1635
                 $request['password']
1636 1636
             )) {
1637 1637
                 throw new RestPasswordIncorrectException();
@@ -1642,12 +1642,12 @@  discard block
 block discarded – undo
1642 1642
             $password_supplied = $request->get_param('password');
1643 1643
             if (empty($password_supplied)) {
1644 1644
                 $query_params['exclude_protected'] = true;
1645
-                if (!$model->exists($query_params)) {
1645
+                if ( ! $model->exists($query_params)) {
1646 1646
                     throw new RestPasswordRequiredException();
1647 1647
                 }
1648 1648
             } else {
1649
-                $query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1650
-                if (!$model->exists($query_params)) {
1649
+                $query_params[0][$model->modelChainAndPassword()] = $password_supplied;
1650
+                if ( ! $model->exists($query_params)) {
1651 1651
                     throw new RestPasswordIncorrectException();
1652 1652
                 }
1653 1653
             }
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Indentation   +1320 added lines, -1320 removed lines patch added patch discarded remove patch
@@ -27,1324 +27,1324 @@
 block discarded – undo
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29 29
 
30
-    /**
31
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
-     */
34
-    const req_type_normal = 0;
35
-
36
-    /**
37
-     * Indicates this is a brand new installation of EE so we should install
38
-     * tables and default data etc
39
-     */
40
-    const req_type_new_activation = 1;
41
-
42
-    /**
43
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
-     * and we just exited maintenance mode). We MUST check the database is setup properly
45
-     * and that default data is setup too
46
-     */
47
-    const req_type_reactivation = 2;
48
-
49
-    /**
50
-     * indicates that EE has been upgraded since its previous request.
51
-     * We may have data migration scripts to call and will want to trigger maintenance mode
52
-     */
53
-    const req_type_upgrade = 3;
54
-
55
-    /**
56
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
-     */
58
-    const req_type_downgrade = 4;
59
-
60
-    /**
61
-     * @deprecated since version 4.6.0.dev.006
62
-     * Now whenever a new_activation is detected the request type is still just
63
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
-     * (Specifically, when the migration manager indicates migrations are finished
67
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
-     */
69
-    const req_type_activation_but_not_installed = 5;
70
-
71
-    /**
72
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
-     */
74
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
-
76
-    /**
77
-     * @var EE_System $_instance
78
-     */
79
-    private static $_instance;
80
-
81
-    /**
82
-     * @var EE_Registry $registry
83
-     */
84
-    private $registry;
85
-
86
-    /**
87
-     * @var LoaderInterface $loader
88
-     */
89
-    private $loader;
90
-
91
-    /**
92
-     * @var EE_Capabilities $capabilities
93
-     */
94
-    private $capabilities;
95
-
96
-    /**
97
-     * @var RequestInterface $request
98
-     */
99
-    private $request;
100
-
101
-    /**
102
-     * @var EE_Maintenance_Mode $maintenance_mode
103
-     */
104
-    private $maintenance_mode;
105
-
106
-    /**
107
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
-     *
110
-     * @var int $_req_type
111
-     */
112
-    private $_req_type;
113
-
114
-    /**
115
-     * Whether or not there was a non-micro version change in EE core version during this request
116
-     *
117
-     * @var boolean $_major_version_change
118
-     */
119
-    private $_major_version_change = false;
120
-
121
-    /**
122
-     * A Context DTO dedicated solely to identifying the current request type.
123
-     *
124
-     * @var RequestTypeContextCheckerInterface $request_type
125
-     */
126
-    private $request_type;
127
-
128
-
129
-    /**
130
-     * @singleton method used to instantiate class object
131
-     * @param EE_Registry|null         $registry
132
-     * @param LoaderInterface|null     $loader
133
-     * @param RequestInterface|null    $request
134
-     * @param EE_Maintenance_Mode|null $maintenance_mode
135
-     * @return EE_System
136
-     */
137
-    public static function instance(
138
-        EE_Registry $registry = null,
139
-        LoaderInterface $loader = null,
140
-        RequestInterface $request = null,
141
-        EE_Maintenance_Mode $maintenance_mode = null
142
-    ) {
143
-        // check if class object is instantiated
144
-        if (! self::$_instance instanceof EE_System) {
145
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
-        }
147
-        return self::$_instance;
148
-    }
149
-
150
-
151
-    /**
152
-     * resets the instance and returns it
153
-     *
154
-     * @return EE_System
155
-     */
156
-    public static function reset()
157
-    {
158
-        self::$_instance->_req_type = null;
159
-        // make sure none of the old hooks are left hanging around
160
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
-        // we need to reset the migration manager in order for it to detect DMSs properly
162
-        EE_Data_Migration_Manager::reset();
163
-        self::instance()->detect_activations_or_upgrades();
164
-        self::instance()->perform_activations_upgrades_and_migrations();
165
-        return self::instance();
166
-    }
167
-
168
-
169
-    /**
170
-     * sets hooks for running rest of system
171
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
-     * starting EE Addons from any other point may lead to problems
173
-     *
174
-     * @param EE_Registry         $registry
175
-     * @param LoaderInterface     $loader
176
-     * @param RequestInterface    $request
177
-     * @param EE_Maintenance_Mode $maintenance_mode
178
-     */
179
-    private function __construct(
180
-        EE_Registry $registry,
181
-        LoaderInterface $loader,
182
-        RequestInterface $request,
183
-        EE_Maintenance_Mode $maintenance_mode
184
-    ) {
185
-        $this->registry = $registry;
186
-        $this->loader = $loader;
187
-        $this->request = $request;
188
-        $this->maintenance_mode = $maintenance_mode;
189
-        do_action('AHEE__EE_System__construct__begin', $this);
190
-        add_action(
191
-            'AHEE__EE_Bootstrap__load_espresso_addons',
192
-            array($this, 'loadCapabilities'),
193
-            5
194
-        );
195
-        add_action(
196
-            'AHEE__EE_Bootstrap__load_espresso_addons',
197
-            array($this, 'loadCommandBus'),
198
-            7
199
-        );
200
-        add_action(
201
-            'AHEE__EE_Bootstrap__load_espresso_addons',
202
-            array($this, 'loadPluginApi'),
203
-            9
204
-        );
205
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
-        add_action(
207
-            'AHEE__EE_Bootstrap__load_espresso_addons',
208
-            array($this, 'load_espresso_addons')
209
-        );
210
-        // when an ee addon is activated, we want to call the core hook(s) again
211
-        // because the newly-activated addon didn't get a chance to run at all
212
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
-        // detect whether install or upgrade
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
-            array($this, 'detect_activations_or_upgrades'),
217
-            3
218
-        );
219
-        // load EE_Config, EE_Textdomain, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_core_configuration',
222
-            array($this, 'load_core_configuration'),
223
-            5
224
-        );
225
-        // load specifications for matching routes to current request
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_core_configuration',
228
-            array($this, 'loadRouteMatchSpecifications')
229
-        );
230
-        // load EE_Config, EE_Textdomain, etc
231
-        add_action(
232
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
-            array($this, 'register_shortcodes_modules_and_widgets'),
234
-            7
235
-        );
236
-        // you wanna get going? I wanna get going... let's get going!
237
-        add_action(
238
-            'AHEE__EE_Bootstrap__brew_espresso',
239
-            array($this, 'brew_espresso'),
240
-            9
241
-        );
242
-        // other housekeeping
243
-        // exclude EE critical pages from wp_list_pages
244
-        add_filter(
245
-            'wp_list_pages_excludes',
246
-            array($this, 'remove_pages_from_wp_list_pages'),
247
-            10
248
-        );
249
-        // ALL EE Addons should use the following hook point to attach their initial setup too
250
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
-        do_action('AHEE__EE_System__construct__complete', $this);
252
-    }
253
-
254
-
255
-    /**
256
-     * load and setup EE_Capabilities
257
-     *
258
-     * @return void
259
-     * @throws EE_Error
260
-     */
261
-    public function loadCapabilities()
262
-    {
263
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
264
-        add_action(
265
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
266
-            function () {
267
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
-            }
269
-        );
270
-    }
271
-
272
-
273
-    /**
274
-     * create and cache the CommandBus, and also add middleware
275
-     * The CapChecker middleware requires the use of EE_Capabilities
276
-     * which is why we need to load the CommandBus after Caps are set up
277
-     *
278
-     * @return void
279
-     * @throws EE_Error
280
-     */
281
-    public function loadCommandBus()
282
-    {
283
-        $this->loader->getShared(
284
-            'CommandBusInterface',
285
-            array(
286
-                null,
287
-                apply_filters(
288
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
-                    array(
290
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
-                    )
293
-                ),
294
-            )
295
-        );
296
-    }
297
-
298
-
299
-    /**
300
-     * @return void
301
-     * @throws EE_Error
302
-     */
303
-    public function loadPluginApi()
304
-    {
305
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
306
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
307
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
-        $this->loader->getShared('EE_Request_Handler');
309
-    }
310
-
311
-
312
-    /**
313
-     * @param string $addon_name
314
-     * @param string $version_constant
315
-     * @param string $min_version_required
316
-     * @param string $load_callback
317
-     * @param string $plugin_file_constant
318
-     * @return void
319
-     */
320
-    private function deactivateIncompatibleAddon(
321
-        $addon_name,
322
-        $version_constant,
323
-        $min_version_required,
324
-        $load_callback,
325
-        $plugin_file_constant
326
-    ) {
327
-        if (! defined($version_constant)) {
328
-            return;
329
-        }
330
-        $addon_version = constant($version_constant);
331
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
-            if (! function_exists('deactivate_plugins')) {
334
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
-            }
336
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
-            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
-            EE_Error::add_error(
339
-                sprintf(
340
-                    esc_html__(
341
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
342
-                        'event_espresso'
343
-                    ),
344
-                    $addon_name,
345
-                    $min_version_required
346
-                ),
347
-                __FILE__,
348
-                __FUNCTION__ . "({$addon_name})",
349
-                __LINE__
350
-            );
351
-            EE_Error::get_notices(false, true);
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * load_espresso_addons
358
-     * allow addons to load first so that they can set hooks for running DMS's, etc
359
-     * this is hooked into both:
360
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
361
-     *        which runs during the WP 'plugins_loaded' action at priority 5
362
-     *    and the WP 'activate_plugin' hook point
363
-     *
364
-     * @access public
365
-     * @return void
366
-     */
367
-    public function load_espresso_addons()
368
-    {
369
-        $this->deactivateIncompatibleAddon(
370
-            'Wait Lists',
371
-            'EE_WAIT_LISTS_VERSION',
372
-            '1.0.0.beta.074',
373
-            'load_espresso_wait_lists',
374
-            'EE_WAIT_LISTS_PLUGIN_FILE'
375
-        );
376
-        $this->deactivateIncompatibleAddon(
377
-            'Automated Upcoming Event Notifications',
378
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
-            '1.0.0.beta.091',
380
-            'load_espresso_automated_upcoming_event_notification',
381
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
-        );
383
-        do_action('AHEE__EE_System__load_espresso_addons');
384
-        // if the WP API basic auth plugin isn't already loaded, load it now.
385
-        // We want it for mobile apps. Just include the entire plugin
386
-        // also, don't load the basic auth when a plugin is getting activated, because
387
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
-        // and causes a fatal error
389
-        if (($this->request->isWordPressApi() || $this->request->isApi())
390
-            && $this->request->getRequestParam('activate') !== 'true'
391
-            && ! function_exists('json_basic_auth_handler')
392
-            && ! function_exists('json_basic_auth_error')
393
-            && ! in_array(
394
-                $this->request->getRequestParam('action'),
395
-                array('activate', 'activate-selected'),
396
-                true
397
-            )
398
-        ) {
399
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
400
-        }
401
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
402
-    }
403
-
404
-
405
-    /**
406
-     * detect_activations_or_upgrades
407
-     * Checks for activation or upgrade of core first;
408
-     * then also checks if any registered addons have been activated or upgraded
409
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
410
-     * which runs during the WP 'plugins_loaded' action at priority 3
411
-     *
412
-     * @access public
413
-     * @return void
414
-     */
415
-    public function detect_activations_or_upgrades()
416
-    {
417
-        // first off: let's make sure to handle core
418
-        $this->detect_if_activation_or_upgrade();
419
-        foreach ($this->registry->addons as $addon) {
420
-            if ($addon instanceof EE_Addon) {
421
-                // detect teh request type for that addon
422
-                $addon->detect_activation_or_upgrade();
423
-            }
424
-        }
425
-    }
426
-
427
-
428
-    /**
429
-     * detect_if_activation_or_upgrade
430
-     * Takes care of detecting whether this is a brand new install or code upgrade,
431
-     * and either setting up the DB or setting up maintenance mode etc.
432
-     *
433
-     * @access public
434
-     * @return void
435
-     */
436
-    public function detect_if_activation_or_upgrade()
437
-    {
438
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
439
-        // check if db has been updated, or if its a brand-new installation
440
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
441
-        $request_type = $this->detect_req_type($espresso_db_update);
442
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
443
-        switch ($request_type) {
444
-            case EE_System::req_type_new_activation:
445
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
446
-                $this->_handle_core_version_change($espresso_db_update);
447
-                break;
448
-            case EE_System::req_type_reactivation:
449
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
450
-                $this->_handle_core_version_change($espresso_db_update);
451
-                break;
452
-            case EE_System::req_type_upgrade:
453
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
454
-                // migrations may be required now that we've upgraded
455
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
456
-                $this->_handle_core_version_change($espresso_db_update);
457
-                break;
458
-            case EE_System::req_type_downgrade:
459
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
460
-                // its possible migrations are no longer required
461
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
462
-                $this->_handle_core_version_change($espresso_db_update);
463
-                break;
464
-            case EE_System::req_type_normal:
465
-            default:
466
-                break;
467
-        }
468
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
469
-    }
470
-
471
-
472
-    /**
473
-     * Updates the list of installed versions and sets hooks for
474
-     * initializing the database later during the request
475
-     *
476
-     * @param array $espresso_db_update
477
-     */
478
-    private function _handle_core_version_change($espresso_db_update)
479
-    {
480
-        $this->update_list_of_installed_versions($espresso_db_update);
481
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
482
-        add_action(
483
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
484
-            array($this, 'initialize_db_if_no_migrations_required')
485
-        );
486
-    }
487
-
488
-
489
-    /**
490
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
491
-     * information about what versions of EE have been installed and activated,
492
-     * NOT necessarily the state of the database
493
-     *
494
-     * @param mixed $espresso_db_update           the value of the WordPress option.
495
-     *                                            If not supplied, fetches it from the options table
496
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
497
-     */
498
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
499
-    {
500
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
501
-        if (! $espresso_db_update) {
502
-            $espresso_db_update = get_option('espresso_db_update');
503
-        }
504
-        // check that option is an array
505
-        if (! is_array($espresso_db_update)) {
506
-            // if option is FALSE, then it never existed
507
-            if ($espresso_db_update === false) {
508
-                // make $espresso_db_update an array and save option with autoload OFF
509
-                $espresso_db_update = array();
510
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
511
-            } else {
512
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
513
-                $espresso_db_update = array($espresso_db_update => array());
514
-                update_option('espresso_db_update', $espresso_db_update);
515
-            }
516
-        } else {
517
-            $corrected_db_update = array();
518
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
519
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
520
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
521
-                    // the key is an int, and the value IS NOT an array
522
-                    // so it must be numerically-indexed, where values are versions installed...
523
-                    // fix it!
524
-                    $version_string = $should_be_array;
525
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
526
-                } else {
527
-                    // ok it checks out
528
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
529
-                }
530
-            }
531
-            $espresso_db_update = $corrected_db_update;
532
-            update_option('espresso_db_update', $espresso_db_update);
533
-        }
534
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
535
-        return $espresso_db_update;
536
-    }
537
-
538
-
539
-    /**
540
-     * Does the traditional work of setting up the plugin's database and adding default data.
541
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
542
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
543
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
544
-     * so that it will be done when migrations are finished
545
-     *
546
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
547
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
548
-     *                                       This is a resource-intensive job
549
-     *                                       so we prefer to only do it when necessary
550
-     * @return void
551
-     * @throws EE_Error
552
-     */
553
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
554
-    {
555
-        $request_type = $this->detect_req_type();
556
-        // only initialize system if we're not in maintenance mode.
557
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
558
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
559
-            $rewrite_rules = $this->loader->getShared(
560
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
561
-            );
562
-            $rewrite_rules->flush();
563
-            if ($verify_schema) {
564
-                EEH_Activation::initialize_db_and_folders();
565
-            }
566
-            EEH_Activation::initialize_db_content();
567
-            EEH_Activation::system_initialization();
568
-            if ($initialize_addons_too) {
569
-                $this->initialize_addons();
570
-            }
571
-        } else {
572
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
573
-        }
574
-        if ($request_type === EE_System::req_type_new_activation
575
-            || $request_type === EE_System::req_type_reactivation
576
-            || (
577
-                $request_type === EE_System::req_type_upgrade
578
-                && $this->is_major_version_change()
579
-            )
580
-        ) {
581
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
582
-        }
583
-    }
584
-
585
-
586
-    /**
587
-     * Initializes the db for all registered addons
588
-     *
589
-     * @throws EE_Error
590
-     */
591
-    public function initialize_addons()
592
-    {
593
-        // foreach registered addon, make sure its db is up-to-date too
594
-        foreach ($this->registry->addons as $addon) {
595
-            if ($addon instanceof EE_Addon) {
596
-                $addon->initialize_db_if_no_migrations_required();
597
-            }
598
-        }
599
-    }
600
-
601
-
602
-    /**
603
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
604
-     *
605
-     * @param    array  $version_history
606
-     * @param    string $current_version_to_add version to be added to the version history
607
-     * @return    boolean success as to whether or not this option was changed
608
-     */
609
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
610
-    {
611
-        if (! $version_history) {
612
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
613
-        }
614
-        if ($current_version_to_add === null) {
615
-            $current_version_to_add = espresso_version();
616
-        }
617
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
618
-        // re-save
619
-        return update_option('espresso_db_update', $version_history);
620
-    }
621
-
622
-
623
-    /**
624
-     * Detects if the current version indicated in the has existed in the list of
625
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
626
-     *
627
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
628
-     *                                  If not supplied, fetches it from the options table.
629
-     *                                  Also, caches its result so later parts of the code can also know whether
630
-     *                                  there's been an update or not. This way we can add the current version to
631
-     *                                  espresso_db_update, but still know if this is a new install or not
632
-     * @return int one of the constants on EE_System::req_type_
633
-     */
634
-    public function detect_req_type($espresso_db_update = null)
635
-    {
636
-        if ($this->_req_type === null) {
637
-            $espresso_db_update = ! empty($espresso_db_update)
638
-                ? $espresso_db_update
639
-                : $this->fix_espresso_db_upgrade_option();
640
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
641
-                $espresso_db_update,
642
-                'ee_espresso_activation',
643
-                espresso_version()
644
-            );
645
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
646
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
647
-        }
648
-        return $this->_req_type;
649
-    }
650
-
651
-
652
-    /**
653
-     * Returns whether or not there was a non-micro version change (ie, change in either
654
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
655
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
656
-     *
657
-     * @param $activation_history
658
-     * @return bool
659
-     */
660
-    private function _detect_major_version_change($activation_history)
661
-    {
662
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
663
-        $previous_version_parts = explode('.', $previous_version);
664
-        $current_version_parts = explode('.', espresso_version());
665
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
666
-               && ($previous_version_parts[0] !== $current_version_parts[0]
667
-                   || $previous_version_parts[1] !== $current_version_parts[1]
668
-               );
669
-    }
670
-
671
-
672
-    /**
673
-     * Returns true if either the major or minor version of EE changed during this request.
674
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
675
-     *
676
-     * @return bool
677
-     */
678
-    public function is_major_version_change()
679
-    {
680
-        return $this->_major_version_change;
681
-    }
682
-
683
-
684
-    /**
685
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
686
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
687
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
688
-     * just activated to (for core that will always be espresso_version())
689
-     *
690
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
691
-     *                                                 ee plugin. for core that's 'espresso_db_update'
692
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
693
-     *                                                 indicate that this plugin was just activated
694
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
695
-     *                                                 espresso_version())
696
-     * @return int one of the constants on EE_System::req_type_*
697
-     */
698
-    public static function detect_req_type_given_activation_history(
699
-        $activation_history_for_addon,
700
-        $activation_indicator_option_name,
701
-        $version_to_upgrade_to
702
-    ) {
703
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
704
-        if ($activation_history_for_addon) {
705
-            // it exists, so this isn't a completely new install
706
-            // check if this version already in that list of previously installed versions
707
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
708
-                // it a version we haven't seen before
709
-                if ($version_is_higher === 1) {
710
-                    $req_type = EE_System::req_type_upgrade;
711
-                } else {
712
-                    $req_type = EE_System::req_type_downgrade;
713
-                }
714
-                delete_option($activation_indicator_option_name);
715
-            } else {
716
-                // its not an update. maybe a reactivation?
717
-                if (get_option($activation_indicator_option_name, false)) {
718
-                    if ($version_is_higher === -1) {
719
-                        $req_type = EE_System::req_type_downgrade;
720
-                    } elseif ($version_is_higher === 0) {
721
-                        // we've seen this version before, but it's an activation. must be a reactivation
722
-                        $req_type = EE_System::req_type_reactivation;
723
-                    } else {// $version_is_higher === 1
724
-                        $req_type = EE_System::req_type_upgrade;
725
-                    }
726
-                    delete_option($activation_indicator_option_name);
727
-                } else {
728
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
729
-                    if ($version_is_higher === -1) {
730
-                        $req_type = EE_System::req_type_downgrade;
731
-                    } elseif ($version_is_higher === 0) {
732
-                        // we've seen this version before and it's not an activation. its normal request
733
-                        $req_type = EE_System::req_type_normal;
734
-                    } else {// $version_is_higher === 1
735
-                        $req_type = EE_System::req_type_upgrade;
736
-                    }
737
-                }
738
-            }
739
-        } else {
740
-            // brand new install
741
-            $req_type = EE_System::req_type_new_activation;
742
-            delete_option($activation_indicator_option_name);
743
-        }
744
-        return $req_type;
745
-    }
746
-
747
-
748
-    /**
749
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
750
-     * the $activation_history_for_addon
751
-     *
752
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
753
-     *                                             sometimes containing 'unknown-date'
754
-     * @param string $version_to_upgrade_to        (current version)
755
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
756
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
757
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
758
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
759
-     */
760
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
761
-    {
762
-        // find the most recently-activated version
763
-        $most_recently_active_version =
764
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
765
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
766
-    }
767
-
768
-
769
-    /**
770
-     * Gets the most recently active version listed in the activation history,
771
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
772
-     *
773
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
774
-     *                                   sometimes containing 'unknown-date'
775
-     * @return string
776
-     */
777
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
778
-    {
779
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
780
-        $most_recently_active_version = '0.0.0.dev.000';
781
-        if (is_array($activation_history)) {
782
-            foreach ($activation_history as $version => $times_activated) {
783
-                // check there is a record of when this version was activated. Otherwise,
784
-                // mark it as unknown
785
-                if (! $times_activated) {
786
-                    $times_activated = array('unknown-date');
787
-                }
788
-                if (is_string($times_activated)) {
789
-                    $times_activated = array($times_activated);
790
-                }
791
-                foreach ($times_activated as $an_activation) {
792
-                    if ($an_activation !== 'unknown-date'
793
-                        && $an_activation
794
-                           > $most_recently_active_version_activation) {
795
-                        $most_recently_active_version = $version;
796
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
797
-                            ? '1970-01-01 00:00:00'
798
-                            : $an_activation;
799
-                    }
800
-                }
801
-            }
802
-        }
803
-        return $most_recently_active_version;
804
-    }
805
-
806
-
807
-    /**
808
-     * This redirects to the about EE page after activation
809
-     *
810
-     * @return void
811
-     */
812
-    public function redirect_to_about_ee()
813
-    {
814
-        $notices = EE_Error::get_notices(false);
815
-        // if current user is an admin and it's not an ajax or rest request
816
-        if (! isset($notices['errors'])
817
-            && $this->request->isAdmin()
818
-            && apply_filters(
819
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
820
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
821
-            )
822
-        ) {
823
-            $query_params = array('page' => 'espresso_about');
824
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
825
-                $query_params['new_activation'] = true;
826
-            }
827
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
828
-                $query_params['reactivation'] = true;
829
-            }
830
-            $url = add_query_arg($query_params, admin_url('admin.php'));
831
-            wp_safe_redirect($url);
832
-            exit();
833
-        }
834
-    }
835
-
836
-
837
-    /**
838
-     * load_core_configuration
839
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
840
-     * which runs during the WP 'plugins_loaded' action at priority 5
841
-     *
842
-     * @return void
843
-     * @throws ReflectionException
844
-     * @throws Exception
845
-     */
846
-    public function load_core_configuration()
847
-    {
848
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
849
-        $this->loader->getShared('EE_Load_Textdomain');
850
-        // load textdomain
851
-        EE_Load_Textdomain::load_textdomain();
852
-        // load caf stuff a chance to play during the activation process too.
853
-        $this->_maybe_brew_regular();
854
-        // load and setup EE_Config and EE_Network_Config
855
-        $config = $this->loader->getShared('EE_Config');
856
-        $this->loader->getShared('EE_Network_Config');
857
-        // setup autoloaders
858
-        // enable logging?
859
-        if ($config->admin->use_remote_logging) {
860
-            $this->loader->getShared('EE_Log');
861
-        }
862
-        // check for activation errors
863
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
864
-        if ($activation_errors) {
865
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
866
-            update_option('ee_plugin_activation_errors', false);
867
-        }
868
-        // get model names
869
-        $this->_parse_model_names();
870
-        // configure custom post type definitions
871
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
872
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
873
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
874
-    }
875
-
876
-
877
-    /**
878
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
879
-     *
880
-     * @return void
881
-     * @throws ReflectionException
882
-     */
883
-    private function _parse_model_names()
884
-    {
885
-        // get all the files in the EE_MODELS folder that end in .model.php
886
-        $models = glob(EE_MODELS . '*.model.php');
887
-        $model_names = array();
888
-        $non_abstract_db_models = array();
889
-        foreach ($models as $model) {
890
-            // get model classname
891
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
892
-            $short_name = str_replace('EEM_', '', $classname);
893
-            $reflectionClass = new ReflectionClass($classname);
894
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
895
-                $non_abstract_db_models[ $short_name ] = $classname;
896
-            }
897
-            $model_names[ $short_name ] = $classname;
898
-        }
899
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
900
-        $this->registry->non_abstract_db_models = apply_filters(
901
-            'FHEE__EE_System__parse_implemented_model_names',
902
-            $non_abstract_db_models
903
-        );
904
-    }
905
-
906
-
907
-    /**
908
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
909
-     * that need to be setup before our EE_System launches.
910
-     *
911
-     * @return void
912
-     * @throws DomainException
913
-     * @throws InvalidArgumentException
914
-     * @throws InvalidDataTypeException
915
-     * @throws InvalidInterfaceException
916
-     * @throws InvalidClassException
917
-     * @throws InvalidFilePathException
918
-     */
919
-    private function _maybe_brew_regular()
920
-    {
921
-        /** @var Domain $domain */
922
-        $domain = DomainFactory::getShared(
923
-            new FullyQualifiedName(
924
-                'EventEspresso\core\domain\Domain'
925
-            ),
926
-            array(
927
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
928
-                Version::fromString(espresso_version()),
929
-            )
930
-        );
931
-        if ($domain->isCaffeinated()) {
932
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
933
-        }
934
-    }
935
-
936
-
937
-    /**
938
-     * @since 4.9.71.p
939
-     * @throws Exception
940
-     */
941
-    public function loadRouteMatchSpecifications()
942
-    {
943
-        try {
944
-            $this->loader->getShared(
945
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
946
-            );
947
-        } catch (Exception $exception) {
948
-            new ExceptionStackTraceDisplay($exception);
949
-        }
950
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
951
-    }
952
-
953
-
954
-    /**
955
-     * register_shortcodes_modules_and_widgets
956
-     * generate lists of shortcodes and modules, then verify paths and classes
957
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
958
-     * which runs during the WP 'plugins_loaded' action at priority 7
959
-     *
960
-     * @access public
961
-     * @return void
962
-     * @throws Exception
963
-     */
964
-    public function register_shortcodes_modules_and_widgets()
965
-    {
966
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
967
-            try {
968
-                // load, register, and add shortcodes the new way
969
-                $this->loader->getShared(
970
-                    'EventEspresso\core\services\shortcodes\ShortcodesManager',
971
-                    array(
972
-                        // and the old way, but we'll put it under control of the new system
973
-                        EE_Config::getLegacyShortcodesManager(),
974
-                    )
975
-                );
976
-            } catch (Exception $exception) {
977
-                new ExceptionStackTraceDisplay($exception);
978
-            }
979
-        }
980
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
981
-        // check for addons using old hook point
982
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
983
-            $this->_incompatible_addon_error();
984
-        }
985
-    }
986
-
987
-
988
-    /**
989
-     * _incompatible_addon_error
990
-     *
991
-     * @access public
992
-     * @return void
993
-     */
994
-    private function _incompatible_addon_error()
995
-    {
996
-        // get array of classes hooking into here
997
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
998
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
999
-        );
1000
-        if (! empty($class_names)) {
1001
-            $msg = __(
1002
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1003
-                'event_espresso'
1004
-            );
1005
-            $msg .= '<ul>';
1006
-            foreach ($class_names as $class_name) {
1007
-                $msg .= '<li><b>Event Espresso - '
1008
-                        . str_replace(
1009
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1010
-                            '',
1011
-                            $class_name
1012
-                        ) . '</b></li>';
1013
-            }
1014
-            $msg .= '</ul>';
1015
-            $msg .= __(
1016
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1017
-                'event_espresso'
1018
-            );
1019
-            // save list of incompatible addons to wp-options for later use
1020
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1021
-            if (is_admin()) {
1022
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1023
-            }
1024
-        }
1025
-    }
1026
-
1027
-
1028
-    /**
1029
-     * brew_espresso
1030
-     * begins the process of setting hooks for initializing EE in the correct order
1031
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1032
-     * which runs during the WP 'plugins_loaded' action at priority 9
1033
-     *
1034
-     * @return void
1035
-     */
1036
-    public function brew_espresso()
1037
-    {
1038
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1039
-        // load some final core systems
1040
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1041
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1042
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1043
-        add_action('init', array($this, 'load_controllers'), 7);
1044
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1045
-        add_action('init', array($this, 'initialize'), 10);
1046
-        add_action('init', array($this, 'initialize_last'), 100);
1047
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1048
-            // pew pew pew
1049
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1050
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1051
-        }
1052
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     *    set_hooks_for_core
1058
-     *
1059
-     * @access public
1060
-     * @return    void
1061
-     * @throws EE_Error
1062
-     */
1063
-    public function set_hooks_for_core()
1064
-    {
1065
-        $this->_deactivate_incompatible_addons();
1066
-        do_action('AHEE__EE_System__set_hooks_for_core');
1067
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1068
-        // caps need to be initialized on every request so that capability maps are set.
1069
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1070
-        $this->registry->CAP->init_caps();
1071
-    }
1072
-
1073
-
1074
-    /**
1075
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1076
-     * deactivates any addons considered incompatible with the current version of EE
1077
-     */
1078
-    private function _deactivate_incompatible_addons()
1079
-    {
1080
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1081
-        if (! empty($incompatible_addons)) {
1082
-            $active_plugins = get_option('active_plugins', array());
1083
-            foreach ($active_plugins as $active_plugin) {
1084
-                foreach ($incompatible_addons as $incompatible_addon) {
1085
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1086
-                        unset($_GET['activate']);
1087
-                        espresso_deactivate_plugin($active_plugin);
1088
-                    }
1089
-                }
1090
-            }
1091
-        }
1092
-    }
1093
-
1094
-
1095
-    /**
1096
-     *    perform_activations_upgrades_and_migrations
1097
-     *
1098
-     * @access public
1099
-     * @return    void
1100
-     */
1101
-    public function perform_activations_upgrades_and_migrations()
1102
-    {
1103
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1104
-    }
1105
-
1106
-
1107
-    /**
1108
-     * @return void
1109
-     * @throws DomainException
1110
-     */
1111
-    public function load_CPTs_and_session()
1112
-    {
1113
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1114
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1115
-        $register_custom_taxonomies = $this->loader->getShared(
1116
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1117
-        );
1118
-        $register_custom_taxonomies->registerCustomTaxonomies();
1119
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1120
-        $register_custom_post_types = $this->loader->getShared(
1121
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1122
-        );
1123
-        $register_custom_post_types->registerCustomPostTypes();
1124
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1125
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1126
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1127
-        );
1128
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1129
-        // load legacy Custom Post Types and Taxonomies
1130
-        $this->loader->getShared('EE_Register_CPTs');
1131
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1132
-    }
1133
-
1134
-
1135
-    /**
1136
-     * load_controllers
1137
-     * this is the best place to load any additional controllers that needs access to EE core.
1138
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1139
-     * time
1140
-     *
1141
-     * @access public
1142
-     * @return void
1143
-     */
1144
-    public function load_controllers()
1145
-    {
1146
-        do_action('AHEE__EE_System__load_controllers__start');
1147
-        // let's get it started
1148
-        if (! $this->maintenance_mode->level()
1149
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1150
-        ) {
1151
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1152
-            $this->loader->getShared('EE_Front_Controller');
1153
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1154
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1155
-            $this->loader->getShared('EE_Admin');
1156
-        } elseif ($this->request->isWordPressHeartbeat()) {
1157
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1158
-        }
1159
-        do_action('AHEE__EE_System__load_controllers__complete');
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     * core_loaded_and_ready
1165
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1166
-     *
1167
-     * @access public
1168
-     * @return void
1169
-     * @throws Exception
1170
-     */
1171
-    public function core_loaded_and_ready()
1172
-    {
1173
-        if ($this->request->isAdmin()
1174
-            || $this->request->isFrontend()
1175
-            || $this->request->isIframe()
1176
-            || $this->request->isWordPressApi()
1177
-        ) {
1178
-            try {
1179
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1180
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1181
-                if ($this->canLoadBlocks()) {
1182
-                    $this->loader->getShared(
1183
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1184
-                    );
1185
-                }
1186
-            } catch (Exception $exception) {
1187
-                new ExceptionStackTraceDisplay($exception);
1188
-            }
1189
-        }
1190
-        if ($this->request->isAdmin()
1191
-            || $this->request->isEeAjax()
1192
-            || $this->request->isFrontend()
1193
-        ) {
1194
-            $this->loader->getShared('EE_Session');
1195
-        }
1196
-        // integrate WP_Query with the EE models
1197
-        $this->loader->getShared('EE_CPT_Strategy');
1198
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1199
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1200
-        // builders require these even on the front-end
1201
-        require_once EE_PUBLIC . 'template_tags.php';
1202
-        // load handler for GraphQL requests
1203
-        if (class_exists('WPGraphQL') && $this->request->isGQL()) {
1204
-            try {
1205
-                $graphQL_request_handler = $this->loader->getShared(
1206
-                    'EventEspresso\core\services\graphql\RequestHandler'
1207
-                );
1208
-                $graphQL_request_handler->init();
1209
-            } catch (Exception $exception) {
1210
-                new ExceptionStackTraceDisplay($exception);
1211
-            }
1212
-        }
1213
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * initialize
1219
-     * this is the best place to begin initializing client code
1220
-     *
1221
-     * @access public
1222
-     * @return void
1223
-     */
1224
-    public function initialize()
1225
-    {
1226
-        do_action('AHEE__EE_System__initialize');
1227
-    }
1228
-
1229
-
1230
-    /**
1231
-     * initialize_last
1232
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1233
-     * initialize has done so
1234
-     *
1235
-     * @access public
1236
-     * @return void
1237
-     */
1238
-    public function initialize_last()
1239
-    {
1240
-        do_action('AHEE__EE_System__initialize_last');
1241
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1242
-        $rewrite_rules = $this->loader->getShared(
1243
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1244
-        );
1245
-        $rewrite_rules->flushRewriteRules();
1246
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1247
-        if (($this->request->isAjax() || $this->request->isAdmin())
1248
-            && $this->maintenance_mode->models_can_query()) {
1249
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1250
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1251
-        }
1252
-    }
1253
-
1254
-
1255
-    /**
1256
-     * @return void
1257
-     * @throws EE_Error
1258
-     */
1259
-    public function addEspressoToolbar()
1260
-    {
1261
-        $this->loader->getShared(
1262
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1263
-            array($this->registry->CAP)
1264
-        );
1265
-    }
1266
-
1267
-
1268
-    /**
1269
-     * do_not_cache
1270
-     * sets no cache headers and defines no cache constants for WP plugins
1271
-     *
1272
-     * @access public
1273
-     * @return void
1274
-     */
1275
-    public static function do_not_cache()
1276
-    {
1277
-        // set no cache constants
1278
-        if (! defined('DONOTCACHEPAGE')) {
1279
-            define('DONOTCACHEPAGE', true);
1280
-        }
1281
-        if (! defined('DONOTCACHCEOBJECT')) {
1282
-            define('DONOTCACHCEOBJECT', true);
1283
-        }
1284
-        if (! defined('DONOTCACHEDB')) {
1285
-            define('DONOTCACHEDB', true);
1286
-        }
1287
-        // add no cache headers
1288
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1289
-        // plus a little extra for nginx and Google Chrome
1290
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1291
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1292
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1293
-    }
1294
-
1295
-
1296
-    /**
1297
-     *    extra_nocache_headers
1298
-     *
1299
-     * @access    public
1300
-     * @param $headers
1301
-     * @return    array
1302
-     */
1303
-    public static function extra_nocache_headers($headers)
1304
-    {
1305
-        // for NGINX
1306
-        $headers['X-Accel-Expires'] = 0;
1307
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1308
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1309
-        return $headers;
1310
-    }
1311
-
1312
-
1313
-    /**
1314
-     *    nocache_headers
1315
-     *
1316
-     * @access    public
1317
-     * @return    void
1318
-     */
1319
-    public static function nocache_headers()
1320
-    {
1321
-        nocache_headers();
1322
-    }
1323
-
1324
-
1325
-    /**
1326
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1327
-     * never returned with the function.
1328
-     *
1329
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1330
-     * @return array
1331
-     */
1332
-    public function remove_pages_from_wp_list_pages($exclude_array)
1333
-    {
1334
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     * Return whether blocks can be registered/loaded or not.
1340
-     * @return bool
1341
-     */
1342
-    private function canLoadBlocks()
1343
-    {
1344
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1345
-               && function_exists('register_block_type')
1346
-               // don't load blocks if in the Divi page builder editor context
1347
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1348
-               && ! $this->request->getRequestParam('et_fb', false);
1349
-    }
30
+	/**
31
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
+	 */
34
+	const req_type_normal = 0;
35
+
36
+	/**
37
+	 * Indicates this is a brand new installation of EE so we should install
38
+	 * tables and default data etc
39
+	 */
40
+	const req_type_new_activation = 1;
41
+
42
+	/**
43
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
45
+	 * and that default data is setup too
46
+	 */
47
+	const req_type_reactivation = 2;
48
+
49
+	/**
50
+	 * indicates that EE has been upgraded since its previous request.
51
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
52
+	 */
53
+	const req_type_upgrade = 3;
54
+
55
+	/**
56
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
+	 */
58
+	const req_type_downgrade = 4;
59
+
60
+	/**
61
+	 * @deprecated since version 4.6.0.dev.006
62
+	 * Now whenever a new_activation is detected the request type is still just
63
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
+	 * (Specifically, when the migration manager indicates migrations are finished
67
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
+	 */
69
+	const req_type_activation_but_not_installed = 5;
70
+
71
+	/**
72
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
+	 */
74
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
+
76
+	/**
77
+	 * @var EE_System $_instance
78
+	 */
79
+	private static $_instance;
80
+
81
+	/**
82
+	 * @var EE_Registry $registry
83
+	 */
84
+	private $registry;
85
+
86
+	/**
87
+	 * @var LoaderInterface $loader
88
+	 */
89
+	private $loader;
90
+
91
+	/**
92
+	 * @var EE_Capabilities $capabilities
93
+	 */
94
+	private $capabilities;
95
+
96
+	/**
97
+	 * @var RequestInterface $request
98
+	 */
99
+	private $request;
100
+
101
+	/**
102
+	 * @var EE_Maintenance_Mode $maintenance_mode
103
+	 */
104
+	private $maintenance_mode;
105
+
106
+	/**
107
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
+	 *
110
+	 * @var int $_req_type
111
+	 */
112
+	private $_req_type;
113
+
114
+	/**
115
+	 * Whether or not there was a non-micro version change in EE core version during this request
116
+	 *
117
+	 * @var boolean $_major_version_change
118
+	 */
119
+	private $_major_version_change = false;
120
+
121
+	/**
122
+	 * A Context DTO dedicated solely to identifying the current request type.
123
+	 *
124
+	 * @var RequestTypeContextCheckerInterface $request_type
125
+	 */
126
+	private $request_type;
127
+
128
+
129
+	/**
130
+	 * @singleton method used to instantiate class object
131
+	 * @param EE_Registry|null         $registry
132
+	 * @param LoaderInterface|null     $loader
133
+	 * @param RequestInterface|null    $request
134
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
135
+	 * @return EE_System
136
+	 */
137
+	public static function instance(
138
+		EE_Registry $registry = null,
139
+		LoaderInterface $loader = null,
140
+		RequestInterface $request = null,
141
+		EE_Maintenance_Mode $maintenance_mode = null
142
+	) {
143
+		// check if class object is instantiated
144
+		if (! self::$_instance instanceof EE_System) {
145
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
+		}
147
+		return self::$_instance;
148
+	}
149
+
150
+
151
+	/**
152
+	 * resets the instance and returns it
153
+	 *
154
+	 * @return EE_System
155
+	 */
156
+	public static function reset()
157
+	{
158
+		self::$_instance->_req_type = null;
159
+		// make sure none of the old hooks are left hanging around
160
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
+		// we need to reset the migration manager in order for it to detect DMSs properly
162
+		EE_Data_Migration_Manager::reset();
163
+		self::instance()->detect_activations_or_upgrades();
164
+		self::instance()->perform_activations_upgrades_and_migrations();
165
+		return self::instance();
166
+	}
167
+
168
+
169
+	/**
170
+	 * sets hooks for running rest of system
171
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
+	 * starting EE Addons from any other point may lead to problems
173
+	 *
174
+	 * @param EE_Registry         $registry
175
+	 * @param LoaderInterface     $loader
176
+	 * @param RequestInterface    $request
177
+	 * @param EE_Maintenance_Mode $maintenance_mode
178
+	 */
179
+	private function __construct(
180
+		EE_Registry $registry,
181
+		LoaderInterface $loader,
182
+		RequestInterface $request,
183
+		EE_Maintenance_Mode $maintenance_mode
184
+	) {
185
+		$this->registry = $registry;
186
+		$this->loader = $loader;
187
+		$this->request = $request;
188
+		$this->maintenance_mode = $maintenance_mode;
189
+		do_action('AHEE__EE_System__construct__begin', $this);
190
+		add_action(
191
+			'AHEE__EE_Bootstrap__load_espresso_addons',
192
+			array($this, 'loadCapabilities'),
193
+			5
194
+		);
195
+		add_action(
196
+			'AHEE__EE_Bootstrap__load_espresso_addons',
197
+			array($this, 'loadCommandBus'),
198
+			7
199
+		);
200
+		add_action(
201
+			'AHEE__EE_Bootstrap__load_espresso_addons',
202
+			array($this, 'loadPluginApi'),
203
+			9
204
+		);
205
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
+		add_action(
207
+			'AHEE__EE_Bootstrap__load_espresso_addons',
208
+			array($this, 'load_espresso_addons')
209
+		);
210
+		// when an ee addon is activated, we want to call the core hook(s) again
211
+		// because the newly-activated addon didn't get a chance to run at all
212
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
+		// detect whether install or upgrade
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
+			array($this, 'detect_activations_or_upgrades'),
217
+			3
218
+		);
219
+		// load EE_Config, EE_Textdomain, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_core_configuration',
222
+			array($this, 'load_core_configuration'),
223
+			5
224
+		);
225
+		// load specifications for matching routes to current request
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_core_configuration',
228
+			array($this, 'loadRouteMatchSpecifications')
229
+		);
230
+		// load EE_Config, EE_Textdomain, etc
231
+		add_action(
232
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
+			array($this, 'register_shortcodes_modules_and_widgets'),
234
+			7
235
+		);
236
+		// you wanna get going? I wanna get going... let's get going!
237
+		add_action(
238
+			'AHEE__EE_Bootstrap__brew_espresso',
239
+			array($this, 'brew_espresso'),
240
+			9
241
+		);
242
+		// other housekeeping
243
+		// exclude EE critical pages from wp_list_pages
244
+		add_filter(
245
+			'wp_list_pages_excludes',
246
+			array($this, 'remove_pages_from_wp_list_pages'),
247
+			10
248
+		);
249
+		// ALL EE Addons should use the following hook point to attach their initial setup too
250
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
+		do_action('AHEE__EE_System__construct__complete', $this);
252
+	}
253
+
254
+
255
+	/**
256
+	 * load and setup EE_Capabilities
257
+	 *
258
+	 * @return void
259
+	 * @throws EE_Error
260
+	 */
261
+	public function loadCapabilities()
262
+	{
263
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
264
+		add_action(
265
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
266
+			function () {
267
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
+			}
269
+		);
270
+	}
271
+
272
+
273
+	/**
274
+	 * create and cache the CommandBus, and also add middleware
275
+	 * The CapChecker middleware requires the use of EE_Capabilities
276
+	 * which is why we need to load the CommandBus after Caps are set up
277
+	 *
278
+	 * @return void
279
+	 * @throws EE_Error
280
+	 */
281
+	public function loadCommandBus()
282
+	{
283
+		$this->loader->getShared(
284
+			'CommandBusInterface',
285
+			array(
286
+				null,
287
+				apply_filters(
288
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
+					array(
290
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
+					)
293
+				),
294
+			)
295
+		);
296
+	}
297
+
298
+
299
+	/**
300
+	 * @return void
301
+	 * @throws EE_Error
302
+	 */
303
+	public function loadPluginApi()
304
+	{
305
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
306
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
307
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
+		$this->loader->getShared('EE_Request_Handler');
309
+	}
310
+
311
+
312
+	/**
313
+	 * @param string $addon_name
314
+	 * @param string $version_constant
315
+	 * @param string $min_version_required
316
+	 * @param string $load_callback
317
+	 * @param string $plugin_file_constant
318
+	 * @return void
319
+	 */
320
+	private function deactivateIncompatibleAddon(
321
+		$addon_name,
322
+		$version_constant,
323
+		$min_version_required,
324
+		$load_callback,
325
+		$plugin_file_constant
326
+	) {
327
+		if (! defined($version_constant)) {
328
+			return;
329
+		}
330
+		$addon_version = constant($version_constant);
331
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
+			if (! function_exists('deactivate_plugins')) {
334
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
+			}
336
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
+			unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
+			EE_Error::add_error(
339
+				sprintf(
340
+					esc_html__(
341
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
342
+						'event_espresso'
343
+					),
344
+					$addon_name,
345
+					$min_version_required
346
+				),
347
+				__FILE__,
348
+				__FUNCTION__ . "({$addon_name})",
349
+				__LINE__
350
+			);
351
+			EE_Error::get_notices(false, true);
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * load_espresso_addons
358
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
359
+	 * this is hooked into both:
360
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
361
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
362
+	 *    and the WP 'activate_plugin' hook point
363
+	 *
364
+	 * @access public
365
+	 * @return void
366
+	 */
367
+	public function load_espresso_addons()
368
+	{
369
+		$this->deactivateIncompatibleAddon(
370
+			'Wait Lists',
371
+			'EE_WAIT_LISTS_VERSION',
372
+			'1.0.0.beta.074',
373
+			'load_espresso_wait_lists',
374
+			'EE_WAIT_LISTS_PLUGIN_FILE'
375
+		);
376
+		$this->deactivateIncompatibleAddon(
377
+			'Automated Upcoming Event Notifications',
378
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
+			'1.0.0.beta.091',
380
+			'load_espresso_automated_upcoming_event_notification',
381
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
+		);
383
+		do_action('AHEE__EE_System__load_espresso_addons');
384
+		// if the WP API basic auth plugin isn't already loaded, load it now.
385
+		// We want it for mobile apps. Just include the entire plugin
386
+		// also, don't load the basic auth when a plugin is getting activated, because
387
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
+		// and causes a fatal error
389
+		if (($this->request->isWordPressApi() || $this->request->isApi())
390
+			&& $this->request->getRequestParam('activate') !== 'true'
391
+			&& ! function_exists('json_basic_auth_handler')
392
+			&& ! function_exists('json_basic_auth_error')
393
+			&& ! in_array(
394
+				$this->request->getRequestParam('action'),
395
+				array('activate', 'activate-selected'),
396
+				true
397
+			)
398
+		) {
399
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
400
+		}
401
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
402
+	}
403
+
404
+
405
+	/**
406
+	 * detect_activations_or_upgrades
407
+	 * Checks for activation or upgrade of core first;
408
+	 * then also checks if any registered addons have been activated or upgraded
409
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
410
+	 * which runs during the WP 'plugins_loaded' action at priority 3
411
+	 *
412
+	 * @access public
413
+	 * @return void
414
+	 */
415
+	public function detect_activations_or_upgrades()
416
+	{
417
+		// first off: let's make sure to handle core
418
+		$this->detect_if_activation_or_upgrade();
419
+		foreach ($this->registry->addons as $addon) {
420
+			if ($addon instanceof EE_Addon) {
421
+				// detect teh request type for that addon
422
+				$addon->detect_activation_or_upgrade();
423
+			}
424
+		}
425
+	}
426
+
427
+
428
+	/**
429
+	 * detect_if_activation_or_upgrade
430
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
431
+	 * and either setting up the DB or setting up maintenance mode etc.
432
+	 *
433
+	 * @access public
434
+	 * @return void
435
+	 */
436
+	public function detect_if_activation_or_upgrade()
437
+	{
438
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
439
+		// check if db has been updated, or if its a brand-new installation
440
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
441
+		$request_type = $this->detect_req_type($espresso_db_update);
442
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
443
+		switch ($request_type) {
444
+			case EE_System::req_type_new_activation:
445
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
446
+				$this->_handle_core_version_change($espresso_db_update);
447
+				break;
448
+			case EE_System::req_type_reactivation:
449
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
450
+				$this->_handle_core_version_change($espresso_db_update);
451
+				break;
452
+			case EE_System::req_type_upgrade:
453
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
454
+				// migrations may be required now that we've upgraded
455
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
456
+				$this->_handle_core_version_change($espresso_db_update);
457
+				break;
458
+			case EE_System::req_type_downgrade:
459
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
460
+				// its possible migrations are no longer required
461
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
462
+				$this->_handle_core_version_change($espresso_db_update);
463
+				break;
464
+			case EE_System::req_type_normal:
465
+			default:
466
+				break;
467
+		}
468
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
469
+	}
470
+
471
+
472
+	/**
473
+	 * Updates the list of installed versions and sets hooks for
474
+	 * initializing the database later during the request
475
+	 *
476
+	 * @param array $espresso_db_update
477
+	 */
478
+	private function _handle_core_version_change($espresso_db_update)
479
+	{
480
+		$this->update_list_of_installed_versions($espresso_db_update);
481
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
482
+		add_action(
483
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
484
+			array($this, 'initialize_db_if_no_migrations_required')
485
+		);
486
+	}
487
+
488
+
489
+	/**
490
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
491
+	 * information about what versions of EE have been installed and activated,
492
+	 * NOT necessarily the state of the database
493
+	 *
494
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
495
+	 *                                            If not supplied, fetches it from the options table
496
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
497
+	 */
498
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
499
+	{
500
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
501
+		if (! $espresso_db_update) {
502
+			$espresso_db_update = get_option('espresso_db_update');
503
+		}
504
+		// check that option is an array
505
+		if (! is_array($espresso_db_update)) {
506
+			// if option is FALSE, then it never existed
507
+			if ($espresso_db_update === false) {
508
+				// make $espresso_db_update an array and save option with autoload OFF
509
+				$espresso_db_update = array();
510
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
511
+			} else {
512
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
513
+				$espresso_db_update = array($espresso_db_update => array());
514
+				update_option('espresso_db_update', $espresso_db_update);
515
+			}
516
+		} else {
517
+			$corrected_db_update = array();
518
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
519
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
520
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
521
+					// the key is an int, and the value IS NOT an array
522
+					// so it must be numerically-indexed, where values are versions installed...
523
+					// fix it!
524
+					$version_string = $should_be_array;
525
+					$corrected_db_update[ $version_string ] = array('unknown-date');
526
+				} else {
527
+					// ok it checks out
528
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
529
+				}
530
+			}
531
+			$espresso_db_update = $corrected_db_update;
532
+			update_option('espresso_db_update', $espresso_db_update);
533
+		}
534
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
535
+		return $espresso_db_update;
536
+	}
537
+
538
+
539
+	/**
540
+	 * Does the traditional work of setting up the plugin's database and adding default data.
541
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
542
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
543
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
544
+	 * so that it will be done when migrations are finished
545
+	 *
546
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
547
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
548
+	 *                                       This is a resource-intensive job
549
+	 *                                       so we prefer to only do it when necessary
550
+	 * @return void
551
+	 * @throws EE_Error
552
+	 */
553
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
554
+	{
555
+		$request_type = $this->detect_req_type();
556
+		// only initialize system if we're not in maintenance mode.
557
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
558
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
559
+			$rewrite_rules = $this->loader->getShared(
560
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
561
+			);
562
+			$rewrite_rules->flush();
563
+			if ($verify_schema) {
564
+				EEH_Activation::initialize_db_and_folders();
565
+			}
566
+			EEH_Activation::initialize_db_content();
567
+			EEH_Activation::system_initialization();
568
+			if ($initialize_addons_too) {
569
+				$this->initialize_addons();
570
+			}
571
+		} else {
572
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
573
+		}
574
+		if ($request_type === EE_System::req_type_new_activation
575
+			|| $request_type === EE_System::req_type_reactivation
576
+			|| (
577
+				$request_type === EE_System::req_type_upgrade
578
+				&& $this->is_major_version_change()
579
+			)
580
+		) {
581
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
582
+		}
583
+	}
584
+
585
+
586
+	/**
587
+	 * Initializes the db for all registered addons
588
+	 *
589
+	 * @throws EE_Error
590
+	 */
591
+	public function initialize_addons()
592
+	{
593
+		// foreach registered addon, make sure its db is up-to-date too
594
+		foreach ($this->registry->addons as $addon) {
595
+			if ($addon instanceof EE_Addon) {
596
+				$addon->initialize_db_if_no_migrations_required();
597
+			}
598
+		}
599
+	}
600
+
601
+
602
+	/**
603
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
604
+	 *
605
+	 * @param    array  $version_history
606
+	 * @param    string $current_version_to_add version to be added to the version history
607
+	 * @return    boolean success as to whether or not this option was changed
608
+	 */
609
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
610
+	{
611
+		if (! $version_history) {
612
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
613
+		}
614
+		if ($current_version_to_add === null) {
615
+			$current_version_to_add = espresso_version();
616
+		}
617
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
618
+		// re-save
619
+		return update_option('espresso_db_update', $version_history);
620
+	}
621
+
622
+
623
+	/**
624
+	 * Detects if the current version indicated in the has existed in the list of
625
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
626
+	 *
627
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
628
+	 *                                  If not supplied, fetches it from the options table.
629
+	 *                                  Also, caches its result so later parts of the code can also know whether
630
+	 *                                  there's been an update or not. This way we can add the current version to
631
+	 *                                  espresso_db_update, but still know if this is a new install or not
632
+	 * @return int one of the constants on EE_System::req_type_
633
+	 */
634
+	public function detect_req_type($espresso_db_update = null)
635
+	{
636
+		if ($this->_req_type === null) {
637
+			$espresso_db_update = ! empty($espresso_db_update)
638
+				? $espresso_db_update
639
+				: $this->fix_espresso_db_upgrade_option();
640
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
641
+				$espresso_db_update,
642
+				'ee_espresso_activation',
643
+				espresso_version()
644
+			);
645
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
646
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
647
+		}
648
+		return $this->_req_type;
649
+	}
650
+
651
+
652
+	/**
653
+	 * Returns whether or not there was a non-micro version change (ie, change in either
654
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
655
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
656
+	 *
657
+	 * @param $activation_history
658
+	 * @return bool
659
+	 */
660
+	private function _detect_major_version_change($activation_history)
661
+	{
662
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
663
+		$previous_version_parts = explode('.', $previous_version);
664
+		$current_version_parts = explode('.', espresso_version());
665
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
666
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
667
+				   || $previous_version_parts[1] !== $current_version_parts[1]
668
+			   );
669
+	}
670
+
671
+
672
+	/**
673
+	 * Returns true if either the major or minor version of EE changed during this request.
674
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
675
+	 *
676
+	 * @return bool
677
+	 */
678
+	public function is_major_version_change()
679
+	{
680
+		return $this->_major_version_change;
681
+	}
682
+
683
+
684
+	/**
685
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
686
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
687
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
688
+	 * just activated to (for core that will always be espresso_version())
689
+	 *
690
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
691
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
692
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
693
+	 *                                                 indicate that this plugin was just activated
694
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
695
+	 *                                                 espresso_version())
696
+	 * @return int one of the constants on EE_System::req_type_*
697
+	 */
698
+	public static function detect_req_type_given_activation_history(
699
+		$activation_history_for_addon,
700
+		$activation_indicator_option_name,
701
+		$version_to_upgrade_to
702
+	) {
703
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
704
+		if ($activation_history_for_addon) {
705
+			// it exists, so this isn't a completely new install
706
+			// check if this version already in that list of previously installed versions
707
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
708
+				// it a version we haven't seen before
709
+				if ($version_is_higher === 1) {
710
+					$req_type = EE_System::req_type_upgrade;
711
+				} else {
712
+					$req_type = EE_System::req_type_downgrade;
713
+				}
714
+				delete_option($activation_indicator_option_name);
715
+			} else {
716
+				// its not an update. maybe a reactivation?
717
+				if (get_option($activation_indicator_option_name, false)) {
718
+					if ($version_is_higher === -1) {
719
+						$req_type = EE_System::req_type_downgrade;
720
+					} elseif ($version_is_higher === 0) {
721
+						// we've seen this version before, but it's an activation. must be a reactivation
722
+						$req_type = EE_System::req_type_reactivation;
723
+					} else {// $version_is_higher === 1
724
+						$req_type = EE_System::req_type_upgrade;
725
+					}
726
+					delete_option($activation_indicator_option_name);
727
+				} else {
728
+					// we've seen this version before and the activation indicate doesn't show it was just activated
729
+					if ($version_is_higher === -1) {
730
+						$req_type = EE_System::req_type_downgrade;
731
+					} elseif ($version_is_higher === 0) {
732
+						// we've seen this version before and it's not an activation. its normal request
733
+						$req_type = EE_System::req_type_normal;
734
+					} else {// $version_is_higher === 1
735
+						$req_type = EE_System::req_type_upgrade;
736
+					}
737
+				}
738
+			}
739
+		} else {
740
+			// brand new install
741
+			$req_type = EE_System::req_type_new_activation;
742
+			delete_option($activation_indicator_option_name);
743
+		}
744
+		return $req_type;
745
+	}
746
+
747
+
748
+	/**
749
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
750
+	 * the $activation_history_for_addon
751
+	 *
752
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
753
+	 *                                             sometimes containing 'unknown-date'
754
+	 * @param string $version_to_upgrade_to        (current version)
755
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
756
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
757
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
758
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
759
+	 */
760
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
761
+	{
762
+		// find the most recently-activated version
763
+		$most_recently_active_version =
764
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
765
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
766
+	}
767
+
768
+
769
+	/**
770
+	 * Gets the most recently active version listed in the activation history,
771
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
772
+	 *
773
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
774
+	 *                                   sometimes containing 'unknown-date'
775
+	 * @return string
776
+	 */
777
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
778
+	{
779
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
780
+		$most_recently_active_version = '0.0.0.dev.000';
781
+		if (is_array($activation_history)) {
782
+			foreach ($activation_history as $version => $times_activated) {
783
+				// check there is a record of when this version was activated. Otherwise,
784
+				// mark it as unknown
785
+				if (! $times_activated) {
786
+					$times_activated = array('unknown-date');
787
+				}
788
+				if (is_string($times_activated)) {
789
+					$times_activated = array($times_activated);
790
+				}
791
+				foreach ($times_activated as $an_activation) {
792
+					if ($an_activation !== 'unknown-date'
793
+						&& $an_activation
794
+						   > $most_recently_active_version_activation) {
795
+						$most_recently_active_version = $version;
796
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
797
+							? '1970-01-01 00:00:00'
798
+							: $an_activation;
799
+					}
800
+				}
801
+			}
802
+		}
803
+		return $most_recently_active_version;
804
+	}
805
+
806
+
807
+	/**
808
+	 * This redirects to the about EE page after activation
809
+	 *
810
+	 * @return void
811
+	 */
812
+	public function redirect_to_about_ee()
813
+	{
814
+		$notices = EE_Error::get_notices(false);
815
+		// if current user is an admin and it's not an ajax or rest request
816
+		if (! isset($notices['errors'])
817
+			&& $this->request->isAdmin()
818
+			&& apply_filters(
819
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
820
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
821
+			)
822
+		) {
823
+			$query_params = array('page' => 'espresso_about');
824
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
825
+				$query_params['new_activation'] = true;
826
+			}
827
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
828
+				$query_params['reactivation'] = true;
829
+			}
830
+			$url = add_query_arg($query_params, admin_url('admin.php'));
831
+			wp_safe_redirect($url);
832
+			exit();
833
+		}
834
+	}
835
+
836
+
837
+	/**
838
+	 * load_core_configuration
839
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
840
+	 * which runs during the WP 'plugins_loaded' action at priority 5
841
+	 *
842
+	 * @return void
843
+	 * @throws ReflectionException
844
+	 * @throws Exception
845
+	 */
846
+	public function load_core_configuration()
847
+	{
848
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
849
+		$this->loader->getShared('EE_Load_Textdomain');
850
+		// load textdomain
851
+		EE_Load_Textdomain::load_textdomain();
852
+		// load caf stuff a chance to play during the activation process too.
853
+		$this->_maybe_brew_regular();
854
+		// load and setup EE_Config and EE_Network_Config
855
+		$config = $this->loader->getShared('EE_Config');
856
+		$this->loader->getShared('EE_Network_Config');
857
+		// setup autoloaders
858
+		// enable logging?
859
+		if ($config->admin->use_remote_logging) {
860
+			$this->loader->getShared('EE_Log');
861
+		}
862
+		// check for activation errors
863
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
864
+		if ($activation_errors) {
865
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
866
+			update_option('ee_plugin_activation_errors', false);
867
+		}
868
+		// get model names
869
+		$this->_parse_model_names();
870
+		// configure custom post type definitions
871
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
872
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
873
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
874
+	}
875
+
876
+
877
+	/**
878
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
879
+	 *
880
+	 * @return void
881
+	 * @throws ReflectionException
882
+	 */
883
+	private function _parse_model_names()
884
+	{
885
+		// get all the files in the EE_MODELS folder that end in .model.php
886
+		$models = glob(EE_MODELS . '*.model.php');
887
+		$model_names = array();
888
+		$non_abstract_db_models = array();
889
+		foreach ($models as $model) {
890
+			// get model classname
891
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
892
+			$short_name = str_replace('EEM_', '', $classname);
893
+			$reflectionClass = new ReflectionClass($classname);
894
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
895
+				$non_abstract_db_models[ $short_name ] = $classname;
896
+			}
897
+			$model_names[ $short_name ] = $classname;
898
+		}
899
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
900
+		$this->registry->non_abstract_db_models = apply_filters(
901
+			'FHEE__EE_System__parse_implemented_model_names',
902
+			$non_abstract_db_models
903
+		);
904
+	}
905
+
906
+
907
+	/**
908
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
909
+	 * that need to be setup before our EE_System launches.
910
+	 *
911
+	 * @return void
912
+	 * @throws DomainException
913
+	 * @throws InvalidArgumentException
914
+	 * @throws InvalidDataTypeException
915
+	 * @throws InvalidInterfaceException
916
+	 * @throws InvalidClassException
917
+	 * @throws InvalidFilePathException
918
+	 */
919
+	private function _maybe_brew_regular()
920
+	{
921
+		/** @var Domain $domain */
922
+		$domain = DomainFactory::getShared(
923
+			new FullyQualifiedName(
924
+				'EventEspresso\core\domain\Domain'
925
+			),
926
+			array(
927
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
928
+				Version::fromString(espresso_version()),
929
+			)
930
+		);
931
+		if ($domain->isCaffeinated()) {
932
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
933
+		}
934
+	}
935
+
936
+
937
+	/**
938
+	 * @since 4.9.71.p
939
+	 * @throws Exception
940
+	 */
941
+	public function loadRouteMatchSpecifications()
942
+	{
943
+		try {
944
+			$this->loader->getShared(
945
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
946
+			);
947
+		} catch (Exception $exception) {
948
+			new ExceptionStackTraceDisplay($exception);
949
+		}
950
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
951
+	}
952
+
953
+
954
+	/**
955
+	 * register_shortcodes_modules_and_widgets
956
+	 * generate lists of shortcodes and modules, then verify paths and classes
957
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
958
+	 * which runs during the WP 'plugins_loaded' action at priority 7
959
+	 *
960
+	 * @access public
961
+	 * @return void
962
+	 * @throws Exception
963
+	 */
964
+	public function register_shortcodes_modules_and_widgets()
965
+	{
966
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
967
+			try {
968
+				// load, register, and add shortcodes the new way
969
+				$this->loader->getShared(
970
+					'EventEspresso\core\services\shortcodes\ShortcodesManager',
971
+					array(
972
+						// and the old way, but we'll put it under control of the new system
973
+						EE_Config::getLegacyShortcodesManager(),
974
+					)
975
+				);
976
+			} catch (Exception $exception) {
977
+				new ExceptionStackTraceDisplay($exception);
978
+			}
979
+		}
980
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
981
+		// check for addons using old hook point
982
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
983
+			$this->_incompatible_addon_error();
984
+		}
985
+	}
986
+
987
+
988
+	/**
989
+	 * _incompatible_addon_error
990
+	 *
991
+	 * @access public
992
+	 * @return void
993
+	 */
994
+	private function _incompatible_addon_error()
995
+	{
996
+		// get array of classes hooking into here
997
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
998
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
999
+		);
1000
+		if (! empty($class_names)) {
1001
+			$msg = __(
1002
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1003
+				'event_espresso'
1004
+			);
1005
+			$msg .= '<ul>';
1006
+			foreach ($class_names as $class_name) {
1007
+				$msg .= '<li><b>Event Espresso - '
1008
+						. str_replace(
1009
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1010
+							'',
1011
+							$class_name
1012
+						) . '</b></li>';
1013
+			}
1014
+			$msg .= '</ul>';
1015
+			$msg .= __(
1016
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1017
+				'event_espresso'
1018
+			);
1019
+			// save list of incompatible addons to wp-options for later use
1020
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1021
+			if (is_admin()) {
1022
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1023
+			}
1024
+		}
1025
+	}
1026
+
1027
+
1028
+	/**
1029
+	 * brew_espresso
1030
+	 * begins the process of setting hooks for initializing EE in the correct order
1031
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1032
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1033
+	 *
1034
+	 * @return void
1035
+	 */
1036
+	public function brew_espresso()
1037
+	{
1038
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1039
+		// load some final core systems
1040
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1041
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1042
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1043
+		add_action('init', array($this, 'load_controllers'), 7);
1044
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1045
+		add_action('init', array($this, 'initialize'), 10);
1046
+		add_action('init', array($this, 'initialize_last'), 100);
1047
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1048
+			// pew pew pew
1049
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1050
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1051
+		}
1052
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 *    set_hooks_for_core
1058
+	 *
1059
+	 * @access public
1060
+	 * @return    void
1061
+	 * @throws EE_Error
1062
+	 */
1063
+	public function set_hooks_for_core()
1064
+	{
1065
+		$this->_deactivate_incompatible_addons();
1066
+		do_action('AHEE__EE_System__set_hooks_for_core');
1067
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1068
+		// caps need to be initialized on every request so that capability maps are set.
1069
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1070
+		$this->registry->CAP->init_caps();
1071
+	}
1072
+
1073
+
1074
+	/**
1075
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1076
+	 * deactivates any addons considered incompatible with the current version of EE
1077
+	 */
1078
+	private function _deactivate_incompatible_addons()
1079
+	{
1080
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1081
+		if (! empty($incompatible_addons)) {
1082
+			$active_plugins = get_option('active_plugins', array());
1083
+			foreach ($active_plugins as $active_plugin) {
1084
+				foreach ($incompatible_addons as $incompatible_addon) {
1085
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1086
+						unset($_GET['activate']);
1087
+						espresso_deactivate_plugin($active_plugin);
1088
+					}
1089
+				}
1090
+			}
1091
+		}
1092
+	}
1093
+
1094
+
1095
+	/**
1096
+	 *    perform_activations_upgrades_and_migrations
1097
+	 *
1098
+	 * @access public
1099
+	 * @return    void
1100
+	 */
1101
+	public function perform_activations_upgrades_and_migrations()
1102
+	{
1103
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1104
+	}
1105
+
1106
+
1107
+	/**
1108
+	 * @return void
1109
+	 * @throws DomainException
1110
+	 */
1111
+	public function load_CPTs_and_session()
1112
+	{
1113
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1114
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1115
+		$register_custom_taxonomies = $this->loader->getShared(
1116
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1117
+		);
1118
+		$register_custom_taxonomies->registerCustomTaxonomies();
1119
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1120
+		$register_custom_post_types = $this->loader->getShared(
1121
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1122
+		);
1123
+		$register_custom_post_types->registerCustomPostTypes();
1124
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1125
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1126
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1127
+		);
1128
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1129
+		// load legacy Custom Post Types and Taxonomies
1130
+		$this->loader->getShared('EE_Register_CPTs');
1131
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1132
+	}
1133
+
1134
+
1135
+	/**
1136
+	 * load_controllers
1137
+	 * this is the best place to load any additional controllers that needs access to EE core.
1138
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1139
+	 * time
1140
+	 *
1141
+	 * @access public
1142
+	 * @return void
1143
+	 */
1144
+	public function load_controllers()
1145
+	{
1146
+		do_action('AHEE__EE_System__load_controllers__start');
1147
+		// let's get it started
1148
+		if (! $this->maintenance_mode->level()
1149
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1150
+		) {
1151
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1152
+			$this->loader->getShared('EE_Front_Controller');
1153
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1154
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1155
+			$this->loader->getShared('EE_Admin');
1156
+		} elseif ($this->request->isWordPressHeartbeat()) {
1157
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1158
+		}
1159
+		do_action('AHEE__EE_System__load_controllers__complete');
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 * core_loaded_and_ready
1165
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1166
+	 *
1167
+	 * @access public
1168
+	 * @return void
1169
+	 * @throws Exception
1170
+	 */
1171
+	public function core_loaded_and_ready()
1172
+	{
1173
+		if ($this->request->isAdmin()
1174
+			|| $this->request->isFrontend()
1175
+			|| $this->request->isIframe()
1176
+			|| $this->request->isWordPressApi()
1177
+		) {
1178
+			try {
1179
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1180
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1181
+				if ($this->canLoadBlocks()) {
1182
+					$this->loader->getShared(
1183
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1184
+					);
1185
+				}
1186
+			} catch (Exception $exception) {
1187
+				new ExceptionStackTraceDisplay($exception);
1188
+			}
1189
+		}
1190
+		if ($this->request->isAdmin()
1191
+			|| $this->request->isEeAjax()
1192
+			|| $this->request->isFrontend()
1193
+		) {
1194
+			$this->loader->getShared('EE_Session');
1195
+		}
1196
+		// integrate WP_Query with the EE models
1197
+		$this->loader->getShared('EE_CPT_Strategy');
1198
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1199
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1200
+		// builders require these even on the front-end
1201
+		require_once EE_PUBLIC . 'template_tags.php';
1202
+		// load handler for GraphQL requests
1203
+		if (class_exists('WPGraphQL') && $this->request->isGQL()) {
1204
+			try {
1205
+				$graphQL_request_handler = $this->loader->getShared(
1206
+					'EventEspresso\core\services\graphql\RequestHandler'
1207
+				);
1208
+				$graphQL_request_handler->init();
1209
+			} catch (Exception $exception) {
1210
+				new ExceptionStackTraceDisplay($exception);
1211
+			}
1212
+		}
1213
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * initialize
1219
+	 * this is the best place to begin initializing client code
1220
+	 *
1221
+	 * @access public
1222
+	 * @return void
1223
+	 */
1224
+	public function initialize()
1225
+	{
1226
+		do_action('AHEE__EE_System__initialize');
1227
+	}
1228
+
1229
+
1230
+	/**
1231
+	 * initialize_last
1232
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1233
+	 * initialize has done so
1234
+	 *
1235
+	 * @access public
1236
+	 * @return void
1237
+	 */
1238
+	public function initialize_last()
1239
+	{
1240
+		do_action('AHEE__EE_System__initialize_last');
1241
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1242
+		$rewrite_rules = $this->loader->getShared(
1243
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1244
+		);
1245
+		$rewrite_rules->flushRewriteRules();
1246
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1247
+		if (($this->request->isAjax() || $this->request->isAdmin())
1248
+			&& $this->maintenance_mode->models_can_query()) {
1249
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1250
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1251
+		}
1252
+	}
1253
+
1254
+
1255
+	/**
1256
+	 * @return void
1257
+	 * @throws EE_Error
1258
+	 */
1259
+	public function addEspressoToolbar()
1260
+	{
1261
+		$this->loader->getShared(
1262
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1263
+			array($this->registry->CAP)
1264
+		);
1265
+	}
1266
+
1267
+
1268
+	/**
1269
+	 * do_not_cache
1270
+	 * sets no cache headers and defines no cache constants for WP plugins
1271
+	 *
1272
+	 * @access public
1273
+	 * @return void
1274
+	 */
1275
+	public static function do_not_cache()
1276
+	{
1277
+		// set no cache constants
1278
+		if (! defined('DONOTCACHEPAGE')) {
1279
+			define('DONOTCACHEPAGE', true);
1280
+		}
1281
+		if (! defined('DONOTCACHCEOBJECT')) {
1282
+			define('DONOTCACHCEOBJECT', true);
1283
+		}
1284
+		if (! defined('DONOTCACHEDB')) {
1285
+			define('DONOTCACHEDB', true);
1286
+		}
1287
+		// add no cache headers
1288
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1289
+		// plus a little extra for nginx and Google Chrome
1290
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1291
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1292
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1293
+	}
1294
+
1295
+
1296
+	/**
1297
+	 *    extra_nocache_headers
1298
+	 *
1299
+	 * @access    public
1300
+	 * @param $headers
1301
+	 * @return    array
1302
+	 */
1303
+	public static function extra_nocache_headers($headers)
1304
+	{
1305
+		// for NGINX
1306
+		$headers['X-Accel-Expires'] = 0;
1307
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1308
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1309
+		return $headers;
1310
+	}
1311
+
1312
+
1313
+	/**
1314
+	 *    nocache_headers
1315
+	 *
1316
+	 * @access    public
1317
+	 * @return    void
1318
+	 */
1319
+	public static function nocache_headers()
1320
+	{
1321
+		nocache_headers();
1322
+	}
1323
+
1324
+
1325
+	/**
1326
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1327
+	 * never returned with the function.
1328
+	 *
1329
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1330
+	 * @return array
1331
+	 */
1332
+	public function remove_pages_from_wp_list_pages($exclude_array)
1333
+	{
1334
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 * Return whether blocks can be registered/loaded or not.
1340
+	 * @return bool
1341
+	 */
1342
+	private function canLoadBlocks()
1343
+	{
1344
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1345
+			   && function_exists('register_block_type')
1346
+			   // don't load blocks if in the Divi page builder editor context
1347
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1348
+			   && ! $this->request->getRequestParam('et_fb', false);
1349
+	}
1350 1350
 }
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
         EE_Maintenance_Mode $maintenance_mode = null
142 142
     ) {
143 143
         // check if class object is instantiated
144
-        if (! self::$_instance instanceof EE_System) {
144
+        if ( ! self::$_instance instanceof EE_System) {
145 145
             self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146 146
         }
147 147
         return self::$_instance;
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
         $this->capabilities = $this->loader->getShared('EE_Capabilities');
264 264
         add_action(
265 265
             'AHEE__EE_Capabilities__init_caps__before_initialization',
266
-            function () {
266
+            function() {
267 267
                 LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268 268
             }
269 269
         );
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
     {
305 305
         // set autoloaders for all of the classes implementing EEI_Plugin_API
306 306
         // which provide helpers for EE plugin authors to more easily register certain components with EE.
307
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
307
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
308 308
         $this->loader->getShared('EE_Request_Handler');
309 309
     }
310 310
 
@@ -324,14 +324,14 @@  discard block
 block discarded – undo
324 324
         $load_callback,
325 325
         $plugin_file_constant
326 326
     ) {
327
-        if (! defined($version_constant)) {
327
+        if ( ! defined($version_constant)) {
328 328
             return;
329 329
         }
330 330
         $addon_version = constant($version_constant);
331 331
         if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332 332
             remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
-            if (! function_exists('deactivate_plugins')) {
334
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
333
+            if ( ! function_exists('deactivate_plugins')) {
334
+                require_once ABSPATH.'wp-admin/includes/plugin.php';
335 335
             }
336 336
             deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337 337
             unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
                     $min_version_required
346 346
                 ),
347 347
                 __FILE__,
348
-                __FUNCTION__ . "({$addon_name})",
348
+                __FUNCTION__."({$addon_name})",
349 349
                 __LINE__
350 350
             );
351 351
             EE_Error::get_notices(false, true);
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
                 true
397 397
             )
398 398
         ) {
399
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
399
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth/basic-auth.php';
400 400
         }
401 401
         do_action('AHEE__EE_System__load_espresso_addons__complete');
402 402
     }
@@ -498,11 +498,11 @@  discard block
 block discarded – undo
498 498
     private function fix_espresso_db_upgrade_option($espresso_db_update = null)
499 499
     {
500 500
         do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
501
-        if (! $espresso_db_update) {
501
+        if ( ! $espresso_db_update) {
502 502
             $espresso_db_update = get_option('espresso_db_update');
503 503
         }
504 504
         // check that option is an array
505
-        if (! is_array($espresso_db_update)) {
505
+        if ( ! is_array($espresso_db_update)) {
506 506
             // if option is FALSE, then it never existed
507 507
             if ($espresso_db_update === false) {
508 508
                 // make $espresso_db_update an array and save option with autoload OFF
@@ -522,10 +522,10 @@  discard block
 block discarded – undo
522 522
                     // so it must be numerically-indexed, where values are versions installed...
523 523
                     // fix it!
524 524
                     $version_string = $should_be_array;
525
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
525
+                    $corrected_db_update[$version_string] = array('unknown-date');
526 526
                 } else {
527 527
                     // ok it checks out
528
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
528
+                    $corrected_db_update[$should_be_version_string] = $should_be_array;
529 529
                 }
530 530
             }
531 531
             $espresso_db_update = $corrected_db_update;
@@ -608,13 +608,13 @@  discard block
 block discarded – undo
608 608
      */
609 609
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
610 610
     {
611
-        if (! $version_history) {
611
+        if ( ! $version_history) {
612 612
             $version_history = $this->fix_espresso_db_upgrade_option($version_history);
613 613
         }
614 614
         if ($current_version_to_add === null) {
615 615
             $current_version_to_add = espresso_version();
616 616
         }
617
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
617
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
618 618
         // re-save
619 619
         return update_option('espresso_db_update', $version_history);
620 620
     }
@@ -704,7 +704,7 @@  discard block
 block discarded – undo
704 704
         if ($activation_history_for_addon) {
705 705
             // it exists, so this isn't a completely new install
706 706
             // check if this version already in that list of previously installed versions
707
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
707
+            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
708 708
                 // it a version we haven't seen before
709 709
                 if ($version_is_higher === 1) {
710 710
                     $req_type = EE_System::req_type_upgrade;
@@ -782,7 +782,7 @@  discard block
 block discarded – undo
782 782
             foreach ($activation_history as $version => $times_activated) {
783 783
                 // check there is a record of when this version was activated. Otherwise,
784 784
                 // mark it as unknown
785
-                if (! $times_activated) {
785
+                if ( ! $times_activated) {
786 786
                     $times_activated = array('unknown-date');
787 787
                 }
788 788
                 if (is_string($times_activated)) {
@@ -813,7 +813,7 @@  discard block
 block discarded – undo
813 813
     {
814 814
         $notices = EE_Error::get_notices(false);
815 815
         // if current user is an admin and it's not an ajax or rest request
816
-        if (! isset($notices['errors'])
816
+        if ( ! isset($notices['errors'])
817 817
             && $this->request->isAdmin()
818 818
             && apply_filters(
819 819
                 'FHEE__EE_System__redirect_to_about_ee__do_redirect',
@@ -883,7 +883,7 @@  discard block
 block discarded – undo
883 883
     private function _parse_model_names()
884 884
     {
885 885
         // get all the files in the EE_MODELS folder that end in .model.php
886
-        $models = glob(EE_MODELS . '*.model.php');
886
+        $models = glob(EE_MODELS.'*.model.php');
887 887
         $model_names = array();
888 888
         $non_abstract_db_models = array();
889 889
         foreach ($models as $model) {
@@ -892,9 +892,9 @@  discard block
 block discarded – undo
892 892
             $short_name = str_replace('EEM_', '', $classname);
893 893
             $reflectionClass = new ReflectionClass($classname);
894 894
             if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
895
-                $non_abstract_db_models[ $short_name ] = $classname;
895
+                $non_abstract_db_models[$short_name] = $classname;
896 896
             }
897
-            $model_names[ $short_name ] = $classname;
897
+            $model_names[$short_name] = $classname;
898 898
         }
899 899
         $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
900 900
         $this->registry->non_abstract_db_models = apply_filters(
@@ -929,7 +929,7 @@  discard block
 block discarded – undo
929 929
             )
930 930
         );
931 931
         if ($domain->isCaffeinated()) {
932
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
932
+            require_once EE_CAFF_PATH.'brewing_regular.php';
933 933
         }
934 934
     }
935 935
 
@@ -997,7 +997,7 @@  discard block
 block discarded – undo
997 997
         $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
998 998
             'AHEE__EE_System__register_shortcodes_modules_and_addons'
999 999
         );
1000
-        if (! empty($class_names)) {
1000
+        if ( ! empty($class_names)) {
1001 1001
             $msg = __(
1002 1002
                 'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1003 1003
                 'event_espresso'
@@ -1009,7 +1009,7 @@  discard block
 block discarded – undo
1009 1009
                             array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1010 1010
                             '',
1011 1011
                             $class_name
1012
-                        ) . '</b></li>';
1012
+                        ).'</b></li>';
1013 1013
             }
1014 1014
             $msg .= '</ul>';
1015 1015
             $msg .= __(
@@ -1078,7 +1078,7 @@  discard block
 block discarded – undo
1078 1078
     private function _deactivate_incompatible_addons()
1079 1079
     {
1080 1080
         $incompatible_addons = get_option('ee_incompatible_addons', array());
1081
-        if (! empty($incompatible_addons)) {
1081
+        if ( ! empty($incompatible_addons)) {
1082 1082
             $active_plugins = get_option('active_plugins', array());
1083 1083
             foreach ($active_plugins as $active_plugin) {
1084 1084
                 foreach ($incompatible_addons as $incompatible_addon) {
@@ -1145,7 +1145,7 @@  discard block
 block discarded – undo
1145 1145
     {
1146 1146
         do_action('AHEE__EE_System__load_controllers__start');
1147 1147
         // let's get it started
1148
-        if (! $this->maintenance_mode->level()
1148
+        if ( ! $this->maintenance_mode->level()
1149 1149
             && ($this->request->isFrontend() || $this->request->isFrontAjax())
1150 1150
         ) {
1151 1151
             do_action('AHEE__EE_System__load_controllers__load_front_controllers');
@@ -1198,7 +1198,7 @@  discard block
 block discarded – undo
1198 1198
         do_action('AHEE__EE_System__core_loaded_and_ready');
1199 1199
         // always load template tags, because it's faster than checking if it's a front-end request, and many page
1200 1200
         // builders require these even on the front-end
1201
-        require_once EE_PUBLIC . 'template_tags.php';
1201
+        require_once EE_PUBLIC.'template_tags.php';
1202 1202
         // load handler for GraphQL requests
1203 1203
         if (class_exists('WPGraphQL') && $this->request->isGQL()) {
1204 1204
             try {
@@ -1275,13 +1275,13 @@  discard block
 block discarded – undo
1275 1275
     public static function do_not_cache()
1276 1276
     {
1277 1277
         // set no cache constants
1278
-        if (! defined('DONOTCACHEPAGE')) {
1278
+        if ( ! defined('DONOTCACHEPAGE')) {
1279 1279
             define('DONOTCACHEPAGE', true);
1280 1280
         }
1281
-        if (! defined('DONOTCACHCEOBJECT')) {
1281
+        if ( ! defined('DONOTCACHCEOBJECT')) {
1282 1282
             define('DONOTCACHCEOBJECT', true);
1283 1283
         }
1284
-        if (! defined('DONOTCACHEDB')) {
1284
+        if ( ! defined('DONOTCACHEDB')) {
1285 1285
             define('DONOTCACHEDB', true);
1286 1286
         }
1287 1287
         // add no cache headers
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 1 patch
Indentation   +1116 added lines, -1116 removed lines patch added patch discarded remove patch
@@ -20,1120 +20,1120 @@
 block discarded – undo
20 20
 class EE_Dependency_Map
21 21
 {
22 22
 
23
-    /**
24
-     * This means that the requested class dependency is not present in the dependency map
25
-     */
26
-    const not_registered = 0;
27
-
28
-    /**
29
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
-     */
31
-    const load_new_object = 1;
32
-
33
-    /**
34
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
-     */
37
-    const load_from_cache = 2;
38
-
39
-    /**
40
-     * When registering a dependency,
41
-     * this indicates to keep any existing dependencies that already exist,
42
-     * and simply discard any new dependencies declared in the incoming data
43
-     */
44
-    const KEEP_EXISTING_DEPENDENCIES = 0;
45
-
46
-    /**
47
-     * When registering a dependency,
48
-     * this indicates to overwrite any existing dependencies that already exist using the incoming data
49
-     */
50
-    const OVERWRITE_DEPENDENCIES = 1;
51
-
52
-
53
-    /**
54
-     * @type EE_Dependency_Map $_instance
55
-     */
56
-    protected static $_instance;
57
-
58
-    /**
59
-     * @var ClassInterfaceCache $class_cache
60
-     */
61
-    private $class_cache;
62
-
63
-    /**
64
-     * @type RequestInterface $request
65
-     */
66
-    protected $request;
67
-
68
-    /**
69
-     * @type LegacyRequestInterface $legacy_request
70
-     */
71
-    protected $legacy_request;
72
-
73
-    /**
74
-     * @type ResponseInterface $response
75
-     */
76
-    protected $response;
77
-
78
-    /**
79
-     * @type LoaderInterface $loader
80
-     */
81
-    protected $loader;
82
-
83
-    /**
84
-     * @type array $_dependency_map
85
-     */
86
-    protected $_dependency_map = array();
87
-
88
-    /**
89
-     * @type array $_class_loaders
90
-     */
91
-    protected $_class_loaders = array();
92
-
93
-
94
-    /**
95
-     * EE_Dependency_Map constructor.
96
-     *
97
-     * @param ClassInterfaceCache $class_cache
98
-     */
99
-    protected function __construct(ClassInterfaceCache $class_cache)
100
-    {
101
-        $this->class_cache = $class_cache;
102
-        do_action('EE_Dependency_Map____construct', $this);
103
-    }
104
-
105
-
106
-    /**
107
-     * @return void
108
-     */
109
-    public function initialize()
110
-    {
111
-        $this->_register_core_dependencies();
112
-        $this->_register_core_class_loaders();
113
-        $this->_register_core_aliases();
114
-    }
115
-
116
-
117
-    /**
118
-     * @singleton method used to instantiate class object
119
-     * @param ClassInterfaceCache|null $class_cache
120
-     * @return EE_Dependency_Map
121
-     */
122
-    public static function instance(ClassInterfaceCache $class_cache = null)
123
-    {
124
-        // check if class object is instantiated, and instantiated properly
125
-        if (! self::$_instance instanceof EE_Dependency_Map
126
-            && $class_cache instanceof ClassInterfaceCache
127
-        ) {
128
-            self::$_instance = new EE_Dependency_Map($class_cache);
129
-        }
130
-        return self::$_instance;
131
-    }
132
-
133
-
134
-    /**
135
-     * @param RequestInterface $request
136
-     */
137
-    public function setRequest(RequestInterface $request)
138
-    {
139
-        $this->request = $request;
140
-    }
141
-
142
-
143
-    /**
144
-     * @param LegacyRequestInterface $legacy_request
145
-     */
146
-    public function setLegacyRequest(LegacyRequestInterface $legacy_request)
147
-    {
148
-        $this->legacy_request = $legacy_request;
149
-    }
150
-
151
-
152
-    /**
153
-     * @param ResponseInterface $response
154
-     */
155
-    public function setResponse(ResponseInterface $response)
156
-    {
157
-        $this->response = $response;
158
-    }
159
-
160
-
161
-    /**
162
-     * @param LoaderInterface $loader
163
-     */
164
-    public function setLoader(LoaderInterface $loader)
165
-    {
166
-        $this->loader = $loader;
167
-    }
168
-
169
-
170
-    /**
171
-     * @param string $class
172
-     * @param array  $dependencies
173
-     * @param int    $overwrite
174
-     * @return bool
175
-     */
176
-    public static function register_dependencies(
177
-        $class,
178
-        array $dependencies,
179
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
180
-    ) {
181
-        return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
182
-    }
183
-
184
-
185
-    /**
186
-     * Assigns an array of class names and corresponding load sources (new or cached)
187
-     * to the class specified by the first parameter.
188
-     * IMPORTANT !!!
189
-     * The order of elements in the incoming $dependencies array MUST match
190
-     * the order of the constructor parameters for the class in question.
191
-     * This is especially important when overriding any existing dependencies that are registered.
192
-     * the third parameter controls whether any duplicate dependencies are overwritten or not.
193
-     *
194
-     * @param string $class
195
-     * @param array  $dependencies
196
-     * @param int    $overwrite
197
-     * @return bool
198
-     */
199
-    public function registerDependencies(
200
-        $class,
201
-        array $dependencies,
202
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
203
-    ) {
204
-        $class = trim($class, '\\');
205
-        $registered = false;
206
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
207
-            self::$_instance->_dependency_map[ $class ] = array();
208
-        }
209
-        // we need to make sure that any aliases used when registering a dependency
210
-        // get resolved to the correct class name
211
-        foreach ($dependencies as $dependency => $load_source) {
212
-            $alias = self::$_instance->getFqnForAlias($dependency);
213
-            if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
215
-            ) {
216
-                unset($dependencies[ $dependency ]);
217
-                $dependencies[ $alias ] = $load_source;
218
-                $registered = true;
219
-            }
220
-        }
221
-        // now add our two lists of dependencies together.
222
-        // using Union (+=) favours the arrays in precedence from left to right,
223
-        // so $dependencies is NOT overwritten because it is listed first
224
-        // ie: with A = B + C, entries in B take precedence over duplicate entries in C
225
-        // Union is way faster than array_merge() but should be used with caution...
226
-        // especially with numerically indexed arrays
227
-        $dependencies += self::$_instance->_dependency_map[ $class ];
228
-        // now we need to ensure that the resulting dependencies
229
-        // array only has the entries that are required for the class
230
-        // so first count how many dependencies were originally registered for the class
231
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
232
-        // if that count is non-zero (meaning dependencies were already registered)
233
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
234
-            // then truncate the  final array to match that count
235
-            ? array_slice($dependencies, 0, $dependency_count)
236
-            // otherwise just take the incoming array because nothing previously existed
237
-            : $dependencies;
238
-        return $registered;
239
-    }
240
-
241
-
242
-    /**
243
-     * @param string $class_name
244
-     * @param string $loader
245
-     * @return bool
246
-     * @throws DomainException
247
-     */
248
-    public static function register_class_loader($class_name, $loader = 'load_core')
249
-    {
250
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251
-            throw new DomainException(
252
-                esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253
-            );
254
-        }
255
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
256
-        if (! is_callable($loader)
257
-            && (
258
-                strpos($loader, 'load_') !== 0
259
-                || ! method_exists('EE_Registry', $loader)
260
-            )
261
-        ) {
262
-            throw new DomainException(
263
-                sprintf(
264
-                    esc_html__(
265
-                        '"%1$s" is not a valid loader method on EE_Registry.',
266
-                        'event_espresso'
267
-                    ),
268
-                    $loader
269
-                )
270
-            );
271
-        }
272
-        $class_name = self::$_instance->getFqnForAlias($class_name);
273
-        if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
-            self::$_instance->_class_loaders[ $class_name ] = $loader;
275
-            return true;
276
-        }
277
-        return false;
278
-    }
279
-
280
-
281
-    /**
282
-     * @return array
283
-     */
284
-    public function dependency_map()
285
-    {
286
-        return $this->_dependency_map;
287
-    }
288
-
289
-
290
-    /**
291
-     * returns TRUE if dependency map contains a listing for the provided class name
292
-     *
293
-     * @param string $class_name
294
-     * @return boolean
295
-     */
296
-    public function has($class_name = '')
297
-    {
298
-        // all legacy models have the same dependencies
299
-        if (strpos($class_name, 'EEM_') === 0) {
300
-            $class_name = 'LEGACY_MODELS';
301
-        }
302
-        return isset($this->_dependency_map[ $class_name ]) ? true : false;
303
-    }
304
-
305
-
306
-    /**
307
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
308
-     *
309
-     * @param string $class_name
310
-     * @param string $dependency
311
-     * @return bool
312
-     */
313
-    public function has_dependency_for_class($class_name = '', $dependency = '')
314
-    {
315
-        // all legacy models have the same dependencies
316
-        if (strpos($class_name, 'EEM_') === 0) {
317
-            $class_name = 'LEGACY_MODELS';
318
-        }
319
-        $dependency = $this->getFqnForAlias($dependency, $class_name);
320
-        return isset($this->_dependency_map[ $class_name ][ $dependency ])
321
-            ? true
322
-            : false;
323
-    }
324
-
325
-
326
-    /**
327
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
328
-     *
329
-     * @param string $class_name
330
-     * @param string $dependency
331
-     * @return int
332
-     */
333
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
334
-    {
335
-        // all legacy models have the same dependencies
336
-        if (strpos($class_name, 'EEM_') === 0) {
337
-            $class_name = 'LEGACY_MODELS';
338
-        }
339
-        $dependency = $this->getFqnForAlias($dependency);
340
-        return $this->has_dependency_for_class($class_name, $dependency)
341
-            ? $this->_dependency_map[ $class_name ][ $dependency ]
342
-            : EE_Dependency_Map::not_registered;
343
-    }
344
-
345
-
346
-    /**
347
-     * @param string $class_name
348
-     * @return string | Closure
349
-     */
350
-    public function class_loader($class_name)
351
-    {
352
-        // all legacy models use load_model()
353
-        if (strpos($class_name, 'EEM_') === 0) {
354
-            return 'load_model';
355
-        }
356
-        // EE_CPT_*_Strategy classes like EE_CPT_Event_Strategy, EE_CPT_Venue_Strategy, etc
357
-        // perform strpos() first to avoid loading regex every time we load a class
358
-        if (strpos($class_name, 'EE_CPT_') === 0
359
-            && preg_match('/^EE_CPT_([a-zA-Z]+)_Strategy$/', $class_name)
360
-        ) {
361
-            return 'load_core';
362
-        }
363
-        $class_name = $this->getFqnForAlias($class_name);
364
-        return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
365
-    }
366
-
367
-
368
-    /**
369
-     * @return array
370
-     */
371
-    public function class_loaders()
372
-    {
373
-        return $this->_class_loaders;
374
-    }
375
-
376
-
377
-    /**
378
-     * adds an alias for a classname
379
-     *
380
-     * @param string $fqcn      the class name that should be used (concrete class to replace interface)
381
-     * @param string $alias     the class name that would be type hinted for (abstract parent or interface)
382
-     * @param string $for_class the class that has the dependency (is type hinting for the interface)
383
-     */
384
-    public function add_alias($fqcn, $alias, $for_class = '')
385
-    {
386
-        $this->class_cache->addAlias($fqcn, $alias, $for_class);
387
-    }
388
-
389
-
390
-    /**
391
-     * Returns TRUE if the provided fully qualified name IS an alias
392
-     * WHY?
393
-     * Because if a class is type hinting for a concretion,
394
-     * then why would we need to find another class to supply it?
395
-     * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
396
-     * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
397
-     * Don't go looking for some substitute.
398
-     * Whereas if a class is type hinting for an interface...
399
-     * then we need to find an actual class to use.
400
-     * So the interface IS the alias for some other FQN,
401
-     * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
402
-     * represents some other class.
403
-     *
404
-     * @param string $fqn
405
-     * @param string $for_class
406
-     * @return bool
407
-     */
408
-    public function isAlias($fqn = '', $for_class = '')
409
-    {
410
-        return $this->class_cache->isAlias($fqn, $for_class);
411
-    }
412
-
413
-
414
-    /**
415
-     * Returns a FQN for provided alias if one exists, otherwise returns the original $alias
416
-     * functions recursively, so that multiple aliases can be used to drill down to a FQN
417
-     *  for example:
418
-     *      if the following two entries were added to the _aliases array:
419
-     *          array(
420
-     *              'interface_alias'           => 'some\namespace\interface'
421
-     *              'some\namespace\interface'  => 'some\namespace\classname'
422
-     *          )
423
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
424
-     *      to load an instance of 'some\namespace\classname'
425
-     *
426
-     * @param string $alias
427
-     * @param string $for_class
428
-     * @return string
429
-     */
430
-    public function getFqnForAlias($alias = '', $for_class = '')
431
-    {
432
-        return (string) $this->class_cache->getFqnForAlias($alias, $for_class);
433
-    }
434
-
435
-
436
-    /**
437
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
438
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
439
-     * This is done by using the following class constants:
440
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
441
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
442
-     */
443
-    protected function _register_core_dependencies()
444
-    {
445
-        $this->_dependency_map = array(
446
-            'EE_Request_Handler'                                                                                          => array(
447
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
448
-            ),
449
-            'EE_System'                                                                                                   => array(
450
-                'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
451
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
452
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
453
-                'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
454
-            ),
455
-            'EE_Session'                                                                                                  => array(
456
-                'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
457
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
458
-                'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
459
-                'EventEspresso\core\services\session\SessionStartHandler'  => EE_Dependency_Map::load_from_cache,
460
-                'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
461
-            ),
462
-            'EE_Cart'                                                                                                     => array(
463
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
464
-            ),
465
-            'EE_Front_Controller'                                                                                         => array(
466
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
467
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
468
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
469
-            ),
470
-            'EE_Messenger_Collection_Loader'                                                                              => array(
471
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
472
-            ),
473
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
474
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
475
-            ),
476
-            'EE_Message_Resource_Manager'                                                                                 => array(
477
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
478
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
479
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
480
-            ),
481
-            'EE_Message_Factory'                                                                                          => array(
482
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
483
-            ),
484
-            'EE_messages'                                                                                                 => array(
485
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
-            ),
487
-            'EE_Messages_Generator'                                                                                       => array(
488
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
489
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
490
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
491
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
492
-            ),
493
-            'EE_Messages_Processor'                                                                                       => array(
494
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
495
-            ),
496
-            'EE_Messages_Queue'                                                                                           => array(
497
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
498
-            ),
499
-            'EE_Messages_Template_Defaults'                                                                               => array(
500
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
501
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
502
-            ),
503
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
504
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
505
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
506
-            ),
507
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
508
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
509
-            ),
510
-            'EventEspresso\services\commands\CommandHandler'                                                              => array(
511
-                'EE_Registry'         => EE_Dependency_Map::load_from_cache,
512
-                'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
513
-            ),
514
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
515
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
516
-            ),
517
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
518
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
519
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
520
-            ),
521
-            'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
522
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
523
-            ),
524
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
525
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
526
-            ),
527
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
528
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
529
-            ),
530
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
531
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
532
-            ),
533
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
534
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
535
-            ),
536
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
537
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
538
-            ),
539
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
540
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
541
-            ),
542
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
543
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
-            ),
545
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
546
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
547
-            ),
548
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
549
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
550
-            ),
551
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
552
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
553
-            ),
554
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
555
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
556
-            ),
557
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
558
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
559
-            ),
560
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
561
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
562
-            ),
563
-            'EE_Data_Migration_Class_Base'                                                                                => array(
564
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
565
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
566
-            ),
567
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
568
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
569
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
570
-            ),
571
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
572
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
573
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
574
-            ),
575
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
576
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
577
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
578
-            ),
579
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
580
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
581
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
582
-            ),
583
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
584
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
585
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
586
-            ),
587
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
588
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
589
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
590
-            ),
591
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
592
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
593
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
594
-            ),
595
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
596
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
597
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
598
-            ),
599
-            'EE_DMS_Core_4_9_0' => array(
600
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
601
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
602
-            ),
603
-            'EE_DMS_Core_4_10_0' => array(
604
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
605
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
606
-                'EE_DMS_Core_4_9_0'                                  => EE_Dependency_Map::load_from_cache,
607
-            ),
608
-            'EventEspresso\core\services\assets\I18nRegistry'                                                             => array(
609
-                array(),
610
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
611
-            ),
612
-            'EventEspresso\core\services\assets\Registry'                                                                 => array(
613
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
614
-                'EventEspresso\core\services\assets\I18nRegistry'    => EE_Dependency_Map::load_from_cache,
615
-            ),
616
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
617
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
-            ),
619
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
620
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
621
-            ),
622
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
623
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
624
-            ),
625
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
626
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
627
-            ),
628
-            'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
629
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
630
-            ),
631
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
632
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
633
-            ),
634
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
635
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
636
-            ),
637
-            'EventEspresso\core\services\cache\BasicCacheManager'                                                         => array(
638
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
639
-            ),
640
-            'EventEspresso\core\services\cache\PostRelatedCacheManager'                                                   => array(
641
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
642
-            ),
643
-            'EventEspresso\core\domain\services\validation\email\EmailValidationService'                                  => array(
644
-                'EE_Registration_Config'                     => EE_Dependency_Map::load_from_cache,
645
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
646
-            ),
647
-            'EventEspresso\core\domain\values\EmailAddress'                                                               => array(
648
-                null,
649
-                'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
650
-            ),
651
-            'EventEspresso\core\services\orm\ModelFieldFactory'                                                           => array(
652
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
653
-            ),
654
-            'LEGACY_MODELS'                                                                                               => array(
655
-                null,
656
-                'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
657
-            ),
658
-            'EE_Module_Request_Router'                                                                                    => array(
659
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
660
-            ),
661
-            'EE_Registration_Processor'                                                                                   => array(
662
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
663
-            ),
664
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'                                      => array(
665
-                null,
666
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
667
-                'EventEspresso\core\services\request\Request'                         => EE_Dependency_Map::load_from_cache,
668
-            ),
669
-            'EventEspresso\core\services\licensing\LicenseService'                                                        => array(
670
-                'EventEspresso\core\domain\services\pue\Stats'  => EE_Dependency_Map::load_from_cache,
671
-                'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
672
-            ),
673
-            'EE_Admin_Transactions_List_Table'                                                                            => array(
674
-                null,
675
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
676
-            ),
677
-            'EventEspresso\core\domain\services\pue\Stats'                                                                => array(
678
-                'EventEspresso\core\domain\services\pue\Config'        => EE_Dependency_Map::load_from_cache,
679
-                'EE_Maintenance_Mode'                                  => EE_Dependency_Map::load_from_cache,
680
-                'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache,
681
-            ),
682
-            'EventEspresso\core\domain\services\pue\Config'                                                               => array(
683
-                'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
684
-                'EE_Config'         => EE_Dependency_Map::load_from_cache,
685
-            ),
686
-            'EventEspresso\core\domain\services\pue\StatsGatherer'                                                        => array(
687
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
688
-                'EEM_Event'          => EE_Dependency_Map::load_from_cache,
689
-                'EEM_Datetime'       => EE_Dependency_Map::load_from_cache,
690
-                'EEM_Ticket'         => EE_Dependency_Map::load_from_cache,
691
-                'EEM_Registration'   => EE_Dependency_Map::load_from_cache,
692
-                'EEM_Transaction'    => EE_Dependency_Map::load_from_cache,
693
-                'EE_Config'          => EE_Dependency_Map::load_from_cache,
694
-            ),
695
-            'EventEspresso\core\domain\services\admin\ExitModal'                                                          => array(
696
-                'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache,
697
-            ),
698
-            'EventEspresso\core\domain\services\admin\PluginUpsells'                                                      => array(
699
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
700
-            ),
701
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha'                                    => array(
702
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
703
-                'EE_Session'             => EE_Dependency_Map::load_from_cache,
704
-            ),
705
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings'                                => array(
706
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
707
-            ),
708
-            'EventEspresso\modules\ticket_selector\ProcessTicketSelector'                                                 => array(
709
-                'EE_Core_Config'                                                          => EE_Dependency_Map::load_from_cache,
710
-                'EventEspresso\core\services\request\Request'                             => EE_Dependency_Map::load_from_cache,
711
-                'EE_Session'                                                              => EE_Dependency_Map::load_from_cache,
712
-                'EEM_Ticket'                                                              => EE_Dependency_Map::load_from_cache,
713
-                'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
714
-            ),
715
-            'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker'                                     => array(
716
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
717
-            ),
718
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'                              => array(
719
-                'EE_Core_Config'                             => EE_Dependency_Map::load_from_cache,
720
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
721
-            ),
722
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'                                => array(
723
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
724
-            ),
725
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'                               => array(
726
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
727
-            ),
728
-            'EE_CPT_Strategy'                                                                                             => array(
729
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
730
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
731
-            ),
732
-            'EventEspresso\core\services\loaders\ObjectIdentifier'                                                        => array(
733
-                'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
734
-            ),
735
-            'EventEspresso\core\domain\services\assets\CoreAssetManager'                                                  => array(
736
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
737
-                'EE_Currency_Config'                                 => EE_Dependency_Map::load_from_cache,
738
-                'EE_Template_Config'                                 => EE_Dependency_Map::load_from_cache,
739
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
740
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
741
-            ),
742
-            'EventEspresso\core\domain\services\admin\privacy\policy\PrivacyPolicy' => array(
743
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
744
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache
745
-            ),
746
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendee' => array(
747
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
748
-            ),
749
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendeeBillingData' => array(
750
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
751
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache
752
-            ),
753
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportCheckins' => array(
754
-                'EEM_Checkin' => EE_Dependency_Map::load_from_cache,
755
-            ),
756
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportRegistration' => array(
757
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache,
758
-            ),
759
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportTransaction' => array(
760
-                'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
761
-            ),
762
-            'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAttendeeData' => array(
763
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
764
-            ),
765
-            'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAnswers' => array(
766
-                'EEM_Answer' => EE_Dependency_Map::load_from_cache,
767
-                'EEM_Question' => EE_Dependency_Map::load_from_cache,
768
-            ),
769
-            'EventEspresso\core\CPTs\CptQueryModifier' => array(
770
-                null,
771
-                null,
772
-                null,
773
-                'EE_Request_Handler'                          => EE_Dependency_Map::load_from_cache,
774
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
775
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
776
-            ),
777
-            'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler' => array(
778
-                'EE_Registry' => EE_Dependency_Map::load_from_cache,
779
-                'EE_Config' => EE_Dependency_Map::load_from_cache
780
-            ),
781
-            'EventEspresso\core\services\editor\BlockRegistrationManager'                                                 => array(
782
-                'EventEspresso\core\services\assets\BlockAssetManagerCollection' => EE_Dependency_Map::load_from_cache,
783
-                'EventEspresso\core\domain\entities\editor\BlockCollection'      => EE_Dependency_Map::load_from_cache,
784
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => EE_Dependency_Map::load_from_cache,
785
-                'EventEspresso\core\services\request\Request'                    => EE_Dependency_Map::load_from_cache,
786
-            ),
787
-            'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => array(
788
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
789
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
790
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
791
-            ),
792
-            'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => array(
793
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
794
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
795
-            ),
796
-            'EventEspresso\core\domain\entities\editor\blocks\EventAttendees' => array(
797
-                'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => self::load_from_cache,
798
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
799
-                'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => self::load_from_cache,
800
-            ),
801
-            'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => array(
802
-                'EventEspresso\core\services\container\Mirror' => EE_Dependency_Map::load_from_cache,
803
-                'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
804
-                'EE_Dependency_Map' => EE_Dependency_Map::load_from_cache,
805
-            ),
806
-            'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => array(
807
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => EE_Dependency_Map::load_from_cache,
808
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
809
-            ),
810
-            'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => array(
811
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationCollection' => EE_Dependency_Map::load_from_cache,
812
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => EE_Dependency_Map::load_from_cache,
813
-            ),
814
-            'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => array(
815
-                'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => EE_Dependency_Map::load_from_cache
816
-            ),
817
-            'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => array(
818
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
819
-            ),
820
-            'EventEspresso\core\libraries\rest_api\controllers\model\Read' => array(
821
-                'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => EE_Dependency_Map::load_from_cache
822
-            ),
823
-            'EventEspresso\core\libraries\rest_api\calculations\Datetime' => array(
824
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
825
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache
826
-            ),
827
-            'EventEspresso\core\libraries\rest_api\calculations\Event' => array(
828
-                'EEM_Event' => EE_Dependency_Map::load_from_cache,
829
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache
830
-            ),
831
-            'EventEspresso\core\libraries\rest_api\calculations\Registration' => array(
832
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache
833
-            ),
834
-            'EventEspresso\core\services\session\SessionStartHandler' => array(
835
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
836
-            ),
837
-            'EE_URL_Validation_Strategy' => array(
838
-                null,
839
-                null,
840
-                'EventEspresso\core\services\validators\URLValidator' => EE_Dependency_Map::load_from_cache
841
-            ),
842
-            'EventEspresso\admin_pages\general_settings\OrganizationSettings' => array(
843
-                'EE_Registry'                                             => EE_Dependency_Map::load_from_cache,
844
-                'EE_Organization_Config'                                  => EE_Dependency_Map::load_from_cache,
845
-                'EE_Core_Config'                                          => EE_Dependency_Map::load_from_cache,
846
-                'EE_Network_Core_Config'                                  => EE_Dependency_Map::load_from_cache,
847
-                'EventEspresso\core\services\address\CountrySubRegionDao' => EE_Dependency_Map::load_from_cache,
848
-            ),
849
-            'EventEspresso\core\services\address\CountrySubRegionDao' => array(
850
-                'EEM_State'                                            => EE_Dependency_Map::load_from_cache,
851
-                'EventEspresso\core\services\validators\JsonValidator' => EE_Dependency_Map::load_from_cache
852
-            ),
853
-            'EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat' => array(
854
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
855
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
856
-            ),
857
-            'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat' => array(
858
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
859
-                'EE_Environment_Config'            => EE_Dependency_Map::load_from_cache,
860
-            ),
861
-            'EventEspresso\core\services\request\files\FilesDataHandler' => array(
862
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
863
-            ),
864
-            'EventEspressoBatchRequest\BatchRequestProcessor'                              => [
865
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
866
-            ],
867
-            'EventEspresso\core\services\graphql\RequestHandler'                           => [
868
-                'EventEspresso\core\services\graphql\ResolverCollection'  => EE_Dependency_Map::load_from_cache,
869
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
870
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
871
-            ],
872
-            'EventEspresso\core\domain\services\converters\spoofers\RestApiSpoofer' => [
873
-                'EventEspresso\core\libraries\rest_api\controllers\model\Read' => EE_Dependency_Map::load_from_cache,
874
-                null
875
-            ],
876
-            'EventEspresso\core\domain\services\graphql\resolvers\EventEditorDataResolver' => [
877
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
878
-                'EventEspresso\core\domain\services\converters\spoofers\RestApiSpoofer' => EE_Dependency_Map::load_from_cache,
879
-            ],
880
-        );
881
-    }
882
-
883
-
884
-    /**
885
-     * Registers how core classes are loaded.
886
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
887
-     *        'EE_Request_Handler' => 'load_core'
888
-     *        'EE_Messages_Queue'  => 'load_lib'
889
-     *        'EEH_Debug_Tools'    => 'load_helper'
890
-     * or, if greater control is required, by providing a custom closure. For example:
891
-     *        'Some_Class' => function () {
892
-     *            return new Some_Class();
893
-     *        },
894
-     * This is required for instantiating dependencies
895
-     * where an interface has been type hinted in a class constructor. For example:
896
-     *        'Required_Interface' => function () {
897
-     *            return new A_Class_That_Implements_Required_Interface();
898
-     *        },
899
-     */
900
-    protected function _register_core_class_loaders()
901
-    {
902
-        $this->_class_loaders = array(
903
-            // load_core
904
-            'EE_Dependency_Map'                            => function () {
905
-                return $this;
906
-            },
907
-            'EE_Capabilities'                              => 'load_core',
908
-            'EE_Encryption'                                => 'load_core',
909
-            'EE_Front_Controller'                          => 'load_core',
910
-            'EE_Module_Request_Router'                     => 'load_core',
911
-            'EE_Registry'                                  => 'load_core',
912
-            'EE_Request'                                   => function () {
913
-                return $this->legacy_request;
914
-            },
915
-            'EventEspresso\core\services\request\Request'  => function () {
916
-                return $this->request;
917
-            },
918
-            'EventEspresso\core\services\request\Response' => function () {
919
-                return $this->response;
920
-            },
921
-            'EE_Base'                                      => 'load_core',
922
-            'EE_Request_Handler'                           => 'load_core',
923
-            'EE_Session'                                   => 'load_core',
924
-            'EE_Cron_Tasks'                                => 'load_core',
925
-            'EE_System'                                    => 'load_core',
926
-            'EE_Maintenance_Mode'                          => 'load_core',
927
-            'EE_Register_CPTs'                             => 'load_core',
928
-            'EE_Admin'                                     => 'load_core',
929
-            'EE_CPT_Strategy'                              => 'load_core',
930
-            // load_class
931
-            'EE_Registration_Processor'                    => 'load_class',
932
-            // load_lib
933
-            'EE_Message_Resource_Manager'                  => 'load_lib',
934
-            'EE_Message_Type_Collection'                   => 'load_lib',
935
-            'EE_Message_Type_Collection_Loader'            => 'load_lib',
936
-            'EE_Messenger_Collection'                      => 'load_lib',
937
-            'EE_Messenger_Collection_Loader'               => 'load_lib',
938
-            'EE_Messages_Processor'                        => 'load_lib',
939
-            'EE_Message_Repository'                        => 'load_lib',
940
-            'EE_Messages_Queue'                            => 'load_lib',
941
-            'EE_Messages_Data_Handler_Collection'          => 'load_lib',
942
-            'EE_Message_Template_Group_Collection'         => 'load_lib',
943
-            'EE_Payment_Method_Manager'                    => 'load_lib',
944
-            'EE_DMS_Core_4_1_0'                            => 'load_dms',
945
-            'EE_DMS_Core_4_2_0'                            => 'load_dms',
946
-            'EE_DMS_Core_4_3_0'                            => 'load_dms',
947
-            'EE_DMS_Core_4_5_0'                            => 'load_dms',
948
-            'EE_DMS_Core_4_6_0'                            => 'load_dms',
949
-            'EE_DMS_Core_4_7_0'                            => 'load_dms',
950
-            'EE_DMS_Core_4_8_0'                            => 'load_dms',
951
-            'EE_DMS_Core_4_9_0'                            => 'load_dms',
952
-            'EE_DMS_Core_4_10_0'                            => 'load_dms',
953
-            'EE_Messages_Generator'                        => function () {
954
-                return EE_Registry::instance()->load_lib(
955
-                    'Messages_Generator',
956
-                    array(),
957
-                    false,
958
-                    false
959
-                );
960
-            },
961
-            'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
962
-                return EE_Registry::instance()->load_lib(
963
-                    'Messages_Template_Defaults',
964
-                    $arguments,
965
-                    false,
966
-                    false
967
-                );
968
-            },
969
-            // load_helper
970
-            'EEH_Parse_Shortcodes'                         => function () {
971
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
972
-                    return new EEH_Parse_Shortcodes();
973
-                }
974
-                return null;
975
-            },
976
-            'EE_Template_Config'                           => function () {
977
-                return EE_Config::instance()->template_settings;
978
-            },
979
-            'EE_Currency_Config'                           => function () {
980
-                return EE_Config::instance()->currency;
981
-            },
982
-            'EE_Registration_Config'                       => function () {
983
-                return EE_Config::instance()->registration;
984
-            },
985
-            'EE_Core_Config'                               => function () {
986
-                return EE_Config::instance()->core;
987
-            },
988
-            'EventEspresso\core\services\loaders\Loader'   => function () {
989
-                return LoaderFactory::getLoader();
990
-            },
991
-            'EE_Network_Config'                            => function () {
992
-                return EE_Network_Config::instance();
993
-            },
994
-            'EE_Config'                                    => function () {
995
-                return EE_Config::instance();
996
-            },
997
-            'EventEspresso\core\domain\Domain'             => function () {
998
-                return DomainFactory::getEventEspressoCoreDomain();
999
-            },
1000
-            'EE_Admin_Config'                              => function () {
1001
-                return EE_Config::instance()->admin;
1002
-            },
1003
-            'EE_Organization_Config'                       => function () {
1004
-                return EE_Config::instance()->organization;
1005
-            },
1006
-            'EE_Network_Core_Config'                       => function () {
1007
-                return EE_Network_Config::instance()->core;
1008
-            },
1009
-            'EE_Environment_Config'                        => function () {
1010
-                return EE_Config::instance()->environment;
1011
-            },
1012
-        );
1013
-    }
1014
-
1015
-
1016
-    /**
1017
-     * can be used for supplying alternate names for classes,
1018
-     * or for connecting interface names to instantiable classes
1019
-     */
1020
-    protected function _register_core_aliases()
1021
-    {
1022
-        $aliases = array(
1023
-            'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
1024
-            'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
1025
-            'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
1026
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
1027
-            'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
1028
-            'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
1029
-            'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1030
-            'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
1031
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1032
-            'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
1033
-            'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1034
-            'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
1035
-            'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
1036
-            'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
1037
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
1038
-            'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
1039
-            'CreateTransactionCommandHandler'                                              => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
1040
-            'CreateAttendeeCommandHandler'                                                 => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
1041
-            'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
1042
-            'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
1043
-            'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1044
-            'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
1045
-            'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1046
-            'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
1047
-            'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
1048
-            'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
1049
-            'CommandFactoryInterface'                                                      => 'EventEspresso\core\services\commands\CommandFactoryInterface',
1050
-            'EventEspresso\core\services\commands\CommandFactoryInterface'                 => 'EventEspresso\core\services\commands\CommandFactory',
1051
-            'EmailValidatorInterface'                                                      => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
1052
-            'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface'  => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
1053
-            'NoticeConverterInterface'                                                     => 'EventEspresso\core\services\notices\NoticeConverterInterface',
1054
-            'EventEspresso\core\services\notices\NoticeConverterInterface'                 => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
1055
-            'NoticesContainerInterface'                                                    => 'EventEspresso\core\services\notices\NoticesContainerInterface',
1056
-            'EventEspresso\core\services\notices\NoticesContainerInterface'                => 'EventEspresso\core\services\notices\NoticesContainer',
1057
-            'EventEspresso\core\services\request\RequestInterface'                         => 'EventEspresso\core\services\request\Request',
1058
-            'EventEspresso\core\services\request\ResponseInterface'                        => 'EventEspresso\core\services\request\Response',
1059
-            'EventEspresso\core\domain\DomainInterface'                                    => 'EventEspresso\core\domain\Domain',
1060
-            'Registration_Processor'                                                       => 'EE_Registration_Processor',
1061
-        );
1062
-        foreach ($aliases as $alias => $fqn) {
1063
-            if (is_array($fqn)) {
1064
-                foreach ($fqn as $class => $for_class) {
1065
-                    $this->class_cache->addAlias($class, $alias, $for_class);
1066
-                }
1067
-                continue;
1068
-            }
1069
-            $this->class_cache->addAlias($fqn, $alias);
1070
-        }
1071
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1072
-            $this->class_cache->addAlias(
1073
-                'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
1074
-                'EventEspresso\core\services\notices\NoticeConverterInterface'
1075
-            );
1076
-        }
1077
-    }
1078
-
1079
-
1080
-    /**
1081
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
1082
-     * request Primarily used by unit tests.
1083
-     */
1084
-    public function reset()
1085
-    {
1086
-        $this->_register_core_class_loaders();
1087
-        $this->_register_core_dependencies();
1088
-    }
1089
-
1090
-
1091
-    /**
1092
-     * PLZ NOTE: a better name for this method would be is_alias()
1093
-     * because it returns TRUE if the provided fully qualified name IS an alias
1094
-     * WHY?
1095
-     * Because if a class is type hinting for a concretion,
1096
-     * then why would we need to find another class to supply it?
1097
-     * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
1098
-     * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
1099
-     * Don't go looking for some substitute.
1100
-     * Whereas if a class is type hinting for an interface...
1101
-     * then we need to find an actual class to use.
1102
-     * So the interface IS the alias for some other FQN,
1103
-     * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
1104
-     * represents some other class.
1105
-     *
1106
-     * @deprecated 4.9.62.p
1107
-     * @param string $fqn
1108
-     * @param string $for_class
1109
-     * @return bool
1110
-     */
1111
-    public function has_alias($fqn = '', $for_class = '')
1112
-    {
1113
-        return $this->isAlias($fqn, $for_class);
1114
-    }
1115
-
1116
-
1117
-    /**
1118
-     * PLZ NOTE: a better name for this method would be get_fqn_for_alias()
1119
-     * because it returns a FQN for provided alias if one exists, otherwise returns the original $alias
1120
-     * functions recursively, so that multiple aliases can be used to drill down to a FQN
1121
-     *  for example:
1122
-     *      if the following two entries were added to the _aliases array:
1123
-     *          array(
1124
-     *              'interface_alias'           => 'some\namespace\interface'
1125
-     *              'some\namespace\interface'  => 'some\namespace\classname'
1126
-     *          )
1127
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
1128
-     *      to load an instance of 'some\namespace\classname'
1129
-     *
1130
-     * @deprecated 4.9.62.p
1131
-     * @param string $alias
1132
-     * @param string $for_class
1133
-     * @return string
1134
-     */
1135
-    public function get_alias($alias = '', $for_class = '')
1136
-    {
1137
-        return $this->getFqnForAlias($alias, $for_class);
1138
-    }
23
+	/**
24
+	 * This means that the requested class dependency is not present in the dependency map
25
+	 */
26
+	const not_registered = 0;
27
+
28
+	/**
29
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
+	 */
31
+	const load_new_object = 1;
32
+
33
+	/**
34
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
+	 */
37
+	const load_from_cache = 2;
38
+
39
+	/**
40
+	 * When registering a dependency,
41
+	 * this indicates to keep any existing dependencies that already exist,
42
+	 * and simply discard any new dependencies declared in the incoming data
43
+	 */
44
+	const KEEP_EXISTING_DEPENDENCIES = 0;
45
+
46
+	/**
47
+	 * When registering a dependency,
48
+	 * this indicates to overwrite any existing dependencies that already exist using the incoming data
49
+	 */
50
+	const OVERWRITE_DEPENDENCIES = 1;
51
+
52
+
53
+	/**
54
+	 * @type EE_Dependency_Map $_instance
55
+	 */
56
+	protected static $_instance;
57
+
58
+	/**
59
+	 * @var ClassInterfaceCache $class_cache
60
+	 */
61
+	private $class_cache;
62
+
63
+	/**
64
+	 * @type RequestInterface $request
65
+	 */
66
+	protected $request;
67
+
68
+	/**
69
+	 * @type LegacyRequestInterface $legacy_request
70
+	 */
71
+	protected $legacy_request;
72
+
73
+	/**
74
+	 * @type ResponseInterface $response
75
+	 */
76
+	protected $response;
77
+
78
+	/**
79
+	 * @type LoaderInterface $loader
80
+	 */
81
+	protected $loader;
82
+
83
+	/**
84
+	 * @type array $_dependency_map
85
+	 */
86
+	protected $_dependency_map = array();
87
+
88
+	/**
89
+	 * @type array $_class_loaders
90
+	 */
91
+	protected $_class_loaders = array();
92
+
93
+
94
+	/**
95
+	 * EE_Dependency_Map constructor.
96
+	 *
97
+	 * @param ClassInterfaceCache $class_cache
98
+	 */
99
+	protected function __construct(ClassInterfaceCache $class_cache)
100
+	{
101
+		$this->class_cache = $class_cache;
102
+		do_action('EE_Dependency_Map____construct', $this);
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return void
108
+	 */
109
+	public function initialize()
110
+	{
111
+		$this->_register_core_dependencies();
112
+		$this->_register_core_class_loaders();
113
+		$this->_register_core_aliases();
114
+	}
115
+
116
+
117
+	/**
118
+	 * @singleton method used to instantiate class object
119
+	 * @param ClassInterfaceCache|null $class_cache
120
+	 * @return EE_Dependency_Map
121
+	 */
122
+	public static function instance(ClassInterfaceCache $class_cache = null)
123
+	{
124
+		// check if class object is instantiated, and instantiated properly
125
+		if (! self::$_instance instanceof EE_Dependency_Map
126
+			&& $class_cache instanceof ClassInterfaceCache
127
+		) {
128
+			self::$_instance = new EE_Dependency_Map($class_cache);
129
+		}
130
+		return self::$_instance;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @param RequestInterface $request
136
+	 */
137
+	public function setRequest(RequestInterface $request)
138
+	{
139
+		$this->request = $request;
140
+	}
141
+
142
+
143
+	/**
144
+	 * @param LegacyRequestInterface $legacy_request
145
+	 */
146
+	public function setLegacyRequest(LegacyRequestInterface $legacy_request)
147
+	{
148
+		$this->legacy_request = $legacy_request;
149
+	}
150
+
151
+
152
+	/**
153
+	 * @param ResponseInterface $response
154
+	 */
155
+	public function setResponse(ResponseInterface $response)
156
+	{
157
+		$this->response = $response;
158
+	}
159
+
160
+
161
+	/**
162
+	 * @param LoaderInterface $loader
163
+	 */
164
+	public function setLoader(LoaderInterface $loader)
165
+	{
166
+		$this->loader = $loader;
167
+	}
168
+
169
+
170
+	/**
171
+	 * @param string $class
172
+	 * @param array  $dependencies
173
+	 * @param int    $overwrite
174
+	 * @return bool
175
+	 */
176
+	public static function register_dependencies(
177
+		$class,
178
+		array $dependencies,
179
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
180
+	) {
181
+		return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
182
+	}
183
+
184
+
185
+	/**
186
+	 * Assigns an array of class names and corresponding load sources (new or cached)
187
+	 * to the class specified by the first parameter.
188
+	 * IMPORTANT !!!
189
+	 * The order of elements in the incoming $dependencies array MUST match
190
+	 * the order of the constructor parameters for the class in question.
191
+	 * This is especially important when overriding any existing dependencies that are registered.
192
+	 * the third parameter controls whether any duplicate dependencies are overwritten or not.
193
+	 *
194
+	 * @param string $class
195
+	 * @param array  $dependencies
196
+	 * @param int    $overwrite
197
+	 * @return bool
198
+	 */
199
+	public function registerDependencies(
200
+		$class,
201
+		array $dependencies,
202
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
203
+	) {
204
+		$class = trim($class, '\\');
205
+		$registered = false;
206
+		if (empty(self::$_instance->_dependency_map[ $class ])) {
207
+			self::$_instance->_dependency_map[ $class ] = array();
208
+		}
209
+		// we need to make sure that any aliases used when registering a dependency
210
+		// get resolved to the correct class name
211
+		foreach ($dependencies as $dependency => $load_source) {
212
+			$alias = self::$_instance->getFqnForAlias($dependency);
213
+			if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
+				|| ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
215
+			) {
216
+				unset($dependencies[ $dependency ]);
217
+				$dependencies[ $alias ] = $load_source;
218
+				$registered = true;
219
+			}
220
+		}
221
+		// now add our two lists of dependencies together.
222
+		// using Union (+=) favours the arrays in precedence from left to right,
223
+		// so $dependencies is NOT overwritten because it is listed first
224
+		// ie: with A = B + C, entries in B take precedence over duplicate entries in C
225
+		// Union is way faster than array_merge() but should be used with caution...
226
+		// especially with numerically indexed arrays
227
+		$dependencies += self::$_instance->_dependency_map[ $class ];
228
+		// now we need to ensure that the resulting dependencies
229
+		// array only has the entries that are required for the class
230
+		// so first count how many dependencies were originally registered for the class
231
+		$dependency_count = count(self::$_instance->_dependency_map[ $class ]);
232
+		// if that count is non-zero (meaning dependencies were already registered)
233
+		self::$_instance->_dependency_map[ $class ] = $dependency_count
234
+			// then truncate the  final array to match that count
235
+			? array_slice($dependencies, 0, $dependency_count)
236
+			// otherwise just take the incoming array because nothing previously existed
237
+			: $dependencies;
238
+		return $registered;
239
+	}
240
+
241
+
242
+	/**
243
+	 * @param string $class_name
244
+	 * @param string $loader
245
+	 * @return bool
246
+	 * @throws DomainException
247
+	 */
248
+	public static function register_class_loader($class_name, $loader = 'load_core')
249
+	{
250
+		if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251
+			throw new DomainException(
252
+				esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253
+			);
254
+		}
255
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
256
+		if (! is_callable($loader)
257
+			&& (
258
+				strpos($loader, 'load_') !== 0
259
+				|| ! method_exists('EE_Registry', $loader)
260
+			)
261
+		) {
262
+			throw new DomainException(
263
+				sprintf(
264
+					esc_html__(
265
+						'"%1$s" is not a valid loader method on EE_Registry.',
266
+						'event_espresso'
267
+					),
268
+					$loader
269
+				)
270
+			);
271
+		}
272
+		$class_name = self::$_instance->getFqnForAlias($class_name);
273
+		if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
+			self::$_instance->_class_loaders[ $class_name ] = $loader;
275
+			return true;
276
+		}
277
+		return false;
278
+	}
279
+
280
+
281
+	/**
282
+	 * @return array
283
+	 */
284
+	public function dependency_map()
285
+	{
286
+		return $this->_dependency_map;
287
+	}
288
+
289
+
290
+	/**
291
+	 * returns TRUE if dependency map contains a listing for the provided class name
292
+	 *
293
+	 * @param string $class_name
294
+	 * @return boolean
295
+	 */
296
+	public function has($class_name = '')
297
+	{
298
+		// all legacy models have the same dependencies
299
+		if (strpos($class_name, 'EEM_') === 0) {
300
+			$class_name = 'LEGACY_MODELS';
301
+		}
302
+		return isset($this->_dependency_map[ $class_name ]) ? true : false;
303
+	}
304
+
305
+
306
+	/**
307
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
308
+	 *
309
+	 * @param string $class_name
310
+	 * @param string $dependency
311
+	 * @return bool
312
+	 */
313
+	public function has_dependency_for_class($class_name = '', $dependency = '')
314
+	{
315
+		// all legacy models have the same dependencies
316
+		if (strpos($class_name, 'EEM_') === 0) {
317
+			$class_name = 'LEGACY_MODELS';
318
+		}
319
+		$dependency = $this->getFqnForAlias($dependency, $class_name);
320
+		return isset($this->_dependency_map[ $class_name ][ $dependency ])
321
+			? true
322
+			: false;
323
+	}
324
+
325
+
326
+	/**
327
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
328
+	 *
329
+	 * @param string $class_name
330
+	 * @param string $dependency
331
+	 * @return int
332
+	 */
333
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
334
+	{
335
+		// all legacy models have the same dependencies
336
+		if (strpos($class_name, 'EEM_') === 0) {
337
+			$class_name = 'LEGACY_MODELS';
338
+		}
339
+		$dependency = $this->getFqnForAlias($dependency);
340
+		return $this->has_dependency_for_class($class_name, $dependency)
341
+			? $this->_dependency_map[ $class_name ][ $dependency ]
342
+			: EE_Dependency_Map::not_registered;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @param string $class_name
348
+	 * @return string | Closure
349
+	 */
350
+	public function class_loader($class_name)
351
+	{
352
+		// all legacy models use load_model()
353
+		if (strpos($class_name, 'EEM_') === 0) {
354
+			return 'load_model';
355
+		}
356
+		// EE_CPT_*_Strategy classes like EE_CPT_Event_Strategy, EE_CPT_Venue_Strategy, etc
357
+		// perform strpos() first to avoid loading regex every time we load a class
358
+		if (strpos($class_name, 'EE_CPT_') === 0
359
+			&& preg_match('/^EE_CPT_([a-zA-Z]+)_Strategy$/', $class_name)
360
+		) {
361
+			return 'load_core';
362
+		}
363
+		$class_name = $this->getFqnForAlias($class_name);
364
+		return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
365
+	}
366
+
367
+
368
+	/**
369
+	 * @return array
370
+	 */
371
+	public function class_loaders()
372
+	{
373
+		return $this->_class_loaders;
374
+	}
375
+
376
+
377
+	/**
378
+	 * adds an alias for a classname
379
+	 *
380
+	 * @param string $fqcn      the class name that should be used (concrete class to replace interface)
381
+	 * @param string $alias     the class name that would be type hinted for (abstract parent or interface)
382
+	 * @param string $for_class the class that has the dependency (is type hinting for the interface)
383
+	 */
384
+	public function add_alias($fqcn, $alias, $for_class = '')
385
+	{
386
+		$this->class_cache->addAlias($fqcn, $alias, $for_class);
387
+	}
388
+
389
+
390
+	/**
391
+	 * Returns TRUE if the provided fully qualified name IS an alias
392
+	 * WHY?
393
+	 * Because if a class is type hinting for a concretion,
394
+	 * then why would we need to find another class to supply it?
395
+	 * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
396
+	 * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
397
+	 * Don't go looking for some substitute.
398
+	 * Whereas if a class is type hinting for an interface...
399
+	 * then we need to find an actual class to use.
400
+	 * So the interface IS the alias for some other FQN,
401
+	 * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
402
+	 * represents some other class.
403
+	 *
404
+	 * @param string $fqn
405
+	 * @param string $for_class
406
+	 * @return bool
407
+	 */
408
+	public function isAlias($fqn = '', $for_class = '')
409
+	{
410
+		return $this->class_cache->isAlias($fqn, $for_class);
411
+	}
412
+
413
+
414
+	/**
415
+	 * Returns a FQN for provided alias if one exists, otherwise returns the original $alias
416
+	 * functions recursively, so that multiple aliases can be used to drill down to a FQN
417
+	 *  for example:
418
+	 *      if the following two entries were added to the _aliases array:
419
+	 *          array(
420
+	 *              'interface_alias'           => 'some\namespace\interface'
421
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
422
+	 *          )
423
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
424
+	 *      to load an instance of 'some\namespace\classname'
425
+	 *
426
+	 * @param string $alias
427
+	 * @param string $for_class
428
+	 * @return string
429
+	 */
430
+	public function getFqnForAlias($alias = '', $for_class = '')
431
+	{
432
+		return (string) $this->class_cache->getFqnForAlias($alias, $for_class);
433
+	}
434
+
435
+
436
+	/**
437
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
438
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
439
+	 * This is done by using the following class constants:
440
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
441
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
442
+	 */
443
+	protected function _register_core_dependencies()
444
+	{
445
+		$this->_dependency_map = array(
446
+			'EE_Request_Handler'                                                                                          => array(
447
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
448
+			),
449
+			'EE_System'                                                                                                   => array(
450
+				'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
451
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
452
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
453
+				'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
454
+			),
455
+			'EE_Session'                                                                                                  => array(
456
+				'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
457
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
458
+				'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
459
+				'EventEspresso\core\services\session\SessionStartHandler'  => EE_Dependency_Map::load_from_cache,
460
+				'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
461
+			),
462
+			'EE_Cart'                                                                                                     => array(
463
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
464
+			),
465
+			'EE_Front_Controller'                                                                                         => array(
466
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
467
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
468
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
469
+			),
470
+			'EE_Messenger_Collection_Loader'                                                                              => array(
471
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
472
+			),
473
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
474
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
475
+			),
476
+			'EE_Message_Resource_Manager'                                                                                 => array(
477
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
478
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
479
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
480
+			),
481
+			'EE_Message_Factory'                                                                                          => array(
482
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
483
+			),
484
+			'EE_messages'                                                                                                 => array(
485
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
+			),
487
+			'EE_Messages_Generator'                                                                                       => array(
488
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
489
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
490
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
491
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
492
+			),
493
+			'EE_Messages_Processor'                                                                                       => array(
494
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
495
+			),
496
+			'EE_Messages_Queue'                                                                                           => array(
497
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
498
+			),
499
+			'EE_Messages_Template_Defaults'                                                                               => array(
500
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
501
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
502
+			),
503
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
504
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
505
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
506
+			),
507
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
508
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
509
+			),
510
+			'EventEspresso\services\commands\CommandHandler'                                                              => array(
511
+				'EE_Registry'         => EE_Dependency_Map::load_from_cache,
512
+				'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
513
+			),
514
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
515
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
516
+			),
517
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
518
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
519
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
520
+			),
521
+			'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
522
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
523
+			),
524
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
525
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
526
+			),
527
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
528
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
529
+			),
530
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
531
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
532
+			),
533
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
534
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
535
+			),
536
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
537
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
538
+			),
539
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
540
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
541
+			),
542
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
543
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
+			),
545
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
546
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
547
+			),
548
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
549
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
550
+			),
551
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
552
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
553
+			),
554
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
555
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
556
+			),
557
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
558
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
559
+			),
560
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
561
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
562
+			),
563
+			'EE_Data_Migration_Class_Base'                                                                                => array(
564
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
565
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
566
+			),
567
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
568
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
569
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
570
+			),
571
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
572
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
573
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
574
+			),
575
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
576
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
577
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
578
+			),
579
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
580
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
581
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
582
+			),
583
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
584
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
585
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
586
+			),
587
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
588
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
589
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
590
+			),
591
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
592
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
593
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
594
+			),
595
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
596
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
597
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
598
+			),
599
+			'EE_DMS_Core_4_9_0' => array(
600
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
601
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
602
+			),
603
+			'EE_DMS_Core_4_10_0' => array(
604
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
605
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
606
+				'EE_DMS_Core_4_9_0'                                  => EE_Dependency_Map::load_from_cache,
607
+			),
608
+			'EventEspresso\core\services\assets\I18nRegistry'                                                             => array(
609
+				array(),
610
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
611
+			),
612
+			'EventEspresso\core\services\assets\Registry'                                                                 => array(
613
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
614
+				'EventEspresso\core\services\assets\I18nRegistry'    => EE_Dependency_Map::load_from_cache,
615
+			),
616
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
617
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
+			),
619
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
620
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
621
+			),
622
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
623
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
624
+			),
625
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
626
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
627
+			),
628
+			'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
629
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
630
+			),
631
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
632
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
633
+			),
634
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
635
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
636
+			),
637
+			'EventEspresso\core\services\cache\BasicCacheManager'                                                         => array(
638
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
639
+			),
640
+			'EventEspresso\core\services\cache\PostRelatedCacheManager'                                                   => array(
641
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
642
+			),
643
+			'EventEspresso\core\domain\services\validation\email\EmailValidationService'                                  => array(
644
+				'EE_Registration_Config'                     => EE_Dependency_Map::load_from_cache,
645
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
646
+			),
647
+			'EventEspresso\core\domain\values\EmailAddress'                                                               => array(
648
+				null,
649
+				'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
650
+			),
651
+			'EventEspresso\core\services\orm\ModelFieldFactory'                                                           => array(
652
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
653
+			),
654
+			'LEGACY_MODELS'                                                                                               => array(
655
+				null,
656
+				'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
657
+			),
658
+			'EE_Module_Request_Router'                                                                                    => array(
659
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
660
+			),
661
+			'EE_Registration_Processor'                                                                                   => array(
662
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
663
+			),
664
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'                                      => array(
665
+				null,
666
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
667
+				'EventEspresso\core\services\request\Request'                         => EE_Dependency_Map::load_from_cache,
668
+			),
669
+			'EventEspresso\core\services\licensing\LicenseService'                                                        => array(
670
+				'EventEspresso\core\domain\services\pue\Stats'  => EE_Dependency_Map::load_from_cache,
671
+				'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
672
+			),
673
+			'EE_Admin_Transactions_List_Table'                                                                            => array(
674
+				null,
675
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
676
+			),
677
+			'EventEspresso\core\domain\services\pue\Stats'                                                                => array(
678
+				'EventEspresso\core\domain\services\pue\Config'        => EE_Dependency_Map::load_from_cache,
679
+				'EE_Maintenance_Mode'                                  => EE_Dependency_Map::load_from_cache,
680
+				'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache,
681
+			),
682
+			'EventEspresso\core\domain\services\pue\Config'                                                               => array(
683
+				'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
684
+				'EE_Config'         => EE_Dependency_Map::load_from_cache,
685
+			),
686
+			'EventEspresso\core\domain\services\pue\StatsGatherer'                                                        => array(
687
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
688
+				'EEM_Event'          => EE_Dependency_Map::load_from_cache,
689
+				'EEM_Datetime'       => EE_Dependency_Map::load_from_cache,
690
+				'EEM_Ticket'         => EE_Dependency_Map::load_from_cache,
691
+				'EEM_Registration'   => EE_Dependency_Map::load_from_cache,
692
+				'EEM_Transaction'    => EE_Dependency_Map::load_from_cache,
693
+				'EE_Config'          => EE_Dependency_Map::load_from_cache,
694
+			),
695
+			'EventEspresso\core\domain\services\admin\ExitModal'                                                          => array(
696
+				'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache,
697
+			),
698
+			'EventEspresso\core\domain\services\admin\PluginUpsells'                                                      => array(
699
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
700
+			),
701
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha'                                    => array(
702
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
703
+				'EE_Session'             => EE_Dependency_Map::load_from_cache,
704
+			),
705
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings'                                => array(
706
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
707
+			),
708
+			'EventEspresso\modules\ticket_selector\ProcessTicketSelector'                                                 => array(
709
+				'EE_Core_Config'                                                          => EE_Dependency_Map::load_from_cache,
710
+				'EventEspresso\core\services\request\Request'                             => EE_Dependency_Map::load_from_cache,
711
+				'EE_Session'                                                              => EE_Dependency_Map::load_from_cache,
712
+				'EEM_Ticket'                                                              => EE_Dependency_Map::load_from_cache,
713
+				'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
714
+			),
715
+			'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker'                                     => array(
716
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
717
+			),
718
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'                              => array(
719
+				'EE_Core_Config'                             => EE_Dependency_Map::load_from_cache,
720
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
721
+			),
722
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'                                => array(
723
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
724
+			),
725
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'                               => array(
726
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
727
+			),
728
+			'EE_CPT_Strategy'                                                                                             => array(
729
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
730
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
731
+			),
732
+			'EventEspresso\core\services\loaders\ObjectIdentifier'                                                        => array(
733
+				'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
734
+			),
735
+			'EventEspresso\core\domain\services\assets\CoreAssetManager'                                                  => array(
736
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
737
+				'EE_Currency_Config'                                 => EE_Dependency_Map::load_from_cache,
738
+				'EE_Template_Config'                                 => EE_Dependency_Map::load_from_cache,
739
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
740
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
741
+			),
742
+			'EventEspresso\core\domain\services\admin\privacy\policy\PrivacyPolicy' => array(
743
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
744
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache
745
+			),
746
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendee' => array(
747
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
748
+			),
749
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendeeBillingData' => array(
750
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
751
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache
752
+			),
753
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportCheckins' => array(
754
+				'EEM_Checkin' => EE_Dependency_Map::load_from_cache,
755
+			),
756
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportRegistration' => array(
757
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache,
758
+			),
759
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportTransaction' => array(
760
+				'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
761
+			),
762
+			'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAttendeeData' => array(
763
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
764
+			),
765
+			'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAnswers' => array(
766
+				'EEM_Answer' => EE_Dependency_Map::load_from_cache,
767
+				'EEM_Question' => EE_Dependency_Map::load_from_cache,
768
+			),
769
+			'EventEspresso\core\CPTs\CptQueryModifier' => array(
770
+				null,
771
+				null,
772
+				null,
773
+				'EE_Request_Handler'                          => EE_Dependency_Map::load_from_cache,
774
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
775
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
776
+			),
777
+			'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler' => array(
778
+				'EE_Registry' => EE_Dependency_Map::load_from_cache,
779
+				'EE_Config' => EE_Dependency_Map::load_from_cache
780
+			),
781
+			'EventEspresso\core\services\editor\BlockRegistrationManager'                                                 => array(
782
+				'EventEspresso\core\services\assets\BlockAssetManagerCollection' => EE_Dependency_Map::load_from_cache,
783
+				'EventEspresso\core\domain\entities\editor\BlockCollection'      => EE_Dependency_Map::load_from_cache,
784
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => EE_Dependency_Map::load_from_cache,
785
+				'EventEspresso\core\services\request\Request'                    => EE_Dependency_Map::load_from_cache,
786
+			),
787
+			'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => array(
788
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
789
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
790
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
791
+			),
792
+			'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => array(
793
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
794
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
795
+			),
796
+			'EventEspresso\core\domain\entities\editor\blocks\EventAttendees' => array(
797
+				'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => self::load_from_cache,
798
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
799
+				'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => self::load_from_cache,
800
+			),
801
+			'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => array(
802
+				'EventEspresso\core\services\container\Mirror' => EE_Dependency_Map::load_from_cache,
803
+				'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
804
+				'EE_Dependency_Map' => EE_Dependency_Map::load_from_cache,
805
+			),
806
+			'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => array(
807
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => EE_Dependency_Map::load_from_cache,
808
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
809
+			),
810
+			'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => array(
811
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationCollection' => EE_Dependency_Map::load_from_cache,
812
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => EE_Dependency_Map::load_from_cache,
813
+			),
814
+			'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => array(
815
+				'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => EE_Dependency_Map::load_from_cache
816
+			),
817
+			'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => array(
818
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
819
+			),
820
+			'EventEspresso\core\libraries\rest_api\controllers\model\Read' => array(
821
+				'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => EE_Dependency_Map::load_from_cache
822
+			),
823
+			'EventEspresso\core\libraries\rest_api\calculations\Datetime' => array(
824
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
825
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache
826
+			),
827
+			'EventEspresso\core\libraries\rest_api\calculations\Event' => array(
828
+				'EEM_Event' => EE_Dependency_Map::load_from_cache,
829
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache
830
+			),
831
+			'EventEspresso\core\libraries\rest_api\calculations\Registration' => array(
832
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache
833
+			),
834
+			'EventEspresso\core\services\session\SessionStartHandler' => array(
835
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
836
+			),
837
+			'EE_URL_Validation_Strategy' => array(
838
+				null,
839
+				null,
840
+				'EventEspresso\core\services\validators\URLValidator' => EE_Dependency_Map::load_from_cache
841
+			),
842
+			'EventEspresso\admin_pages\general_settings\OrganizationSettings' => array(
843
+				'EE_Registry'                                             => EE_Dependency_Map::load_from_cache,
844
+				'EE_Organization_Config'                                  => EE_Dependency_Map::load_from_cache,
845
+				'EE_Core_Config'                                          => EE_Dependency_Map::load_from_cache,
846
+				'EE_Network_Core_Config'                                  => EE_Dependency_Map::load_from_cache,
847
+				'EventEspresso\core\services\address\CountrySubRegionDao' => EE_Dependency_Map::load_from_cache,
848
+			),
849
+			'EventEspresso\core\services\address\CountrySubRegionDao' => array(
850
+				'EEM_State'                                            => EE_Dependency_Map::load_from_cache,
851
+				'EventEspresso\core\services\validators\JsonValidator' => EE_Dependency_Map::load_from_cache
852
+			),
853
+			'EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat' => array(
854
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
855
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
856
+			),
857
+			'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat' => array(
858
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
859
+				'EE_Environment_Config'            => EE_Dependency_Map::load_from_cache,
860
+			),
861
+			'EventEspresso\core\services\request\files\FilesDataHandler' => array(
862
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
863
+			),
864
+			'EventEspressoBatchRequest\BatchRequestProcessor'                              => [
865
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
866
+			],
867
+			'EventEspresso\core\services\graphql\RequestHandler'                           => [
868
+				'EventEspresso\core\services\graphql\ResolverCollection'  => EE_Dependency_Map::load_from_cache,
869
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
870
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
871
+			],
872
+			'EventEspresso\core\domain\services\converters\spoofers\RestApiSpoofer' => [
873
+				'EventEspresso\core\libraries\rest_api\controllers\model\Read' => EE_Dependency_Map::load_from_cache,
874
+				null
875
+			],
876
+			'EventEspresso\core\domain\services\graphql\resolvers\EventEditorDataResolver' => [
877
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
878
+				'EventEspresso\core\domain\services\converters\spoofers\RestApiSpoofer' => EE_Dependency_Map::load_from_cache,
879
+			],
880
+		);
881
+	}
882
+
883
+
884
+	/**
885
+	 * Registers how core classes are loaded.
886
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
887
+	 *        'EE_Request_Handler' => 'load_core'
888
+	 *        'EE_Messages_Queue'  => 'load_lib'
889
+	 *        'EEH_Debug_Tools'    => 'load_helper'
890
+	 * or, if greater control is required, by providing a custom closure. For example:
891
+	 *        'Some_Class' => function () {
892
+	 *            return new Some_Class();
893
+	 *        },
894
+	 * This is required for instantiating dependencies
895
+	 * where an interface has been type hinted in a class constructor. For example:
896
+	 *        'Required_Interface' => function () {
897
+	 *            return new A_Class_That_Implements_Required_Interface();
898
+	 *        },
899
+	 */
900
+	protected function _register_core_class_loaders()
901
+	{
902
+		$this->_class_loaders = array(
903
+			// load_core
904
+			'EE_Dependency_Map'                            => function () {
905
+				return $this;
906
+			},
907
+			'EE_Capabilities'                              => 'load_core',
908
+			'EE_Encryption'                                => 'load_core',
909
+			'EE_Front_Controller'                          => 'load_core',
910
+			'EE_Module_Request_Router'                     => 'load_core',
911
+			'EE_Registry'                                  => 'load_core',
912
+			'EE_Request'                                   => function () {
913
+				return $this->legacy_request;
914
+			},
915
+			'EventEspresso\core\services\request\Request'  => function () {
916
+				return $this->request;
917
+			},
918
+			'EventEspresso\core\services\request\Response' => function () {
919
+				return $this->response;
920
+			},
921
+			'EE_Base'                                      => 'load_core',
922
+			'EE_Request_Handler'                           => 'load_core',
923
+			'EE_Session'                                   => 'load_core',
924
+			'EE_Cron_Tasks'                                => 'load_core',
925
+			'EE_System'                                    => 'load_core',
926
+			'EE_Maintenance_Mode'                          => 'load_core',
927
+			'EE_Register_CPTs'                             => 'load_core',
928
+			'EE_Admin'                                     => 'load_core',
929
+			'EE_CPT_Strategy'                              => 'load_core',
930
+			// load_class
931
+			'EE_Registration_Processor'                    => 'load_class',
932
+			// load_lib
933
+			'EE_Message_Resource_Manager'                  => 'load_lib',
934
+			'EE_Message_Type_Collection'                   => 'load_lib',
935
+			'EE_Message_Type_Collection_Loader'            => 'load_lib',
936
+			'EE_Messenger_Collection'                      => 'load_lib',
937
+			'EE_Messenger_Collection_Loader'               => 'load_lib',
938
+			'EE_Messages_Processor'                        => 'load_lib',
939
+			'EE_Message_Repository'                        => 'load_lib',
940
+			'EE_Messages_Queue'                            => 'load_lib',
941
+			'EE_Messages_Data_Handler_Collection'          => 'load_lib',
942
+			'EE_Message_Template_Group_Collection'         => 'load_lib',
943
+			'EE_Payment_Method_Manager'                    => 'load_lib',
944
+			'EE_DMS_Core_4_1_0'                            => 'load_dms',
945
+			'EE_DMS_Core_4_2_0'                            => 'load_dms',
946
+			'EE_DMS_Core_4_3_0'                            => 'load_dms',
947
+			'EE_DMS_Core_4_5_0'                            => 'load_dms',
948
+			'EE_DMS_Core_4_6_0'                            => 'load_dms',
949
+			'EE_DMS_Core_4_7_0'                            => 'load_dms',
950
+			'EE_DMS_Core_4_8_0'                            => 'load_dms',
951
+			'EE_DMS_Core_4_9_0'                            => 'load_dms',
952
+			'EE_DMS_Core_4_10_0'                            => 'load_dms',
953
+			'EE_Messages_Generator'                        => function () {
954
+				return EE_Registry::instance()->load_lib(
955
+					'Messages_Generator',
956
+					array(),
957
+					false,
958
+					false
959
+				);
960
+			},
961
+			'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
962
+				return EE_Registry::instance()->load_lib(
963
+					'Messages_Template_Defaults',
964
+					$arguments,
965
+					false,
966
+					false
967
+				);
968
+			},
969
+			// load_helper
970
+			'EEH_Parse_Shortcodes'                         => function () {
971
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
972
+					return new EEH_Parse_Shortcodes();
973
+				}
974
+				return null;
975
+			},
976
+			'EE_Template_Config'                           => function () {
977
+				return EE_Config::instance()->template_settings;
978
+			},
979
+			'EE_Currency_Config'                           => function () {
980
+				return EE_Config::instance()->currency;
981
+			},
982
+			'EE_Registration_Config'                       => function () {
983
+				return EE_Config::instance()->registration;
984
+			},
985
+			'EE_Core_Config'                               => function () {
986
+				return EE_Config::instance()->core;
987
+			},
988
+			'EventEspresso\core\services\loaders\Loader'   => function () {
989
+				return LoaderFactory::getLoader();
990
+			},
991
+			'EE_Network_Config'                            => function () {
992
+				return EE_Network_Config::instance();
993
+			},
994
+			'EE_Config'                                    => function () {
995
+				return EE_Config::instance();
996
+			},
997
+			'EventEspresso\core\domain\Domain'             => function () {
998
+				return DomainFactory::getEventEspressoCoreDomain();
999
+			},
1000
+			'EE_Admin_Config'                              => function () {
1001
+				return EE_Config::instance()->admin;
1002
+			},
1003
+			'EE_Organization_Config'                       => function () {
1004
+				return EE_Config::instance()->organization;
1005
+			},
1006
+			'EE_Network_Core_Config'                       => function () {
1007
+				return EE_Network_Config::instance()->core;
1008
+			},
1009
+			'EE_Environment_Config'                        => function () {
1010
+				return EE_Config::instance()->environment;
1011
+			},
1012
+		);
1013
+	}
1014
+
1015
+
1016
+	/**
1017
+	 * can be used for supplying alternate names for classes,
1018
+	 * or for connecting interface names to instantiable classes
1019
+	 */
1020
+	protected function _register_core_aliases()
1021
+	{
1022
+		$aliases = array(
1023
+			'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
1024
+			'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
1025
+			'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
1026
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
1027
+			'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
1028
+			'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
1029
+			'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1030
+			'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
1031
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1032
+			'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
1033
+			'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1034
+			'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
1035
+			'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
1036
+			'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
1037
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
1038
+			'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
1039
+			'CreateTransactionCommandHandler'                                              => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
1040
+			'CreateAttendeeCommandHandler'                                                 => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
1041
+			'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
1042
+			'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
1043
+			'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1044
+			'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
1045
+			'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1046
+			'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
1047
+			'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
1048
+			'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
1049
+			'CommandFactoryInterface'                                                      => 'EventEspresso\core\services\commands\CommandFactoryInterface',
1050
+			'EventEspresso\core\services\commands\CommandFactoryInterface'                 => 'EventEspresso\core\services\commands\CommandFactory',
1051
+			'EmailValidatorInterface'                                                      => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
1052
+			'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface'  => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
1053
+			'NoticeConverterInterface'                                                     => 'EventEspresso\core\services\notices\NoticeConverterInterface',
1054
+			'EventEspresso\core\services\notices\NoticeConverterInterface'                 => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
1055
+			'NoticesContainerInterface'                                                    => 'EventEspresso\core\services\notices\NoticesContainerInterface',
1056
+			'EventEspresso\core\services\notices\NoticesContainerInterface'                => 'EventEspresso\core\services\notices\NoticesContainer',
1057
+			'EventEspresso\core\services\request\RequestInterface'                         => 'EventEspresso\core\services\request\Request',
1058
+			'EventEspresso\core\services\request\ResponseInterface'                        => 'EventEspresso\core\services\request\Response',
1059
+			'EventEspresso\core\domain\DomainInterface'                                    => 'EventEspresso\core\domain\Domain',
1060
+			'Registration_Processor'                                                       => 'EE_Registration_Processor',
1061
+		);
1062
+		foreach ($aliases as $alias => $fqn) {
1063
+			if (is_array($fqn)) {
1064
+				foreach ($fqn as $class => $for_class) {
1065
+					$this->class_cache->addAlias($class, $alias, $for_class);
1066
+				}
1067
+				continue;
1068
+			}
1069
+			$this->class_cache->addAlias($fqn, $alias);
1070
+		}
1071
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1072
+			$this->class_cache->addAlias(
1073
+				'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
1074
+				'EventEspresso\core\services\notices\NoticeConverterInterface'
1075
+			);
1076
+		}
1077
+	}
1078
+
1079
+
1080
+	/**
1081
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
1082
+	 * request Primarily used by unit tests.
1083
+	 */
1084
+	public function reset()
1085
+	{
1086
+		$this->_register_core_class_loaders();
1087
+		$this->_register_core_dependencies();
1088
+	}
1089
+
1090
+
1091
+	/**
1092
+	 * PLZ NOTE: a better name for this method would be is_alias()
1093
+	 * because it returns TRUE if the provided fully qualified name IS an alias
1094
+	 * WHY?
1095
+	 * Because if a class is type hinting for a concretion,
1096
+	 * then why would we need to find another class to supply it?
1097
+	 * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
1098
+	 * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
1099
+	 * Don't go looking for some substitute.
1100
+	 * Whereas if a class is type hinting for an interface...
1101
+	 * then we need to find an actual class to use.
1102
+	 * So the interface IS the alias for some other FQN,
1103
+	 * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
1104
+	 * represents some other class.
1105
+	 *
1106
+	 * @deprecated 4.9.62.p
1107
+	 * @param string $fqn
1108
+	 * @param string $for_class
1109
+	 * @return bool
1110
+	 */
1111
+	public function has_alias($fqn = '', $for_class = '')
1112
+	{
1113
+		return $this->isAlias($fqn, $for_class);
1114
+	}
1115
+
1116
+
1117
+	/**
1118
+	 * PLZ NOTE: a better name for this method would be get_fqn_for_alias()
1119
+	 * because it returns a FQN for provided alias if one exists, otherwise returns the original $alias
1120
+	 * functions recursively, so that multiple aliases can be used to drill down to a FQN
1121
+	 *  for example:
1122
+	 *      if the following two entries were added to the _aliases array:
1123
+	 *          array(
1124
+	 *              'interface_alias'           => 'some\namespace\interface'
1125
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
1126
+	 *          )
1127
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
1128
+	 *      to load an instance of 'some\namespace\classname'
1129
+	 *
1130
+	 * @deprecated 4.9.62.p
1131
+	 * @param string $alias
1132
+	 * @param string $for_class
1133
+	 * @return string
1134
+	 */
1135
+	public function get_alias($alias = '', $for_class = '')
1136
+	{
1137
+		return $this->getFqnForAlias($alias, $for_class);
1138
+	}
1139 1139
 }
Please login to merge, or discard this patch.
core/services/converters/json/ModelObjectToJsonConverterInterface.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -15,50 +15,50 @@
 block discarded – undo
15 15
 interface ModelObjectToJsonConverterInterface
16 16
 {
17 17
 
18
-    /**
19
-     * @param array $entities
20
-     * @return array
21
-     * @since $VID:$
22
-     */
23
-    public function convertAndEncodeArrayOf(array $entities);
18
+	/**
19
+	 * @param array $entities
20
+	 * @return array
21
+	 * @since $VID:$
22
+	 */
23
+	public function convertAndEncodeArrayOf(array $entities);
24 24
 
25 25
 
26
-    /**
27
-     * @param $entity
28
-     * @return false|string
29
-     * @since $VID:$
30
-     */
31
-    public function convertAndEncode($entity);
26
+	/**
27
+	 * @param $entity
28
+	 * @return false|string
29
+	 * @since $VID:$
30
+	 */
31
+	public function convertAndEncode($entity);
32 32
 
33 33
 
34
-    /**
35
-     * @param array $entities
36
-     * @return array
37
-     * @since $VID:$
38
-     */
39
-    public function convertArrayOf(array $entities);
34
+	/**
35
+	 * @param array $entities
36
+	 * @return array
37
+	 * @since $VID:$
38
+	 */
39
+	public function convertArrayOf(array $entities);
40 40
 
41 41
 
42
-    /**
43
-     * @param $entity
44
-     * @return array
45
-     * @since $VID:$
46
-     */
47
-    public function convert($entity);
42
+	/**
43
+	 * @param $entity
44
+	 * @return array
45
+	 * @since $VID:$
46
+	 */
47
+	public function convert($entity);
48 48
 
49 49
 
50
-    /**
51
-     * @param array $entities
52
-     * @return array
53
-     * @since $VID:$
54
-     */
55
-    public function encodeArrayOf(array $entities);
50
+	/**
51
+	 * @param array $entities
52
+	 * @return array
53
+	 * @since $VID:$
54
+	 */
55
+	public function encodeArrayOf(array $entities);
56 56
 
57 57
 
58
-    /**
59
-     * @param array $entity_array
60
-     * @return false|string
61
-     * @since $VID:$
62
-     */
63
-    public function encode(array $entity_array);
58
+	/**
59
+	 * @param array $entity_array
60
+	 * @return false|string
61
+	 * @since $VID:$
62
+	 */
63
+	public function encode(array $entity_array);
64 64
 }
65 65
\ No newline at end of file
Please login to merge, or discard this patch.
core/services/graphql/ResolverCollection.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -16,36 +16,36 @@
 block discarded – undo
16 16
 class ResolverCollection extends Collection
17 17
 {
18 18
 
19
-    const COLLECTION_NAME = 'espresso_graphql_resolvers';
20
-
21
-
22
-    /**
23
-     * ResolverCollection constructor
24
-     *
25
-     * @throws InvalidInterfaceException
26
-     */
27
-    public function __construct()
28
-    {
29
-        parent::__construct(
30
-            'EventEspresso\core\services\graphql\ResolverInterface',
31
-            ResolverCollection::COLLECTION_NAME
32
-        );
33
-    }
34
-
35
-
36
-    /**
37
-     * getIdentifier
38
-     * Overrides EventEspresso\core\services\collections\Collection::getIdentifier()
39
-     * If no $identifier is supplied, then the  fully qualified class name is used
40
-     *
41
-     * @param        $object
42
-     * @param mixed  $identifier
43
-     * @return bool
44
-     */
45
-    public function getIdentifier($object, $identifier = null)
46
-    {
47
-        return ! empty($identifier)
48
-            ? $identifier
49
-            : get_class($object);
50
-    }
19
+	const COLLECTION_NAME = 'espresso_graphql_resolvers';
20
+
21
+
22
+	/**
23
+	 * ResolverCollection constructor
24
+	 *
25
+	 * @throws InvalidInterfaceException
26
+	 */
27
+	public function __construct()
28
+	{
29
+		parent::__construct(
30
+			'EventEspresso\core\services\graphql\ResolverInterface',
31
+			ResolverCollection::COLLECTION_NAME
32
+		);
33
+	}
34
+
35
+
36
+	/**
37
+	 * getIdentifier
38
+	 * Overrides EventEspresso\core\services\collections\Collection::getIdentifier()
39
+	 * If no $identifier is supplied, then the  fully qualified class name is used
40
+	 *
41
+	 * @param        $object
42
+	 * @param mixed  $identifier
43
+	 * @return bool
44
+	 */
45
+	public function getIdentifier($object, $identifier = null)
46
+	{
47
+		return ! empty($identifier)
48
+			? $identifier
49
+			: get_class($object);
50
+	}
51 51
 }
52 52
\ No newline at end of file
Please login to merge, or discard this patch.
core/services/graphql/RequestHandler.php 2 patches
Indentation   +126 added lines, -126 removed lines patch added patch discarded remove patch
@@ -21,131 +21,131 @@
 block discarded – undo
21 21
 class RequestHandler
22 22
 {
23 23
 
24
-    /**
25
-     * @var LoaderInterface $loader
26
-     */
27
-    protected $loader;
28
-
29
-    /**
30
-     * @var RequestInterface $request
31
-     */
32
-    protected $request;
33
-
34
-    /**
35
-     * @var CollectionInterface|ResolverInterface[] $resolvers
36
-     */
37
-    private $resolvers;
38
-
39
-
40
-    /**
41
-     * RequestHandler constructor.
42
-     *
43
-     * @param ResolverCollection $resolvers
44
-     * @param RequestInterface $request
45
-     * @param LoaderInterface $loader
46
-     */
47
-    public function __construct(ResolverCollection $resolvers, RequestInterface $request, LoaderInterface $loader)
48
-    {
49
-        $this->resolvers = $resolvers;
50
-        $this->request = $request;
51
-        $this->loader = $loader;
52
-    }
53
-
54
-
55
-    /**
56
-     * @return CollectionInterface|ResolverInterface[]
57
-     * @throws CollectionLoaderException
58
-     * @throws CollectionDetailsException
59
-     * @since 4.9.71.p
60
-     */
61
-    private function populateResolverCollection()
62
-    {
63
-        $loader = new CollectionLoader(
64
-            new CollectionDetails(
65
-            // collection name
66
-                ResolverCollection::COLLECTION_NAME,
67
-                // collection interface
68
-                'EventEspresso\core\services\graphql\ResolverInterface',
69
-                // FQCNs for classes to add (all classes within each namespace will be loaded)
70
-                apply_filters(
71
-                    'FHEE__EventEspresso_core_services_graphql_RequestHandler__populateResolverCollection__collection_FQCNs',
72
-                    ['EventEspresso\core\domain\services\graphql\resolvers']
73
-                ),
74
-                // filepaths to classes to add
75
-                array(),
76
-                // file mask to use if parsing folder for files to add
77
-                '',
78
-                // what to use as identifier for collection entities
79
-                // using CLASS NAME prevents duplicates (works like a singleton)
80
-                CollectionDetails::ID_CLASS_NAME
81
-            ),
82
-            $this->resolvers
83
-        );
84
-        return $loader->getCollection();
85
-    }
86
-
87
-
88
-    /**
89
-     * @throws CollectionDetailsException
90
-     * @throws CollectionLoaderException
91
-     * @since $VID:$
92
-     */
93
-    public function init()
94
-    {
95
-        // getting data from current request ( $_GET, $_POST, $_REQUEST, etc )
96
-        // retrieve ALL params from $_REQUEST
97
-        $all = $this->request->getParams();
98
-        // retrieve a single param from $_REQUEST
99
-        $one = $this->request->getRequestParam( 'key', 'default value if not found' );
100
-        // retrieve params matching a pattern from $_REQUEST using regex
101
-        $matches = $this->request->getMatch( '/regex-pattern-with-?-or-*-wildcards/', 'default value if not found' );
102
-
103
-        $query_data = new \stdClass();
104
-        $query_data->eventId = 1;
105
-
106
-        // loading classes
107
-
108
-        // get shared instance (works like a singleton)
109
-        $sharedClass = $this->loader->getShared(
110
-            'EventEspresso\core\domain\services\graphql\mutators\QueryMutator',
111
-            [ $query_data ]
112
-        );
113
-        // get NON-shared unique instance (creates new instance every call)
114
-        $uniqueClass = $this->loader->getNew(
115
-            'EventEspresso\core\domain\services\graphql\mutators\QueryMutator',
116
-            [ $query_data ]
117
-        );
118
-
119
-        // Register GQL resolvers by first loading all ResolverInterface objects
120
-        // in EventEspresso\core\domain\services\graphql\resolvers.
121
-        // Other folders can be added to that list by addons
122
-        // simply by using the collection FQCNs filter in that method.
123
-        // Alternately, an addon could load a shared instance of the collection
124
-        // and manually add/remove/replace resolvers as needed
125
-        $this->populateResolverCollection();
126
-        add_action('graphql_register_types', [$this, 'registerResolvers']);
127
-    }
128
-
129
-
130
-    public function registerResolvers()
131
-    {
132
-        // loop through the collection of resolvers and register them.
133
-        // We're taking care of calling register_graphql_field() from here,
134
-        // which centralizes where everything happens, allowing for more control
135
-        // and making the resolver classes easier to unit test because
136
-        // they are decoupled from the third party api
137
-        foreach ($this->resolvers as $resolver) {
138
-            /** @var ResolverInterface $resolver */
139
-             register_graphql_field(
140
-                $resolver->query(),
141
-                $resolver->field(),
142
-                [
143
-                    'type'    => $resolver->type(),
144
-                    'resolve' => [$resolver, 'resolve']
145
-                ]
146
-            );
147
-
148
-        }
149
-    }
24
+	/**
25
+	 * @var LoaderInterface $loader
26
+	 */
27
+	protected $loader;
28
+
29
+	/**
30
+	 * @var RequestInterface $request
31
+	 */
32
+	protected $request;
33
+
34
+	/**
35
+	 * @var CollectionInterface|ResolverInterface[] $resolvers
36
+	 */
37
+	private $resolvers;
38
+
39
+
40
+	/**
41
+	 * RequestHandler constructor.
42
+	 *
43
+	 * @param ResolverCollection $resolvers
44
+	 * @param RequestInterface $request
45
+	 * @param LoaderInterface $loader
46
+	 */
47
+	public function __construct(ResolverCollection $resolvers, RequestInterface $request, LoaderInterface $loader)
48
+	{
49
+		$this->resolvers = $resolvers;
50
+		$this->request = $request;
51
+		$this->loader = $loader;
52
+	}
53
+
54
+
55
+	/**
56
+	 * @return CollectionInterface|ResolverInterface[]
57
+	 * @throws CollectionLoaderException
58
+	 * @throws CollectionDetailsException
59
+	 * @since 4.9.71.p
60
+	 */
61
+	private function populateResolverCollection()
62
+	{
63
+		$loader = new CollectionLoader(
64
+			new CollectionDetails(
65
+			// collection name
66
+				ResolverCollection::COLLECTION_NAME,
67
+				// collection interface
68
+				'EventEspresso\core\services\graphql\ResolverInterface',
69
+				// FQCNs for classes to add (all classes within each namespace will be loaded)
70
+				apply_filters(
71
+					'FHEE__EventEspresso_core_services_graphql_RequestHandler__populateResolverCollection__collection_FQCNs',
72
+					['EventEspresso\core\domain\services\graphql\resolvers']
73
+				),
74
+				// filepaths to classes to add
75
+				array(),
76
+				// file mask to use if parsing folder for files to add
77
+				'',
78
+				// what to use as identifier for collection entities
79
+				// using CLASS NAME prevents duplicates (works like a singleton)
80
+				CollectionDetails::ID_CLASS_NAME
81
+			),
82
+			$this->resolvers
83
+		);
84
+		return $loader->getCollection();
85
+	}
86
+
87
+
88
+	/**
89
+	 * @throws CollectionDetailsException
90
+	 * @throws CollectionLoaderException
91
+	 * @since $VID:$
92
+	 */
93
+	public function init()
94
+	{
95
+		// getting data from current request ( $_GET, $_POST, $_REQUEST, etc )
96
+		// retrieve ALL params from $_REQUEST
97
+		$all = $this->request->getParams();
98
+		// retrieve a single param from $_REQUEST
99
+		$one = $this->request->getRequestParam( 'key', 'default value if not found' );
100
+		// retrieve params matching a pattern from $_REQUEST using regex
101
+		$matches = $this->request->getMatch( '/regex-pattern-with-?-or-*-wildcards/', 'default value if not found' );
102
+
103
+		$query_data = new \stdClass();
104
+		$query_data->eventId = 1;
105
+
106
+		// loading classes
107
+
108
+		// get shared instance (works like a singleton)
109
+		$sharedClass = $this->loader->getShared(
110
+			'EventEspresso\core\domain\services\graphql\mutators\QueryMutator',
111
+			[ $query_data ]
112
+		);
113
+		// get NON-shared unique instance (creates new instance every call)
114
+		$uniqueClass = $this->loader->getNew(
115
+			'EventEspresso\core\domain\services\graphql\mutators\QueryMutator',
116
+			[ $query_data ]
117
+		);
118
+
119
+		// Register GQL resolvers by first loading all ResolverInterface objects
120
+		// in EventEspresso\core\domain\services\graphql\resolvers.
121
+		// Other folders can be added to that list by addons
122
+		// simply by using the collection FQCNs filter in that method.
123
+		// Alternately, an addon could load a shared instance of the collection
124
+		// and manually add/remove/replace resolvers as needed
125
+		$this->populateResolverCollection();
126
+		add_action('graphql_register_types', [$this, 'registerResolvers']);
127
+	}
128
+
129
+
130
+	public function registerResolvers()
131
+	{
132
+		// loop through the collection of resolvers and register them.
133
+		// We're taking care of calling register_graphql_field() from here,
134
+		// which centralizes where everything happens, allowing for more control
135
+		// and making the resolver classes easier to unit test because
136
+		// they are decoupled from the third party api
137
+		foreach ($this->resolvers as $resolver) {
138
+			/** @var ResolverInterface $resolver */
139
+			 register_graphql_field(
140
+				$resolver->query(),
141
+				$resolver->field(),
142
+				[
143
+					'type'    => $resolver->type(),
144
+					'resolve' => [$resolver, 'resolve']
145
+				]
146
+			);
147
+
148
+		}
149
+	}
150 150
 
151 151
 }
152 152
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -96,9 +96,9 @@  discard block
 block discarded – undo
96 96
         // retrieve ALL params from $_REQUEST
97 97
         $all = $this->request->getParams();
98 98
         // retrieve a single param from $_REQUEST
99
-        $one = $this->request->getRequestParam( 'key', 'default value if not found' );
99
+        $one = $this->request->getRequestParam('key', 'default value if not found');
100 100
         // retrieve params matching a pattern from $_REQUEST using regex
101
-        $matches = $this->request->getMatch( '/regex-pattern-with-?-or-*-wildcards/', 'default value if not found' );
101
+        $matches = $this->request->getMatch('/regex-pattern-with-?-or-*-wildcards/', 'default value if not found');
102 102
 
103 103
         $query_data = new \stdClass();
104 104
         $query_data->eventId = 1;
@@ -108,12 +108,12 @@  discard block
 block discarded – undo
108 108
         // get shared instance (works like a singleton)
109 109
         $sharedClass = $this->loader->getShared(
110 110
             'EventEspresso\core\domain\services\graphql\mutators\QueryMutator',
111
-            [ $query_data ]
111
+            [$query_data]
112 112
         );
113 113
         // get NON-shared unique instance (creates new instance every call)
114 114
         $uniqueClass = $this->loader->getNew(
115 115
             'EventEspresso\core\domain\services\graphql\mutators\QueryMutator',
116
-            [ $query_data ]
116
+            [$query_data]
117 117
         );
118 118
 
119 119
         // Register GQL resolvers by first loading all ResolverInterface objects
Please login to merge, or discard this patch.
core/services/graphql/ResolverInterface.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -16,31 +16,31 @@
 block discarded – undo
16 16
 interface ResolverInterface
17 17
 {
18 18
 
19
-    /**
20
-     * @return string
21
-     * @since $VID:$
22
-     */
23
-    public function query();
19
+	/**
20
+	 * @return string
21
+	 * @since $VID:$
22
+	 */
23
+	public function query();
24 24
 
25
-    /**
26
-     * @return string
27
-     * @since $VID:$
28
-     */
29
-    public function field();
25
+	/**
26
+	 * @return string
27
+	 * @since $VID:$
28
+	 */
29
+	public function field();
30 30
 
31
-    /**
32
-     * @return string
33
-     * @since $VID:$
34
-     */
35
-    public function type();
31
+	/**
32
+	 * @return string
33
+	 * @since $VID:$
34
+	 */
35
+	public function type();
36 36
 
37
-    /**
38
-     * @param             $root
39
-     * @param array       $args
40
-     * @param AppContext  $context
41
-     * @param ResolveInfo $info
42
-     * @return mixed
43
-     * @since $VID:$
44
-     */
45
-    public function resolve($root, array $args, AppContext $context, ResolveInfo $info);
37
+	/**
38
+	 * @param             $root
39
+	 * @param array       $args
40
+	 * @param AppContext  $context
41
+	 * @param ResolveInfo $info
42
+	 * @return mixed
43
+	 * @since $VID:$
44
+	 */
45
+	public function resolve($root, array $args, AppContext $context, ResolveInfo $info);
46 46
 }
47 47
\ No newline at end of file
Please login to merge, or discard this patch.
core/domain/entities/custom_post_types/CustomPostTypeDefinitions.php 2 patches
Indentation   +266 added lines, -266 removed lines patch added patch discarded remove patch
@@ -17,290 +17,290 @@
 block discarded – undo
17 17
 class CustomPostTypeDefinitions
18 18
 {
19 19
 
20
-    /**
21
-     * @var EE_Core_Config
22
-     */
23
-    public $core_config;
20
+	/**
21
+	 * @var EE_Core_Config
22
+	 */
23
+	public $core_config;
24 24
 
25
-    /**
26
-     * @var array $custom_post_types
27
-     */
28
-    private $custom_post_types;
25
+	/**
26
+	 * @var array $custom_post_types
27
+	 */
28
+	private $custom_post_types;
29 29
 
30
-    /**
31
-     * @var LoaderInterface $loader
32
-     */
33
-    private $loader;
30
+	/**
31
+	 * @var LoaderInterface $loader
32
+	 */
33
+	private $loader;
34 34
 
35 35
 
36
-    /**
37
-     * EspressoCustomPostTypeDefinitions constructor.
38
-     *
39
-     * @param EE_Core_Config  $core_config
40
-     * @param LoaderInterface $loader
41
-     */
42
-    public function __construct(EE_Core_Config $core_config, LoaderInterface $loader)
43
-    {
44
-        $this->core_config = $core_config;
45
-        $this->loader = $loader;
46
-        $this->setDefinitions();
47
-    }
36
+	/**
37
+	 * EspressoCustomPostTypeDefinitions constructor.
38
+	 *
39
+	 * @param EE_Core_Config  $core_config
40
+	 * @param LoaderInterface $loader
41
+	 */
42
+	public function __construct(EE_Core_Config $core_config, LoaderInterface $loader)
43
+	{
44
+		$this->core_config = $core_config;
45
+		$this->loader = $loader;
46
+		$this->setDefinitions();
47
+	}
48 48
 
49 49
 
50
-    /**
51
-     * defines Espresso Custom Post Types
52
-     * NOTE the ['args']['page_templates'] array index is something specific to our CPTs
53
-     * and not part of the WP custom post type api.
54
-     *
55
-     * @return void
56
-     */
57
-    private function setDefinitions()
58
-    {
59
-        $this->custom_post_types = array(
60
-            'espresso_events'    => array(
61
-                'singular_name' => esc_html__('Event', 'event_espresso'),
62
-                'plural_name'   => esc_html__('Events', 'event_espresso'),
63
-                'singular_slug' => esc_html__('event', 'event_espresso'),
64
-                'plural_slug'   => $this->core_config->event_cpt_slug,
65
-                'class_name'    => 'EE_Event',
66
-                'model_name'    => 'EEM_Event',
67
-                'args'          => array(
68
-                    'public'              => true,
69
-                    'show_in_nav_menus'   => true,
70
-                    'show_in_graphql'     => true,
71
-                    'graphql_single_name' => __( 'Event', 'event_espresso' ),
72
-                    'graphql_plural_name' => __( 'Events', 'event_espresso' ),
73
-                    'capability_type'     => 'event',
74
-                    'capabilities'        => array(
75
-                        'edit_post'              => 'ee_edit_event',
76
-                        'read_post'              => 'ee_read_event',
77
-                        'delete_post'            => 'ee_delete_event',
78
-                        'edit_posts'             => 'ee_edit_events',
79
-                        'edit_others_posts'      => 'ee_edit_others_events',
80
-                        'publish_posts'          => 'ee_publish_events',
81
-                        'read_private_posts'     => 'ee_read_private_events',
82
-                        'delete_posts'           => 'ee_delete_events',
83
-                        'delete_private_posts'   => 'ee_delete_private_events',
84
-                        'delete_published_posts' => 'ee_delete_published_events',
85
-                        'delete_others_posts'    => 'ee_delete_others_events',
86
-                        'edit_private_posts'     => 'ee_edit_private_events',
87
-                        'edit_published_posts'   => 'ee_edit_published_events',
88
-                    ),
89
-                    'taxonomies'          => array(
90
-                        'espresso_event_categories',
91
-                        'espresso_event_type',
92
-                        'post_tag',
93
-                    ),
94
-                    'page_templates'      => true,
95
-                ),
96
-            ),
97
-            'espresso_venues'    => array(
98
-                'singular_name' => esc_html__('Venue', 'event_espresso'),
99
-                'plural_name'   => esc_html__('Venues', 'event_espresso'),
100
-                'singular_slug' => esc_html__('venue', 'event_espresso'),
101
-                'plural_slug'   => esc_html__('venues', 'event_espresso'),
102
-                'class_name'    => 'EE_Venue',
103
-                'model_name'    => 'EEM_Venue',
104
-                'args'          => array(
105
-                    'public'            => true,
106
-                    'show_in_nav_menus' => false, // by default this doesn't show for decaf,
107
-                    'capability_type'   => 'venue',
108
-                    'capabilities'      => array(
109
-                        'edit_post'              => 'ee_edit_venue',
110
-                        'read_post'              => 'ee_read_venue',
111
-                        'delete_post'            => 'ee_delete_venue',
112
-                        'edit_posts'             => 'ee_edit_venues',
113
-                        'edit_others_posts'      => 'ee_edit_others_venues',
114
-                        'publish_posts'          => 'ee_publish_venues',
115
-                        'read_private_posts'     => 'ee_read_private_venues',
116
-                        'delete_posts'           => 'ee_delete_venues',
117
-                        'delete_private_posts'   => 'ee_delete_private_venues',
118
-                        'delete_published_posts' => 'ee_delete_published_venues',
119
-                        'delete_others_posts'    => 'ee_edit_others_venues',
120
-                        'edit_private_posts'     => 'ee_edit_private_venues',
121
-                        'edit_published_posts'   => 'ee_edit_published_venues',
122
-                    ),
123
-                    'taxonomies'        => array(
124
-                        'espresso_venue_categories',
125
-                        'post_tag',
126
-                    ),
127
-                    'page_templates'    => true,
128
-                ),
129
-            ),
130
-            'espresso_attendees' => array(
131
-                'singular_name' => esc_html__('Contact', 'event_espresso'),
132
-                'plural_name'   => esc_html__('Contacts', 'event_espresso'),
133
-                'singular_slug' => esc_html__('contact', 'event_espresso'),
134
-                'plural_slug'   => esc_html__('contacts', 'event_espresso'),
135
-                'class_name'    => 'EE_Attendee',
136
-                'model_name'    => 'EEM_Attendee',
137
-                'args'          => array(
138
-                    'public'             => false,
139
-                    'publicly_queryable' => false,
140
-                    'hierarchical'       => false,
141
-                    'has_archive'        => false,
142
-                    'supports'           => array(
143
-                        'editor',
144
-                        'thumbnail',
145
-                        'excerpt',
146
-                        'custom-fields',
147
-                        'comments',
148
-                    ),
149
-                    'taxonomies'         => array('post_tag'),
150
-                    'capability_type'    => 'contact',
151
-                    'capabilities'       => array(
152
-                        'edit_post'              => 'ee_edit_contact',
153
-                        'read_post'              => 'ee_read_contact',
154
-                        'delete_post'            => 'ee_delete_contact',
155
-                        'edit_posts'             => 'ee_edit_contacts',
156
-                        'edit_others_posts'      => 'ee_edit_contacts',
157
-                        'publish_posts'          => 'ee_edit_contacts',
158
-                        'read_private_posts'     => 'ee_edit_contacts',
159
-                        'delete_posts'           => 'ee_delete_contacts',
160
-                        'delete_private_posts'   => 'ee_delete_contacts',
161
-                        'delete_published_posts' => 'ee_delete_contacts',
162
-                        'delete_others_posts'    => 'ee_delete_contacts',
163
-                        'edit_private_posts'     => 'ee_edit_contacts',
164
-                        'edit_published_posts'   => 'ee_edit_contacts',
165
-                    ),
166
-                ),
167
-            ),
168
-        );
169
-    }
50
+	/**
51
+	 * defines Espresso Custom Post Types
52
+	 * NOTE the ['args']['page_templates'] array index is something specific to our CPTs
53
+	 * and not part of the WP custom post type api.
54
+	 *
55
+	 * @return void
56
+	 */
57
+	private function setDefinitions()
58
+	{
59
+		$this->custom_post_types = array(
60
+			'espresso_events'    => array(
61
+				'singular_name' => esc_html__('Event', 'event_espresso'),
62
+				'plural_name'   => esc_html__('Events', 'event_espresso'),
63
+				'singular_slug' => esc_html__('event', 'event_espresso'),
64
+				'plural_slug'   => $this->core_config->event_cpt_slug,
65
+				'class_name'    => 'EE_Event',
66
+				'model_name'    => 'EEM_Event',
67
+				'args'          => array(
68
+					'public'              => true,
69
+					'show_in_nav_menus'   => true,
70
+					'show_in_graphql'     => true,
71
+					'graphql_single_name' => __( 'Event', 'event_espresso' ),
72
+					'graphql_plural_name' => __( 'Events', 'event_espresso' ),
73
+					'capability_type'     => 'event',
74
+					'capabilities'        => array(
75
+						'edit_post'              => 'ee_edit_event',
76
+						'read_post'              => 'ee_read_event',
77
+						'delete_post'            => 'ee_delete_event',
78
+						'edit_posts'             => 'ee_edit_events',
79
+						'edit_others_posts'      => 'ee_edit_others_events',
80
+						'publish_posts'          => 'ee_publish_events',
81
+						'read_private_posts'     => 'ee_read_private_events',
82
+						'delete_posts'           => 'ee_delete_events',
83
+						'delete_private_posts'   => 'ee_delete_private_events',
84
+						'delete_published_posts' => 'ee_delete_published_events',
85
+						'delete_others_posts'    => 'ee_delete_others_events',
86
+						'edit_private_posts'     => 'ee_edit_private_events',
87
+						'edit_published_posts'   => 'ee_edit_published_events',
88
+					),
89
+					'taxonomies'          => array(
90
+						'espresso_event_categories',
91
+						'espresso_event_type',
92
+						'post_tag',
93
+					),
94
+					'page_templates'      => true,
95
+				),
96
+			),
97
+			'espresso_venues'    => array(
98
+				'singular_name' => esc_html__('Venue', 'event_espresso'),
99
+				'plural_name'   => esc_html__('Venues', 'event_espresso'),
100
+				'singular_slug' => esc_html__('venue', 'event_espresso'),
101
+				'plural_slug'   => esc_html__('venues', 'event_espresso'),
102
+				'class_name'    => 'EE_Venue',
103
+				'model_name'    => 'EEM_Venue',
104
+				'args'          => array(
105
+					'public'            => true,
106
+					'show_in_nav_menus' => false, // by default this doesn't show for decaf,
107
+					'capability_type'   => 'venue',
108
+					'capabilities'      => array(
109
+						'edit_post'              => 'ee_edit_venue',
110
+						'read_post'              => 'ee_read_venue',
111
+						'delete_post'            => 'ee_delete_venue',
112
+						'edit_posts'             => 'ee_edit_venues',
113
+						'edit_others_posts'      => 'ee_edit_others_venues',
114
+						'publish_posts'          => 'ee_publish_venues',
115
+						'read_private_posts'     => 'ee_read_private_venues',
116
+						'delete_posts'           => 'ee_delete_venues',
117
+						'delete_private_posts'   => 'ee_delete_private_venues',
118
+						'delete_published_posts' => 'ee_delete_published_venues',
119
+						'delete_others_posts'    => 'ee_edit_others_venues',
120
+						'edit_private_posts'     => 'ee_edit_private_venues',
121
+						'edit_published_posts'   => 'ee_edit_published_venues',
122
+					),
123
+					'taxonomies'        => array(
124
+						'espresso_venue_categories',
125
+						'post_tag',
126
+					),
127
+					'page_templates'    => true,
128
+				),
129
+			),
130
+			'espresso_attendees' => array(
131
+				'singular_name' => esc_html__('Contact', 'event_espresso'),
132
+				'plural_name'   => esc_html__('Contacts', 'event_espresso'),
133
+				'singular_slug' => esc_html__('contact', 'event_espresso'),
134
+				'plural_slug'   => esc_html__('contacts', 'event_espresso'),
135
+				'class_name'    => 'EE_Attendee',
136
+				'model_name'    => 'EEM_Attendee',
137
+				'args'          => array(
138
+					'public'             => false,
139
+					'publicly_queryable' => false,
140
+					'hierarchical'       => false,
141
+					'has_archive'        => false,
142
+					'supports'           => array(
143
+						'editor',
144
+						'thumbnail',
145
+						'excerpt',
146
+						'custom-fields',
147
+						'comments',
148
+					),
149
+					'taxonomies'         => array('post_tag'),
150
+					'capability_type'    => 'contact',
151
+					'capabilities'       => array(
152
+						'edit_post'              => 'ee_edit_contact',
153
+						'read_post'              => 'ee_read_contact',
154
+						'delete_post'            => 'ee_delete_contact',
155
+						'edit_posts'             => 'ee_edit_contacts',
156
+						'edit_others_posts'      => 'ee_edit_contacts',
157
+						'publish_posts'          => 'ee_edit_contacts',
158
+						'read_private_posts'     => 'ee_edit_contacts',
159
+						'delete_posts'           => 'ee_delete_contacts',
160
+						'delete_private_posts'   => 'ee_delete_contacts',
161
+						'delete_published_posts' => 'ee_delete_contacts',
162
+						'delete_others_posts'    => 'ee_delete_contacts',
163
+						'edit_private_posts'     => 'ee_edit_contacts',
164
+						'edit_published_posts'   => 'ee_edit_contacts',
165
+					),
166
+				),
167
+			),
168
+		);
169
+	}
170 170
 
171 171
 
172
-    /**
173
-     * @return array
174
-     */
175
-    public function getDefinitions()
176
-    {
177
-        return (array) apply_filters(
178
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
179
-            // legacy filter applied for now,
180
-            // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
181
-            apply_filters(
182
-                'FHEE__EE_Register_CPTs__get_CPTs__cpts',
183
-                $this->custom_post_types
184
-            )
185
-        );
186
-    }
172
+	/**
173
+	 * @return array
174
+	 */
175
+	public function getDefinitions()
176
+	{
177
+		return (array) apply_filters(
178
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
179
+			// legacy filter applied for now,
180
+			// later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
181
+			apply_filters(
182
+				'FHEE__EE_Register_CPTs__get_CPTs__cpts',
183
+				$this->custom_post_types
184
+			)
185
+		);
186
+	}
187 187
 
188 188
 
189
-    /**
190
-     * @return array
191
-     */
192
-    public function getCustomPostTypeSlugs()
193
-    {
194
-        return array_keys($this->getDefinitions());
195
-    }
189
+	/**
190
+	 * @return array
191
+	 */
192
+	public function getCustomPostTypeSlugs()
193
+	{
194
+		return array_keys($this->getDefinitions());
195
+	}
196 196
 
197 197
 
198
-    /**
199
-     * This basically goes through the CPT array and returns only CPT's
200
-     * that have the ['args']['public'] option set as false
201
-     *
202
-     * @return array
203
-     */
204
-    public function getPrivateCustomPostTypes()
205
-    {
206
-        $private_CPTs = array();
207
-        foreach ($this->getDefinitions() as $CPT => $details) {
208
-            if (empty($details['args']['public'])) {
209
-                $private_CPTs[ $CPT ] = $details;
210
-            }
211
-        }
212
-        return $private_CPTs;
213
-    }
198
+	/**
199
+	 * This basically goes through the CPT array and returns only CPT's
200
+	 * that have the ['args']['public'] option set as false
201
+	 *
202
+	 * @return array
203
+	 */
204
+	public function getPrivateCustomPostTypes()
205
+	{
206
+		$private_CPTs = array();
207
+		foreach ($this->getDefinitions() as $CPT => $details) {
208
+			if (empty($details['args']['public'])) {
209
+				$private_CPTs[ $CPT ] = $details;
210
+			}
211
+		}
212
+		return $private_CPTs;
213
+	}
214 214
 
215 215
 
216
-    /**
217
-     * This returns the corresponding model name for cpts registered by EE.
218
-     *
219
-     * @param string $post_type_slug    If a slug is included, then attempt to retrieve
220
-     *                                  the model name for the given cpt slug.
221
-     *                                  Otherwise if empty, then we'll return
222
-     *                                  all cpt model names for cpts registered in EE.
223
-     * @return array                    Empty array if no matching model names for the given slug
224
-     *                                  or an array of model names indexed by post type slug.
225
-     */
226
-    public function getCustomPostTypeModelNames($post_type_slug = '')
227
-    {
228
-        $cpts = $this->getDefinitions();
229
-        // first if slug passed in...
230
-        if (! empty($post_type_slug)) {
231
-            // check that slug and cpt match
232
-            if (! isset($cpts[ $post_type_slug ])) {
233
-                return array();
234
-            }
235
-            if (empty($cpts[ $post_type_slug ]['class_name'])
236
-                && empty($cpts[ $post_type_slug ]['model_name'])
237
-            ) {
238
-                return array();
239
-            }
240
-            // k let's get the model name for this cpt.
241
-            return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
242
-        }
243
-        // if we made it here then we're returning an array of cpt model names indexed by post_type_slug.
244
-        $cpt_models = array();
245
-        foreach ($cpts as $slug => $args) {
246
-            $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
247
-            if (! empty($model)) {
248
-                $cpt_models[ $slug ] = $model;
249
-            }
250
-        }
251
-        return $cpt_models;
252
-    }
216
+	/**
217
+	 * This returns the corresponding model name for cpts registered by EE.
218
+	 *
219
+	 * @param string $post_type_slug    If a slug is included, then attempt to retrieve
220
+	 *                                  the model name for the given cpt slug.
221
+	 *                                  Otherwise if empty, then we'll return
222
+	 *                                  all cpt model names for cpts registered in EE.
223
+	 * @return array                    Empty array if no matching model names for the given slug
224
+	 *                                  or an array of model names indexed by post type slug.
225
+	 */
226
+	public function getCustomPostTypeModelNames($post_type_slug = '')
227
+	{
228
+		$cpts = $this->getDefinitions();
229
+		// first if slug passed in...
230
+		if (! empty($post_type_slug)) {
231
+			// check that slug and cpt match
232
+			if (! isset($cpts[ $post_type_slug ])) {
233
+				return array();
234
+			}
235
+			if (empty($cpts[ $post_type_slug ]['class_name'])
236
+				&& empty($cpts[ $post_type_slug ]['model_name'])
237
+			) {
238
+				return array();
239
+			}
240
+			// k let's get the model name for this cpt.
241
+			return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
242
+		}
243
+		// if we made it here then we're returning an array of cpt model names indexed by post_type_slug.
244
+		$cpt_models = array();
245
+		foreach ($cpts as $slug => $args) {
246
+			$model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
247
+			if (! empty($model)) {
248
+				$cpt_models[ $slug ] = $model;
249
+			}
250
+		}
251
+		return $cpt_models;
252
+	}
253 253
 
254 254
 
255
-    /**
256
-     * @param       $post_type_slug
257
-     * @param array $cpt
258
-     * @return array
259
-     */
260
-    private function getCustomPostTypeModelName($post_type_slug, array $cpt)
261
-    {
262
-        if (! empty($cpt['model_name'])) {
263
-            return array($post_type_slug => $cpt['model_name']);
264
-        }
265
-        if (! empty($cpt['class_name'])) {
266
-            return array(
267
-                $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']),
268
-            );
269
-        }
270
-        return array();
271
-    }
255
+	/**
256
+	 * @param       $post_type_slug
257
+	 * @param array $cpt
258
+	 * @return array
259
+	 */
260
+	private function getCustomPostTypeModelName($post_type_slug, array $cpt)
261
+	{
262
+		if (! empty($cpt['model_name'])) {
263
+			return array($post_type_slug => $cpt['model_name']);
264
+		}
265
+		if (! empty($cpt['class_name'])) {
266
+			return array(
267
+				$post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']),
268
+			);
269
+		}
270
+		return array();
271
+	}
272 272
 
273 273
 
274
-    /**
275
-     * @param string $class_name
276
-     * @return string
277
-     */
278
-    private function deriveCptModelNameFromClassName($class_name)
279
-    {
280
-        return str_replace('EE', 'EEM', $class_name);
281
-    }
274
+	/**
275
+	 * @param string $class_name
276
+	 * @return string
277
+	 */
278
+	private function deriveCptModelNameFromClassName($class_name)
279
+	{
280
+		return str_replace('EE', 'EEM', $class_name);
281
+	}
282 282
 
283 283
 
284
-    /**
285
-     * This instantiates cpt models related to the cpts registered via EE.
286
-     *
287
-     * @since 4.6.16.rc.000
288
-     * @param string $post_type_slug If valid slug is provided, then will instantiate the model only for
289
-     *                               the cpt matching the given slug.  Otherwise all cpt models will be
290
-     *                               instantiated (if possible).
291
-     * @return EEM_CPT_Base[]        successful instantiation will return an array of successfully instantiated
292
-     *                               EEM models indexed by post slug.
293
-     */
294
-    public function getCustomPostTypeModels($post_type_slug = '')
295
-    {
296
-        $cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug);
297
-        $instantiated = array();
298
-        foreach ($cpt_model_names as $slug => $model_name) {
299
-            $model = $this->loader->getShared($model_name);
300
-            if ($model instanceof EEM_CPT_Base) {
301
-                $instantiated[ $slug ] = $model;
302
-            }
303
-        }
304
-        return $instantiated;
305
-    }
284
+	/**
285
+	 * This instantiates cpt models related to the cpts registered via EE.
286
+	 *
287
+	 * @since 4.6.16.rc.000
288
+	 * @param string $post_type_slug If valid slug is provided, then will instantiate the model only for
289
+	 *                               the cpt matching the given slug.  Otherwise all cpt models will be
290
+	 *                               instantiated (if possible).
291
+	 * @return EEM_CPT_Base[]        successful instantiation will return an array of successfully instantiated
292
+	 *                               EEM models indexed by post slug.
293
+	 */
294
+	public function getCustomPostTypeModels($post_type_slug = '')
295
+	{
296
+		$cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug);
297
+		$instantiated = array();
298
+		foreach ($cpt_model_names as $slug => $model_name) {
299
+			$model = $this->loader->getShared($model_name);
300
+			if ($model instanceof EEM_CPT_Base) {
301
+				$instantiated[ $slug ] = $model;
302
+			}
303
+		}
304
+		return $instantiated;
305
+	}
306 306
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -68,8 +68,8 @@  discard block
 block discarded – undo
68 68
                     'public'              => true,
69 69
                     'show_in_nav_menus'   => true,
70 70
                     'show_in_graphql'     => true,
71
-                    'graphql_single_name' => __( 'Event', 'event_espresso' ),
72
-                    'graphql_plural_name' => __( 'Events', 'event_espresso' ),
71
+                    'graphql_single_name' => __('Event', 'event_espresso'),
72
+                    'graphql_plural_name' => __('Events', 'event_espresso'),
73 73
                     'capability_type'     => 'event',
74 74
                     'capabilities'        => array(
75 75
                         'edit_post'              => 'ee_edit_event',
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
         $private_CPTs = array();
207 207
         foreach ($this->getDefinitions() as $CPT => $details) {
208 208
             if (empty($details['args']['public'])) {
209
-                $private_CPTs[ $CPT ] = $details;
209
+                $private_CPTs[$CPT] = $details;
210 210
             }
211 211
         }
212 212
         return $private_CPTs;
@@ -227,25 +227,25 @@  discard block
 block discarded – undo
227 227
     {
228 228
         $cpts = $this->getDefinitions();
229 229
         // first if slug passed in...
230
-        if (! empty($post_type_slug)) {
230
+        if ( ! empty($post_type_slug)) {
231 231
             // check that slug and cpt match
232
-            if (! isset($cpts[ $post_type_slug ])) {
232
+            if ( ! isset($cpts[$post_type_slug])) {
233 233
                 return array();
234 234
             }
235
-            if (empty($cpts[ $post_type_slug ]['class_name'])
236
-                && empty($cpts[ $post_type_slug ]['model_name'])
235
+            if (empty($cpts[$post_type_slug]['class_name'])
236
+                && empty($cpts[$post_type_slug]['model_name'])
237 237
             ) {
238 238
                 return array();
239 239
             }
240 240
             // k let's get the model name for this cpt.
241
-            return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
241
+            return $this->getCustomPostTypeModelName($post_type_slug, $cpts[$post_type_slug]);
242 242
         }
243 243
         // if we made it here then we're returning an array of cpt model names indexed by post_type_slug.
244 244
         $cpt_models = array();
245 245
         foreach ($cpts as $slug => $args) {
246
-            $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
247
-            if (! empty($model)) {
248
-                $cpt_models[ $slug ] = $model;
246
+            $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[$post_type_slug]);
247
+            if ( ! empty($model)) {
248
+                $cpt_models[$slug] = $model;
249 249
             }
250 250
         }
251 251
         return $cpt_models;
@@ -259,10 +259,10 @@  discard block
 block discarded – undo
259 259
      */
260 260
     private function getCustomPostTypeModelName($post_type_slug, array $cpt)
261 261
     {
262
-        if (! empty($cpt['model_name'])) {
262
+        if ( ! empty($cpt['model_name'])) {
263 263
             return array($post_type_slug => $cpt['model_name']);
264 264
         }
265
-        if (! empty($cpt['class_name'])) {
265
+        if ( ! empty($cpt['class_name'])) {
266 266
             return array(
267 267
                 $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']),
268 268
             );
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
         foreach ($cpt_model_names as $slug => $model_name) {
299 299
             $model = $this->loader->getShared($model_name);
300 300
             if ($model instanceof EEM_CPT_Base) {
301
-                $instantiated[ $slug ] = $model;
301
+                $instantiated[$slug] = $model;
302 302
             }
303 303
         }
304 304
         return $instantiated;
Please login to merge, or discard this patch.
core/domain/services/converters/spoofers/RestApiSpoofer.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -27,58 +27,58 @@
 block discarded – undo
27 27
 class RestApiSpoofer
28 28
 {
29 29
 
30
-    /**
31
-     * @var Read
32
-     */
33
-    protected $rest_api;
30
+	/**
31
+	 * @var Read
32
+	 */
33
+	protected $rest_api;
34 34
 
35 35
 
36
-    /**
37
-     * RestApiSpoofer constructor.
38
-     *
39
-     * @param Read     $rest_api
40
-     * @param string   $api_version
41
-     */
42
-    public function __construct(Read $rest_api, $api_version = '4.8.36')
43
-    {
44
-        $this->rest_api = $rest_api;
45
-        $this->rest_api->setRequestedVersion($api_version);
46
-    }
36
+	/**
37
+	 * RestApiSpoofer constructor.
38
+	 *
39
+	 * @param Read     $rest_api
40
+	 * @param string   $api_version
41
+	 */
42
+	public function __construct(Read $rest_api, $api_version = '4.8.36')
43
+	{
44
+		$this->rest_api = $rest_api;
45
+		$this->rest_api->setRequestedVersion($api_version);
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * @param EEM_Base $model
51
-     * @param array    $query_params
52
-     * @param string   $include
53
-     * @return array
54
-     * @throws EE_Error
55
-     * @throws InvalidArgumentException
56
-     * @throws InvalidDataTypeException
57
-     * @throws InvalidInterfaceException
58
-     * @throws ModelConfigurationException
59
-     * @throws ReflectionException
60
-     * @throws RestException
61
-     * @throws RestPasswordIncorrectException
62
-     * @throws RestPasswordRequiredException
63
-     * @throws UnexpectedEntityException
64
-     * @since $VID:$
65
-     */
66
-    public function getApiResults(EEM_Base $model, array $query_params, $include = '')
67
-    {
68
-        /** @type array $results */
69
-        $results = $model->get_all_wpdb_results($query_params);
70
-        $rest_request = new WP_REST_Request();
71
-        $rest_request->set_param('include', $include);
72
-        $rest_request->set_param('caps', null);
73
-        $nice_results = array();
74
-        foreach ($results as $result) {
75
-            $nice_results[] = $this->rest_api->createEntityFromWpdbResult(
76
-                $model,
77
-                $result,
78
-                $rest_request
79
-            );
80
-        }
81
-        return $nice_results;
82
-    }
49
+	/**
50
+	 * @param EEM_Base $model
51
+	 * @param array    $query_params
52
+	 * @param string   $include
53
+	 * @return array
54
+	 * @throws EE_Error
55
+	 * @throws InvalidArgumentException
56
+	 * @throws InvalidDataTypeException
57
+	 * @throws InvalidInterfaceException
58
+	 * @throws ModelConfigurationException
59
+	 * @throws ReflectionException
60
+	 * @throws RestException
61
+	 * @throws RestPasswordIncorrectException
62
+	 * @throws RestPasswordRequiredException
63
+	 * @throws UnexpectedEntityException
64
+	 * @since $VID:$
65
+	 */
66
+	public function getApiResults(EEM_Base $model, array $query_params, $include = '')
67
+	{
68
+		/** @type array $results */
69
+		$results = $model->get_all_wpdb_results($query_params);
70
+		$rest_request = new WP_REST_Request();
71
+		$rest_request->set_param('include', $include);
72
+		$rest_request->set_param('caps', null);
73
+		$nice_results = array();
74
+		foreach ($results as $result) {
75
+			$nice_results[] = $this->rest_api->createEntityFromWpdbResult(
76
+				$model,
77
+				$result,
78
+				$rest_request
79
+			);
80
+		}
81
+		return $nice_results;
82
+	}
83 83
 
84 84
 }
85 85
\ No newline at end of file
Please login to merge, or discard this patch.