Completed
Branch master (87a62b)
by
unknown
18:29 queued 13:45
created
core/libraries/rest_api/controllers/model/Read.php 2 patches
Spacing   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
         $controller = self::getReadController();
100 100
         try {
101 101
             $controller->setRequestedVersion($version);
102
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
102
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
103 103
                 return $controller->sendResponse(
104 104
                     new WP_Error(
105 105
                         'endpoint_parsing_error',
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
         $controller = self::getReadController();
141 141
         try {
142 142
             $controller->setRequestedVersion($version);
143
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
143
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
144 144
                 return [];
145 145
             }
146 146
             // get the model for this version
@@ -203,11 +203,11 @@  discard block
 block discarded – undo
203 203
      */
204 204
     protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema): array
205 205
     {
206
-        if (isset($schema['properties'][ $field_name ]['default'])) {
207
-            if (is_array($schema['properties'][ $field_name ]['default'])) {
208
-                foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
206
+        if (isset($schema['properties'][$field_name]['default'])) {
207
+            if (is_array($schema['properties'][$field_name]['default'])) {
208
+                foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
209 209
                     if ($default_key === 'raw') {
210
-                        $schema['properties'][ $field_name ]['default'][ $default_key ] =
210
+                        $schema['properties'][$field_name]['default'][$default_key] =
211 211
                             ModelDataTranslator::prepareFieldValueForJson(
212 212
                                 $field,
213 213
                                 $default_value,
@@ -216,9 +216,9 @@  discard block
 block discarded – undo
216 216
                     }
217 217
                 }
218 218
             } else {
219
-                $schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
219
+                $schema['properties'][$field_name]['default'] = ModelDataTranslator::prepareFieldValueForJson(
220 220
                     $field,
221
-                    $schema['properties'][ $field_name ]['default'],
221
+                    $schema['properties'][$field_name]['default'],
222 222
                     $this->getModelVersionInfo()->requestedVersion()
223 223
                 );
224 224
             }
@@ -240,9 +240,9 @@  discard block
 block discarded – undo
240 240
     protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema): array
241 241
     {
242 242
         if ($field instanceof EE_Datetime_Field) {
243
-            $schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
243
+            $schema['properties'][$field_name.'_gmt'] = $field->getSchema();
244 244
             // modify the description
245
-            $schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
245
+            $schema['properties'][$field_name.'_gmt']['description'] = sprintf(
246 246
                 esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
247 247
                 wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
248 248
             );
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
         $controller = self::getReadController();
293 293
         try {
294 294
             $controller->setRequestedVersion($version);
295
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
295
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
296 296
                 return $controller->sendResponse(
297 297
                     new WP_Error(
298 298
                         'endpoint_parsing_error',
@@ -376,7 +376,7 @@  discard block
 block discarded – undo
376 376
     public function getEntitiesFromModel(EEM_Base $model, WP_REST_Request $request): array
377 377
     {
378 378
         $query_params = $this->createModelQueryParams($model, $request->get_params());
379
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
379
+        if ( ! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
380 380
             $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
381 381
             throw new RestException(
382 382
                 sprintf('rest_%s_cannot_list', $model_name_plural),
@@ -388,7 +388,7 @@  discard block
 block discarded – undo
388 388
                 ['status' => 403]
389 389
             );
390 390
         }
391
-        if (! $request->get_header('no_rest_headers')) {
391
+        if ( ! $request->get_header('no_rest_headers')) {
392 392
             $this->setHeadersFromQueryParams($model, $query_params);
393 393
         }
394 394
         /** @type array $results */
@@ -435,7 +435,7 @@  discard block
 block discarded – undo
435 435
         $context       = $this->validateContext($request->get_param('caps'));
436 436
         $model         = $relation->get_this_model();
437 437
         $related_model = $relation->get_other_model();
438
-        if (! isset($primary_model_query_params[0])) {
438
+        if ( ! isset($primary_model_query_params[0])) {
439 439
             $primary_model_query_params[0] = [];
440 440
         }
441 441
         // check if they can access the 1st model object
@@ -499,13 +499,13 @@  discard block
 block discarded – undo
499 499
         );
500 500
         $query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
501 501
         foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
502
-            $query_params[0][ $relation->get_this_model()->get_this_model_name()
502
+            $query_params[0][$relation->get_this_model()->get_this_model_name()
503 503
                               . '.'
504
-                              . $where_condition_key ] = $where_condition_value;
504
+                              . $where_condition_key] = $where_condition_value;
505 505
         }
506 506
         $query_params['default_where_conditions'] = 'none';
507 507
         $query_params['caps']                     = $context;
508
-        if (! $request->get_header('no_rest_headers')) {
508
+        if ( ! $request->get_header('no_rest_headers')) {
509 509
             $this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
510 510
         }
511 511
         /** @type array $results */
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
                     $result,
526 526
                     $request
527 527
                 );
528
-                $joined_result     = array_merge($join_model_result, $nice_result);
528
+                $joined_result = array_merge($join_model_result, $nice_result);
529 529
                 // but keep the meta stuff from the main model
530 530
                 if (isset($nice_result['meta'])) {
531 531
                     $joined_result['meta'] = $nice_result['meta'];
@@ -564,7 +564,7 @@  discard block
 block discarded – undo
564 564
      */
565 565
     public function getEntitiesFromRelation($id, EE_Model_Relation_Base $relation, WP_REST_Request $request): array
566 566
     {
567
-        if (! $relation->get_this_model()->has_primary_key_field()) {
567
+        if ( ! $relation->get_this_model()->has_primary_key_field()) {
568 568
             throw new EE_Error(
569 569
                 sprintf(
570 570
                     esc_html__(
@@ -610,7 +610,7 @@  discard block
 block discarded – undo
610 610
             Capabilities::getMissingPermissionsString($model, $query_params['caps'])
611 611
         );
612 612
         // normally the limit to a 2-part array, where the 2nd item is the limit
613
-        if (! isset($query_params['limit'])) {
613
+        if ( ! isset($query_params['limit'])) {
614 614
             $query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
615 615
         }
616 616
         if (is_array($query_params['limit'])) {
@@ -658,7 +658,7 @@  discard block
 block discarded – undo
658 658
         ?WP_REST_Request $rest_request,
659 659
         string $deprecated = null
660 660
     ): array {
661
-        if (! $rest_request instanceof WP_REST_Request) {
661
+        if ( ! $rest_request instanceof WP_REST_Request) {
662 662
             // ok so this was called in the old style, where the 3rd arg was
663 663
             // $include, and the 4th arg was $context
664 664
             // now setup the request just to avoid fatal errors, although we won't be able
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
             $rest_request,
713 713
             $has_protected_fields
714 714
         );
715
-        $entity_array                       = apply_filters(
715
+        $entity_array = apply_filters(
716 716
             'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
717 717
             $entity_array,
718 718
             $model,
@@ -744,7 +744,7 @@  discard block
 block discarded – undo
744 744
             $rest_request,
745 745
             $this
746 746
         );
747
-        if (! $current_user_full_access_to_entity) {
747
+        if ( ! $current_user_full_access_to_entity) {
748 748
             $result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
749 749
                 $entity_array,
750 750
                 $model,
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
      */
780 780
     protected function addProtectedProperty(EEM_Base $model, array $results_so_far, bool $protected): array
781 781
     {
782
-        if (! $protected || ! $model->hasPassword()) {
782
+        if ( ! $protected || ! $model->hasPassword()) {
783 783
             return $results_so_far;
784 784
         }
785 785
         $password_field  = $model->getPasswordField();
@@ -828,8 +828,8 @@  discard block
 block discarded – undo
828 828
         if ($do_chevy_shuffle) {
829 829
             global $post;
830 830
             $old_post = $post;
831
-            $post     = get_post($result[ $model->primary_key_name() ]);
832
-            if (! $post instanceof WP_Post) {
831
+            $post     = get_post($result[$model->primary_key_name()]);
832
+            if ( ! $post instanceof WP_Post) {
833 833
                 // well that's weird, because $result is what we JUST fetched from the database
834 834
                 throw new RestException(
835 835
                     'error_fetching_post_from_database_results',
@@ -839,7 +839,7 @@  discard block
 block discarded – undo
839 839
                     )
840 840
                 );
841 841
             }
842
-            $model_object_classname          = 'EE_' . $model->get_this_model_name();
842
+            $model_object_classname          = 'EE_'.$model->get_this_model_name();
843 843
             $post->{$model_object_classname} = EE_Registry::instance()->load_class(
844 844
                 $model_object_classname,
845 845
                 $result,
@@ -850,14 +850,14 @@  discard block
 block discarded – undo
850 850
         foreach ($result as $field_name => $field_value) {
851 851
             $field_obj = $model->field_settings_for($field_name);
852 852
             if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
853
-                unset($result[ $field_name ]);
853
+                unset($result[$field_name]);
854 854
             } elseif (
855 855
                 $this->isSubclassOfOne(
856 856
                     $field_obj,
857 857
                     $this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
858 858
                 )
859 859
             ) {
860
-                $result[ $field_name ] = [
860
+                $result[$field_name] = [
861 861
                     'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
862 862
                     'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
863 863
                 ];
@@ -867,7 +867,7 @@  discard block
 block discarded – undo
867 867
                     $this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
868 868
                 )
869 869
             ) {
870
-                $result[ $field_name ] = [
870
+                $result[$field_name] = [
871 871
                     'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
872 872
                     'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
873 873
                 ];
@@ -898,10 +898,10 @@  discard block
 block discarded – undo
898 898
                         $this->getModelVersionInfo()->requestedVersion()
899 899
                     );
900 900
                 }
901
-                $result[ $field_name . '_gmt' ] = $gmt_date;
902
-                $result[ $field_name ]          = $local_date;
901
+                $result[$field_name.'_gmt'] = $gmt_date;
902
+                $result[$field_name]          = $local_date;
903 903
             } else {
904
-                $result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
904
+                $result[$field_name] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
905 905
             }
906 906
         }
907 907
         if ($do_chevy_shuffle) {
@@ -958,7 +958,7 @@  discard block
 block discarded – undo
958 958
     protected function addExtraFields(EEM_Base $model, array $db_row, array $entity_array): array
959 959
     {
960 960
         if ($model instanceof EEM_CPT_Base) {
961
-            $entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
961
+            $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
962 962
         }
963 963
         return $entity_array;
964 964
     }
@@ -984,7 +984,7 @@  discard block
 block discarded – undo
984 984
                     'href' => $this->getVersionedLinkTo(
985 985
                         EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
986 986
                         . '/'
987
-                        . $entity_array[ $model->primary_key_name() ]
987
+                        . $entity_array[$model->primary_key_name()]
988 988
                     ),
989 989
                 ],
990 990
             ];
@@ -1001,12 +1001,12 @@  discard block
 block discarded – undo
1001 1001
             foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
1002 1002
                 $related_model_part                                                      =
1003 1003
                     Read::getRelatedEntityName($relation_name, $relation_obj);
1004
-                $links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = [
1004
+                $links[EED_Core_Rest_Api::ee_api_link_namespace.$related_model_part] = [
1005 1005
                     [
1006 1006
                         'href'   => $this->getVersionedLinkTo(
1007 1007
                             EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
1008 1008
                             . '/'
1009
-                            . $entity_array[ $model->primary_key_name() ]
1009
+                            . $entity_array[$model->primary_key_name()]
1010 1010
                             . '/'
1011 1011
                             . $related_model_part
1012 1012
                         ),
@@ -1046,12 +1046,12 @@  discard block
 block discarded – undo
1046 1046
         bool $included_items_protected = false
1047 1047
     ): array {
1048 1048
         // if $db_row not included, hope the entity array has what we need
1049
-        if (! $db_row) {
1049
+        if ( ! $db_row) {
1050 1050
             $db_row = $entity_array;
1051 1051
         }
1052 1052
         $relation_settings = $this->getModelVersionInfo()->relationSettings($model);
1053 1053
         foreach ($relation_settings as $relation_name => $relation_obj) {
1054
-            $related_fields_to_include   = $this->explodeAndGetItemsPrefixedWith(
1054
+            $related_fields_to_include = $this->explodeAndGetItemsPrefixedWith(
1055 1055
                 $rest_request->get_param('include'),
1056 1056
                 $relation_name
1057 1057
             );
@@ -1079,7 +1079,7 @@  discard block
 block discarded – undo
1079 1079
                         $model->deduce_fields_n_values_from_cols_n_values($db_row)
1080 1080
                     )
1081 1081
                 );
1082
-                if (! $included_items_protected) {
1082
+                if ( ! $included_items_protected) {
1083 1083
                     try {
1084 1084
                         $related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1085 1085
                             $primary_model_query_params,
@@ -1100,7 +1100,7 @@  discard block
 block discarded – undo
1100 1100
                             ? null
1101 1101
                             : [];
1102 1102
                 }
1103
-                $entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1103
+                $entity_array[Read::getRelatedEntityName($relation_name, $relation_obj)] = $related_results;
1104 1104
             }
1105 1105
         }
1106 1106
         return $entity_array;
@@ -1127,7 +1127,7 @@  discard block
 block discarded – undo
1127 1127
         $includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1128 1128
         $includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1129 1129
         // if they passed in * or didn't specify any includes, return everything
1130
-        if (! empty($includes_for_this_model) && ! in_array('*', $includes_for_this_model, true)) {
1130
+        if ( ! empty($includes_for_this_model) && ! in_array('*', $includes_for_this_model, true)) {
1131 1131
             if ($model->has_primary_key_field()) {
1132 1132
                 // always include the primary key. ya just gotta know that at least
1133 1133
                 $includes_for_this_model[] = $model->primary_key_name();
@@ -1185,13 +1185,13 @@  discard block
 block discarded – undo
1185 1185
                 $schema = $this->fields_calculator->getJsonSchemaForModel($model);
1186 1186
                 if (
1187 1187
                     $row_is_protected
1188
-                    && isset($schema['properties'][ $field_to_calculate ]['protected'])
1189
-                    && $schema['properties'][ $field_to_calculate ]['protected']
1188
+                    && isset($schema['properties'][$field_to_calculate]['protected'])
1189
+                    && $schema['properties'][$field_to_calculate]['protected']
1190 1190
                 ) {
1191 1191
                     $calculated_value   = null;
1192 1192
                     $protected_fields[] = $field_to_calculate;
1193
-                    if ($schema['properties'][ $field_to_calculate ]['type']) {
1194
-                        switch ($schema['properties'][ $field_to_calculate ]['type']) {
1193
+                    if ($schema['properties'][$field_to_calculate]['type']) {
1194
+                        switch ($schema['properties'][$field_to_calculate]['type']) {
1195 1195
                             case 'boolean':
1196 1196
                                 $calculated_value = false;
1197 1197
                                 break;
@@ -1311,7 +1311,7 @@  discard block
 block discarded – undo
1311 1311
      */
1312 1312
     public function validateContext(?string $context): string
1313 1313
     {
1314
-        if (! $context) {
1314
+        if ( ! $context) {
1315 1315
             $context = EEM_Base::caps_read;
1316 1316
         }
1317 1317
         $valid_contexts = EEM_Base::valid_cap_contexts();
@@ -1335,7 +1335,7 @@  discard block
 block discarded – undo
1335 1335
             EEM_Base::default_where_conditions_minimum_all,
1336 1336
             EEM_Base::default_where_conditions_minimum_others,
1337 1337
         ];
1338
-        if (! $default_where_conditions) {
1338
+        if ( ! $default_where_conditions) {
1339 1339
             $default_where_conditions = EEM_Base::default_where_conditions_all;
1340 1340
         }
1341 1341
         if (
@@ -1426,14 +1426,14 @@  discard block
 block discarded – undo
1426 1426
         }
1427 1427
         if (isset($query_params['limit'])) {
1428 1428
             // limit should be either a string like '23' or '23,43', or an array with two items in it
1429
-            if (! is_array($query_params['limit'])) {
1429
+            if ( ! is_array($query_params['limit'])) {
1430 1430
                 $limit_array = explode(',', (string) $query_params['limit']);
1431 1431
             } else {
1432 1432
                 $limit_array = $query_params['limit'];
1433 1433
             }
1434 1434
             $sanitized_limit = [];
1435 1435
             foreach ($limit_array as $limit_part) {
1436
-                if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1436
+                if ($this->debug_mode && ( ! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1437 1437
                     throw new EE_Error(
1438 1438
                         sprintf(
1439 1439
                             esc_html__(
@@ -1490,7 +1490,7 @@  discard block
 block discarded – undo
1490 1490
     {
1491 1491
         $model_ready_query_params = [];
1492 1492
         foreach ($query_params as $key => $value) {
1493
-            $model_ready_query_params[ $key ] = is_array($value)
1493
+            $model_ready_query_params[$key] = is_array($value)
1494 1494
                 ? $this->prepareRestQueryParamsKeyForModels($model, $value)
1495 1495
                 : $value;
1496 1496
         }
@@ -1509,9 +1509,9 @@  discard block
 block discarded – undo
1509 1509
         $model_ready_query_params = [];
1510 1510
         foreach ($query_params as $key => $value) {
1511 1511
             if (is_array($value)) {
1512
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1512
+                $model_ready_query_params[$key] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1513 1513
             } else {
1514
-                $model_ready_query_params[ $key ] = $value;
1514
+                $model_ready_query_params[$key] = $value;
1515 1515
             }
1516 1516
         }
1517 1517
         return $model_ready_query_params;
@@ -1543,17 +1543,17 @@  discard block
 block discarded – undo
1543 1543
         foreach ($exploded_contents as $item) {
1544 1544
             $item = trim($item);
1545 1545
             // if no prefix was provided, so we look for items with no "." in them
1546
-            if (! $prefix) {
1546
+            if ( ! $prefix) {
1547 1547
                 // does this item have a period?
1548 1548
                 if (strpos($item, '.') === false) {
1549 1549
                     // if not, then its what we're looking for
1550 1550
                     $contents_with_prefix[] = $item;
1551 1551
                 }
1552
-            } elseif (strpos($item, $prefix . '.') === 0) {
1552
+            } elseif (strpos($item, $prefix.'.') === 0) {
1553 1553
                 // this item has the prefix and a period, grab it
1554 1554
                 $contents_with_prefix[] = substr(
1555 1555
                     $item,
1556
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1556
+                    strpos($item, $prefix.'.') + strlen($prefix.'.')
1557 1557
                 );
1558 1558
             } elseif ($item === $prefix) {
1559 1559
                 // this item is JUST the prefix
@@ -1596,9 +1596,9 @@  discard block
 block discarded – undo
1596 1596
         if ($model_name) {
1597 1597
             foreach ($includes as $field_to_include) {
1598 1598
                 $field_to_include = trim($field_to_include);
1599
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1599
+                if (strpos($field_to_include, $model_name.'.') === 0) {
1600 1600
                     // found the model name at the exact start
1601
-                    $field_sans_model_name         = str_replace($model_name . '.', '', $field_to_include);
1601
+                    $field_sans_model_name         = str_replace($model_name.'.', '', $field_to_include);
1602 1602
                     $extracted_fields_to_include[] = $field_sans_model_name;
1603 1603
                 } elseif ($field_to_include === $model_name) {
1604 1604
                     $extracted_fields_to_include[] = '*';
@@ -1641,7 +1641,7 @@  discard block
 block discarded – undo
1641 1641
         $restricted_query_params['caps'] = $context;
1642 1642
         $this->setDebugInfo('model query params', $restricted_query_params);
1643 1643
         $model_rows = $model->get_all_wpdb_results($restricted_query_params);
1644
-        if (! empty($model_rows)) {
1644
+        if ( ! empty($model_rows)) {
1645 1645
             return $this->createEntityFromWpdbResult(
1646 1646
                 $model,
1647 1647
                 reset($model_rows),
@@ -1653,7 +1653,7 @@  discard block
 block discarded – undo
1653 1653
         if ($model->exists($query_params)) {
1654 1654
             // you got shafted- it existed but we didn't want to tell you!
1655 1655
             throw new RestException(
1656
-                'rest_user_cannot_' . $context,
1656
+                'rest_user_cannot_'.$context,
1657 1657
                 sprintf(
1658 1658
                     __('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1659 1659
                     $context,
@@ -1705,14 +1705,14 @@  discard block
 block discarded – undo
1705 1705
         // if this entity requires a password, they better give it and it better be right!
1706 1706
         if (
1707 1707
             $model->hasPassword()
1708
-            && $model_row[ $model->getPasswordField()->get_qualified_column() ] !== ''
1708
+            && $model_row[$model->getPasswordField()->get_qualified_column()] !== ''
1709 1709
         ) {
1710 1710
             if (empty($request['password'])) {
1711 1711
                 throw new RestPasswordRequiredException();
1712 1712
             }
1713 1713
             if (
1714 1714
                 ! hash_equals(
1715
-                    $model_row[ $model->getPasswordField()->get_qualified_column() ],
1715
+                    $model_row[$model->getPasswordField()->get_qualified_column()],
1716 1716
                     $request['password']
1717 1717
                 )
1718 1718
             ) {
@@ -1726,12 +1726,12 @@  discard block
 block discarded – undo
1726 1726
             $password_supplied = $request->get_param('password');
1727 1727
             if (empty($password_supplied)) {
1728 1728
                 $query_params['exclude_protected'] = true;
1729
-                if (! $model->exists($query_params)) {
1729
+                if ( ! $model->exists($query_params)) {
1730 1730
                     throw new RestPasswordRequiredException();
1731 1731
                 }
1732 1732
             } else {
1733
-                $query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1734
-                if (! $model->exists($query_params)) {
1733
+                $query_params[0][$model->modelChainAndPassword()] = $password_supplied;
1734
+                if ( ! $model->exists($query_params)) {
1735 1735
                     throw new RestPasswordIncorrectException();
1736 1736
                 }
1737 1737
             }
Please login to merge, or discard this patch.
Indentation   +1684 added lines, -1684 removed lines patch added patch discarded remove patch
@@ -51,1688 +51,1688 @@
 block discarded – undo
51 51
  */
52 52
 class Read extends Base
53 53
 {
54
-    /**
55
-     * @var CalculatedModelFields
56
-     */
57
-    protected $fields_calculator;
58
-
59
-
60
-    /**
61
-     * Read constructor.
62
-     *
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
-     * @return Read
74
-     */
75
-    private static function getReadController(): Read
76
-    {
77
-        return LoaderFactory::getLoader()->getNew(Read::class);
78
-    }
79
-
80
-
81
-    /**
82
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
83
-     *
84
-     * @param WP_REST_Request $request
85
-     * @param string          $version
86
-     * @param string          $model_name
87
-     * @return WP_REST_Response
88
-     * @throws InvalidArgumentException
89
-     * @throws InvalidDataTypeException
90
-     * @throws InvalidInterfaceException
91
-     */
92
-    public static function handleRequestGetAll(
93
-        WP_REST_Request $request,
94
-        string $version,
95
-        string $model_name
96
-    ): WP_REST_Response {
97
-        $controller = self::getReadController();
98
-        try {
99
-            $controller->setRequestedVersion($version);
100
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
101
-                return $controller->sendResponse(
102
-                    new WP_Error(
103
-                        'endpoint_parsing_error',
104
-                        sprintf(
105
-                            esc_html__(
106
-                                'There is no model for endpoint %s. Please contact event espresso support',
107
-                                'event_espresso'
108
-                            ),
109
-                            $model_name
110
-                        )
111
-                    )
112
-                );
113
-            }
114
-            return $controller->sendResponse(
115
-                $controller->getEntitiesFromModel(
116
-                    $controller->getModelVersionInfo()->loadModel($model_name),
117
-                    $request
118
-                )
119
-            );
120
-        } catch (Exception $e) {
121
-            return $controller->sendResponse($e);
122
-        }
123
-    }
124
-
125
-
126
-    /**
127
-     * Prepares and returns schema for any OPTIONS request.
128
-     *
129
-     * @param string $version    The API endpoint version being used.
130
-     * @param string $model_name Something like `Event` or `Registration`
131
-     * @return array
132
-     * @throws InvalidArgumentException
133
-     * @throws InvalidDataTypeException
134
-     * @throws InvalidInterfaceException
135
-     */
136
-    public static function handleSchemaRequest(string $version, string $model_name): array
137
-    {
138
-        $controller = self::getReadController();
139
-        try {
140
-            $controller->setRequestedVersion($version);
141
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
142
-                return [];
143
-            }
144
-            // get the model for this version
145
-            $model        = $controller->getModelVersionInfo()->loadModel($model_name);
146
-            $model_schema = new JsonModelSchema(
147
-                $model,
148
-                LoaderFactory::getLoader()->getShared('EventEspresso\core\libraries\rest_api\CalculatedModelFields')
149
-            );
150
-            return $model_schema->getModelSchemaForRelations(
151
-                $controller->getModelVersionInfo()->relationSettings($model),
152
-                $controller->customizeSchemaForRestResponse(
153
-                    $model,
154
-                    $model_schema->getModelSchemaForFields(
155
-                        $controller->getModelVersionInfo()->fieldsOnModelInThisVersion($model),
156
-                        $model_schema->getInitialSchemaStructure()
157
-                    )
158
-                )
159
-            );
160
-        } catch (Exception $e) {
161
-            return [];
162
-        }
163
-    }
164
-
165
-
166
-    /**
167
-     * This loops through each field in the given schema for the model and does the following:
168
-     * - add any extra fields that are REST API specific and related to existing fields.
169
-     * - transform default values into the correct format for a REST API response.
170
-     *
171
-     * @param EEM_Base $model
172
-     * @param array    $schema
173
-     * @return array  The final schema.
174
-     * @throws EE_Error
175
-     */
176
-    public function customizeSchemaForRestResponse(EEM_Base $model, array $schema): array
177
-    {
178
-        foreach ($this->getModelVersionInfo()->fieldsOnModelInThisVersion($model) as $field_name => $field) {
179
-            $schema = $this->translateDefaultsForRestResponse(
180
-                $field_name,
181
-                $field,
182
-                $this->maybeAddExtraFieldsToSchema($field_name, $field, $schema)
183
-            );
184
-        }
185
-        return $schema;
186
-    }
187
-
188
-
189
-    /**
190
-     * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
191
-     * response.
192
-     *
193
-     * @param                      $field_name
194
-     * @param EE_Model_Field_Base  $field
195
-     * @param array                $schema
196
-     * @return array
197
-     * @throws RestException  if a default value has a PHP object, which we should never do
198
-     *                                  (but if we did, let's know about it ASAP, so let the exception bubble up)
199
-     * @throws EE_Error
200
-     *
201
-     */
202
-    protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema): array
203
-    {
204
-        if (isset($schema['properties'][ $field_name ]['default'])) {
205
-            if (is_array($schema['properties'][ $field_name ]['default'])) {
206
-                foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
207
-                    if ($default_key === 'raw') {
208
-                        $schema['properties'][ $field_name ]['default'][ $default_key ] =
209
-                            ModelDataTranslator::prepareFieldValueForJson(
210
-                                $field,
211
-                                $default_value,
212
-                                $this->getModelVersionInfo()->requestedVersion()
213
-                            );
214
-                    }
215
-                }
216
-            } else {
217
-                $schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
218
-                    $field,
219
-                    $schema['properties'][ $field_name ]['default'],
220
-                    $this->getModelVersionInfo()->requestedVersion()
221
-                );
222
-            }
223
-        }
224
-        return $schema;
225
-    }
226
-
227
-
228
-    /**
229
-     * Adds additional fields to the schema
230
-     * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
231
-     * needs to be added to the schema.
232
-     *
233
-     * @param                      $field_name
234
-     * @param EE_Model_Field_Base  $field
235
-     * @param array                $schema
236
-     * @return array
237
-     */
238
-    protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema): array
239
-    {
240
-        if ($field instanceof EE_Datetime_Field) {
241
-            $schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
242
-            // modify the description
243
-            $schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
244
-                esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
245
-                wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
246
-            );
247
-        }
248
-        return $schema;
249
-    }
250
-
251
-
252
-    /**
253
-     * Used to figure out the route from the request when a `WP_REST_Request` object is not available
254
-     *
255
-     * @return string
256
-     */
257
-    protected function getRouteFromRequest(): string
258
-    {
259
-        if (
260
-            isset($GLOBALS['wp'])
261
-            && $GLOBALS['wp'] instanceof WP
262
-            && isset($GLOBALS['wp']->query_vars['rest_route'])
263
-        ) {
264
-            return $GLOBALS['wp']->query_vars['rest_route'];
265
-        }
266
-        /** @var RequestInterface $request */
267
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
268
-        return $request->serverParamIsSet('PATH_INFO')
269
-            ? $request->getServerParam('PATH_INFO')
270
-            : '/';
271
-    }
272
-
273
-
274
-    /**
275
-     * Gets a single entity related to the model indicated in the path and its id
276
-     *
277
-     * @param WP_REST_Request $request
278
-     * @param string          $version
279
-     * @param string          $model_name
280
-     * @return WP_REST_Response
281
-     * @throws InvalidDataTypeException
282
-     * @throws InvalidInterfaceException
283
-     * @throws InvalidArgumentException
284
-     */
285
-    public static function handleRequestGetOne(
286
-        WP_REST_Request $request,
287
-        string $version,
288
-        string $model_name
289
-    ): WP_REST_Response {
290
-        $controller = self::getReadController();
291
-        try {
292
-            $controller->setRequestedVersion($version);
293
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
294
-                return $controller->sendResponse(
295
-                    new WP_Error(
296
-                        'endpoint_parsing_error',
297
-                        sprintf(
298
-                            esc_html__(
299
-                                'There is no model for endpoint %s. Please contact event espresso support',
300
-                                'event_espresso'
301
-                            ),
302
-                            $model_name
303
-                        )
304
-                    )
305
-                );
306
-            }
307
-            return $controller->sendResponse(
308
-                $controller->getEntityFromModel(
309
-                    $controller->getModelVersionInfo()->loadModel($model_name),
310
-                    $request
311
-                )
312
-            );
313
-        } catch (Exception $e) {
314
-            return $controller->sendResponse($e);
315
-        }
316
-    }
317
-
318
-
319
-    /**
320
-     * Gets all the related entities (or if its a belongs-to relation just the one)
321
-     * to the item with the given id
322
-     *
323
-     * @param WP_REST_Request $request
324
-     * @param string          $version
325
-     * @param string          $model_name
326
-     * @param string          $related_model_name
327
-     * @return WP_REST_Response
328
-     * @throws InvalidDataTypeException
329
-     * @throws InvalidInterfaceException
330
-     * @throws InvalidArgumentException
331
-     */
332
-    public static function handleRequestGetRelated(
333
-        WP_REST_Request $request,
334
-        string $version,
335
-        string $model_name,
336
-        string $related_model_name
337
-    ): WP_REST_Response {
338
-        $controller = self::getReadController();
339
-        try {
340
-            $controller->setRequestedVersion($version);
341
-            $main_model = $controller->validateModel($model_name);
342
-            $controller->validateModel($related_model_name);
343
-            return $controller->sendResponse(
344
-                $controller->getEntitiesFromRelation(
345
-                    $request->get_param('id'),
346
-                    $main_model->related_settings_for($related_model_name),
347
-                    $request
348
-                )
349
-            );
350
-        } catch (Exception $e) {
351
-            return $controller->sendResponse($e);
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * Gets a collection for the given model and filters
358
-     *
359
-     * @param EEM_Base        $model
360
-     * @param WP_REST_Request $request
361
-     * @return array
362
-     * @throws DomainException
363
-     * @throws EE_Error
364
-     * @throws InvalidArgumentException
365
-     * @throws InvalidDataTypeException
366
-     * @throws InvalidInterfaceException
367
-     * @throws ModelConfigurationException
368
-     * @throws ReflectionException
369
-     * @throws RestException
370
-     * @throws RestPasswordIncorrectException
371
-     * @throws RestPasswordRequiredException
372
-     * @throws UnexpectedEntityException
373
-     */
374
-    public function getEntitiesFromModel(EEM_Base $model, WP_REST_Request $request): array
375
-    {
376
-        $query_params = $this->createModelQueryParams($model, $request->get_params());
377
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
378
-            $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
379
-            throw new RestException(
380
-                sprintf('rest_%s_cannot_list', $model_name_plural),
381
-                sprintf(
382
-                    esc_html__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
383
-                    $model_name_plural,
384
-                    Capabilities::getMissingPermissionsString($model, $query_params['caps'])
385
-                ),
386
-                ['status' => 403]
387
-            );
388
-        }
389
-        if (! $request->get_header('no_rest_headers')) {
390
-            $this->setHeadersFromQueryParams($model, $query_params);
391
-        }
392
-        /** @type array $results */
393
-        $results      = $model->get_all_wpdb_results($query_params);
394
-        $nice_results = [];
395
-        foreach ($results as $result) {
396
-            $nice_results[] = $this->createEntityFromWpdbResult(
397
-                $model,
398
-                $result,
399
-                $request
400
-            );
401
-        }
402
-        return $nice_results;
403
-    }
404
-
405
-
406
-    /**
407
-     * Gets the collection for given relation object
408
-     * The same as Read::get_entities_from_model(), except if the relation
409
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
410
-     * the join-model-object into the results
411
-     *
412
-     * @param array                  $primary_model_query_params  query params for finding the item from which
413
-     *                                                            relations will be based
414
-     * @param EE_Model_Relation_Base $relation
415
-     * @param WP_REST_Request        $request
416
-     * @return array|null
417
-     * @throws DomainException
418
-     * @throws EE_Error
419
-     * @throws InvalidArgumentException
420
-     * @throws InvalidDataTypeException
421
-     * @throws InvalidInterfaceException
422
-     * @throws ModelConfigurationException
423
-     * @throws ReflectionException
424
-     * @throws RestException
425
-     * @throws ModelConfigurationException
426
-     * @throws UnexpectedEntityException
427
-     */
428
-    protected function getEntitiesFromRelationUsingModelQueryParams(
429
-        array $primary_model_query_params,
430
-        EE_Model_Relation_Base $relation,
431
-        WP_REST_Request $request
432
-    ) {
433
-        $context       = $this->validateContext($request->get_param('caps'));
434
-        $model         = $relation->get_this_model();
435
-        $related_model = $relation->get_other_model();
436
-        if (! isset($primary_model_query_params[0])) {
437
-            $primary_model_query_params[0] = [];
438
-        }
439
-        // check if they can access the 1st model object
440
-        $primary_model_query_params = [
441
-            0       => $primary_model_query_params[0],
442
-            'limit' => 1,
443
-        ];
444
-        if ($model instanceof EEM_Soft_Delete_Base) {
445
-            $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included(
446
-                $primary_model_query_params
447
-            );
448
-        }
449
-        $restricted_query_params          = $primary_model_query_params;
450
-        $restricted_query_params['caps']  = $context;
451
-        $restricted_query_params['limit'] = 1;
452
-        $this->setDebugInfo('main model query params', $restricted_query_params);
453
-        $this->setDebugInfo('missing caps', Capabilities::getMissingPermissionsString($related_model, $context));
454
-        $primary_model_rows = $model->get_all_wpdb_results($restricted_query_params);
455
-        $primary_model_row  = null;
456
-        if (is_array($primary_model_rows)) {
457
-            $primary_model_row = reset($primary_model_rows);
458
-        }
459
-        if (
460
-            ! (
461
-                $primary_model_row
462
-                && Capabilities::currentUserHasPartialAccessTo($related_model, $context)
463
-            )
464
-        ) {
465
-            if ($relation instanceof EE_Belongs_To_Relation) {
466
-                $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
467
-            } else {
468
-                $related_model_name_maybe_plural = EEH_Inflector::pluralize_and_lower(
469
-                    $related_model->get_this_model_name()
470
-                );
471
-            }
472
-            throw new RestException(
473
-                sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
474
-                sprintf(
475
-                    esc_html__(
476
-                        'Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
477
-                        'event_espresso'
478
-                    ),
479
-                    $related_model_name_maybe_plural,
480
-                    $relation->get_this_model()->get_this_model_name(),
481
-                    implode(
482
-                        ',',
483
-                        array_keys(
484
-                            Capabilities::getMissingPermissions($related_model, $context)
485
-                        )
486
-                    )
487
-                ),
488
-                ['status' => 403]
489
-            );
490
-        }
491
-
492
-        $this->checkPassword(
493
-            $model,
494
-            $primary_model_row,
495
-            $restricted_query_params,
496
-            $request
497
-        );
498
-        $query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
499
-        foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
500
-            $query_params[0][ $relation->get_this_model()->get_this_model_name()
501
-                              . '.'
502
-                              . $where_condition_key ] = $where_condition_value;
503
-        }
504
-        $query_params['default_where_conditions'] = 'none';
505
-        $query_params['caps']                     = $context;
506
-        if (! $request->get_header('no_rest_headers')) {
507
-            $this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
508
-        }
509
-        /** @type array $results */
510
-        $results      = $relation->get_other_model()->get_all_wpdb_results($query_params);
511
-        $nice_results = [];
512
-        foreach ($results as $result) {
513
-            $nice_result = $this->createEntityFromWpdbResult(
514
-                $relation->get_other_model(),
515
-                $result,
516
-                $request
517
-            );
518
-            if ($relation instanceof EE_HABTM_Relation) {
519
-                // put the unusual stuff (properties from the HABTM relation) first, and make sure
520
-                // if there are conflicts we prefer the properties from the main model
521
-                $join_model_result = $this->createEntityFromWpdbResult(
522
-                    $relation->get_join_model(),
523
-                    $result,
524
-                    $request
525
-                );
526
-                $joined_result     = array_merge($join_model_result, $nice_result);
527
-                // but keep the meta stuff from the main model
528
-                if (isset($nice_result['meta'])) {
529
-                    $joined_result['meta'] = $nice_result['meta'];
530
-                }
531
-                $nice_result = $joined_result;
532
-            }
533
-            $nice_results[] = $nice_result;
534
-        }
535
-        if ($relation instanceof EE_Belongs_To_Relation) {
536
-            return array_shift($nice_results);
537
-        } else {
538
-            return $nice_results;
539
-        }
540
-    }
541
-
542
-
543
-    /**
544
-     * Gets the collection for given relation object
545
-     * The same as Read::get_entities_from_model(), except if the relation
546
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
547
-     * the join-model-object into the results
548
-     *
549
-     * @param int|string             $id the ID of the thing we are fetching related stuff from
550
-     * @param EE_Model_Relation_Base $relation
551
-     * @param WP_REST_Request        $request
552
-     * @return array
553
-     * @throws DomainException
554
-     * @throws EE_Error
555
-     * @throws InvalidArgumentException
556
-     * @throws InvalidDataTypeException
557
-     * @throws InvalidInterfaceException
558
-     * @throws ReflectionException
559
-     * @throws RestException
560
-     * @throws ModelConfigurationException
561
-     * @throws UnexpectedEntityException
562
-     */
563
-    public function getEntitiesFromRelation($id, EE_Model_Relation_Base $relation, WP_REST_Request $request): array
564
-    {
565
-        if (! $relation->get_this_model()->has_primary_key_field()) {
566
-            throw new EE_Error(
567
-                sprintf(
568
-                    esc_html__(
569
-                    // @codingStandardsIgnoreStart
570
-                        'Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
571
-                        // @codingStandardsIgnoreEnd
572
-                        'event_espresso'
573
-                    ),
574
-                    $relation->get_this_model()->get_this_model_name()
575
-                )
576
-            );
577
-        }
578
-        // can we edit that main item?
579
-        // if not, show nothing but an error
580
-        // otherwise, please proceed
581
-        return $this->getEntitiesFromRelationUsingModelQueryParams(
582
-            [
583
-                [
584
-                    $relation->get_this_model()->primary_key_name() => $id,
585
-                ],
586
-            ],
587
-            $relation,
588
-            $request
589
-        );
590
-    }
591
-
592
-
593
-    /**
594
-     * Sets the headers that are based on the model and query params,
595
-     * like the total records. This should only be called on the original request
596
-     * from the client, not on subsequent internal
597
-     *
598
-     * @param EEM_Base $model
599
-     * @param array    $query_params
600
-     * @return void
601
-     * @throws EE_Error
602
-     */
603
-    protected function setHeadersFromQueryParams(EEM_Base $model, array $query_params)
604
-    {
605
-        $this->setDebugInfo('model query params', $query_params);
606
-        $this->setDebugInfo(
607
-            'missing caps',
608
-            Capabilities::getMissingPermissionsString($model, $query_params['caps'])
609
-        );
610
-        // normally the limit to a 2-part array, where the 2nd item is the limit
611
-        if (! isset($query_params['limit'])) {
612
-            $query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
613
-        }
614
-        if (is_array($query_params['limit'])) {
615
-            $limit_parts = $query_params['limit'];
616
-        } else {
617
-            $limit_parts = explode(',', $query_params['limit']);
618
-            if (count($limit_parts) === 1) {
619
-                $limit_parts = [0, $limit_parts[0]];
620
-            }
621
-        }
622
-        // remove the group by and having parts of the query, as those will
623
-        // make the sql query return an array of values, instead of just a single value
624
-        unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
625
-        $count = $model->count($query_params, null, true);
626
-        $pages = $count / $limit_parts[1];
627
-        $this->setResponseHeader('Total', $count, false);
628
-        $this->setResponseHeader('PageSize', $limit_parts[1], false);
629
-        $this->setResponseHeader('TotalPages', ceil($pages), false);
630
-    }
631
-
632
-
633
-    /**
634
-     * Changes database results into REST API entities
635
-     *
636
-     * @param EEM_Base             $model
637
-     * @param array                $db_row     like results from $wpdb->get_results()
638
-     * @param WP_REST_Request|null $rest_request
639
-     * @param string|null          $deprecated no longer used
640
-     * @return array ready for being converted into json for sending to client
641
-     * @throws DomainException
642
-     * @throws EE_Error
643
-     * @throws InvalidArgumentException
644
-     * @throws InvalidDataTypeException
645
-     * @throws InvalidInterfaceException
646
-     * @throws ModelConfigurationException
647
-     * @throws ReflectionException
648
-     * @throws RestException
649
-     * @throws RestPasswordIncorrectException
650
-     * @throws RestPasswordRequiredException
651
-     * @throws UnexpectedEntityException
652
-     */
653
-    public function createEntityFromWpdbResult(
654
-        EEM_Base $model,
655
-        array $db_row,
656
-        ?WP_REST_Request $rest_request,
657
-        string $deprecated = null
658
-    ): array {
659
-        if (! $rest_request instanceof WP_REST_Request) {
660
-            // ok so this was called in the old style, where the 3rd arg was
661
-            // $include, and the 4th arg was $context
662
-            // now setup the request just to avoid fatal errors, although we won't be able
663
-            // to truly make use of it because it's kinda devoid of info
664
-            $rest_request = new WP_REST_Request();
665
-            $rest_request->set_param('include', $rest_request);
666
-            $rest_request->set_param('caps', $deprecated);
667
-        }
668
-        if ($rest_request->get_param('caps') === null) {
669
-            $rest_request->set_param('caps', EEM_Base::caps_read);
670
-        }
671
-        $current_user_full_access_to_entity = $model->currentUserCan(
672
-            EEM_Base::caps_read_admin,
673
-            $model->deduce_fields_n_values_from_cols_n_values($db_row)
674
-        );
675
-        $entity_array                       = $this->createBareEntityFromWpdbResults($model, $db_row);
676
-        $entity_array                       = $this->addExtraFields($model, $db_row, $entity_array);
677
-        $entity_array['_links']             = $this->getEntityLinks($model, $db_row, $entity_array);
678
-        // when it's a regular read request for a model with a password and the password wasn't provided
679
-        // remove the password protected fields
680
-        $has_protected_fields = false;
681
-        try {
682
-            $this->checkPassword(
683
-                $model,
684
-                $db_row,
685
-                $model->alter_query_params_to_restrict_by_ID(
686
-                    $model->get_index_primary_key_string(
687
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
688
-                    )
689
-                ),
690
-                $rest_request
691
-            );
692
-        } catch (RestPasswordRequiredException $e) {
693
-            if ($model->hasPassword()) {
694
-                // just remove protected fields
695
-                $has_protected_fields = true;
696
-                $entity_array         = Capabilities::filterOutPasswordProtectedFields(
697
-                    $entity_array,
698
-                    $model,
699
-                    $this->getModelVersionInfo()
700
-                );
701
-            } else {
702
-                // that's a problem. None of this should be accessible if no password was provided
703
-                throw $e;
704
-            }
705
-        }
706
-
707
-        $entity_array['_calculated_fields'] = $this->getEntityCalculations(
708
-            $model,
709
-            $db_row,
710
-            $rest_request,
711
-            $has_protected_fields
712
-        );
713
-        $entity_array                       = apply_filters(
714
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
715
-            $entity_array,
716
-            $model,
717
-            $rest_request->get_param('caps'),
718
-            $rest_request,
719
-            $this
720
-        );
721
-        // add an empty protected property for now. If it's still around after we remove everything the request didn't
722
-        // want, we'll populate it then. k?
723
-        $entity_array['_protected'] = [];
724
-        // remove any properties the request didn't want. This way _protected won't bother mentioning them
725
-        $entity_array = $this->includeOnlyRequestedProperties($model, $rest_request, $entity_array);
726
-        $entity_array = $this->includeRequestedModels(
727
-            $model,
728
-            $rest_request,
729
-            $entity_array,
730
-            $db_row,
731
-            $has_protected_fields
732
-        );
733
-        // if they still wanted the _protected property, add it.
734
-        if (isset($entity_array['_protected'])) {
735
-            $entity_array = $this->addProtectedProperty($model, $entity_array, $has_protected_fields);
736
-        }
737
-        $entity_array = apply_filters(
738
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
739
-            $entity_array,
740
-            $model,
741
-            $rest_request->get_param('caps'),
742
-            $rest_request,
743
-            $this
744
-        );
745
-        if (! $current_user_full_access_to_entity) {
746
-            $result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
747
-                $entity_array,
748
-                $model,
749
-                $rest_request->get_param('caps'),
750
-                $this->getModelVersionInfo()
751
-            );
752
-        } else {
753
-            $result_without_inaccessible_fields = $entity_array;
754
-        }
755
-        $this->setDebugInfo(
756
-            'inaccessible fields',
757
-            array_keys(array_diff_key((array) $entity_array, (array) $result_without_inaccessible_fields))
758
-        );
759
-        return apply_filters(
760
-            'FHEE__Read__create_entity_from_wpdb_results__entity_return',
761
-            $result_without_inaccessible_fields,
762
-            $model,
763
-            $rest_request->get_param('caps')
764
-        );
765
-    }
766
-
767
-
768
-    /**
769
-     * Returns an array describing which fields can be protected, and which actually were removed this request
770
-     *
771
-     * @param EEM_Base $model
772
-     * @param array    $results_so_far
773
-     * @param bool     $protected
774
-     * @return array results
775
-     * @throws EE_Error
776
-     * @since 4.9.74.p
777
-     */
778
-    protected function addProtectedProperty(EEM_Base $model, array $results_so_far, bool $protected): array
779
-    {
780
-        if (! $protected || ! $model->hasPassword()) {
781
-            return $results_so_far;
782
-        }
783
-        $password_field  = $model->getPasswordField();
784
-        $all_protected   = array_merge(
785
-            [$password_field->get_name()],
786
-            $password_field->protectedFields()
787
-        );
788
-        $fields_included = array_keys($results_so_far);
789
-        $fields_included = array_intersect(
790
-            $all_protected,
791
-            $fields_included
792
-        );
793
-        foreach ($fields_included as $field_name) {
794
-            $results_so_far['_protected'][] = $field_name;
795
-        }
796
-        return $results_so_far;
797
-    }
798
-
799
-
800
-    /**
801
-     * Creates a REST entity array (JSON object we're going to return in the response, but
802
-     * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
803
-     * from $wpdb->get_row( $sql, ARRAY_A)
804
-     *
805
-     * @param EEM_Base $model
806
-     * @param array    $db_row
807
-     * @return array entity mostly ready for converting to JSON and sending in the response
808
-     * @throws EE_Error
809
-     * @throws ReflectionException
810
-     * @throws RestException
811
-     */
812
-    protected function createBareEntityFromWpdbResults(EEM_Base $model, array $db_row): array
813
-    {
814
-        $result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
815
-        $result = array_intersect_key(
816
-            $result,
817
-            $this->getModelVersionInfo()->fieldsOnModelInThisVersion($model)
818
-        );
819
-        // if this is a CPT, we need to set the global $post to it,
820
-        // otherwise shortcodes etc won't work properly while rendering it
821
-        if ($model instanceof EEM_CPT_Base) {
822
-            $do_chevy_shuffle = true;
823
-        } else {
824
-            $do_chevy_shuffle = false;
825
-        }
826
-        if ($do_chevy_shuffle) {
827
-            global $post;
828
-            $old_post = $post;
829
-            $post     = get_post($result[ $model->primary_key_name() ]);
830
-            if (! $post instanceof WP_Post) {
831
-                // well that's weird, because $result is what we JUST fetched from the database
832
-                throw new RestException(
833
-                    'error_fetching_post_from_database_results',
834
-                    esc_html__(
835
-                        'An item was retrieved from the database but it\'s not a WP_Post like it should be.',
836
-                        'event_espresso'
837
-                    )
838
-                );
839
-            }
840
-            $model_object_classname          = 'EE_' . $model->get_this_model_name();
841
-            $post->{$model_object_classname} = EE_Registry::instance()->load_class(
842
-                $model_object_classname,
843
-                $result,
844
-                false,
845
-                false
846
-            );
847
-        }
848
-        foreach ($result as $field_name => $field_value) {
849
-            $field_obj = $model->field_settings_for($field_name);
850
-            if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
851
-                unset($result[ $field_name ]);
852
-            } elseif (
853
-                $this->isSubclassOfOne(
854
-                    $field_obj,
855
-                    $this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
856
-                )
857
-            ) {
858
-                $result[ $field_name ] = [
859
-                    'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
860
-                    'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
861
-                ];
862
-            } elseif (
863
-                $this->isSubclassOfOne(
864
-                    $field_obj,
865
-                    $this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
866
-                )
867
-            ) {
868
-                $result[ $field_name ] = [
869
-                    'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
870
-                    'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
871
-                ];
872
-            } elseif ($field_obj instanceof EE_Datetime_Field) {
873
-                $field_value = $field_obj->prepare_for_set_from_db($field_value);
874
-                // if the value is null, but we're not supposed to permit null, then set to the field's default
875
-                if (is_null($field_value)) {
876
-                    $field_value = $field_obj->getDefaultDateTimeObj();
877
-                }
878
-                if (is_null($field_value)) {
879
-                    $gmt_date = $local_date = ModelDataTranslator::prepareFieldValuesForJson(
880
-                        $field_obj,
881
-                        $field_value,
882
-                        $this->getModelVersionInfo()->requestedVersion()
883
-                    );
884
-                } else {
885
-                    $timezone = $field_value->getTimezone();
886
-                    EEH_DTT_Helper::setTimezone($field_value, new DateTimeZone('UTC'));
887
-                    $gmt_date = ModelDataTranslator::prepareFieldValuesForJson(
888
-                        $field_obj,
889
-                        $field_value,
890
-                        $this->getModelVersionInfo()->requestedVersion()
891
-                    );
892
-                    EEH_DTT_Helper::setTimezone($field_value, $timezone);
893
-                    $local_date = ModelDataTranslator::prepareFieldValuesForJson(
894
-                        $field_obj,
895
-                        $field_value,
896
-                        $this->getModelVersionInfo()->requestedVersion()
897
-                    );
898
-                }
899
-                $result[ $field_name . '_gmt' ] = $gmt_date;
900
-                $result[ $field_name ]          = $local_date;
901
-            } else {
902
-                $result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
903
-            }
904
-        }
905
-        if ($do_chevy_shuffle) {
906
-            $post = $old_post;
907
-        }
908
-        return $result;
909
-    }
910
-
911
-
912
-    /**
913
-     * Takes a value all the way from the DB representation, to the model object's representation, to the
914
-     * user-facing PHP representation, to the REST API representation. (Assumes you've already taken from the DB
915
-     * representation using $field_obj->prepare_for_set_from_db())
916
-     *
917
-     * @param EE_Model_Field_Base $field_obj
918
-     * @param mixed               $value  as it's stored on a model object
919
-     * @param string              $format valid values are 'normal' (default), 'pretty', 'datetime_obj'
920
-     * @return array|int
921
-     * @throws RestException if $value contains a PHP object
922
-     * @throws EE_Error
923
-     */
924
-    protected function prepareFieldObjValueForJson(
925
-        EE_Model_Field_Base $field_obj,
926
-        $value,
927
-        string $format = 'normal'
928
-    ) {
929
-        $value = $field_obj->prepare_for_set_from_db($value);
930
-        switch ($format) {
931
-            case 'pretty':
932
-                $value = $field_obj->prepare_for_pretty_echoing($value);
933
-                break;
934
-            case 'normal':
935
-            default:
936
-                $value = $field_obj->prepare_for_get($value);
937
-                break;
938
-        }
939
-        return ModelDataTranslator::prepareFieldValuesForJson(
940
-            $field_obj,
941
-            $value,
942
-            $this->getModelVersionInfo()->requestedVersion()
943
-        );
944
-    }
945
-
946
-
947
-    /**
948
-     * Adds a few extra fields to the entity response
949
-     *
950
-     * @param EEM_Base $model
951
-     * @param array    $db_row
952
-     * @param array    $entity_array
953
-     * @return array modified entity
954
-     * @throws EE_Error
955
-     */
956
-    protected function addExtraFields(EEM_Base $model, array $db_row, array $entity_array): array
957
-    {
958
-        if ($model instanceof EEM_CPT_Base) {
959
-            $entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
960
-        }
961
-        return $entity_array;
962
-    }
963
-
964
-
965
-    /**
966
-     * Gets links we want to add to the response
967
-     *
968
-     * @param EEM_Base        $model
969
-     * @param array           $db_row
970
-     * @param array           $entity_array
971
-     * @return array the _links item in the entity
972
-     * @throws EE_Error
973
-     * @global WP_REST_Server $wp_rest_server
974
-     */
975
-    protected function getEntityLinks(EEM_Base $model, array $db_row, array $entity_array): array
976
-    {
977
-        // add basic links
978
-        $links = [];
979
-        if ($model->has_primary_key_field()) {
980
-            $links['self'] = [
981
-                [
982
-                    'href' => $this->getVersionedLinkTo(
983
-                        EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
984
-                        . '/'
985
-                        . $entity_array[ $model->primary_key_name() ]
986
-                    ),
987
-                ],
988
-            ];
989
-        }
990
-        $links['collection'] = [
991
-            [
992
-                'href' => $this->getVersionedLinkTo(
993
-                    EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
994
-                ),
995
-            ],
996
-        ];
997
-        // add links to related models
998
-        if ($model->has_primary_key_field()) {
999
-            foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
1000
-                $related_model_part                                                      =
1001
-                    Read::getRelatedEntityName($relation_name, $relation_obj);
1002
-                $links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = [
1003
-                    [
1004
-                        'href'   => $this->getVersionedLinkTo(
1005
-                            EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
1006
-                            . '/'
1007
-                            . $entity_array[ $model->primary_key_name() ]
1008
-                            . '/'
1009
-                            . $related_model_part
1010
-                        ),
1011
-                        'single' => $relation_obj instanceof EE_Belongs_To_Relation,
1012
-                    ],
1013
-                ];
1014
-            }
1015
-        }
1016
-        return $links;
1017
-    }
1018
-
1019
-
1020
-    /**
1021
-     * Adds the included models indicated in the request to the entity provided
1022
-     *
1023
-     * @param EEM_Base        $model
1024
-     * @param WP_REST_Request $rest_request
1025
-     * @param array           $entity_array
1026
-     * @param array           $db_row
1027
-     * @param boolean         $included_items_protected if the original item is password protected, don't include any
1028
-     *                                                  related models.
1029
-     * @return array the modified entity
1030
-     * @throws DomainException
1031
-     * @throws EE_Error
1032
-     * @throws InvalidArgumentException
1033
-     * @throws InvalidDataTypeException
1034
-     * @throws InvalidInterfaceException
1035
-     * @throws ModelConfigurationException
1036
-     * @throws ReflectionException
1037
-     * @throws UnexpectedEntityException
1038
-     */
1039
-    protected function includeRequestedModels(
1040
-        EEM_Base $model,
1041
-        WP_REST_Request $rest_request,
1042
-        array $entity_array,
1043
-        array $db_row = [],
1044
-        bool $included_items_protected = false
1045
-    ): array {
1046
-        // if $db_row not included, hope the entity array has what we need
1047
-        if (! $db_row) {
1048
-            $db_row = $entity_array;
1049
-        }
1050
-        $relation_settings = $this->getModelVersionInfo()->relationSettings($model);
1051
-        foreach ($relation_settings as $relation_name => $relation_obj) {
1052
-            $related_fields_to_include   = $this->explodeAndGetItemsPrefixedWith(
1053
-                $rest_request->get_param('include'),
1054
-                $relation_name
1055
-            );
1056
-            $related_fields_to_calculate = $this->explodeAndGetItemsPrefixedWith(
1057
-                $rest_request->get_param('calculate'),
1058
-                $relation_name
1059
-            );
1060
-            // did they specify they wanted to include a related model, or
1061
-            // specific fields from a related model?
1062
-            // or did they specify to calculate a field from a related model?
1063
-            if ($related_fields_to_include || $related_fields_to_calculate) {
1064
-                // if so, we should include at least some part of the related model
1065
-                $pretend_related_request = new WP_REST_Request();
1066
-                $pretend_related_request->set_query_params(
1067
-                    [
1068
-                        'caps'      => $rest_request->get_param('caps'),
1069
-                        'include'   => $related_fields_to_include,
1070
-                        'calculate' => $related_fields_to_calculate,
1071
-                        'password'  => $rest_request->get_param('password'),
1072
-                    ]
1073
-                );
1074
-                $pretend_related_request->add_header('no_rest_headers', true);
1075
-                $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
1076
-                    $model->get_index_primary_key_string(
1077
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
1078
-                    )
1079
-                );
1080
-                if (! $included_items_protected) {
1081
-                    try {
1082
-                        $related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1083
-                            $primary_model_query_params,
1084
-                            $relation_obj,
1085
-                            $pretend_related_request
1086
-                        );
1087
-                    } catch (RestException $e) {
1088
-                        $related_results = null;
1089
-                    }
1090
-                } else {
1091
-                    // they're protected, hide them.
1092
-                    $related_results              = null;
1093
-                    $entity_array['_protected'][] = Read::getRelatedEntityName($relation_name, $relation_obj);
1094
-                }
1095
-                if ($related_results instanceof WP_Error || $related_results === null) {
1096
-                    $related_results =
1097
-                        $relation_obj instanceof EE_Belongs_To_Relation
1098
-                            ? null
1099
-                            : [];
1100
-                }
1101
-                $entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1102
-            }
1103
-        }
1104
-        return $entity_array;
1105
-    }
1106
-
1107
-
1108
-    /**
1109
-     * If the user has requested only specific properties (including meta properties like _links or _protected)
1110
-     * remove everything else.
1111
-     *
1112
-     * @param EEM_Base        $model
1113
-     * @param WP_REST_Request $rest_request
1114
-     * @param                 $entity_array
1115
-     * @return array
1116
-     * @throws EE_Error
1117
-     * @since 4.9.74.p
1118
-     */
1119
-    protected function includeOnlyRequestedProperties(
1120
-        EEM_Base $model,
1121
-        WP_REST_Request $rest_request,
1122
-        $entity_array
1123
-    ): array {
1124
-
1125
-        $includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1126
-        $includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1127
-        // if they passed in * or didn't specify any includes, return everything
1128
-        if (! empty($includes_for_this_model) && ! in_array('*', $includes_for_this_model, true)) {
1129
-            if ($model->has_primary_key_field()) {
1130
-                // always include the primary key. ya just gotta know that at least
1131
-                $includes_for_this_model[] = $model->primary_key_name();
1132
-            }
1133
-            if ($this->explodeAndGetItemsPrefixedWith($rest_request->get_param('calculate'), '')) {
1134
-                $includes_for_this_model[] = '_calculated_fields';
1135
-            }
1136
-            $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
1137
-        }
1138
-        return $entity_array;
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     * Returns a new array with all the names of models removed. Eg
1144
-     * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
1145
-     *
1146
-     * @param array $array
1147
-     * @return array
1148
-     */
1149
-    private function removeModelNamesFromArray(array $array): array
1150
-    {
1151
-        return array_diff($array, array_keys(EE_Registry::instance()->non_abstract_db_models));
1152
-    }
1153
-
1154
-
1155
-    /**
1156
-     * Gets the calculated fields for the response
1157
-     *
1158
-     * @param EEM_Base        $model
1159
-     * @param array           $wpdb_row
1160
-     * @param WP_REST_Request $rest_request
1161
-     * @param bool            $row_is_protected whether this row is password protected or not
1162
-     * @return stdClass the _calculations item in the entity
1163
-     * @throws RestException if a default value has a PHP object, which should never do (and if we
1164
-     *                                          did, let's know about it ASAP, so let the exception bubble up)
1165
-     * @throws EE_Error
1166
-     */
1167
-    protected function getEntityCalculations(
1168
-        EEM_Base $model,
1169
-        array $wpdb_row,
1170
-        WP_REST_Request $rest_request,
1171
-        bool $row_is_protected = false
1172
-    ): stdClass {
1173
-        $calculated_fields = $this->explodeAndGetItemsPrefixedWith(
1174
-            $rest_request->get_param('calculate'),
1175
-            ''
1176
-        );
1177
-        // note: setting calculate=* doesn't do anything
1178
-        $calculated_fields_to_return = new stdClass();
1179
-        $protected_fields            = [];
1180
-        foreach ($calculated_fields as $field_to_calculate) {
1181
-            try {
1182
-                // it's password protected, so they shouldn't be able to read this. Remove the value
1183
-                $schema = $this->fields_calculator->getJsonSchemaForModel($model);
1184
-                if (
1185
-                    $row_is_protected
1186
-                    && isset($schema['properties'][ $field_to_calculate ]['protected'])
1187
-                    && $schema['properties'][ $field_to_calculate ]['protected']
1188
-                ) {
1189
-                    $calculated_value   = null;
1190
-                    $protected_fields[] = $field_to_calculate;
1191
-                    if ($schema['properties'][ $field_to_calculate ]['type']) {
1192
-                        switch ($schema['properties'][ $field_to_calculate ]['type']) {
1193
-                            case 'boolean':
1194
-                                $calculated_value = false;
1195
-                                break;
1196
-                            case 'integer':
1197
-                                $calculated_value = 0;
1198
-                                break;
1199
-                            case 'string':
1200
-                                $calculated_value = '';
1201
-                                break;
1202
-                            case 'array':
1203
-                                $calculated_value = [];
1204
-                                break;
1205
-                            case 'object':
1206
-                                $calculated_value = new stdClass();
1207
-                                break;
1208
-                        }
1209
-                    }
1210
-                } else {
1211
-                    $calculated_value = ModelDataTranslator::prepareFieldValueForJson(
1212
-                        null,
1213
-                        $this->fields_calculator->retrieveCalculatedFieldValue(
1214
-                            $model,
1215
-                            $field_to_calculate,
1216
-                            $wpdb_row,
1217
-                            $rest_request,
1218
-                            $this
1219
-                        ),
1220
-                        $this->getModelVersionInfo()->requestedVersion()
1221
-                    );
1222
-                }
1223
-                $calculated_fields_to_return->{$field_to_calculate} = $calculated_value;
1224
-            } catch (RestException $e) {
1225
-                // if we don't have permission to read it, just leave it out. but let devs know about the problem
1226
-                $this->setResponseHeader(
1227
-                    'Notices-Field-Calculation-Errors['
1228
-                    . $e->getStringCode()
1229
-                    . ']['
1230
-                    . $model->get_this_model_name()
1231
-                    . ']['
1232
-                    . $field_to_calculate
1233
-                    . ']',
1234
-                    $e->getMessage()
1235
-                );
1236
-            }
1237
-        }
1238
-        $calculated_fields_to_return->_protected = $protected_fields;
1239
-        return $calculated_fields_to_return;
1240
-    }
1241
-
1242
-
1243
-    /**
1244
-     * Gets the full URL to the resource, taking the requested version into account
1245
-     *
1246
-     * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
1247
-     * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
1248
-     * @throws EE_Error
1249
-     */
1250
-    public function getVersionedLinkTo(string $link_part_after_version_and_slash): string
1251
-    {
1252
-        return rest_url(
1253
-            EED_Core_Rest_Api::get_versioned_route_to(
1254
-                $link_part_after_version_and_slash,
1255
-                $this->getModelVersionInfo()->requestedVersion()
1256
-            )
1257
-        );
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * Gets the correct lowercase name for the relation in the API according
1263
-     * to the relation's type
1264
-     *
1265
-     * @param string                 $relation_name
1266
-     * @param EE_Model_Relation_Base $relation_obj
1267
-     * @return string
1268
-     */
1269
-    public static function getRelatedEntityName(string $relation_name, EE_Model_Relation_Base $relation_obj): string
1270
-    {
1271
-        if ($relation_obj instanceof EE_Belongs_To_Relation) {
1272
-            return strtolower($relation_name);
1273
-        }
1274
-        return EEH_Inflector::pluralize_and_lower($relation_name);
1275
-    }
1276
-
1277
-
1278
-    /**
1279
-     * Gets the one model object with the specified id for the specified model
1280
-     *
1281
-     * @param EEM_Base        $model
1282
-     * @param WP_REST_Request $request
1283
-     * @return array
1284
-     * @throws EE_Error
1285
-     * @throws InvalidArgumentException
1286
-     * @throws InvalidDataTypeException
1287
-     * @throws InvalidInterfaceException
1288
-     * @throws ModelConfigurationException
1289
-     * @throws ReflectionException
1290
-     * @throws RestException
1291
-     * @throws RestPasswordIncorrectException
1292
-     * @throws RestPasswordRequiredException
1293
-     * @throws UnexpectedEntityException
1294
-     * @throws DomainException
1295
-     */
1296
-    public function getEntityFromModel(EEM_Base $model, WP_REST_Request $request): array
1297
-    {
1298
-        $context = $this->validateContext($request->get_param('caps'));
1299
-        return $this->getOneOrReportPermissionError($model, $request, $context);
1300
-    }
1301
-
1302
-
1303
-    /**
1304
-     * If a context is provided which isn't valid, maybe it was added in a future
1305
-     * version so just treat it as a default read
1306
-     *
1307
-     * @param string|null $context
1308
-     * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
1309
-     */
1310
-    public function validateContext(?string $context): string
1311
-    {
1312
-        if (! $context) {
1313
-            $context = EEM_Base::caps_read;
1314
-        }
1315
-        $valid_contexts = EEM_Base::valid_cap_contexts();
1316
-        if (in_array($context, $valid_contexts, true)) {
1317
-            return $context;
1318
-        }
1319
-        return EEM_Base::caps_read;
1320
-    }
1321
-
1322
-
1323
-    /**
1324
-     * Verifies the passed in value is an allowable default where conditions value.
1325
-     *
1326
-     * @param string $default_where_conditions
1327
-     * @return string
1328
-     */
1329
-    public function validateDefaultQueryParams(string $default_where_conditions): string
1330
-    {
1331
-        $valid_default_where_conditions_for_api_calls = [
1332
-            EEM_Base::default_where_conditions_all,
1333
-            EEM_Base::default_where_conditions_minimum_all,
1334
-            EEM_Base::default_where_conditions_minimum_others,
1335
-        ];
1336
-        if (! $default_where_conditions) {
1337
-            $default_where_conditions = EEM_Base::default_where_conditions_all;
1338
-        }
1339
-        if (
1340
-            in_array(
1341
-                $default_where_conditions,
1342
-                $valid_default_where_conditions_for_api_calls,
1343
-                true
1344
-            )
1345
-        ) {
1346
-            return $default_where_conditions;
1347
-        }
1348
-        return EEM_Base::default_where_conditions_all;
1349
-    }
1350
-
1351
-
1352
-    /**
1353
-     * Translates API filter get parameter into model query params @param EEM_Base $model
1354
-     *
1355
-     * @param array $query_params
1356
-     * @return array model query params (@see
1357
-     *               https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions)
1358
-     *               or FALSE to indicate that absolutely no results should be returned
1359
-     * @throws EE_Error
1360
-     * @throws InvalidArgumentException
1361
-     * @throws InvalidDataTypeException
1362
-     * @throws InvalidInterfaceException
1363
-     * @throws RestException
1364
-     * @throws DomainException
1365
-     * @see
1366
-     * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions.
1367
-     * Note: right now the query parameter keys for fields (and related fields) can be left as-is, but it's quite
1368
-     * possible this will change someday. Also, this method's contents might be candidate for moving to
1369
-     * Model_Data_Translator
1370
-     *
1371
-     */
1372
-    public function createModelQueryParams(EEM_Base $model, array $query_params): array
1373
-    {
1374
-        $model_query_params = [];
1375
-        if (isset($query_params['where'])) {
1376
-            $model_query_params[0] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1377
-                $query_params['where'],
1378
-                $model,
1379
-                $this->getModelVersionInfo()->requestedVersion()
1380
-            );
1381
-        }
1382
-        if (isset($query_params['order_by'])) {
1383
-            $order_by = $query_params['order_by'];
1384
-        } elseif (isset($query_params['orderby'])) {
1385
-            $order_by = $query_params['orderby'];
1386
-        } else {
1387
-            $order_by = null;
1388
-        }
1389
-        if ($order_by !== null) {
1390
-            if (is_array($order_by)) {
1391
-                $order_by = ModelDataTranslator::prepareFieldNamesInArrayKeysFromJson($order_by);
1392
-            } else {
1393
-                // it's a single item
1394
-                $order_by = ModelDataTranslator::prepareFieldNameFromJson($order_by);
1395
-            }
1396
-            $model_query_params['order_by'] = $order_by;
1397
-        }
1398
-        if (isset($query_params['group_by'])) {
1399
-            $group_by = $query_params['group_by'];
1400
-        } elseif (isset($query_params['groupby'])) {
1401
-            $group_by = $query_params['groupby'];
1402
-        } else {
1403
-            $group_by = array_keys($model->get_combined_primary_key_fields());
1404
-        }
1405
-        // make sure they're all real names
1406
-        if (is_array($group_by)) {
1407
-            $group_by = ModelDataTranslator::prepareFieldNamesFromJson($group_by);
1408
-        }
1409
-        if ($group_by !== null) {
1410
-            $model_query_params['group_by'] = $group_by;
1411
-        }
1412
-        if (isset($query_params['having'])) {
1413
-            $model_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1414
-                $query_params['having'],
1415
-                $model,
1416
-                $this->getModelVersionInfo()->requestedVersion()
1417
-            );
1418
-        }
1419
-        if (isset($query_params['order'])) {
1420
-            $model_query_params['order'] = $query_params['order'];
1421
-        }
1422
-        if (isset($query_params['mine'])) {
1423
-            $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1424
-        }
1425
-        if (isset($query_params['limit'])) {
1426
-            // limit should be either a string like '23' or '23,43', or an array with two items in it
1427
-            if (! is_array($query_params['limit'])) {
1428
-                $limit_array = explode(',', (string) $query_params['limit']);
1429
-            } else {
1430
-                $limit_array = $query_params['limit'];
1431
-            }
1432
-            $sanitized_limit = [];
1433
-            foreach ($limit_array as $limit_part) {
1434
-                if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1435
-                    throw new EE_Error(
1436
-                        sprintf(
1437
-                            esc_html__(
1438
-                            // @codingStandardsIgnoreStart
1439
-                                '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.',
1440
-                                // @codingStandardsIgnoreEnd
1441
-                                'event_espresso'
1442
-                            ),
1443
-                            wp_json_encode($query_params['limit'])
1444
-                        )
1445
-                    );
1446
-                }
1447
-                $sanitized_limit[] = (int) $limit_part;
1448
-            }
1449
-            $model_query_params['limit'] = implode(',', $sanitized_limit);
1450
-        } else {
1451
-            $model_query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
1452
-        }
1453
-        if (isset($query_params['caps'])) {
1454
-            $model_query_params['caps'] = $this->validateContext($query_params['caps']);
1455
-        } else {
1456
-            $model_query_params['caps'] = EEM_Base::caps_read;
1457
-        }
1458
-        if (isset($query_params['default_where_conditions'])) {
1459
-            $model_query_params['default_where_conditions'] = $this->validateDefaultQueryParams(
1460
-                $query_params['default_where_conditions']
1461
-            );
1462
-        }
1463
-        // if this is a model protected by a password on another model, exclude the password protected
1464
-        // entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1465
-        // though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1466
-        if (
1467
-            $model_query_params['caps'] === EEM_Base::caps_read
1468
-            && empty($query_params['password'])
1469
-            && ! $model->hasPassword()
1470
-            && $model->restrictedByRelatedModelPassword()
1471
-        ) {
1472
-            $model_query_params['exclude_protected'] = true;
1473
-        }
1474
-
1475
-        return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_params, $model);
1476
-    }
1477
-
1478
-
1479
-    /**
1480
-     * Changes the REST-style query params for use in the models
1481
-     *
1482
-     * @param EEM_Base $model
1483
-     * @param array    $query_params sub-array from @see EEM_Base::get_all()
1484
-     * @return array
1485
-     * @deprecated
1486
-     */
1487
-    public function prepareRestQueryParamsKeyForModels(EEM_Base $model, array $query_params): array
1488
-    {
1489
-        $model_ready_query_params = [];
1490
-        foreach ($query_params as $key => $value) {
1491
-            $model_ready_query_params[ $key ] = is_array($value)
1492
-                ? $this->prepareRestQueryParamsKeyForModels($model, $value)
1493
-                : $value;
1494
-        }
1495
-        return $model_ready_query_params;
1496
-    }
1497
-
1498
-
1499
-    /**
1500
-     * @param $model
1501
-     * @param $query_params
1502
-     * @return array
1503
-     * @deprecated instead use ModelDataTranslator::prepareFieldValuesFromJson()
1504
-     */
1505
-    public function prepareRestQueryParamsValuesForModels($model, $query_params): array
1506
-    {
1507
-        $model_ready_query_params = [];
1508
-        foreach ($query_params as $key => $value) {
1509
-            if (is_array($value)) {
1510
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1511
-            } else {
1512
-                $model_ready_query_params[ $key ] = $value;
1513
-            }
1514
-        }
1515
-        return $model_ready_query_params;
1516
-    }
1517
-
1518
-
1519
-    /**
1520
-     * Explodes the string on commas, and only returns items with $prefix followed by a period.
1521
-     * If no prefix is specified, returns items with no period.
1522
-     *
1523
-     * @param string|array $string_to_explode eg "jibba,jabba, blah, blah, blah" or array('jibba', 'jabba' )
1524
-     * @param string       $prefix            "Event" or "foobar"
1525
-     * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1526
-     *                                        we only return strings starting with that and a period; if no prefix was
1527
-     *                                        specified we return all items containing NO periods
1528
-     */
1529
-    public function explodeAndGetItemsPrefixedWith($string_to_explode, string $prefix): array
1530
-    {
1531
-        if (is_string($string_to_explode)) {
1532
-            $exploded_contents = explode(',', $string_to_explode);
1533
-        } elseif (is_array($string_to_explode)) {
1534
-            $exploded_contents = $string_to_explode;
1535
-        } else {
1536
-            $exploded_contents = [];
1537
-        }
1538
-        // if the string was empty, we want an empty array
1539
-        $exploded_contents    = array_filter($exploded_contents);
1540
-        $contents_with_prefix = [];
1541
-        foreach ($exploded_contents as $item) {
1542
-            $item = trim($item);
1543
-            // if no prefix was provided, so we look for items with no "." in them
1544
-            if (! $prefix) {
1545
-                // does this item have a period?
1546
-                if (strpos($item, '.') === false) {
1547
-                    // if not, then its what we're looking for
1548
-                    $contents_with_prefix[] = $item;
1549
-                }
1550
-            } elseif (strpos($item, $prefix . '.') === 0) {
1551
-                // this item has the prefix and a period, grab it
1552
-                $contents_with_prefix[] = substr(
1553
-                    $item,
1554
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1555
-                );
1556
-            } elseif ($item === $prefix) {
1557
-                // this item is JUST the prefix
1558
-                // so let's grab everything after, which is a blank string
1559
-                $contents_with_prefix[] = '';
1560
-            }
1561
-        }
1562
-        return $contents_with_prefix;
1563
-    }
1564
-
1565
-
1566
-    /**
1567
-     * @param string      $include_string @see Read:handle_request_get_all
1568
-     * @param string|null $model_name
1569
-     * @return array of fields for this model. If $model_name is provided, then
1570
-     *                                    the fields for that model, with the model's name removed from each.
1571
-     *                                    If $include_string was blank or '*' returns an empty array
1572
-     * @throws EE_Error
1573
-     * @throws EE_Error
1574
-     * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1575
-     *                                    Deprecated because its return values were really quite confusing- sometimes
1576
-     *                                    it
1577
-     *                                    returned an empty array (when the include string was blank or '*') or
1578
-     *                                    sometimes it returned array('*') (when you provided a model and a model of
1579
-     *                                    that kind was found). Parses the $include_string so we fetch all the field
1580
-     *                                    names relating to THIS model
1581
-     *                                    (ie have NO period in them), or for the provided model (ie start with the
1582
-     *                                    model name and then a period).
1583
-     */
1584
-    public function extractIncludesForThisModel(string $include_string, string $model_name = null): array
1585
-    {
1586
-        if (is_array($include_string)) {
1587
-            $include_string = implode(',', $include_string);
1588
-        }
1589
-        if ($include_string === '*' || $include_string === '') {
1590
-            return [];
1591
-        }
1592
-        $includes                    = explode(',', $include_string);
1593
-        $extracted_fields_to_include = [];
1594
-        if ($model_name) {
1595
-            foreach ($includes as $field_to_include) {
1596
-                $field_to_include = trim($field_to_include);
1597
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1598
-                    // found the model name at the exact start
1599
-                    $field_sans_model_name         = str_replace($model_name . '.', '', $field_to_include);
1600
-                    $extracted_fields_to_include[] = $field_sans_model_name;
1601
-                } elseif ($field_to_include === $model_name) {
1602
-                    $extracted_fields_to_include[] = '*';
1603
-                }
1604
-            }
1605
-        } else {
1606
-            // look for ones with no period
1607
-            foreach ($includes as $field_to_include) {
1608
-                $field_to_include = trim($field_to_include);
1609
-                if (
1610
-                    strpos($field_to_include, '.') === false
1611
-                    && ! $this->getModelVersionInfo()->isModelNameInThisVersion($field_to_include)
1612
-                ) {
1613
-                    $extracted_fields_to_include[] = $field_to_include;
1614
-                }
1615
-            }
1616
-        }
1617
-        return $extracted_fields_to_include;
1618
-    }
1619
-
1620
-
1621
-    /**
1622
-     * Gets the single item using the model according to the request in the context given, otherwise
1623
-     * returns that it's inaccessible to the current user
1624
-     *
1625
-     * @param EEM_Base        $model
1626
-     * @param WP_REST_Request $request
1627
-     * @param null            $context
1628
-     * @return array
1629
-     * @throws EE_Error
1630
-     * @throws ReflectionException
1631
-     */
1632
-    public function getOneOrReportPermissionError(EEM_Base $model, WP_REST_Request $request, $context = null): array
1633
-    {
1634
-        $query_params = [[$model->primary_key_name() => $request->get_param('id')], 'limit' => 1];
1635
-        if ($model instanceof EEM_Soft_Delete_Base) {
1636
-            $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
1637
-        }
1638
-        $restricted_query_params         = $query_params;
1639
-        $restricted_query_params['caps'] = $context;
1640
-        $this->setDebugInfo('model query params', $restricted_query_params);
1641
-        $model_rows = $model->get_all_wpdb_results($restricted_query_params);
1642
-        if (! empty($model_rows)) {
1643
-            return $this->createEntityFromWpdbResult(
1644
-                $model,
1645
-                reset($model_rows),
1646
-                $request
1647
-            );
1648
-        }
1649
-        // ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
1650
-        $lowercase_model_name = strtolower($model->get_this_model_name());
1651
-        if ($model->exists($query_params)) {
1652
-            // you got shafted- it existed but we didn't want to tell you!
1653
-            throw new RestException(
1654
-                'rest_user_cannot_' . $context,
1655
-                sprintf(
1656
-                    __('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1657
-                    $context,
1658
-                    $lowercase_model_name,
1659
-                    Capabilities::getMissingPermissionsString(
1660
-                        $model,
1661
-                        $context
1662
-                    )
1663
-                ),
1664
-                ['status' => 403]
1665
-            );
1666
-        }
1667
-        // it's not you. It just doesn't exist
1668
-        throw new RestException(
1669
-            sprintf('rest_%s_invalid_id', $lowercase_model_name),
1670
-            sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
1671
-            ['status' => 404]
1672
-        );
1673
-    }
1674
-
1675
-
1676
-    /**
1677
-     * Checks that if this content requires a password to be read, that it's been provided and is correct.
1678
-     *
1679
-     * @param EEM_Base        $model
1680
-     * @param array           $model_row
1681
-     * @param array           $query_params Adds 'default_where_conditions' => 'minimum'
1682
-     *                                      to ensure we don't confuse trashed with password protected.
1683
-     * @param WP_REST_Request $request
1684
-     * @throws EE_Error
1685
-     * @throws InvalidArgumentException
1686
-     * @throws InvalidDataTypeException
1687
-     * @throws InvalidInterfaceException
1688
-     * @throws RestPasswordRequiredException
1689
-     * @throws RestPasswordIncorrectException
1690
-     * @throws ModelConfigurationException
1691
-     * @throws ReflectionException
1692
-     * @since 4.9.74.p
1693
-     */
1694
-    protected function checkPassword(EEM_Base $model, array $model_row, array $query_params, WP_REST_Request $request)
1695
-    {
1696
-        $query_params['default_where_conditions'] = 'minimum';
1697
-        // stuff is only "protected" for front-end requests. Elsewhere, you either get full permission to access the object
1698
-        // or you don't.
1699
-        $request_caps = $request->get_param('caps');
1700
-        if (isset($request_caps) && $request_caps !== EEM_Base::caps_read) {
1701
-            return;
1702
-        }
1703
-        // if this entity requires a password, they better give it and it better be right!
1704
-        if (
1705
-            $model->hasPassword()
1706
-            && $model_row[ $model->getPasswordField()->get_qualified_column() ] !== ''
1707
-        ) {
1708
-            if (empty($request['password'])) {
1709
-                throw new RestPasswordRequiredException();
1710
-            }
1711
-            if (
1712
-                ! hash_equals(
1713
-                    $model_row[ $model->getPasswordField()->get_qualified_column() ],
1714
-                    $request['password']
1715
-                )
1716
-            ) {
1717
-                throw new RestPasswordIncorrectException();
1718
-            }
1719
-        } elseif (
1720
-            // wait! maybe this content is password protected
1721
-            $model->restrictedByRelatedModelPassword()
1722
-            && $request->get_param('caps') === EEM_Base::caps_read
1723
-        ) {
1724
-            $password_supplied = $request->get_param('password');
1725
-            if (empty($password_supplied)) {
1726
-                $query_params['exclude_protected'] = true;
1727
-                if (! $model->exists($query_params)) {
1728
-                    throw new RestPasswordRequiredException();
1729
-                }
1730
-            } else {
1731
-                $query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1732
-                if (! $model->exists($query_params)) {
1733
-                    throw new RestPasswordIncorrectException();
1734
-                }
1735
-            }
1736
-        }
1737
-    }
54
+	/**
55
+	 * @var CalculatedModelFields
56
+	 */
57
+	protected $fields_calculator;
58
+
59
+
60
+	/**
61
+	 * Read constructor.
62
+	 *
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
+	 * @return Read
74
+	 */
75
+	private static function getReadController(): Read
76
+	{
77
+		return LoaderFactory::getLoader()->getNew(Read::class);
78
+	}
79
+
80
+
81
+	/**
82
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
83
+	 *
84
+	 * @param WP_REST_Request $request
85
+	 * @param string          $version
86
+	 * @param string          $model_name
87
+	 * @return WP_REST_Response
88
+	 * @throws InvalidArgumentException
89
+	 * @throws InvalidDataTypeException
90
+	 * @throws InvalidInterfaceException
91
+	 */
92
+	public static function handleRequestGetAll(
93
+		WP_REST_Request $request,
94
+		string $version,
95
+		string $model_name
96
+	): WP_REST_Response {
97
+		$controller = self::getReadController();
98
+		try {
99
+			$controller->setRequestedVersion($version);
100
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
101
+				return $controller->sendResponse(
102
+					new WP_Error(
103
+						'endpoint_parsing_error',
104
+						sprintf(
105
+							esc_html__(
106
+								'There is no model for endpoint %s. Please contact event espresso support',
107
+								'event_espresso'
108
+							),
109
+							$model_name
110
+						)
111
+					)
112
+				);
113
+			}
114
+			return $controller->sendResponse(
115
+				$controller->getEntitiesFromModel(
116
+					$controller->getModelVersionInfo()->loadModel($model_name),
117
+					$request
118
+				)
119
+			);
120
+		} catch (Exception $e) {
121
+			return $controller->sendResponse($e);
122
+		}
123
+	}
124
+
125
+
126
+	/**
127
+	 * Prepares and returns schema for any OPTIONS request.
128
+	 *
129
+	 * @param string $version    The API endpoint version being used.
130
+	 * @param string $model_name Something like `Event` or `Registration`
131
+	 * @return array
132
+	 * @throws InvalidArgumentException
133
+	 * @throws InvalidDataTypeException
134
+	 * @throws InvalidInterfaceException
135
+	 */
136
+	public static function handleSchemaRequest(string $version, string $model_name): array
137
+	{
138
+		$controller = self::getReadController();
139
+		try {
140
+			$controller->setRequestedVersion($version);
141
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
142
+				return [];
143
+			}
144
+			// get the model for this version
145
+			$model        = $controller->getModelVersionInfo()->loadModel($model_name);
146
+			$model_schema = new JsonModelSchema(
147
+				$model,
148
+				LoaderFactory::getLoader()->getShared('EventEspresso\core\libraries\rest_api\CalculatedModelFields')
149
+			);
150
+			return $model_schema->getModelSchemaForRelations(
151
+				$controller->getModelVersionInfo()->relationSettings($model),
152
+				$controller->customizeSchemaForRestResponse(
153
+					$model,
154
+					$model_schema->getModelSchemaForFields(
155
+						$controller->getModelVersionInfo()->fieldsOnModelInThisVersion($model),
156
+						$model_schema->getInitialSchemaStructure()
157
+					)
158
+				)
159
+			);
160
+		} catch (Exception $e) {
161
+			return [];
162
+		}
163
+	}
164
+
165
+
166
+	/**
167
+	 * This loops through each field in the given schema for the model and does the following:
168
+	 * - add any extra fields that are REST API specific and related to existing fields.
169
+	 * - transform default values into the correct format for a REST API response.
170
+	 *
171
+	 * @param EEM_Base $model
172
+	 * @param array    $schema
173
+	 * @return array  The final schema.
174
+	 * @throws EE_Error
175
+	 */
176
+	public function customizeSchemaForRestResponse(EEM_Base $model, array $schema): array
177
+	{
178
+		foreach ($this->getModelVersionInfo()->fieldsOnModelInThisVersion($model) as $field_name => $field) {
179
+			$schema = $this->translateDefaultsForRestResponse(
180
+				$field_name,
181
+				$field,
182
+				$this->maybeAddExtraFieldsToSchema($field_name, $field, $schema)
183
+			);
184
+		}
185
+		return $schema;
186
+	}
187
+
188
+
189
+	/**
190
+	 * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
191
+	 * response.
192
+	 *
193
+	 * @param                      $field_name
194
+	 * @param EE_Model_Field_Base  $field
195
+	 * @param array                $schema
196
+	 * @return array
197
+	 * @throws RestException  if a default value has a PHP object, which we should never do
198
+	 *                                  (but if we did, let's know about it ASAP, so let the exception bubble up)
199
+	 * @throws EE_Error
200
+	 *
201
+	 */
202
+	protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema): array
203
+	{
204
+		if (isset($schema['properties'][ $field_name ]['default'])) {
205
+			if (is_array($schema['properties'][ $field_name ]['default'])) {
206
+				foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
207
+					if ($default_key === 'raw') {
208
+						$schema['properties'][ $field_name ]['default'][ $default_key ] =
209
+							ModelDataTranslator::prepareFieldValueForJson(
210
+								$field,
211
+								$default_value,
212
+								$this->getModelVersionInfo()->requestedVersion()
213
+							);
214
+					}
215
+				}
216
+			} else {
217
+				$schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
218
+					$field,
219
+					$schema['properties'][ $field_name ]['default'],
220
+					$this->getModelVersionInfo()->requestedVersion()
221
+				);
222
+			}
223
+		}
224
+		return $schema;
225
+	}
226
+
227
+
228
+	/**
229
+	 * Adds additional fields to the schema
230
+	 * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
231
+	 * needs to be added to the schema.
232
+	 *
233
+	 * @param                      $field_name
234
+	 * @param EE_Model_Field_Base  $field
235
+	 * @param array                $schema
236
+	 * @return array
237
+	 */
238
+	protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema): array
239
+	{
240
+		if ($field instanceof EE_Datetime_Field) {
241
+			$schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
242
+			// modify the description
243
+			$schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
244
+				esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
245
+				wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
246
+			);
247
+		}
248
+		return $schema;
249
+	}
250
+
251
+
252
+	/**
253
+	 * Used to figure out the route from the request when a `WP_REST_Request` object is not available
254
+	 *
255
+	 * @return string
256
+	 */
257
+	protected function getRouteFromRequest(): string
258
+	{
259
+		if (
260
+			isset($GLOBALS['wp'])
261
+			&& $GLOBALS['wp'] instanceof WP
262
+			&& isset($GLOBALS['wp']->query_vars['rest_route'])
263
+		) {
264
+			return $GLOBALS['wp']->query_vars['rest_route'];
265
+		}
266
+		/** @var RequestInterface $request */
267
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
268
+		return $request->serverParamIsSet('PATH_INFO')
269
+			? $request->getServerParam('PATH_INFO')
270
+			: '/';
271
+	}
272
+
273
+
274
+	/**
275
+	 * Gets a single entity related to the model indicated in the path and its id
276
+	 *
277
+	 * @param WP_REST_Request $request
278
+	 * @param string          $version
279
+	 * @param string          $model_name
280
+	 * @return WP_REST_Response
281
+	 * @throws InvalidDataTypeException
282
+	 * @throws InvalidInterfaceException
283
+	 * @throws InvalidArgumentException
284
+	 */
285
+	public static function handleRequestGetOne(
286
+		WP_REST_Request $request,
287
+		string $version,
288
+		string $model_name
289
+	): WP_REST_Response {
290
+		$controller = self::getReadController();
291
+		try {
292
+			$controller->setRequestedVersion($version);
293
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
294
+				return $controller->sendResponse(
295
+					new WP_Error(
296
+						'endpoint_parsing_error',
297
+						sprintf(
298
+							esc_html__(
299
+								'There is no model for endpoint %s. Please contact event espresso support',
300
+								'event_espresso'
301
+							),
302
+							$model_name
303
+						)
304
+					)
305
+				);
306
+			}
307
+			return $controller->sendResponse(
308
+				$controller->getEntityFromModel(
309
+					$controller->getModelVersionInfo()->loadModel($model_name),
310
+					$request
311
+				)
312
+			);
313
+		} catch (Exception $e) {
314
+			return $controller->sendResponse($e);
315
+		}
316
+	}
317
+
318
+
319
+	/**
320
+	 * Gets all the related entities (or if its a belongs-to relation just the one)
321
+	 * to the item with the given id
322
+	 *
323
+	 * @param WP_REST_Request $request
324
+	 * @param string          $version
325
+	 * @param string          $model_name
326
+	 * @param string          $related_model_name
327
+	 * @return WP_REST_Response
328
+	 * @throws InvalidDataTypeException
329
+	 * @throws InvalidInterfaceException
330
+	 * @throws InvalidArgumentException
331
+	 */
332
+	public static function handleRequestGetRelated(
333
+		WP_REST_Request $request,
334
+		string $version,
335
+		string $model_name,
336
+		string $related_model_name
337
+	): WP_REST_Response {
338
+		$controller = self::getReadController();
339
+		try {
340
+			$controller->setRequestedVersion($version);
341
+			$main_model = $controller->validateModel($model_name);
342
+			$controller->validateModel($related_model_name);
343
+			return $controller->sendResponse(
344
+				$controller->getEntitiesFromRelation(
345
+					$request->get_param('id'),
346
+					$main_model->related_settings_for($related_model_name),
347
+					$request
348
+				)
349
+			);
350
+		} catch (Exception $e) {
351
+			return $controller->sendResponse($e);
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * Gets a collection for the given model and filters
358
+	 *
359
+	 * @param EEM_Base        $model
360
+	 * @param WP_REST_Request $request
361
+	 * @return array
362
+	 * @throws DomainException
363
+	 * @throws EE_Error
364
+	 * @throws InvalidArgumentException
365
+	 * @throws InvalidDataTypeException
366
+	 * @throws InvalidInterfaceException
367
+	 * @throws ModelConfigurationException
368
+	 * @throws ReflectionException
369
+	 * @throws RestException
370
+	 * @throws RestPasswordIncorrectException
371
+	 * @throws RestPasswordRequiredException
372
+	 * @throws UnexpectedEntityException
373
+	 */
374
+	public function getEntitiesFromModel(EEM_Base $model, WP_REST_Request $request): array
375
+	{
376
+		$query_params = $this->createModelQueryParams($model, $request->get_params());
377
+		if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
378
+			$model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
379
+			throw new RestException(
380
+				sprintf('rest_%s_cannot_list', $model_name_plural),
381
+				sprintf(
382
+					esc_html__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
383
+					$model_name_plural,
384
+					Capabilities::getMissingPermissionsString($model, $query_params['caps'])
385
+				),
386
+				['status' => 403]
387
+			);
388
+		}
389
+		if (! $request->get_header('no_rest_headers')) {
390
+			$this->setHeadersFromQueryParams($model, $query_params);
391
+		}
392
+		/** @type array $results */
393
+		$results      = $model->get_all_wpdb_results($query_params);
394
+		$nice_results = [];
395
+		foreach ($results as $result) {
396
+			$nice_results[] = $this->createEntityFromWpdbResult(
397
+				$model,
398
+				$result,
399
+				$request
400
+			);
401
+		}
402
+		return $nice_results;
403
+	}
404
+
405
+
406
+	/**
407
+	 * Gets the collection for given relation object
408
+	 * The same as Read::get_entities_from_model(), except if the relation
409
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
410
+	 * the join-model-object into the results
411
+	 *
412
+	 * @param array                  $primary_model_query_params  query params for finding the item from which
413
+	 *                                                            relations will be based
414
+	 * @param EE_Model_Relation_Base $relation
415
+	 * @param WP_REST_Request        $request
416
+	 * @return array|null
417
+	 * @throws DomainException
418
+	 * @throws EE_Error
419
+	 * @throws InvalidArgumentException
420
+	 * @throws InvalidDataTypeException
421
+	 * @throws InvalidInterfaceException
422
+	 * @throws ModelConfigurationException
423
+	 * @throws ReflectionException
424
+	 * @throws RestException
425
+	 * @throws ModelConfigurationException
426
+	 * @throws UnexpectedEntityException
427
+	 */
428
+	protected function getEntitiesFromRelationUsingModelQueryParams(
429
+		array $primary_model_query_params,
430
+		EE_Model_Relation_Base $relation,
431
+		WP_REST_Request $request
432
+	) {
433
+		$context       = $this->validateContext($request->get_param('caps'));
434
+		$model         = $relation->get_this_model();
435
+		$related_model = $relation->get_other_model();
436
+		if (! isset($primary_model_query_params[0])) {
437
+			$primary_model_query_params[0] = [];
438
+		}
439
+		// check if they can access the 1st model object
440
+		$primary_model_query_params = [
441
+			0       => $primary_model_query_params[0],
442
+			'limit' => 1,
443
+		];
444
+		if ($model instanceof EEM_Soft_Delete_Base) {
445
+			$primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included(
446
+				$primary_model_query_params
447
+			);
448
+		}
449
+		$restricted_query_params          = $primary_model_query_params;
450
+		$restricted_query_params['caps']  = $context;
451
+		$restricted_query_params['limit'] = 1;
452
+		$this->setDebugInfo('main model query params', $restricted_query_params);
453
+		$this->setDebugInfo('missing caps', Capabilities::getMissingPermissionsString($related_model, $context));
454
+		$primary_model_rows = $model->get_all_wpdb_results($restricted_query_params);
455
+		$primary_model_row  = null;
456
+		if (is_array($primary_model_rows)) {
457
+			$primary_model_row = reset($primary_model_rows);
458
+		}
459
+		if (
460
+			! (
461
+				$primary_model_row
462
+				&& Capabilities::currentUserHasPartialAccessTo($related_model, $context)
463
+			)
464
+		) {
465
+			if ($relation instanceof EE_Belongs_To_Relation) {
466
+				$related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
467
+			} else {
468
+				$related_model_name_maybe_plural = EEH_Inflector::pluralize_and_lower(
469
+					$related_model->get_this_model_name()
470
+				);
471
+			}
472
+			throw new RestException(
473
+				sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
474
+				sprintf(
475
+					esc_html__(
476
+						'Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
477
+						'event_espresso'
478
+					),
479
+					$related_model_name_maybe_plural,
480
+					$relation->get_this_model()->get_this_model_name(),
481
+					implode(
482
+						',',
483
+						array_keys(
484
+							Capabilities::getMissingPermissions($related_model, $context)
485
+						)
486
+					)
487
+				),
488
+				['status' => 403]
489
+			);
490
+		}
491
+
492
+		$this->checkPassword(
493
+			$model,
494
+			$primary_model_row,
495
+			$restricted_query_params,
496
+			$request
497
+		);
498
+		$query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
499
+		foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
500
+			$query_params[0][ $relation->get_this_model()->get_this_model_name()
501
+							  . '.'
502
+							  . $where_condition_key ] = $where_condition_value;
503
+		}
504
+		$query_params['default_where_conditions'] = 'none';
505
+		$query_params['caps']                     = $context;
506
+		if (! $request->get_header('no_rest_headers')) {
507
+			$this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
508
+		}
509
+		/** @type array $results */
510
+		$results      = $relation->get_other_model()->get_all_wpdb_results($query_params);
511
+		$nice_results = [];
512
+		foreach ($results as $result) {
513
+			$nice_result = $this->createEntityFromWpdbResult(
514
+				$relation->get_other_model(),
515
+				$result,
516
+				$request
517
+			);
518
+			if ($relation instanceof EE_HABTM_Relation) {
519
+				// put the unusual stuff (properties from the HABTM relation) first, and make sure
520
+				// if there are conflicts we prefer the properties from the main model
521
+				$join_model_result = $this->createEntityFromWpdbResult(
522
+					$relation->get_join_model(),
523
+					$result,
524
+					$request
525
+				);
526
+				$joined_result     = array_merge($join_model_result, $nice_result);
527
+				// but keep the meta stuff from the main model
528
+				if (isset($nice_result['meta'])) {
529
+					$joined_result['meta'] = $nice_result['meta'];
530
+				}
531
+				$nice_result = $joined_result;
532
+			}
533
+			$nice_results[] = $nice_result;
534
+		}
535
+		if ($relation instanceof EE_Belongs_To_Relation) {
536
+			return array_shift($nice_results);
537
+		} else {
538
+			return $nice_results;
539
+		}
540
+	}
541
+
542
+
543
+	/**
544
+	 * Gets the collection for given relation object
545
+	 * The same as Read::get_entities_from_model(), except if the relation
546
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
547
+	 * the join-model-object into the results
548
+	 *
549
+	 * @param int|string             $id the ID of the thing we are fetching related stuff from
550
+	 * @param EE_Model_Relation_Base $relation
551
+	 * @param WP_REST_Request        $request
552
+	 * @return array
553
+	 * @throws DomainException
554
+	 * @throws EE_Error
555
+	 * @throws InvalidArgumentException
556
+	 * @throws InvalidDataTypeException
557
+	 * @throws InvalidInterfaceException
558
+	 * @throws ReflectionException
559
+	 * @throws RestException
560
+	 * @throws ModelConfigurationException
561
+	 * @throws UnexpectedEntityException
562
+	 */
563
+	public function getEntitiesFromRelation($id, EE_Model_Relation_Base $relation, WP_REST_Request $request): array
564
+	{
565
+		if (! $relation->get_this_model()->has_primary_key_field()) {
566
+			throw new EE_Error(
567
+				sprintf(
568
+					esc_html__(
569
+					// @codingStandardsIgnoreStart
570
+						'Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
571
+						// @codingStandardsIgnoreEnd
572
+						'event_espresso'
573
+					),
574
+					$relation->get_this_model()->get_this_model_name()
575
+				)
576
+			);
577
+		}
578
+		// can we edit that main item?
579
+		// if not, show nothing but an error
580
+		// otherwise, please proceed
581
+		return $this->getEntitiesFromRelationUsingModelQueryParams(
582
+			[
583
+				[
584
+					$relation->get_this_model()->primary_key_name() => $id,
585
+				],
586
+			],
587
+			$relation,
588
+			$request
589
+		);
590
+	}
591
+
592
+
593
+	/**
594
+	 * Sets the headers that are based on the model and query params,
595
+	 * like the total records. This should only be called on the original request
596
+	 * from the client, not on subsequent internal
597
+	 *
598
+	 * @param EEM_Base $model
599
+	 * @param array    $query_params
600
+	 * @return void
601
+	 * @throws EE_Error
602
+	 */
603
+	protected function setHeadersFromQueryParams(EEM_Base $model, array $query_params)
604
+	{
605
+		$this->setDebugInfo('model query params', $query_params);
606
+		$this->setDebugInfo(
607
+			'missing caps',
608
+			Capabilities::getMissingPermissionsString($model, $query_params['caps'])
609
+		);
610
+		// normally the limit to a 2-part array, where the 2nd item is the limit
611
+		if (! isset($query_params['limit'])) {
612
+			$query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
613
+		}
614
+		if (is_array($query_params['limit'])) {
615
+			$limit_parts = $query_params['limit'];
616
+		} else {
617
+			$limit_parts = explode(',', $query_params['limit']);
618
+			if (count($limit_parts) === 1) {
619
+				$limit_parts = [0, $limit_parts[0]];
620
+			}
621
+		}
622
+		// remove the group by and having parts of the query, as those will
623
+		// make the sql query return an array of values, instead of just a single value
624
+		unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
625
+		$count = $model->count($query_params, null, true);
626
+		$pages = $count / $limit_parts[1];
627
+		$this->setResponseHeader('Total', $count, false);
628
+		$this->setResponseHeader('PageSize', $limit_parts[1], false);
629
+		$this->setResponseHeader('TotalPages', ceil($pages), false);
630
+	}
631
+
632
+
633
+	/**
634
+	 * Changes database results into REST API entities
635
+	 *
636
+	 * @param EEM_Base             $model
637
+	 * @param array                $db_row     like results from $wpdb->get_results()
638
+	 * @param WP_REST_Request|null $rest_request
639
+	 * @param string|null          $deprecated no longer used
640
+	 * @return array ready for being converted into json for sending to client
641
+	 * @throws DomainException
642
+	 * @throws EE_Error
643
+	 * @throws InvalidArgumentException
644
+	 * @throws InvalidDataTypeException
645
+	 * @throws InvalidInterfaceException
646
+	 * @throws ModelConfigurationException
647
+	 * @throws ReflectionException
648
+	 * @throws RestException
649
+	 * @throws RestPasswordIncorrectException
650
+	 * @throws RestPasswordRequiredException
651
+	 * @throws UnexpectedEntityException
652
+	 */
653
+	public function createEntityFromWpdbResult(
654
+		EEM_Base $model,
655
+		array $db_row,
656
+		?WP_REST_Request $rest_request,
657
+		string $deprecated = null
658
+	): array {
659
+		if (! $rest_request instanceof WP_REST_Request) {
660
+			// ok so this was called in the old style, where the 3rd arg was
661
+			// $include, and the 4th arg was $context
662
+			// now setup the request just to avoid fatal errors, although we won't be able
663
+			// to truly make use of it because it's kinda devoid of info
664
+			$rest_request = new WP_REST_Request();
665
+			$rest_request->set_param('include', $rest_request);
666
+			$rest_request->set_param('caps', $deprecated);
667
+		}
668
+		if ($rest_request->get_param('caps') === null) {
669
+			$rest_request->set_param('caps', EEM_Base::caps_read);
670
+		}
671
+		$current_user_full_access_to_entity = $model->currentUserCan(
672
+			EEM_Base::caps_read_admin,
673
+			$model->deduce_fields_n_values_from_cols_n_values($db_row)
674
+		);
675
+		$entity_array                       = $this->createBareEntityFromWpdbResults($model, $db_row);
676
+		$entity_array                       = $this->addExtraFields($model, $db_row, $entity_array);
677
+		$entity_array['_links']             = $this->getEntityLinks($model, $db_row, $entity_array);
678
+		// when it's a regular read request for a model with a password and the password wasn't provided
679
+		// remove the password protected fields
680
+		$has_protected_fields = false;
681
+		try {
682
+			$this->checkPassword(
683
+				$model,
684
+				$db_row,
685
+				$model->alter_query_params_to_restrict_by_ID(
686
+					$model->get_index_primary_key_string(
687
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
688
+					)
689
+				),
690
+				$rest_request
691
+			);
692
+		} catch (RestPasswordRequiredException $e) {
693
+			if ($model->hasPassword()) {
694
+				// just remove protected fields
695
+				$has_protected_fields = true;
696
+				$entity_array         = Capabilities::filterOutPasswordProtectedFields(
697
+					$entity_array,
698
+					$model,
699
+					$this->getModelVersionInfo()
700
+				);
701
+			} else {
702
+				// that's a problem. None of this should be accessible if no password was provided
703
+				throw $e;
704
+			}
705
+		}
706
+
707
+		$entity_array['_calculated_fields'] = $this->getEntityCalculations(
708
+			$model,
709
+			$db_row,
710
+			$rest_request,
711
+			$has_protected_fields
712
+		);
713
+		$entity_array                       = apply_filters(
714
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
715
+			$entity_array,
716
+			$model,
717
+			$rest_request->get_param('caps'),
718
+			$rest_request,
719
+			$this
720
+		);
721
+		// add an empty protected property for now. If it's still around after we remove everything the request didn't
722
+		// want, we'll populate it then. k?
723
+		$entity_array['_protected'] = [];
724
+		// remove any properties the request didn't want. This way _protected won't bother mentioning them
725
+		$entity_array = $this->includeOnlyRequestedProperties($model, $rest_request, $entity_array);
726
+		$entity_array = $this->includeRequestedModels(
727
+			$model,
728
+			$rest_request,
729
+			$entity_array,
730
+			$db_row,
731
+			$has_protected_fields
732
+		);
733
+		// if they still wanted the _protected property, add it.
734
+		if (isset($entity_array['_protected'])) {
735
+			$entity_array = $this->addProtectedProperty($model, $entity_array, $has_protected_fields);
736
+		}
737
+		$entity_array = apply_filters(
738
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
739
+			$entity_array,
740
+			$model,
741
+			$rest_request->get_param('caps'),
742
+			$rest_request,
743
+			$this
744
+		);
745
+		if (! $current_user_full_access_to_entity) {
746
+			$result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
747
+				$entity_array,
748
+				$model,
749
+				$rest_request->get_param('caps'),
750
+				$this->getModelVersionInfo()
751
+			);
752
+		} else {
753
+			$result_without_inaccessible_fields = $entity_array;
754
+		}
755
+		$this->setDebugInfo(
756
+			'inaccessible fields',
757
+			array_keys(array_diff_key((array) $entity_array, (array) $result_without_inaccessible_fields))
758
+		);
759
+		return apply_filters(
760
+			'FHEE__Read__create_entity_from_wpdb_results__entity_return',
761
+			$result_without_inaccessible_fields,
762
+			$model,
763
+			$rest_request->get_param('caps')
764
+		);
765
+	}
766
+
767
+
768
+	/**
769
+	 * Returns an array describing which fields can be protected, and which actually were removed this request
770
+	 *
771
+	 * @param EEM_Base $model
772
+	 * @param array    $results_so_far
773
+	 * @param bool     $protected
774
+	 * @return array results
775
+	 * @throws EE_Error
776
+	 * @since 4.9.74.p
777
+	 */
778
+	protected function addProtectedProperty(EEM_Base $model, array $results_so_far, bool $protected): array
779
+	{
780
+		if (! $protected || ! $model->hasPassword()) {
781
+			return $results_so_far;
782
+		}
783
+		$password_field  = $model->getPasswordField();
784
+		$all_protected   = array_merge(
785
+			[$password_field->get_name()],
786
+			$password_field->protectedFields()
787
+		);
788
+		$fields_included = array_keys($results_so_far);
789
+		$fields_included = array_intersect(
790
+			$all_protected,
791
+			$fields_included
792
+		);
793
+		foreach ($fields_included as $field_name) {
794
+			$results_so_far['_protected'][] = $field_name;
795
+		}
796
+		return $results_so_far;
797
+	}
798
+
799
+
800
+	/**
801
+	 * Creates a REST entity array (JSON object we're going to return in the response, but
802
+	 * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
803
+	 * from $wpdb->get_row( $sql, ARRAY_A)
804
+	 *
805
+	 * @param EEM_Base $model
806
+	 * @param array    $db_row
807
+	 * @return array entity mostly ready for converting to JSON and sending in the response
808
+	 * @throws EE_Error
809
+	 * @throws ReflectionException
810
+	 * @throws RestException
811
+	 */
812
+	protected function createBareEntityFromWpdbResults(EEM_Base $model, array $db_row): array
813
+	{
814
+		$result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
815
+		$result = array_intersect_key(
816
+			$result,
817
+			$this->getModelVersionInfo()->fieldsOnModelInThisVersion($model)
818
+		);
819
+		// if this is a CPT, we need to set the global $post to it,
820
+		// otherwise shortcodes etc won't work properly while rendering it
821
+		if ($model instanceof EEM_CPT_Base) {
822
+			$do_chevy_shuffle = true;
823
+		} else {
824
+			$do_chevy_shuffle = false;
825
+		}
826
+		if ($do_chevy_shuffle) {
827
+			global $post;
828
+			$old_post = $post;
829
+			$post     = get_post($result[ $model->primary_key_name() ]);
830
+			if (! $post instanceof WP_Post) {
831
+				// well that's weird, because $result is what we JUST fetched from the database
832
+				throw new RestException(
833
+					'error_fetching_post_from_database_results',
834
+					esc_html__(
835
+						'An item was retrieved from the database but it\'s not a WP_Post like it should be.',
836
+						'event_espresso'
837
+					)
838
+				);
839
+			}
840
+			$model_object_classname          = 'EE_' . $model->get_this_model_name();
841
+			$post->{$model_object_classname} = EE_Registry::instance()->load_class(
842
+				$model_object_classname,
843
+				$result,
844
+				false,
845
+				false
846
+			);
847
+		}
848
+		foreach ($result as $field_name => $field_value) {
849
+			$field_obj = $model->field_settings_for($field_name);
850
+			if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
851
+				unset($result[ $field_name ]);
852
+			} elseif (
853
+				$this->isSubclassOfOne(
854
+					$field_obj,
855
+					$this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
856
+				)
857
+			) {
858
+				$result[ $field_name ] = [
859
+					'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
860
+					'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
861
+				];
862
+			} elseif (
863
+				$this->isSubclassOfOne(
864
+					$field_obj,
865
+					$this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
866
+				)
867
+			) {
868
+				$result[ $field_name ] = [
869
+					'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
870
+					'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
871
+				];
872
+			} elseif ($field_obj instanceof EE_Datetime_Field) {
873
+				$field_value = $field_obj->prepare_for_set_from_db($field_value);
874
+				// if the value is null, but we're not supposed to permit null, then set to the field's default
875
+				if (is_null($field_value)) {
876
+					$field_value = $field_obj->getDefaultDateTimeObj();
877
+				}
878
+				if (is_null($field_value)) {
879
+					$gmt_date = $local_date = ModelDataTranslator::prepareFieldValuesForJson(
880
+						$field_obj,
881
+						$field_value,
882
+						$this->getModelVersionInfo()->requestedVersion()
883
+					);
884
+				} else {
885
+					$timezone = $field_value->getTimezone();
886
+					EEH_DTT_Helper::setTimezone($field_value, new DateTimeZone('UTC'));
887
+					$gmt_date = ModelDataTranslator::prepareFieldValuesForJson(
888
+						$field_obj,
889
+						$field_value,
890
+						$this->getModelVersionInfo()->requestedVersion()
891
+					);
892
+					EEH_DTT_Helper::setTimezone($field_value, $timezone);
893
+					$local_date = ModelDataTranslator::prepareFieldValuesForJson(
894
+						$field_obj,
895
+						$field_value,
896
+						$this->getModelVersionInfo()->requestedVersion()
897
+					);
898
+				}
899
+				$result[ $field_name . '_gmt' ] = $gmt_date;
900
+				$result[ $field_name ]          = $local_date;
901
+			} else {
902
+				$result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
903
+			}
904
+		}
905
+		if ($do_chevy_shuffle) {
906
+			$post = $old_post;
907
+		}
908
+		return $result;
909
+	}
910
+
911
+
912
+	/**
913
+	 * Takes a value all the way from the DB representation, to the model object's representation, to the
914
+	 * user-facing PHP representation, to the REST API representation. (Assumes you've already taken from the DB
915
+	 * representation using $field_obj->prepare_for_set_from_db())
916
+	 *
917
+	 * @param EE_Model_Field_Base $field_obj
918
+	 * @param mixed               $value  as it's stored on a model object
919
+	 * @param string              $format valid values are 'normal' (default), 'pretty', 'datetime_obj'
920
+	 * @return array|int
921
+	 * @throws RestException if $value contains a PHP object
922
+	 * @throws EE_Error
923
+	 */
924
+	protected function prepareFieldObjValueForJson(
925
+		EE_Model_Field_Base $field_obj,
926
+		$value,
927
+		string $format = 'normal'
928
+	) {
929
+		$value = $field_obj->prepare_for_set_from_db($value);
930
+		switch ($format) {
931
+			case 'pretty':
932
+				$value = $field_obj->prepare_for_pretty_echoing($value);
933
+				break;
934
+			case 'normal':
935
+			default:
936
+				$value = $field_obj->prepare_for_get($value);
937
+				break;
938
+		}
939
+		return ModelDataTranslator::prepareFieldValuesForJson(
940
+			$field_obj,
941
+			$value,
942
+			$this->getModelVersionInfo()->requestedVersion()
943
+		);
944
+	}
945
+
946
+
947
+	/**
948
+	 * Adds a few extra fields to the entity response
949
+	 *
950
+	 * @param EEM_Base $model
951
+	 * @param array    $db_row
952
+	 * @param array    $entity_array
953
+	 * @return array modified entity
954
+	 * @throws EE_Error
955
+	 */
956
+	protected function addExtraFields(EEM_Base $model, array $db_row, array $entity_array): array
957
+	{
958
+		if ($model instanceof EEM_CPT_Base) {
959
+			$entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
960
+		}
961
+		return $entity_array;
962
+	}
963
+
964
+
965
+	/**
966
+	 * Gets links we want to add to the response
967
+	 *
968
+	 * @param EEM_Base        $model
969
+	 * @param array           $db_row
970
+	 * @param array           $entity_array
971
+	 * @return array the _links item in the entity
972
+	 * @throws EE_Error
973
+	 * @global WP_REST_Server $wp_rest_server
974
+	 */
975
+	protected function getEntityLinks(EEM_Base $model, array $db_row, array $entity_array): array
976
+	{
977
+		// add basic links
978
+		$links = [];
979
+		if ($model->has_primary_key_field()) {
980
+			$links['self'] = [
981
+				[
982
+					'href' => $this->getVersionedLinkTo(
983
+						EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
984
+						. '/'
985
+						. $entity_array[ $model->primary_key_name() ]
986
+					),
987
+				],
988
+			];
989
+		}
990
+		$links['collection'] = [
991
+			[
992
+				'href' => $this->getVersionedLinkTo(
993
+					EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
994
+				),
995
+			],
996
+		];
997
+		// add links to related models
998
+		if ($model->has_primary_key_field()) {
999
+			foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
1000
+				$related_model_part                                                      =
1001
+					Read::getRelatedEntityName($relation_name, $relation_obj);
1002
+				$links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = [
1003
+					[
1004
+						'href'   => $this->getVersionedLinkTo(
1005
+							EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
1006
+							. '/'
1007
+							. $entity_array[ $model->primary_key_name() ]
1008
+							. '/'
1009
+							. $related_model_part
1010
+						),
1011
+						'single' => $relation_obj instanceof EE_Belongs_To_Relation,
1012
+					],
1013
+				];
1014
+			}
1015
+		}
1016
+		return $links;
1017
+	}
1018
+
1019
+
1020
+	/**
1021
+	 * Adds the included models indicated in the request to the entity provided
1022
+	 *
1023
+	 * @param EEM_Base        $model
1024
+	 * @param WP_REST_Request $rest_request
1025
+	 * @param array           $entity_array
1026
+	 * @param array           $db_row
1027
+	 * @param boolean         $included_items_protected if the original item is password protected, don't include any
1028
+	 *                                                  related models.
1029
+	 * @return array the modified entity
1030
+	 * @throws DomainException
1031
+	 * @throws EE_Error
1032
+	 * @throws InvalidArgumentException
1033
+	 * @throws InvalidDataTypeException
1034
+	 * @throws InvalidInterfaceException
1035
+	 * @throws ModelConfigurationException
1036
+	 * @throws ReflectionException
1037
+	 * @throws UnexpectedEntityException
1038
+	 */
1039
+	protected function includeRequestedModels(
1040
+		EEM_Base $model,
1041
+		WP_REST_Request $rest_request,
1042
+		array $entity_array,
1043
+		array $db_row = [],
1044
+		bool $included_items_protected = false
1045
+	): array {
1046
+		// if $db_row not included, hope the entity array has what we need
1047
+		if (! $db_row) {
1048
+			$db_row = $entity_array;
1049
+		}
1050
+		$relation_settings = $this->getModelVersionInfo()->relationSettings($model);
1051
+		foreach ($relation_settings as $relation_name => $relation_obj) {
1052
+			$related_fields_to_include   = $this->explodeAndGetItemsPrefixedWith(
1053
+				$rest_request->get_param('include'),
1054
+				$relation_name
1055
+			);
1056
+			$related_fields_to_calculate = $this->explodeAndGetItemsPrefixedWith(
1057
+				$rest_request->get_param('calculate'),
1058
+				$relation_name
1059
+			);
1060
+			// did they specify they wanted to include a related model, or
1061
+			// specific fields from a related model?
1062
+			// or did they specify to calculate a field from a related model?
1063
+			if ($related_fields_to_include || $related_fields_to_calculate) {
1064
+				// if so, we should include at least some part of the related model
1065
+				$pretend_related_request = new WP_REST_Request();
1066
+				$pretend_related_request->set_query_params(
1067
+					[
1068
+						'caps'      => $rest_request->get_param('caps'),
1069
+						'include'   => $related_fields_to_include,
1070
+						'calculate' => $related_fields_to_calculate,
1071
+						'password'  => $rest_request->get_param('password'),
1072
+					]
1073
+				);
1074
+				$pretend_related_request->add_header('no_rest_headers', true);
1075
+				$primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
1076
+					$model->get_index_primary_key_string(
1077
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
1078
+					)
1079
+				);
1080
+				if (! $included_items_protected) {
1081
+					try {
1082
+						$related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1083
+							$primary_model_query_params,
1084
+							$relation_obj,
1085
+							$pretend_related_request
1086
+						);
1087
+					} catch (RestException $e) {
1088
+						$related_results = null;
1089
+					}
1090
+				} else {
1091
+					// they're protected, hide them.
1092
+					$related_results              = null;
1093
+					$entity_array['_protected'][] = Read::getRelatedEntityName($relation_name, $relation_obj);
1094
+				}
1095
+				if ($related_results instanceof WP_Error || $related_results === null) {
1096
+					$related_results =
1097
+						$relation_obj instanceof EE_Belongs_To_Relation
1098
+							? null
1099
+							: [];
1100
+				}
1101
+				$entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1102
+			}
1103
+		}
1104
+		return $entity_array;
1105
+	}
1106
+
1107
+
1108
+	/**
1109
+	 * If the user has requested only specific properties (including meta properties like _links or _protected)
1110
+	 * remove everything else.
1111
+	 *
1112
+	 * @param EEM_Base        $model
1113
+	 * @param WP_REST_Request $rest_request
1114
+	 * @param                 $entity_array
1115
+	 * @return array
1116
+	 * @throws EE_Error
1117
+	 * @since 4.9.74.p
1118
+	 */
1119
+	protected function includeOnlyRequestedProperties(
1120
+		EEM_Base $model,
1121
+		WP_REST_Request $rest_request,
1122
+		$entity_array
1123
+	): array {
1124
+
1125
+		$includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1126
+		$includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1127
+		// if they passed in * or didn't specify any includes, return everything
1128
+		if (! empty($includes_for_this_model) && ! in_array('*', $includes_for_this_model, true)) {
1129
+			if ($model->has_primary_key_field()) {
1130
+				// always include the primary key. ya just gotta know that at least
1131
+				$includes_for_this_model[] = $model->primary_key_name();
1132
+			}
1133
+			if ($this->explodeAndGetItemsPrefixedWith($rest_request->get_param('calculate'), '')) {
1134
+				$includes_for_this_model[] = '_calculated_fields';
1135
+			}
1136
+			$entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
1137
+		}
1138
+		return $entity_array;
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 * Returns a new array with all the names of models removed. Eg
1144
+	 * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
1145
+	 *
1146
+	 * @param array $array
1147
+	 * @return array
1148
+	 */
1149
+	private function removeModelNamesFromArray(array $array): array
1150
+	{
1151
+		return array_diff($array, array_keys(EE_Registry::instance()->non_abstract_db_models));
1152
+	}
1153
+
1154
+
1155
+	/**
1156
+	 * Gets the calculated fields for the response
1157
+	 *
1158
+	 * @param EEM_Base        $model
1159
+	 * @param array           $wpdb_row
1160
+	 * @param WP_REST_Request $rest_request
1161
+	 * @param bool            $row_is_protected whether this row is password protected or not
1162
+	 * @return stdClass the _calculations item in the entity
1163
+	 * @throws RestException if a default value has a PHP object, which should never do (and if we
1164
+	 *                                          did, let's know about it ASAP, so let the exception bubble up)
1165
+	 * @throws EE_Error
1166
+	 */
1167
+	protected function getEntityCalculations(
1168
+		EEM_Base $model,
1169
+		array $wpdb_row,
1170
+		WP_REST_Request $rest_request,
1171
+		bool $row_is_protected = false
1172
+	): stdClass {
1173
+		$calculated_fields = $this->explodeAndGetItemsPrefixedWith(
1174
+			$rest_request->get_param('calculate'),
1175
+			''
1176
+		);
1177
+		// note: setting calculate=* doesn't do anything
1178
+		$calculated_fields_to_return = new stdClass();
1179
+		$protected_fields            = [];
1180
+		foreach ($calculated_fields as $field_to_calculate) {
1181
+			try {
1182
+				// it's password protected, so they shouldn't be able to read this. Remove the value
1183
+				$schema = $this->fields_calculator->getJsonSchemaForModel($model);
1184
+				if (
1185
+					$row_is_protected
1186
+					&& isset($schema['properties'][ $field_to_calculate ]['protected'])
1187
+					&& $schema['properties'][ $field_to_calculate ]['protected']
1188
+				) {
1189
+					$calculated_value   = null;
1190
+					$protected_fields[] = $field_to_calculate;
1191
+					if ($schema['properties'][ $field_to_calculate ]['type']) {
1192
+						switch ($schema['properties'][ $field_to_calculate ]['type']) {
1193
+							case 'boolean':
1194
+								$calculated_value = false;
1195
+								break;
1196
+							case 'integer':
1197
+								$calculated_value = 0;
1198
+								break;
1199
+							case 'string':
1200
+								$calculated_value = '';
1201
+								break;
1202
+							case 'array':
1203
+								$calculated_value = [];
1204
+								break;
1205
+							case 'object':
1206
+								$calculated_value = new stdClass();
1207
+								break;
1208
+						}
1209
+					}
1210
+				} else {
1211
+					$calculated_value = ModelDataTranslator::prepareFieldValueForJson(
1212
+						null,
1213
+						$this->fields_calculator->retrieveCalculatedFieldValue(
1214
+							$model,
1215
+							$field_to_calculate,
1216
+							$wpdb_row,
1217
+							$rest_request,
1218
+							$this
1219
+						),
1220
+						$this->getModelVersionInfo()->requestedVersion()
1221
+					);
1222
+				}
1223
+				$calculated_fields_to_return->{$field_to_calculate} = $calculated_value;
1224
+			} catch (RestException $e) {
1225
+				// if we don't have permission to read it, just leave it out. but let devs know about the problem
1226
+				$this->setResponseHeader(
1227
+					'Notices-Field-Calculation-Errors['
1228
+					. $e->getStringCode()
1229
+					. ']['
1230
+					. $model->get_this_model_name()
1231
+					. ']['
1232
+					. $field_to_calculate
1233
+					. ']',
1234
+					$e->getMessage()
1235
+				);
1236
+			}
1237
+		}
1238
+		$calculated_fields_to_return->_protected = $protected_fields;
1239
+		return $calculated_fields_to_return;
1240
+	}
1241
+
1242
+
1243
+	/**
1244
+	 * Gets the full URL to the resource, taking the requested version into account
1245
+	 *
1246
+	 * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
1247
+	 * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
1248
+	 * @throws EE_Error
1249
+	 */
1250
+	public function getVersionedLinkTo(string $link_part_after_version_and_slash): string
1251
+	{
1252
+		return rest_url(
1253
+			EED_Core_Rest_Api::get_versioned_route_to(
1254
+				$link_part_after_version_and_slash,
1255
+				$this->getModelVersionInfo()->requestedVersion()
1256
+			)
1257
+		);
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * Gets the correct lowercase name for the relation in the API according
1263
+	 * to the relation's type
1264
+	 *
1265
+	 * @param string                 $relation_name
1266
+	 * @param EE_Model_Relation_Base $relation_obj
1267
+	 * @return string
1268
+	 */
1269
+	public static function getRelatedEntityName(string $relation_name, EE_Model_Relation_Base $relation_obj): string
1270
+	{
1271
+		if ($relation_obj instanceof EE_Belongs_To_Relation) {
1272
+			return strtolower($relation_name);
1273
+		}
1274
+		return EEH_Inflector::pluralize_and_lower($relation_name);
1275
+	}
1276
+
1277
+
1278
+	/**
1279
+	 * Gets the one model object with the specified id for the specified model
1280
+	 *
1281
+	 * @param EEM_Base        $model
1282
+	 * @param WP_REST_Request $request
1283
+	 * @return array
1284
+	 * @throws EE_Error
1285
+	 * @throws InvalidArgumentException
1286
+	 * @throws InvalidDataTypeException
1287
+	 * @throws InvalidInterfaceException
1288
+	 * @throws ModelConfigurationException
1289
+	 * @throws ReflectionException
1290
+	 * @throws RestException
1291
+	 * @throws RestPasswordIncorrectException
1292
+	 * @throws RestPasswordRequiredException
1293
+	 * @throws UnexpectedEntityException
1294
+	 * @throws DomainException
1295
+	 */
1296
+	public function getEntityFromModel(EEM_Base $model, WP_REST_Request $request): array
1297
+	{
1298
+		$context = $this->validateContext($request->get_param('caps'));
1299
+		return $this->getOneOrReportPermissionError($model, $request, $context);
1300
+	}
1301
+
1302
+
1303
+	/**
1304
+	 * If a context is provided which isn't valid, maybe it was added in a future
1305
+	 * version so just treat it as a default read
1306
+	 *
1307
+	 * @param string|null $context
1308
+	 * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
1309
+	 */
1310
+	public function validateContext(?string $context): string
1311
+	{
1312
+		if (! $context) {
1313
+			$context = EEM_Base::caps_read;
1314
+		}
1315
+		$valid_contexts = EEM_Base::valid_cap_contexts();
1316
+		if (in_array($context, $valid_contexts, true)) {
1317
+			return $context;
1318
+		}
1319
+		return EEM_Base::caps_read;
1320
+	}
1321
+
1322
+
1323
+	/**
1324
+	 * Verifies the passed in value is an allowable default where conditions value.
1325
+	 *
1326
+	 * @param string $default_where_conditions
1327
+	 * @return string
1328
+	 */
1329
+	public function validateDefaultQueryParams(string $default_where_conditions): string
1330
+	{
1331
+		$valid_default_where_conditions_for_api_calls = [
1332
+			EEM_Base::default_where_conditions_all,
1333
+			EEM_Base::default_where_conditions_minimum_all,
1334
+			EEM_Base::default_where_conditions_minimum_others,
1335
+		];
1336
+		if (! $default_where_conditions) {
1337
+			$default_where_conditions = EEM_Base::default_where_conditions_all;
1338
+		}
1339
+		if (
1340
+			in_array(
1341
+				$default_where_conditions,
1342
+				$valid_default_where_conditions_for_api_calls,
1343
+				true
1344
+			)
1345
+		) {
1346
+			return $default_where_conditions;
1347
+		}
1348
+		return EEM_Base::default_where_conditions_all;
1349
+	}
1350
+
1351
+
1352
+	/**
1353
+	 * Translates API filter get parameter into model query params @param EEM_Base $model
1354
+	 *
1355
+	 * @param array $query_params
1356
+	 * @return array model query params (@see
1357
+	 *               https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions)
1358
+	 *               or FALSE to indicate that absolutely no results should be returned
1359
+	 * @throws EE_Error
1360
+	 * @throws InvalidArgumentException
1361
+	 * @throws InvalidDataTypeException
1362
+	 * @throws InvalidInterfaceException
1363
+	 * @throws RestException
1364
+	 * @throws DomainException
1365
+	 * @see
1366
+	 * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions.
1367
+	 * Note: right now the query parameter keys for fields (and related fields) can be left as-is, but it's quite
1368
+	 * possible this will change someday. Also, this method's contents might be candidate for moving to
1369
+	 * Model_Data_Translator
1370
+	 *
1371
+	 */
1372
+	public function createModelQueryParams(EEM_Base $model, array $query_params): array
1373
+	{
1374
+		$model_query_params = [];
1375
+		if (isset($query_params['where'])) {
1376
+			$model_query_params[0] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1377
+				$query_params['where'],
1378
+				$model,
1379
+				$this->getModelVersionInfo()->requestedVersion()
1380
+			);
1381
+		}
1382
+		if (isset($query_params['order_by'])) {
1383
+			$order_by = $query_params['order_by'];
1384
+		} elseif (isset($query_params['orderby'])) {
1385
+			$order_by = $query_params['orderby'];
1386
+		} else {
1387
+			$order_by = null;
1388
+		}
1389
+		if ($order_by !== null) {
1390
+			if (is_array($order_by)) {
1391
+				$order_by = ModelDataTranslator::prepareFieldNamesInArrayKeysFromJson($order_by);
1392
+			} else {
1393
+				// it's a single item
1394
+				$order_by = ModelDataTranslator::prepareFieldNameFromJson($order_by);
1395
+			}
1396
+			$model_query_params['order_by'] = $order_by;
1397
+		}
1398
+		if (isset($query_params['group_by'])) {
1399
+			$group_by = $query_params['group_by'];
1400
+		} elseif (isset($query_params['groupby'])) {
1401
+			$group_by = $query_params['groupby'];
1402
+		} else {
1403
+			$group_by = array_keys($model->get_combined_primary_key_fields());
1404
+		}
1405
+		// make sure they're all real names
1406
+		if (is_array($group_by)) {
1407
+			$group_by = ModelDataTranslator::prepareFieldNamesFromJson($group_by);
1408
+		}
1409
+		if ($group_by !== null) {
1410
+			$model_query_params['group_by'] = $group_by;
1411
+		}
1412
+		if (isset($query_params['having'])) {
1413
+			$model_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1414
+				$query_params['having'],
1415
+				$model,
1416
+				$this->getModelVersionInfo()->requestedVersion()
1417
+			);
1418
+		}
1419
+		if (isset($query_params['order'])) {
1420
+			$model_query_params['order'] = $query_params['order'];
1421
+		}
1422
+		if (isset($query_params['mine'])) {
1423
+			$model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1424
+		}
1425
+		if (isset($query_params['limit'])) {
1426
+			// limit should be either a string like '23' or '23,43', or an array with two items in it
1427
+			if (! is_array($query_params['limit'])) {
1428
+				$limit_array = explode(',', (string) $query_params['limit']);
1429
+			} else {
1430
+				$limit_array = $query_params['limit'];
1431
+			}
1432
+			$sanitized_limit = [];
1433
+			foreach ($limit_array as $limit_part) {
1434
+				if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1435
+					throw new EE_Error(
1436
+						sprintf(
1437
+							esc_html__(
1438
+							// @codingStandardsIgnoreStart
1439
+								'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.',
1440
+								// @codingStandardsIgnoreEnd
1441
+								'event_espresso'
1442
+							),
1443
+							wp_json_encode($query_params['limit'])
1444
+						)
1445
+					);
1446
+				}
1447
+				$sanitized_limit[] = (int) $limit_part;
1448
+			}
1449
+			$model_query_params['limit'] = implode(',', $sanitized_limit);
1450
+		} else {
1451
+			$model_query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
1452
+		}
1453
+		if (isset($query_params['caps'])) {
1454
+			$model_query_params['caps'] = $this->validateContext($query_params['caps']);
1455
+		} else {
1456
+			$model_query_params['caps'] = EEM_Base::caps_read;
1457
+		}
1458
+		if (isset($query_params['default_where_conditions'])) {
1459
+			$model_query_params['default_where_conditions'] = $this->validateDefaultQueryParams(
1460
+				$query_params['default_where_conditions']
1461
+			);
1462
+		}
1463
+		// if this is a model protected by a password on another model, exclude the password protected
1464
+		// entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1465
+		// though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1466
+		if (
1467
+			$model_query_params['caps'] === EEM_Base::caps_read
1468
+			&& empty($query_params['password'])
1469
+			&& ! $model->hasPassword()
1470
+			&& $model->restrictedByRelatedModelPassword()
1471
+		) {
1472
+			$model_query_params['exclude_protected'] = true;
1473
+		}
1474
+
1475
+		return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_params, $model);
1476
+	}
1477
+
1478
+
1479
+	/**
1480
+	 * Changes the REST-style query params for use in the models
1481
+	 *
1482
+	 * @param EEM_Base $model
1483
+	 * @param array    $query_params sub-array from @see EEM_Base::get_all()
1484
+	 * @return array
1485
+	 * @deprecated
1486
+	 */
1487
+	public function prepareRestQueryParamsKeyForModels(EEM_Base $model, array $query_params): array
1488
+	{
1489
+		$model_ready_query_params = [];
1490
+		foreach ($query_params as $key => $value) {
1491
+			$model_ready_query_params[ $key ] = is_array($value)
1492
+				? $this->prepareRestQueryParamsKeyForModels($model, $value)
1493
+				: $value;
1494
+		}
1495
+		return $model_ready_query_params;
1496
+	}
1497
+
1498
+
1499
+	/**
1500
+	 * @param $model
1501
+	 * @param $query_params
1502
+	 * @return array
1503
+	 * @deprecated instead use ModelDataTranslator::prepareFieldValuesFromJson()
1504
+	 */
1505
+	public function prepareRestQueryParamsValuesForModels($model, $query_params): array
1506
+	{
1507
+		$model_ready_query_params = [];
1508
+		foreach ($query_params as $key => $value) {
1509
+			if (is_array($value)) {
1510
+				$model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1511
+			} else {
1512
+				$model_ready_query_params[ $key ] = $value;
1513
+			}
1514
+		}
1515
+		return $model_ready_query_params;
1516
+	}
1517
+
1518
+
1519
+	/**
1520
+	 * Explodes the string on commas, and only returns items with $prefix followed by a period.
1521
+	 * If no prefix is specified, returns items with no period.
1522
+	 *
1523
+	 * @param string|array $string_to_explode eg "jibba,jabba, blah, blah, blah" or array('jibba', 'jabba' )
1524
+	 * @param string       $prefix            "Event" or "foobar"
1525
+	 * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1526
+	 *                                        we only return strings starting with that and a period; if no prefix was
1527
+	 *                                        specified we return all items containing NO periods
1528
+	 */
1529
+	public function explodeAndGetItemsPrefixedWith($string_to_explode, string $prefix): array
1530
+	{
1531
+		if (is_string($string_to_explode)) {
1532
+			$exploded_contents = explode(',', $string_to_explode);
1533
+		} elseif (is_array($string_to_explode)) {
1534
+			$exploded_contents = $string_to_explode;
1535
+		} else {
1536
+			$exploded_contents = [];
1537
+		}
1538
+		// if the string was empty, we want an empty array
1539
+		$exploded_contents    = array_filter($exploded_contents);
1540
+		$contents_with_prefix = [];
1541
+		foreach ($exploded_contents as $item) {
1542
+			$item = trim($item);
1543
+			// if no prefix was provided, so we look for items with no "." in them
1544
+			if (! $prefix) {
1545
+				// does this item have a period?
1546
+				if (strpos($item, '.') === false) {
1547
+					// if not, then its what we're looking for
1548
+					$contents_with_prefix[] = $item;
1549
+				}
1550
+			} elseif (strpos($item, $prefix . '.') === 0) {
1551
+				// this item has the prefix and a period, grab it
1552
+				$contents_with_prefix[] = substr(
1553
+					$item,
1554
+					strpos($item, $prefix . '.') + strlen($prefix . '.')
1555
+				);
1556
+			} elseif ($item === $prefix) {
1557
+				// this item is JUST the prefix
1558
+				// so let's grab everything after, which is a blank string
1559
+				$contents_with_prefix[] = '';
1560
+			}
1561
+		}
1562
+		return $contents_with_prefix;
1563
+	}
1564
+
1565
+
1566
+	/**
1567
+	 * @param string      $include_string @see Read:handle_request_get_all
1568
+	 * @param string|null $model_name
1569
+	 * @return array of fields for this model. If $model_name is provided, then
1570
+	 *                                    the fields for that model, with the model's name removed from each.
1571
+	 *                                    If $include_string was blank or '*' returns an empty array
1572
+	 * @throws EE_Error
1573
+	 * @throws EE_Error
1574
+	 * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1575
+	 *                                    Deprecated because its return values were really quite confusing- sometimes
1576
+	 *                                    it
1577
+	 *                                    returned an empty array (when the include string was blank or '*') or
1578
+	 *                                    sometimes it returned array('*') (when you provided a model and a model of
1579
+	 *                                    that kind was found). Parses the $include_string so we fetch all the field
1580
+	 *                                    names relating to THIS model
1581
+	 *                                    (ie have NO period in them), or for the provided model (ie start with the
1582
+	 *                                    model name and then a period).
1583
+	 */
1584
+	public function extractIncludesForThisModel(string $include_string, string $model_name = null): array
1585
+	{
1586
+		if (is_array($include_string)) {
1587
+			$include_string = implode(',', $include_string);
1588
+		}
1589
+		if ($include_string === '*' || $include_string === '') {
1590
+			return [];
1591
+		}
1592
+		$includes                    = explode(',', $include_string);
1593
+		$extracted_fields_to_include = [];
1594
+		if ($model_name) {
1595
+			foreach ($includes as $field_to_include) {
1596
+				$field_to_include = trim($field_to_include);
1597
+				if (strpos($field_to_include, $model_name . '.') === 0) {
1598
+					// found the model name at the exact start
1599
+					$field_sans_model_name         = str_replace($model_name . '.', '', $field_to_include);
1600
+					$extracted_fields_to_include[] = $field_sans_model_name;
1601
+				} elseif ($field_to_include === $model_name) {
1602
+					$extracted_fields_to_include[] = '*';
1603
+				}
1604
+			}
1605
+		} else {
1606
+			// look for ones with no period
1607
+			foreach ($includes as $field_to_include) {
1608
+				$field_to_include = trim($field_to_include);
1609
+				if (
1610
+					strpos($field_to_include, '.') === false
1611
+					&& ! $this->getModelVersionInfo()->isModelNameInThisVersion($field_to_include)
1612
+				) {
1613
+					$extracted_fields_to_include[] = $field_to_include;
1614
+				}
1615
+			}
1616
+		}
1617
+		return $extracted_fields_to_include;
1618
+	}
1619
+
1620
+
1621
+	/**
1622
+	 * Gets the single item using the model according to the request in the context given, otherwise
1623
+	 * returns that it's inaccessible to the current user
1624
+	 *
1625
+	 * @param EEM_Base        $model
1626
+	 * @param WP_REST_Request $request
1627
+	 * @param null            $context
1628
+	 * @return array
1629
+	 * @throws EE_Error
1630
+	 * @throws ReflectionException
1631
+	 */
1632
+	public function getOneOrReportPermissionError(EEM_Base $model, WP_REST_Request $request, $context = null): array
1633
+	{
1634
+		$query_params = [[$model->primary_key_name() => $request->get_param('id')], 'limit' => 1];
1635
+		if ($model instanceof EEM_Soft_Delete_Base) {
1636
+			$query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
1637
+		}
1638
+		$restricted_query_params         = $query_params;
1639
+		$restricted_query_params['caps'] = $context;
1640
+		$this->setDebugInfo('model query params', $restricted_query_params);
1641
+		$model_rows = $model->get_all_wpdb_results($restricted_query_params);
1642
+		if (! empty($model_rows)) {
1643
+			return $this->createEntityFromWpdbResult(
1644
+				$model,
1645
+				reset($model_rows),
1646
+				$request
1647
+			);
1648
+		}
1649
+		// ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
1650
+		$lowercase_model_name = strtolower($model->get_this_model_name());
1651
+		if ($model->exists($query_params)) {
1652
+			// you got shafted- it existed but we didn't want to tell you!
1653
+			throw new RestException(
1654
+				'rest_user_cannot_' . $context,
1655
+				sprintf(
1656
+					__('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1657
+					$context,
1658
+					$lowercase_model_name,
1659
+					Capabilities::getMissingPermissionsString(
1660
+						$model,
1661
+						$context
1662
+					)
1663
+				),
1664
+				['status' => 403]
1665
+			);
1666
+		}
1667
+		// it's not you. It just doesn't exist
1668
+		throw new RestException(
1669
+			sprintf('rest_%s_invalid_id', $lowercase_model_name),
1670
+			sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
1671
+			['status' => 404]
1672
+		);
1673
+	}
1674
+
1675
+
1676
+	/**
1677
+	 * Checks that if this content requires a password to be read, that it's been provided and is correct.
1678
+	 *
1679
+	 * @param EEM_Base        $model
1680
+	 * @param array           $model_row
1681
+	 * @param array           $query_params Adds 'default_where_conditions' => 'minimum'
1682
+	 *                                      to ensure we don't confuse trashed with password protected.
1683
+	 * @param WP_REST_Request $request
1684
+	 * @throws EE_Error
1685
+	 * @throws InvalidArgumentException
1686
+	 * @throws InvalidDataTypeException
1687
+	 * @throws InvalidInterfaceException
1688
+	 * @throws RestPasswordRequiredException
1689
+	 * @throws RestPasswordIncorrectException
1690
+	 * @throws ModelConfigurationException
1691
+	 * @throws ReflectionException
1692
+	 * @since 4.9.74.p
1693
+	 */
1694
+	protected function checkPassword(EEM_Base $model, array $model_row, array $query_params, WP_REST_Request $request)
1695
+	{
1696
+		$query_params['default_where_conditions'] = 'minimum';
1697
+		// stuff is only "protected" for front-end requests. Elsewhere, you either get full permission to access the object
1698
+		// or you don't.
1699
+		$request_caps = $request->get_param('caps');
1700
+		if (isset($request_caps) && $request_caps !== EEM_Base::caps_read) {
1701
+			return;
1702
+		}
1703
+		// if this entity requires a password, they better give it and it better be right!
1704
+		if (
1705
+			$model->hasPassword()
1706
+			&& $model_row[ $model->getPasswordField()->get_qualified_column() ] !== ''
1707
+		) {
1708
+			if (empty($request['password'])) {
1709
+				throw new RestPasswordRequiredException();
1710
+			}
1711
+			if (
1712
+				! hash_equals(
1713
+					$model_row[ $model->getPasswordField()->get_qualified_column() ],
1714
+					$request['password']
1715
+				)
1716
+			) {
1717
+				throw new RestPasswordIncorrectException();
1718
+			}
1719
+		} elseif (
1720
+			// wait! maybe this content is password protected
1721
+			$model->restrictedByRelatedModelPassword()
1722
+			&& $request->get_param('caps') === EEM_Base::caps_read
1723
+		) {
1724
+			$password_supplied = $request->get_param('password');
1725
+			if (empty($password_supplied)) {
1726
+				$query_params['exclude_protected'] = true;
1727
+				if (! $model->exists($query_params)) {
1728
+					throw new RestPasswordRequiredException();
1729
+				}
1730
+			} else {
1731
+				$query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1732
+				if (! $model->exists($query_params)) {
1733
+					throw new RestPasswordIncorrectException();
1734
+				}
1735
+			}
1736
+		}
1737
+	}
1738 1738
 }
Please login to merge, or discard this patch.
core/services/helpers/datetime/AbstractHelper.php 2 patches
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
             new DateTimeZone($timezone_string);
50 50
         } catch (Exception $e) {
51 51
             // sometimes we take exception to exceptions
52
-            if (! $throw_error) {
52
+            if ( ! $throw_error) {
53 53
                 return false;
54 54
             }
55 55
             throw new EE_Error(
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
     public function getTimezoneOffset(DateTimeZone $date_time_zone, $time = null)
102 102
     {
103 103
         $transition = $this->getTimezoneTransitions($date_time_zone, $time);
104
-        if (! isset($transition['offset'])) {
104
+        if ( ! isset($transition['offset'])) {
105 105
             throw new DomainException(
106 106
                 sprintf(
107 107
                     esc_html__('An invalid timezone transition was received %1$s', 'event_espresso'),
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
     public function timezoneSelectInput($timezone_string = '')
124 124
     {
125 125
         // get WP date time format
126
-        $datetime_format = get_option('date_format') . ' ' . get_option('time_format');
126
+        $datetime_format = get_option('date_format').' '.get_option('time_format');
127 127
         // if passed a value, then use that, else get WP option
128 128
         $timezone_string = ! empty($timezone_string) ? $timezone_string : (string) get_option('timezone_string');
129 129
         // check if the timezone is valid but don't throw any errors if it isn't
@@ -137,9 +137,9 @@  discard block
 block discarded – undo
137 137
             $timezone_string = 'UTC';
138 138
             $check_zone_info = false;
139 139
             if ($gmt_offset > 0) {
140
-                $timezone_string = 'UTC+' . $gmt_offset;
140
+                $timezone_string = 'UTC+'.$gmt_offset;
141 141
             } elseif ($gmt_offset < 0) {
142
-                $timezone_string = 'UTC' . $gmt_offset;
142
+                $timezone_string = 'UTC'.$gmt_offset;
143 143
             }
144 144
         }
145 145
         ?>
@@ -159,14 +159,14 @@  discard block
 block discarded – undo
159 159
                 esc_html__('%1$sUTC%2$s time is %3$s', 'event_espresso'),
160 160
                 '<abbr title="Coordinated Universal Time">',
161 161
                 '</abbr>',
162
-                '<code>' . date_i18n($datetime_format, false, true) . '</code>'
162
+                '<code>'.date_i18n($datetime_format, false, true).'</code>'
163 163
             );
164 164
             ?></span>
165 165
         <?php
166
-        if (! empty($timezone_string) || ! empty($gmt_offset)) : ?>
166
+        if ( ! empty($timezone_string) || ! empty($gmt_offset)) : ?>
167 167
         <br/>
168 168
         <span><?php
169
-        printf(esc_html__('Local time is %1$s', 'event_espresso'), '<code>' . date_i18n($datetime_format) . '</code>');
169
+        printf(esc_html__('Local time is %1$s', 'event_espresso'), '<code>'.date_i18n($datetime_format).'</code>');
170 170
         ?></span>
171 171
             <?php
172 172
         endif; ?>
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
                     // transition time from date_i18n().
208 208
                     printf(
209 209
                         $message,
210
-                        '<code >' . date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])) . '</code >'
210
+                        '<code >'.date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])).'</code >'
211 211
                     );
212 212
                 } else {
213 213
                     esc_html_e('This timezone does not observe daylight saving time.', 'event_espresso');
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
         $unix_timestamp  = $unix_timestamp === 0 ? time() : (int) $unix_timestamp;
241 241
         $timezone_string = $this->getValidTimezoneString($timezone_string);
242 242
         $TimeZone        = new DateTimeZone($timezone_string);
243
-        $DateTime        = new DateTime('@' . $unix_timestamp, $TimeZone);
243
+        $DateTime        = new DateTime('@'.$unix_timestamp, $TimeZone);
244 244
         $offset          = timezone_offset_get($TimeZone, $DateTime);
245 245
         return (int) $DateTime->format('U') + (int) $offset;
246 246
     }
Please login to merge, or discard this patch.
Indentation   +247 added lines, -247 removed lines patch added patch discarded remove patch
@@ -11,136 +11,136 @@  discard block
 block discarded – undo
11 11
 
12 12
 abstract class AbstractHelper implements HelperInterface
13 13
 {
14
-    /**
15
-     * Ensures that a valid timezone string is returned.
16
-     *
17
-     * @param string $timezone_string  When not provided then attempt to use the timezone_string set in the WP Time
18
-     *                                 settings (or derive from set UTC offset).
19
-     * @return string
20
-     * @throws EE_Error
21
-     */
22
-    public function getValidTimezoneString($timezone_string = '')
23
-    {
24
-        $timezone_string = ! empty($timezone_string) ? $timezone_string : (string) get_option('timezone_string');
25
-        $timezone_string = ! empty($timezone_string)
26
-            ? $timezone_string
27
-            : $this->getTimezoneStringFromGmtOffset();
28
-        $this->validateTimezone($timezone_string);
29
-        return $timezone_string;
30
-    }
14
+	/**
15
+	 * Ensures that a valid timezone string is returned.
16
+	 *
17
+	 * @param string $timezone_string  When not provided then attempt to use the timezone_string set in the WP Time
18
+	 *                                 settings (or derive from set UTC offset).
19
+	 * @return string
20
+	 * @throws EE_Error
21
+	 */
22
+	public function getValidTimezoneString($timezone_string = '')
23
+	{
24
+		$timezone_string = ! empty($timezone_string) ? $timezone_string : (string) get_option('timezone_string');
25
+		$timezone_string = ! empty($timezone_string)
26
+			? $timezone_string
27
+			: $this->getTimezoneStringFromGmtOffset();
28
+		$this->validateTimezone($timezone_string);
29
+		return $timezone_string;
30
+	}
31 31
 
32 32
 
33 33
 
34
-    /**
35
-     * The only purpose for this static method is to validate that the incoming timezone is a valid php timezone.
36
-     *
37
-     * @param string $timezone_string
38
-     * @param bool   $throw_error
39
-     * @return bool
40
-     * @throws EE_Error
41
-     */
42
-    public function validateTimezone($timezone_string, $throw_error = true)
43
-    {
44
-        // easiest way to test a timezone string is just see if it throws an error when you try to create a
45
-        // DateTimeZone object with it
46
-        try {
47
-            new DateTimeZone($timezone_string);
48
-        } catch (Exception $e) {
49
-            // sometimes we take exception to exceptions
50
-            if (! $throw_error) {
51
-                return false;
52
-            }
53
-            throw new EE_Error(
54
-                sprintf(
55
-                    esc_html__(
56
-                        'The timezone given (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
57
-                        'event_espresso'
58
-                    ),
59
-                    $timezone_string,
60
-                    '<a href="http://www.php.net/manual/en/timezones.php">',
61
-                    '</a>'
62
-                )
63
-            );
64
-        }
65
-        return true;
66
-    }
34
+	/**
35
+	 * The only purpose for this static method is to validate that the incoming timezone is a valid php timezone.
36
+	 *
37
+	 * @param string $timezone_string
38
+	 * @param bool   $throw_error
39
+	 * @return bool
40
+	 * @throws EE_Error
41
+	 */
42
+	public function validateTimezone($timezone_string, $throw_error = true)
43
+	{
44
+		// easiest way to test a timezone string is just see if it throws an error when you try to create a
45
+		// DateTimeZone object with it
46
+		try {
47
+			new DateTimeZone($timezone_string);
48
+		} catch (Exception $e) {
49
+			// sometimes we take exception to exceptions
50
+			if (! $throw_error) {
51
+				return false;
52
+			}
53
+			throw new EE_Error(
54
+				sprintf(
55
+					esc_html__(
56
+						'The timezone given (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
57
+						'event_espresso'
58
+					),
59
+					$timezone_string,
60
+					'<a href="http://www.php.net/manual/en/timezones.php">',
61
+					'</a>'
62
+				)
63
+			);
64
+		}
65
+		return true;
66
+	}
67 67
 
68 68
 
69
-    /**
70
-     * Gets the site's GMT offset based on either the timezone string
71
-     * (in which case the gmt offset will vary depending on the location's
72
-     * observance of daylight savings time) or the gmt_offset wp option
73
-     *
74
-     * @return int  seconds offset
75
-     */
76
-    public function getSiteTimezoneGmtOffset()
77
-    {
78
-        $timezone_string = (string) get_option('timezone_string');
79
-        if ($timezone_string) {
80
-            try {
81
-                $timezone = new DateTimeZone($timezone_string);
82
-                return $timezone->getOffset(new DateTime()); // in WordPress DateTime defaults to UTC
83
-            } catch (Exception $e) {
84
-            }
85
-        }
86
-        $offset = get_option('gmt_offset');
87
-        return (int) ($offset * HOUR_IN_SECONDS);
88
-    }
69
+	/**
70
+	 * Gets the site's GMT offset based on either the timezone string
71
+	 * (in which case the gmt offset will vary depending on the location's
72
+	 * observance of daylight savings time) or the gmt_offset wp option
73
+	 *
74
+	 * @return int  seconds offset
75
+	 */
76
+	public function getSiteTimezoneGmtOffset()
77
+	{
78
+		$timezone_string = (string) get_option('timezone_string');
79
+		if ($timezone_string) {
80
+			try {
81
+				$timezone = new DateTimeZone($timezone_string);
82
+				return $timezone->getOffset(new DateTime()); // in WordPress DateTime defaults to UTC
83
+			} catch (Exception $e) {
84
+			}
85
+		}
86
+		$offset = get_option('gmt_offset');
87
+		return (int) ($offset * HOUR_IN_SECONDS);
88
+	}
89 89
 
90 90
 
91
-    /**
92
-     * Get Timezone offset for given timezone object
93
-     *
94
-     * @param DateTimeZone $date_time_zone
95
-     * @param null|int     $time
96
-     * @return int
97
-     * @throws DomainException
98
-     */
99
-    public function getTimezoneOffset(DateTimeZone $date_time_zone, $time = null)
100
-    {
101
-        $transition = $this->getTimezoneTransitions($date_time_zone, $time);
102
-        if (! isset($transition['offset'])) {
103
-            throw new DomainException(
104
-                sprintf(
105
-                    esc_html__('An invalid timezone transition was received %1$s', 'event_espresso'),
106
-                    print_r($transition, true)
107
-                )
108
-            );
109
-        }
110
-        return $transition['offset'];
111
-    }
91
+	/**
92
+	 * Get Timezone offset for given timezone object
93
+	 *
94
+	 * @param DateTimeZone $date_time_zone
95
+	 * @param null|int     $time
96
+	 * @return int
97
+	 * @throws DomainException
98
+	 */
99
+	public function getTimezoneOffset(DateTimeZone $date_time_zone, $time = null)
100
+	{
101
+		$transition = $this->getTimezoneTransitions($date_time_zone, $time);
102
+		if (! isset($transition['offset'])) {
103
+			throw new DomainException(
104
+				sprintf(
105
+					esc_html__('An invalid timezone transition was received %1$s', 'event_espresso'),
106
+					print_r($transition, true)
107
+				)
108
+			);
109
+		}
110
+		return $transition['offset'];
111
+	}
112 112
 
113 113
 
114
-    /**
115
-     * Provide a timezone select input
116
-     *
117
-     * @param string $timezone_string
118
-     * @return string
119
-     * @throws EE_Error
120
-     */
121
-    public function timezoneSelectInput($timezone_string = '')
122
-    {
123
-        // get WP date time format
124
-        $datetime_format = get_option('date_format') . ' ' . get_option('time_format');
125
-        // if passed a value, then use that, else get WP option
126
-        $timezone_string = ! empty($timezone_string) ? $timezone_string : (string) get_option('timezone_string');
127
-        // check if the timezone is valid but don't throw any errors if it isn't
128
-        $timezone_string = $this->validateTimezone($timezone_string, false)
129
-            ? $timezone_string
130
-            : '';
131
-        $gmt_offset      = get_option('gmt_offset');
132
-        $check_zone_info = true;
133
-        if (empty($timezone_string)) {
134
-            // Create a UTC+- zone if no timezone string exists
135
-            $timezone_string = 'UTC';
136
-            $check_zone_info = false;
137
-            if ($gmt_offset > 0) {
138
-                $timezone_string = 'UTC+' . $gmt_offset;
139
-            } elseif ($gmt_offset < 0) {
140
-                $timezone_string = 'UTC' . $gmt_offset;
141
-            }
142
-        }
143
-        ?>
114
+	/**
115
+	 * Provide a timezone select input
116
+	 *
117
+	 * @param string $timezone_string
118
+	 * @return string
119
+	 * @throws EE_Error
120
+	 */
121
+	public function timezoneSelectInput($timezone_string = '')
122
+	{
123
+		// get WP date time format
124
+		$datetime_format = get_option('date_format') . ' ' . get_option('time_format');
125
+		// if passed a value, then use that, else get WP option
126
+		$timezone_string = ! empty($timezone_string) ? $timezone_string : (string) get_option('timezone_string');
127
+		// check if the timezone is valid but don't throw any errors if it isn't
128
+		$timezone_string = $this->validateTimezone($timezone_string, false)
129
+			? $timezone_string
130
+			: '';
131
+		$gmt_offset      = get_option('gmt_offset');
132
+		$check_zone_info = true;
133
+		if (empty($timezone_string)) {
134
+			// Create a UTC+- zone if no timezone string exists
135
+			$timezone_string = 'UTC';
136
+			$check_zone_info = false;
137
+			if ($gmt_offset > 0) {
138
+				$timezone_string = 'UTC+' . $gmt_offset;
139
+			} elseif ($gmt_offset < 0) {
140
+				$timezone_string = 'UTC' . $gmt_offset;
141
+			}
142
+		}
143
+		?>
144 144
         <p>
145 145
             <label for="timezone_string"><?php esc_html_e('timezone', 'event_espresso'); ?></label>
146 146
             <select id="timezone_string" name="timezone_string">
@@ -153,153 +153,153 @@  discard block
 block discarded – undo
153 153
         <p>
154 154
         <span>
155 155
             <?php
156
-            printf(
157
-                esc_html__('%1$sUTC%2$s time is %3$s', 'event_espresso'),
158
-                '<abbr title="Coordinated Universal Time">',
159
-                '</abbr>',
160
-                '<code>' . date_i18n($datetime_format, false, true) . '</code>'
161
-            );
162
-            ?></span>
156
+			printf(
157
+				esc_html__('%1$sUTC%2$s time is %3$s', 'event_espresso'),
158
+				'<abbr title="Coordinated Universal Time">',
159
+				'</abbr>',
160
+				'<code>' . date_i18n($datetime_format, false, true) . '</code>'
161
+			);
162
+			?></span>
163 163
         <?php
164
-        if (! empty($timezone_string) || ! empty($gmt_offset)) : ?>
164
+		if (! empty($timezone_string) || ! empty($gmt_offset)) : ?>
165 165
         <br/>
166 166
         <span><?php
167
-        printf(esc_html__('Local time is %1$s', 'event_espresso'), '<code>' . date_i18n($datetime_format) . '</code>');
168
-        ?></span>
167
+		printf(esc_html__('Local time is %1$s', 'event_espresso'), '<code>' . date_i18n($datetime_format) . '</code>');
168
+		?></span>
169 169
             <?php
170
-        endif; ?>
170
+		endif; ?>
171 171
 
172 172
         <?php
173
-        if ($check_zone_info && $timezone_string) : ?>
173
+		if ($check_zone_info && $timezone_string) : ?>
174 174
         <br/>
175 175
         <span>
176 176
                 <?php
177
-                // Set TZ so localtime works.
178
-                date_default_timezone_set($timezone_string);
179
-                $now = localtime(time(), true);
180
-                if ($now['tm_isdst']) {
181
-                    esc_html_e('This timezone is currently in daylight saving time.', 'event_espresso');
182
-                } else {
183
-                    esc_html_e('This timezone is currently in standard time.', 'event_espresso');
184
-                }
185
-                ?>
177
+				// Set TZ so localtime works.
178
+				date_default_timezone_set($timezone_string);
179
+				$now = localtime(time(), true);
180
+				if ($now['tm_isdst']) {
181
+					esc_html_e('This timezone is currently in daylight saving time.', 'event_espresso');
182
+				} else {
183
+					esc_html_e('This timezone is currently in standard time.', 'event_espresso');
184
+				}
185
+				?>
186 186
             <br/>
187 187
             <?php
188
-            if (function_exists('timezone_transitions_get')) {
189
-                $found                   = false;
190
-                $date_time_zone_selected = new DateTimeZone($timezone_string);
191
-                $tz_offset               = timezone_offset_get($date_time_zone_selected, date_create());
192
-                $right_now               = time();
193
-                $tr['isdst']             = false;
194
-                foreach (timezone_transitions_get($date_time_zone_selected) as $tr) {
195
-                    if ($tr['ts'] > $right_now) {
196
-                        $found = true;
197
-                        break;
198
-                    }
199
-                }
200
-                if ($found) {
201
-                    $message = $tr['isdst']
202
-                        ? esc_html__(' Daylight saving time begins on: %s.', 'event_espresso')
203
-                        : esc_html__(' Standard time begins  on: %s.', 'event_espresso');
204
-                    // Add the difference between the current offset and the new offset to ts to get the correct
205
-                    // transition time from date_i18n().
206
-                    printf(
207
-                        $message,
208
-                        '<code >' . date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])) . '</code >'
209
-                    );
210
-                } else {
211
-                    esc_html_e('This timezone does not observe daylight saving time.', 'event_espresso');
212
-                }
213
-            }
214
-            // Set back to UTC.
215
-            date_default_timezone_set('UTC');
216
-            ?>
188
+			if (function_exists('timezone_transitions_get')) {
189
+				$found                   = false;
190
+				$date_time_zone_selected = new DateTimeZone($timezone_string);
191
+				$tz_offset               = timezone_offset_get($date_time_zone_selected, date_create());
192
+				$right_now               = time();
193
+				$tr['isdst']             = false;
194
+				foreach (timezone_transitions_get($date_time_zone_selected) as $tr) {
195
+					if ($tr['ts'] > $right_now) {
196
+						$found = true;
197
+						break;
198
+					}
199
+				}
200
+				if ($found) {
201
+					$message = $tr['isdst']
202
+						? esc_html__(' Daylight saving time begins on: %s.', 'event_espresso')
203
+						: esc_html__(' Standard time begins  on: %s.', 'event_espresso');
204
+					// Add the difference between the current offset and the new offset to ts to get the correct
205
+					// transition time from date_i18n().
206
+					printf(
207
+						$message,
208
+						'<code >' . date_i18n($datetime_format, $tr['ts'] + ($tz_offset - $tr['offset'])) . '</code >'
209
+					);
210
+				} else {
211
+					esc_html_e('This timezone does not observe daylight saving time.', 'event_espresso');
212
+				}
213
+			}
214
+			// Set back to UTC.
215
+			date_default_timezone_set('UTC');
216
+			?>
217 217
         </span></p>
218 218
             <?php
219
-        endif;
220
-    }
219
+		endif;
220
+	}
221 221
 
222 222
 
223
-    /**
224
-     * This method will take an incoming unix timestamp and add the offset to it for the given timezone_string.
225
-     * If no unix timestamp is given then time() is used.  If no timezone is given then the set timezone string for
226
-     * the site is used.
227
-     * This is used typically when using a Unix timestamp any core WP functions that expect their specially
228
-     * computed timestamp (i.e. date_i18n() )
229
-     *
230
-     * @param int    $unix_timestamp  if 0, then time() will be used.
231
-     * @param string $timezone_string timezone_string. If empty, then the current set timezone for the
232
-     *                                site will be used.
233
-     * @return int      unix_timestamp value with the offset applied for the given timezone.
234
-     * @throws EE_Error
235
-     */
236
-    public function getTimestampWithOffset($unix_timestamp = 0, $timezone_string = '')
237
-    {
238
-        $unix_timestamp  = $unix_timestamp === 0 ? time() : (int) $unix_timestamp;
239
-        $timezone_string = $this->getValidTimezoneString($timezone_string);
240
-        $TimeZone        = new DateTimeZone($timezone_string);
241
-        $DateTime        = new DateTime('@' . $unix_timestamp, $TimeZone);
242
-        $offset          = timezone_offset_get($TimeZone, $DateTime);
243
-        return (int) $DateTime->format('U') + (int) $offset;
244
-    }
223
+	/**
224
+	 * This method will take an incoming unix timestamp and add the offset to it for the given timezone_string.
225
+	 * If no unix timestamp is given then time() is used.  If no timezone is given then the set timezone string for
226
+	 * the site is used.
227
+	 * This is used typically when using a Unix timestamp any core WP functions that expect their specially
228
+	 * computed timestamp (i.e. date_i18n() )
229
+	 *
230
+	 * @param int    $unix_timestamp  if 0, then time() will be used.
231
+	 * @param string $timezone_string timezone_string. If empty, then the current set timezone for the
232
+	 *                                site will be used.
233
+	 * @return int      unix_timestamp value with the offset applied for the given timezone.
234
+	 * @throws EE_Error
235
+	 */
236
+	public function getTimestampWithOffset($unix_timestamp = 0, $timezone_string = '')
237
+	{
238
+		$unix_timestamp  = $unix_timestamp === 0 ? time() : (int) $unix_timestamp;
239
+		$timezone_string = $this->getValidTimezoneString($timezone_string);
240
+		$TimeZone        = new DateTimeZone($timezone_string);
241
+		$DateTime        = new DateTime('@' . $unix_timestamp, $TimeZone);
242
+		$offset          = timezone_offset_get($TimeZone, $DateTime);
243
+		return (int) $DateTime->format('U') + (int) $offset;
244
+	}
245 245
 
246 246
 
247
-    /**
248
-     * Get Timezone Transitions
249
-     *
250
-     * @param DateTimeZone $date_time_zone
251
-     * @param int|null     $time
252
-     * @param bool         $first_only
253
-     * @return array|mixed
254
-     */
255
-    public function getTimezoneTransitions(DateTimeZone $date_time_zone, $time = null, $first_only = true)
256
-    {
257
-        $time        = is_int($time) || $time === null ? $time : (int) strtotime($time);
258
-        $time        = preg_match(EE_Datetime_Field::unix_timestamp_regex, $time) ? $time : time();
259
-        $transitions = $date_time_zone->getTransitions($time);
260
-        return $first_only && ! isset($transitions['ts']) ? reset($transitions) : $transitions;
261
-    }
247
+	/**
248
+	 * Get Timezone Transitions
249
+	 *
250
+	 * @param DateTimeZone $date_time_zone
251
+	 * @param int|null     $time
252
+	 * @param bool         $first_only
253
+	 * @return array|mixed
254
+	 */
255
+	public function getTimezoneTransitions(DateTimeZone $date_time_zone, $time = null, $first_only = true)
256
+	{
257
+		$time        = is_int($time) || $time === null ? $time : (int) strtotime($time);
258
+		$time        = preg_match(EE_Datetime_Field::unix_timestamp_regex, $time) ? $time : time();
259
+		$transitions = $date_time_zone->getTransitions($time);
260
+		return $first_only && ! isset($transitions['ts']) ? reset($transitions) : $transitions;
261
+	}
262 262
 
263 263
 
264 264
 
265
-    /**
266
-     * Default to just returning the provided $gmt_offset.  Children can override if adjustment needed.
267
-     *
268
-     * @param int $gmt_offset
269
-     * @return int
270
-     */
271
-    public function adjustInvalidGmtOffsets($gmt_offset = 0)
272
-    {
273
-        return $gmt_offset;
274
-    }
265
+	/**
266
+	 * Default to just returning the provided $gmt_offset.  Children can override if adjustment needed.
267
+	 *
268
+	 * @param int $gmt_offset
269
+	 * @return int
270
+	 */
271
+	public function adjustInvalidGmtOffsets($gmt_offset = 0)
272
+	{
273
+		return $gmt_offset;
274
+	}
275 275
 
276 276
 
277 277
 
278
-    /**
279
-     * This receives an incoming gmt_offset and santizes it.  If the provide value is an empty string, then this will
280
-     * attempt to get the offset from the timezone string.  If this returns a string, then a timezone string was
281
-     * successfully derived from existing timezone_string in the db.  If not, then a float is returned for the provided
282
-     * offset.
283
-     * @param  float|string $gmt_offset
284
-     * @return float|string
285
-     */
286
-    protected function sanitizeInitialIncomingGmtOffsetForGettingTimezoneString($gmt_offset)
287
-    {
288
-        // if there is no incoming gmt_offset, then because WP hooks in on timezone_string, we need to see if that is
289
-        // set because it will override `gmt_offset` via `pre_get_option` filter.  If that's set, then let's just use
290
-        // that!  Otherwise we'll leave timezone_string at the default of 'UTC' before doing other logic.
291
-        if ($gmt_offset === '') {
292
-            // autoloaded so no need to set to a variable.  There will not be multiple hits to the db.
293
-            if (get_option('timezone_string')) {
294
-                return (string) get_option('timezone_string');
295
-            }
296
-        }
297
-        $gmt_offset = $gmt_offset !== '' ? $gmt_offset : (string) get_option('gmt_offset');
298
-        $gmt_offset = (float) $gmt_offset;
299
-        // if $gmt_offset is 0 or is still an empty string, then just return UTC
300
-        if ($gmt_offset === (float) 0) {
301
-            return 'UTC';
302
-        }
303
-        return $gmt_offset;
304
-    }
278
+	/**
279
+	 * This receives an incoming gmt_offset and santizes it.  If the provide value is an empty string, then this will
280
+	 * attempt to get the offset from the timezone string.  If this returns a string, then a timezone string was
281
+	 * successfully derived from existing timezone_string in the db.  If not, then a float is returned for the provided
282
+	 * offset.
283
+	 * @param  float|string $gmt_offset
284
+	 * @return float|string
285
+	 */
286
+	protected function sanitizeInitialIncomingGmtOffsetForGettingTimezoneString($gmt_offset)
287
+	{
288
+		// if there is no incoming gmt_offset, then because WP hooks in on timezone_string, we need to see if that is
289
+		// set because it will override `gmt_offset` via `pre_get_option` filter.  If that's set, then let's just use
290
+		// that!  Otherwise we'll leave timezone_string at the default of 'UTC' before doing other logic.
291
+		if ($gmt_offset === '') {
292
+			// autoloaded so no need to set to a variable.  There will not be multiple hits to the db.
293
+			if (get_option('timezone_string')) {
294
+				return (string) get_option('timezone_string');
295
+			}
296
+		}
297
+		$gmt_offset = $gmt_offset !== '' ? $gmt_offset : (string) get_option('gmt_offset');
298
+		$gmt_offset = (float) $gmt_offset;
299
+		// if $gmt_offset is 0 or is still an empty string, then just return UTC
300
+		if ($gmt_offset === (float) 0) {
301
+			return 'UTC';
302
+		}
303
+		return $gmt_offset;
304
+	}
305 305
 }
Please login to merge, or discard this patch.
core/services/loaders/LoaderInterface.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -8,58 +8,58 @@
 block discarded – undo
8 8
 interface LoaderInterface
9 9
 {
10 10
 
11
-    /**
12
-     * Can be for instantiating a new instance of a class,
13
-     * or for getting a shared instance of a class (default)
14
-     *
15
-     * @param FullyQualifiedName|string $fqcn
16
-     * @param array                     $arguments
17
-     * @param bool                      $shared
18
-     * @return mixed
19
-     */
20
-    public function load($fqcn, array $arguments = [], $shared = true);
11
+	/**
12
+	 * Can be for instantiating a new instance of a class,
13
+	 * or for getting a shared instance of a class (default)
14
+	 *
15
+	 * @param FullyQualifiedName|string $fqcn
16
+	 * @param array                     $arguments
17
+	 * @param bool                      $shared
18
+	 * @return mixed
19
+	 */
20
+	public function load($fqcn, array $arguments = [], $shared = true);
21 21
 
22 22
 
23
-    /**
24
-     * Used for instantiating a new instance of a class
25
-     *
26
-     * @param FullyQualifiedName|string $fqcn
27
-     * @param array                     $arguments
28
-     * @return mixed
29
-     */
30
-    public function getNew($fqcn, array $arguments = []);
23
+	/**
24
+	 * Used for instantiating a new instance of a class
25
+	 *
26
+	 * @param FullyQualifiedName|string $fqcn
27
+	 * @param array                     $arguments
28
+	 * @return mixed
29
+	 */
30
+	public function getNew($fqcn, array $arguments = []);
31 31
 
32 32
 
33
-    /**
34
-     * Used for getting a shared instance of a class
35
-     *
36
-     * @param FullyQualifiedName|string $fqcn
37
-     * @param array                     $arguments
38
-     * @return mixed
39
-     */
40
-    public function getShared($fqcn, array $arguments = []);
33
+	/**
34
+	 * Used for getting a shared instance of a class
35
+	 *
36
+	 * @param FullyQualifiedName|string $fqcn
37
+	 * @param array                     $arguments
38
+	 * @return mixed
39
+	 */
40
+	public function getShared($fqcn, array $arguments = []);
41 41
 
42 42
 
43
-    /**
44
-     * @param FullyQualifiedName|string $fqcn
45
-     * @param mixed                     $object
46
-     * @param array                     $arguments
47
-     * @return bool
48
-     * @throws InvalidArgumentException
49
-     */
50
-    public function share($fqcn, $object, array $arguments = []);
43
+	/**
44
+	 * @param FullyQualifiedName|string $fqcn
45
+	 * @param mixed                     $object
46
+	 * @param array                     $arguments
47
+	 * @return bool
48
+	 * @throws InvalidArgumentException
49
+	 */
50
+	public function share($fqcn, $object, array $arguments = []);
51 51
 
52 52
 
53
-    /**
54
-     * @param FullyQualifiedName|string $fqcn
55
-     * @return bool
56
-     * @throws InvalidArgumentException
57
-     */
58
-    public function remove($fqcn);
53
+	/**
54
+	 * @param FullyQualifiedName|string $fqcn
55
+	 * @return bool
56
+	 * @throws InvalidArgumentException
57
+	 */
58
+	public function remove($fqcn);
59 59
 
60 60
 
61
-    /**
62
-     * calls reset() on loader if method exists
63
-     */
64
-    public function reset();
61
+	/**
62
+	 * calls reset() on loader if method exists
63
+	 */
64
+	public function reset();
65 65
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegFormDependencyHandler.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -7,62 +7,62 @@
 block discarded – undo
7 7
 
8 8
 class RegFormDependencyHandler extends DependencyHandler
9 9
 {
10
-    /**
11
-     * @return void
12
-     */
13
-    public function registerDependencies()
14
-    {
15
-        $reg_form_dependencies = [
16
-            'EventEspresso\core\domain\services\registration\form\v1\RegForm'                => [
17
-                null,
18
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
19
-            ],
20
-            'EventEspresso\core\domain\services\registration\form\v1\RegistrantForm'         => [
21
-                null,
22
-                null,
23
-                null,
24
-                null,
25
-                null,
26
-                'EEM_Event_Question_Group' => EE_Dependency_Map::load_from_cache,
27
-            ],
28
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory' => [
29
-                null,
30
-                'EEM_Answer' => EE_Dependency_Map::load_from_cache,
31
-            ],
32
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionGroup'   => [
33
-                null,
34
-                null,
35
-                null,
36
-                'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory' => EE_Dependency_Map::load_from_cache,
37
-            ],
38
-            'EventEspresso\core\domain\services\registration\form\v1\CountryOptions'         => [
39
-                null,
40
-                'EEM_Answer'  => EE_Dependency_Map::load_from_cache,
41
-                'EEM_Country' => EE_Dependency_Map::load_from_cache,
42
-            ],
43
-            'EventEspresso\core\domain\services\registration\form\v1\StateOptions'           => [
44
-                null,
45
-                'EEM_State' => EE_Dependency_Map::load_from_cache,
46
-            ],
47
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormHandler'         => [
48
-                null,
49
-                'EventEspresso\core\domain\services\registration\form\v1\RegistrantData'         => EE_Dependency_Map::load_from_cache,
50
-                'EventEspresso\core\domain\services\registration\form\v1\RegFormAttendeeFactory' => EE_Dependency_Map::load_from_cache,
51
-                'EE_Registration_Processor'                                                      => EE_Dependency_Map::load_from_cache,
52
-            ],
53
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormInputHandler'    => [
54
-                null,
55
-                null,
56
-                'EEM_Attendee'                                                           => EE_Dependency_Map::load_from_cache,
57
-                'EventEspresso\core\domain\services\registration\form\v1\RegistrantData' => EE_Dependency_Map::load_from_cache,
58
-            ],
59
-            'EventEspresso\core\domain\services\registration\form\v1\RegFormAttendeeFactory' => [
60
-                'EventEspresso\core\services\commands\CommandBus'                        => EE_Dependency_Map::load_from_cache,
61
-                'EventEspresso\core\domain\services\registration\form\v1\RegistrantData' => EE_Dependency_Map::load_from_cache,
62
-            ],
63
-        ];
64
-        foreach ($reg_form_dependencies as $class => $dependencies) {
65
-            $this->dependency_map->registerDependencies($class, $dependencies);
66
-        }
67
-    }
10
+	/**
11
+	 * @return void
12
+	 */
13
+	public function registerDependencies()
14
+	{
15
+		$reg_form_dependencies = [
16
+			'EventEspresso\core\domain\services\registration\form\v1\RegForm'                => [
17
+				null,
18
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
19
+			],
20
+			'EventEspresso\core\domain\services\registration\form\v1\RegistrantForm'         => [
21
+				null,
22
+				null,
23
+				null,
24
+				null,
25
+				null,
26
+				'EEM_Event_Question_Group' => EE_Dependency_Map::load_from_cache,
27
+			],
28
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory' => [
29
+				null,
30
+				'EEM_Answer' => EE_Dependency_Map::load_from_cache,
31
+			],
32
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionGroup'   => [
33
+				null,
34
+				null,
35
+				null,
36
+				'EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory' => EE_Dependency_Map::load_from_cache,
37
+			],
38
+			'EventEspresso\core\domain\services\registration\form\v1\CountryOptions'         => [
39
+				null,
40
+				'EEM_Answer'  => EE_Dependency_Map::load_from_cache,
41
+				'EEM_Country' => EE_Dependency_Map::load_from_cache,
42
+			],
43
+			'EventEspresso\core\domain\services\registration\form\v1\StateOptions'           => [
44
+				null,
45
+				'EEM_State' => EE_Dependency_Map::load_from_cache,
46
+			],
47
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormHandler'         => [
48
+				null,
49
+				'EventEspresso\core\domain\services\registration\form\v1\RegistrantData'         => EE_Dependency_Map::load_from_cache,
50
+				'EventEspresso\core\domain\services\registration\form\v1\RegFormAttendeeFactory' => EE_Dependency_Map::load_from_cache,
51
+				'EE_Registration_Processor'                                                      => EE_Dependency_Map::load_from_cache,
52
+			],
53
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormInputHandler'    => [
54
+				null,
55
+				null,
56
+				'EEM_Attendee'                                                           => EE_Dependency_Map::load_from_cache,
57
+				'EventEspresso\core\domain\services\registration\form\v1\RegistrantData' => EE_Dependency_Map::load_from_cache,
58
+			],
59
+			'EventEspresso\core\domain\services\registration\form\v1\RegFormAttendeeFactory' => [
60
+				'EventEspresso\core\services\commands\CommandBus'                        => EE_Dependency_Map::load_from_cache,
61
+				'EventEspresso\core\domain\services\registration\form\v1\RegistrantData' => EE_Dependency_Map::load_from_cache,
62
+			],
63
+		];
64
+		foreach ($reg_form_dependencies as $class => $dependencies) {
65
+			$this->dependency_map->registerDependencies($class, $dependencies);
66
+		}
67
+	}
68 68
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegFormHandler.php 2 patches
Indentation   +279 added lines, -279 removed lines patch added patch discarded remove patch
@@ -18,310 +18,310 @@
 block discarded – undo
18 18
 class RegFormHandler
19 19
 {
20 20
 
21
-    /**
22
-     * @var EE_Checkout
23
-     */
24
-    public $checkout;
21
+	/**
22
+	 * @var EE_Checkout
23
+	 */
24
+	public $checkout;
25 25
 
26
-    /**
27
-     * @var RegFormInputHandler
28
-     */
29
-    public $input_handler;
26
+	/**
27
+	 * @var RegFormInputHandler
28
+	 */
29
+	public $input_handler;
30 30
 
31
-    /**
32
-     * @var array
33
-     */
34
-    private $non_input_form_sections;
31
+	/**
32
+	 * @var array
33
+	 */
34
+	private $non_input_form_sections;
35 35
 
36
-    /**
37
-     * @var RegFormAttendeeFactory
38
-     */
39
-    private $attendee_factory;
36
+	/**
37
+	 * @var RegFormAttendeeFactory
38
+	 */
39
+	private $attendee_factory;
40 40
 
41
-    /**
42
-     * @var RegistrantData
43
-     */
44
-    private $registrant_data;
41
+	/**
42
+	 * @var RegistrantData
43
+	 */
44
+	private $registrant_data;
45 45
 
46
-    /**
47
-     * @var EE_Registration_Processor
48
-     */
49
-    private $registration_processor;
46
+	/**
47
+	 * @var EE_Registration_Processor
48
+	 */
49
+	private $registration_processor;
50 50
 
51
-    /**
52
-     * @var bool
53
-     */
54
-    private $valid;
51
+	/**
52
+	 * @var bool
53
+	 */
54
+	private $valid;
55 55
 
56 56
 
57
-    /**
58
-     * RegFormHandler constructor.
59
-     */
60
-    public function __construct(
61
-        EE_Checkout $checkout,
62
-        RegistrantData $registrant_data,
63
-        RegFormAttendeeFactory $attendee_factory,
64
-        EE_Registration_Processor $registration_processor
65
-    ) {
66
-        $this->checkout                = $checkout;
67
-        $this->registrant_data         = $registrant_data;
68
-        $this->attendee_factory        = $attendee_factory;
69
-        $this->registration_processor  = $registration_processor;
70
-        // reg form sections that do not contain inputs
71
-        $this->non_input_form_sections = [
72
-            'primary_registrant',
73
-            'additional_attendee_reg_info',
74
-            'spco_copy_attendee_chk',
75
-        ];
76
-        $this->initializeInputHandler();
77
-    }
57
+	/**
58
+	 * RegFormHandler constructor.
59
+	 */
60
+	public function __construct(
61
+		EE_Checkout $checkout,
62
+		RegistrantData $registrant_data,
63
+		RegFormAttendeeFactory $attendee_factory,
64
+		EE_Registration_Processor $registration_processor
65
+	) {
66
+		$this->checkout                = $checkout;
67
+		$this->registrant_data         = $registrant_data;
68
+		$this->attendee_factory        = $attendee_factory;
69
+		$this->registration_processor  = $registration_processor;
70
+		// reg form sections that do not contain inputs
71
+		$this->non_input_form_sections = [
72
+			'primary_registrant',
73
+			'additional_attendee_reg_info',
74
+			'spco_copy_attendee_chk',
75
+		];
76
+		$this->initializeInputHandler();
77
+	}
78 78
 
79 79
 
80
-    private function initializeInputHandler()
81
-    {
82
-        $reg_form = $this->checkout->current_step->reg_form;
83
-        $required_questions = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
84
-        $this->input_handler = LoaderFactory::getShared(
85
-            RegFormInputHandler::class,
86
-            [ $this->checkout->reg_url_link, $required_questions ]
87
-        );
88
-    }
80
+	private function initializeInputHandler()
81
+	{
82
+		$reg_form = $this->checkout->current_step->reg_form;
83
+		$required_questions = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
84
+		$this->input_handler = LoaderFactory::getShared(
85
+			RegFormInputHandler::class,
86
+			[ $this->checkout->reg_url_link, $required_questions ]
87
+		);
88
+	}
89 89
 
90 90
 
91
-    /**
92
-     * @return int
93
-     */
94
-    public function attendeeCount(): int
95
-    {
96
-        return $this->registrant_data->attendeeCount();
97
-    }
91
+	/**
92
+	 * @return int
93
+	 */
94
+	public function attendeeCount(): int
95
+	{
96
+		return $this->registrant_data->attendeeCount();
97
+	}
98 98
 
99 99
 
100
-    /**
101
-     * @return bool
102
-     */
103
-    private function isInvalid(): bool
104
-    {
105
-        $this->valid = false;
106
-        return $this->valid;
107
-    }
100
+	/**
101
+	 * @return bool
102
+	 */
103
+	private function isInvalid(): bool
104
+	{
105
+		$this->valid = false;
106
+		return $this->valid;
107
+	}
108 108
 
109 109
 
110
-    /**
111
-     * @param EE_Registration[] $registrations
112
-     * @param array[][]         $reg_form_data
113
-     * @return bool
114
-     * @throws EntityNotFoundException
115
-     * @throws EE_Error
116
-     * @throws InvalidArgumentException
117
-     * @throws ReflectionException
118
-     * @throws RuntimeException
119
-     * @throws InvalidDataTypeException
120
-     * @throws InvalidInterfaceException
121
-     */
122
-    public function processRegistrations(array $registrations, array $reg_form_data): bool
123
-    {
124
-        // start off optimistic, then trip this to false if anything goes wrong
125
-        $this->valid = true;
126
-        foreach ($registrations as $registration) {
127
-            // verify EE_Registration object
128
-            if (! $this->isValidRegistration($registration)) {
129
-                return $this->isInvalid();
130
-            }
131
-            $reg_url_link = $registration->reg_url_link();
132
-            // reg_url_link exists ?
133
-            if (! $this->isValidRegUrlLink($reg_url_link)) {
134
-                return $this->isInvalid();
135
-            }
136
-            // should this registration be processed during this visit ?
137
-            if (! $this->checkout->visit_allows_processing_of_this_registration($registration)) {
138
-                continue;
139
-            }
140
-            // if NOT revisiting, then let's save the registration now,
141
-            // so that we have a REG_ID to use when generating other objects
142
-            if (! $this->checkout->revisit) {
143
-                $registration->save();
144
-            }
145
-            /**
146
-             * This allows plugins to trigger a fail on processing of a
147
-             * registration for any conditions they may have for it to pass.
148
-             *
149
-             * @var bool if true is returned by the plugin then the registration processing is halted.
150
-             */
151
-            if (
152
-                apply_filters(
153
-                    'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegistrations__bypass',
154
-                    false,
155
-                    $this->registrant_data->attendeeCount(),
156
-                    $registration,
157
-                    $registrations,
158
-                    $reg_form_data,
159
-                    $this
160
-                )
161
-            ) {
162
-                return $this->isInvalid();
163
-            }
110
+	/**
111
+	 * @param EE_Registration[] $registrations
112
+	 * @param array[][]         $reg_form_data
113
+	 * @return bool
114
+	 * @throws EntityNotFoundException
115
+	 * @throws EE_Error
116
+	 * @throws InvalidArgumentException
117
+	 * @throws ReflectionException
118
+	 * @throws RuntimeException
119
+	 * @throws InvalidDataTypeException
120
+	 * @throws InvalidInterfaceException
121
+	 */
122
+	public function processRegistrations(array $registrations, array $reg_form_data): bool
123
+	{
124
+		// start off optimistic, then trip this to false if anything goes wrong
125
+		$this->valid = true;
126
+		foreach ($registrations as $registration) {
127
+			// verify EE_Registration object
128
+			if (! $this->isValidRegistration($registration)) {
129
+				return $this->isInvalid();
130
+			}
131
+			$reg_url_link = $registration->reg_url_link();
132
+			// reg_url_link exists ?
133
+			if (! $this->isValidRegUrlLink($reg_url_link)) {
134
+				return $this->isInvalid();
135
+			}
136
+			// should this registration be processed during this visit ?
137
+			if (! $this->checkout->visit_allows_processing_of_this_registration($registration)) {
138
+				continue;
139
+			}
140
+			// if NOT revisiting, then let's save the registration now,
141
+			// so that we have a REG_ID to use when generating other objects
142
+			if (! $this->checkout->revisit) {
143
+				$registration->save();
144
+			}
145
+			/**
146
+			 * This allows plugins to trigger a fail on processing of a
147
+			 * registration for any conditions they may have for it to pass.
148
+			 *
149
+			 * @var bool if true is returned by the plugin then the registration processing is halted.
150
+			 */
151
+			if (
152
+				apply_filters(
153
+					'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegistrations__bypass',
154
+					false,
155
+					$this->registrant_data->attendeeCount(),
156
+					$registration,
157
+					$registrations,
158
+					$reg_form_data,
159
+					$this
160
+				)
161
+			) {
162
+				return $this->isInvalid();
163
+			}
164 164
 
165
-            // Houston, we have a registration!
166
-            if (! $this->processRegistration($registration, $reg_url_link, $reg_form_data)) {
167
-                return $this->isInvalid();
168
-            }
169
-        }
170
-        return $this->valid;
171
-    }
165
+			// Houston, we have a registration!
166
+			if (! $this->processRegistration($registration, $reg_url_link, $reg_form_data)) {
167
+				return $this->isInvalid();
168
+			}
169
+		}
170
+		return $this->valid;
171
+	}
172 172
 
173 173
 
174
-    /**
175
-     * @param string $reg_url_link
176
-     * @return bool
177
-     */
178
-    private function isValidRegUrlLink(string $reg_url_link): bool
179
-    {
180
-        if (! empty($reg_url_link)) {
181
-            return true;
182
-        }
183
-        EE_Error::add_error(
184
-            esc_html__(
185
-                'An invalid or missing line item ID was encountered while attempting to process the registration form.',
186
-                'event_espresso'
187
-            ),
188
-            __FILE__,
189
-            __FUNCTION__,
190
-            __LINE__
191
-        );
192
-        return false;
193
-    }
174
+	/**
175
+	 * @param string $reg_url_link
176
+	 * @return bool
177
+	 */
178
+	private function isValidRegUrlLink(string $reg_url_link): bool
179
+	{
180
+		if (! empty($reg_url_link)) {
181
+			return true;
182
+		}
183
+		EE_Error::add_error(
184
+			esc_html__(
185
+				'An invalid or missing line item ID was encountered while attempting to process the registration form.',
186
+				'event_espresso'
187
+			),
188
+			__FILE__,
189
+			__FUNCTION__,
190
+			__LINE__
191
+		);
192
+		return false;
193
+	}
194 194
 
195 195
 
196
-    /**
197
-     * @param EE_Registration|null $registration
198
-     * @return bool
199
-     */
200
-    private function isValidRegistration(?EE_Registration $registration): bool
201
-    {
202
-        // verify EE_Registration object
203
-        if ($registration instanceof EE_Registration) {
204
-            return true;
205
-        }
206
-        EE_Error::add_error(
207
-            esc_html__(
208
-                'An invalid Registration object was discovered when attempting to process your registration information.',
209
-                'event_espresso'
210
-            ),
211
-            __FILE__,
212
-            __FUNCTION__,
213
-            __LINE__
214
-        );
215
-        return false;
216
-    }
196
+	/**
197
+	 * @param EE_Registration|null $registration
198
+	 * @return bool
199
+	 */
200
+	private function isValidRegistration(?EE_Registration $registration): bool
201
+	{
202
+		// verify EE_Registration object
203
+		if ($registration instanceof EE_Registration) {
204
+			return true;
205
+		}
206
+		EE_Error::add_error(
207
+			esc_html__(
208
+				'An invalid Registration object was discovered when attempting to process your registration information.',
209
+				'event_espresso'
210
+			),
211
+			__FILE__,
212
+			__FUNCTION__,
213
+			__LINE__
214
+		);
215
+		return false;
216
+	}
217 217
 
218 218
 
219
-    /**
220
-     * @param EE_Registration $registration
221
-     * @param string          $reg_url_link
222
-     * @param array[][]       $reg_form_data
223
-     * @return bool
224
-     * @throws EE_Error
225
-     * @throws ReflectionException
226
-     */
227
-    private function processRegistration(
228
-        EE_Registration $registration,
229
-        string $reg_url_link,
230
-        array $reg_form_data
231
-    ): bool {
232
-        $this->registrant_data->initializeRegistrantData($registration);
233
-        if (! $this->processRegFormData($registration, $reg_url_link, $reg_form_data)) {
234
-            return false;
235
-        }
236
-        // RegFormAttendeeFactory
237
-        if (! $this->attendee_factory->create($registration, $reg_url_link)) {
238
-            return false;
239
-        }
240
-        // at this point, we should have enough details about the registrant to consider the registration
241
-        // NOT incomplete
242
-        $this->registration_processor->toggle_incomplete_registration_status_to_default(
243
-            $registration,
244
-            false,
245
-            new Context(
246
-                'spco_reg_step_attendee_information_process_registrations',
247
-                esc_html__(
248
-                    'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
249
-                    'event_espresso'
250
-                )
251
-            )
252
-        );
253
-        // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
254
-        // abandoned
255
-        $this->checkout->transaction->toggle_failed_transaction_status();
256
-        // if we've gotten this far, then let's save what we have
257
-        $registration->save();
258
-        // add relation between TXN and registration
259
-        $this->associateRegistrationWithTransaction($registration);
260
-        return true;
261
-    }
219
+	/**
220
+	 * @param EE_Registration $registration
221
+	 * @param string          $reg_url_link
222
+	 * @param array[][]       $reg_form_data
223
+	 * @return bool
224
+	 * @throws EE_Error
225
+	 * @throws ReflectionException
226
+	 */
227
+	private function processRegistration(
228
+		EE_Registration $registration,
229
+		string $reg_url_link,
230
+		array $reg_form_data
231
+	): bool {
232
+		$this->registrant_data->initializeRegistrantData($registration);
233
+		if (! $this->processRegFormData($registration, $reg_url_link, $reg_form_data)) {
234
+			return false;
235
+		}
236
+		// RegFormAttendeeFactory
237
+		if (! $this->attendee_factory->create($registration, $reg_url_link)) {
238
+			return false;
239
+		}
240
+		// at this point, we should have enough details about the registrant to consider the registration
241
+		// NOT incomplete
242
+		$this->registration_processor->toggle_incomplete_registration_status_to_default(
243
+			$registration,
244
+			false,
245
+			new Context(
246
+				'spco_reg_step_attendee_information_process_registrations',
247
+				esc_html__(
248
+					'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
249
+					'event_espresso'
250
+				)
251
+			)
252
+		);
253
+		// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
254
+		// abandoned
255
+		$this->checkout->transaction->toggle_failed_transaction_status();
256
+		// if we've gotten this far, then let's save what we have
257
+		$registration->save();
258
+		// add relation between TXN and registration
259
+		$this->associateRegistrationWithTransaction($registration);
260
+		return true;
261
+	}
262 262
 
263 263
 
264
-    /**
265
-     * @param EE_Registration $registration
266
-     * @param string          $reg_url_link
267
-     * @param array           $reg_form_data
268
-     * @return bool
269
-     * @throws EE_Error
270
-     * @throws ReflectionException
271
-     */
272
-    private function processRegFormData(EE_Registration $registration, string $reg_url_link, array $reg_form_data): bool
273
-    {
274
-        if (isset($reg_form_data[ $reg_url_link ])) {
275
-            // do we need to copy basic info from primary attendee ?
276
-            $copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
277
-                                  && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
278
-            $this->registrant_data->setCopyPrimary($copy_primary);
279
-            // filter form input data for this registration
280
-            $reg_form_data[ $reg_url_link ] = (array) apply_filters(
281
-                'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegFormData__registrant_form_data',
282
-                $reg_form_data[ $reg_url_link ],
283
-                $registration
284
-            );
285
-            if (isset($reg_form_data['primary_attendee'])) {
286
-                $primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
287
-                $this->registrant_data->addPrimaryRegistrantDataValue('reg_url_link', $primary_reg_url_link);
288
-                unset($reg_form_data['primary_attendee']);
289
-            }
290
-            // now loop through our array of valid post data && process attendee reg forms
291
-            foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
292
-                if (in_array($form_section, $this->non_input_form_sections, true)) {
293
-                    continue;
294
-                }
295
-                foreach ($form_inputs as $form_input => $input_value) {
296
-                    $input_processed = $this->input_handler->processFormInput(
297
-                        $registration,
298
-                        $reg_url_link,
299
-                        $form_input,
300
-                        $input_value
301
-                    );
302
-                    if (! $input_processed) {
303
-                        return false;
304
-                    }
305
-                }
306
-            }
307
-        }
308
-        return true;
309
-    }
264
+	/**
265
+	 * @param EE_Registration $registration
266
+	 * @param string          $reg_url_link
267
+	 * @param array           $reg_form_data
268
+	 * @return bool
269
+	 * @throws EE_Error
270
+	 * @throws ReflectionException
271
+	 */
272
+	private function processRegFormData(EE_Registration $registration, string $reg_url_link, array $reg_form_data): bool
273
+	{
274
+		if (isset($reg_form_data[ $reg_url_link ])) {
275
+			// do we need to copy basic info from primary attendee ?
276
+			$copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
277
+								  && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
278
+			$this->registrant_data->setCopyPrimary($copy_primary);
279
+			// filter form input data for this registration
280
+			$reg_form_data[ $reg_url_link ] = (array) apply_filters(
281
+				'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegFormData__registrant_form_data',
282
+				$reg_form_data[ $reg_url_link ],
283
+				$registration
284
+			);
285
+			if (isset($reg_form_data['primary_attendee'])) {
286
+				$primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
287
+				$this->registrant_data->addPrimaryRegistrantDataValue('reg_url_link', $primary_reg_url_link);
288
+				unset($reg_form_data['primary_attendee']);
289
+			}
290
+			// now loop through our array of valid post data && process attendee reg forms
291
+			foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
292
+				if (in_array($form_section, $this->non_input_form_sections, true)) {
293
+					continue;
294
+				}
295
+				foreach ($form_inputs as $form_input => $input_value) {
296
+					$input_processed = $this->input_handler->processFormInput(
297
+						$registration,
298
+						$reg_url_link,
299
+						$form_input,
300
+						$input_value
301
+					);
302
+					if (! $input_processed) {
303
+						return false;
304
+					}
305
+				}
306
+			}
307
+		}
308
+		return true;
309
+	}
310 310
 
311 311
 
312
-    /**
313
-     * @param EE_Registration $registration
314
-     * @return void
315
-     * @throws EE_Error
316
-     * @throws InvalidArgumentException
317
-     * @throws ReflectionException
318
-     * @throws InvalidDataTypeException
319
-     * @throws InvalidInterfaceException
320
-     */
321
-    private function associateRegistrationWithTransaction(EE_Registration $registration)
322
-    {
323
-        // add relation to registration
324
-        $this->checkout->transaction->_add_relation_to($registration, 'Registration');
325
-        $this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
326
-    }
312
+	/**
313
+	 * @param EE_Registration $registration
314
+	 * @return void
315
+	 * @throws EE_Error
316
+	 * @throws InvalidArgumentException
317
+	 * @throws ReflectionException
318
+	 * @throws InvalidDataTypeException
319
+	 * @throws InvalidInterfaceException
320
+	 */
321
+	private function associateRegistrationWithTransaction(EE_Registration $registration)
322
+	{
323
+		// add relation to registration
324
+		$this->checkout->transaction->_add_relation_to($registration, 'Registration');
325
+		$this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
326
+	}
327 327
 }
Please login to merge, or discard this patch.
Spacing   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
         $required_questions = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
84 84
         $this->input_handler = LoaderFactory::getShared(
85 85
             RegFormInputHandler::class,
86
-            [ $this->checkout->reg_url_link, $required_questions ]
86
+            [$this->checkout->reg_url_link, $required_questions]
87 87
         );
88 88
     }
89 89
 
@@ -125,21 +125,21 @@  discard block
 block discarded – undo
125 125
         $this->valid = true;
126 126
         foreach ($registrations as $registration) {
127 127
             // verify EE_Registration object
128
-            if (! $this->isValidRegistration($registration)) {
128
+            if ( ! $this->isValidRegistration($registration)) {
129 129
                 return $this->isInvalid();
130 130
             }
131 131
             $reg_url_link = $registration->reg_url_link();
132 132
             // reg_url_link exists ?
133
-            if (! $this->isValidRegUrlLink($reg_url_link)) {
133
+            if ( ! $this->isValidRegUrlLink($reg_url_link)) {
134 134
                 return $this->isInvalid();
135 135
             }
136 136
             // should this registration be processed during this visit ?
137
-            if (! $this->checkout->visit_allows_processing_of_this_registration($registration)) {
137
+            if ( ! $this->checkout->visit_allows_processing_of_this_registration($registration)) {
138 138
                 continue;
139 139
             }
140 140
             // if NOT revisiting, then let's save the registration now,
141 141
             // so that we have a REG_ID to use when generating other objects
142
-            if (! $this->checkout->revisit) {
142
+            if ( ! $this->checkout->revisit) {
143 143
                 $registration->save();
144 144
             }
145 145
             /**
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
             }
164 164
 
165 165
             // Houston, we have a registration!
166
-            if (! $this->processRegistration($registration, $reg_url_link, $reg_form_data)) {
166
+            if ( ! $this->processRegistration($registration, $reg_url_link, $reg_form_data)) {
167 167
                 return $this->isInvalid();
168 168
             }
169 169
         }
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
      */
178 178
     private function isValidRegUrlLink(string $reg_url_link): bool
179 179
     {
180
-        if (! empty($reg_url_link)) {
180
+        if ( ! empty($reg_url_link)) {
181 181
             return true;
182 182
         }
183 183
         EE_Error::add_error(
@@ -230,11 +230,11 @@  discard block
 block discarded – undo
230 230
         array $reg_form_data
231 231
     ): bool {
232 232
         $this->registrant_data->initializeRegistrantData($registration);
233
-        if (! $this->processRegFormData($registration, $reg_url_link, $reg_form_data)) {
233
+        if ( ! $this->processRegFormData($registration, $reg_url_link, $reg_form_data)) {
234 234
             return false;
235 235
         }
236 236
         // RegFormAttendeeFactory
237
-        if (! $this->attendee_factory->create($registration, $reg_url_link)) {
237
+        if ( ! $this->attendee_factory->create($registration, $reg_url_link)) {
238 238
             return false;
239 239
         }
240 240
         // at this point, we should have enough details about the registrant to consider the registration
@@ -271,15 +271,15 @@  discard block
 block discarded – undo
271 271
      */
272 272
     private function processRegFormData(EE_Registration $registration, string $reg_url_link, array $reg_form_data): bool
273 273
     {
274
-        if (isset($reg_form_data[ $reg_url_link ])) {
274
+        if (isset($reg_form_data[$reg_url_link])) {
275 275
             // do we need to copy basic info from primary attendee ?
276
-            $copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
277
-                                  && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
276
+            $copy_primary = isset($reg_form_data[$reg_url_link]['additional_attendee_reg_info'])
277
+                                  && absint($reg_form_data[$reg_url_link]['additional_attendee_reg_info']) === 0;
278 278
             $this->registrant_data->setCopyPrimary($copy_primary);
279 279
             // filter form input data for this registration
280
-            $reg_form_data[ $reg_url_link ] = (array) apply_filters(
280
+            $reg_form_data[$reg_url_link] = (array) apply_filters(
281 281
                 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegFormData__registrant_form_data',
282
-                $reg_form_data[ $reg_url_link ],
282
+                $reg_form_data[$reg_url_link],
283 283
                 $registration
284 284
             );
285 285
             if (isset($reg_form_data['primary_attendee'])) {
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
                 unset($reg_form_data['primary_attendee']);
289 289
             }
290 290
             // now loop through our array of valid post data && process attendee reg forms
291
-            foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
291
+            foreach ($reg_form_data[$reg_url_link] as $form_section => $form_inputs) {
292 292
                 if (in_array($form_section, $this->non_input_form_sections, true)) {
293 293
                     continue;
294 294
                 }
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
                         $form_input,
300 300
                         $input_value
301 301
                     );
302
-                    if (! $input_processed) {
302
+                    if ( ! $input_processed) {
303 303
                         return false;
304 304
                     }
305 305
                 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/CountryOptions.php 2 patches
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -13,109 +13,109 @@
 block discarded – undo
13 13
 
14 14
 class CountryOptions
15 15
 {
16
-    /**
17
-     * the action being performed on the current step
18
-     *
19
-     * @var string
20
-     */
21
-    public $action = '';
16
+	/**
17
+	 * the action being performed on the current step
18
+	 *
19
+	 * @var string
20
+	 */
21
+	public $action = '';
22 22
 
23
-    /**
24
-     * @var EEM_Answer
25
-     */
26
-    public $answer_model;
23
+	/**
24
+	 * @var EEM_Answer
25
+	 */
26
+	public $answer_model;
27 27
 
28
-    /**
29
-     * @var EEM_Country
30
-     */
31
-    public $country_model;
28
+	/**
29
+	 * @var EEM_Country
30
+	 */
31
+	public $country_model;
32 32
 
33
-    /**
34
-     * @var [][]
35
-     */
36
-    private $country_options = [];
33
+	/**
34
+	 * @var [][]
35
+	 */
36
+	private $country_options = [];
37 37
 
38 38
 
39
-    /**
40
-     * CountryOptions constructor.
41
-     *
42
-     * @param string      $action
43
-     * @param EEM_Answer  $answer_model
44
-     * @param EEM_Country $country_model
45
-     */
46
-    public function __construct(string $action, EEM_Answer $answer_model, EEM_Country $country_model)
47
-    {
48
-        $this->action        = $action;
49
-        $this->answer_model  = $answer_model;
50
-        $this->country_model = $country_model;
51
-        add_filter(
52
-            'FHEE__EE_Question__generate_form_input__country_options',
53
-            [$this, 'forLegacyFormInput'],
54
-            10,
55
-            4
56
-        );
57
-    }
39
+	/**
40
+	 * CountryOptions constructor.
41
+	 *
42
+	 * @param string      $action
43
+	 * @param EEM_Answer  $answer_model
44
+	 * @param EEM_Country $country_model
45
+	 */
46
+	public function __construct(string $action, EEM_Answer $answer_model, EEM_Country $country_model)
47
+	{
48
+		$this->action        = $action;
49
+		$this->answer_model  = $answer_model;
50
+		$this->country_model = $country_model;
51
+		add_filter(
52
+			'FHEE__EE_Question__generate_form_input__country_options',
53
+			[$this, 'forLegacyFormInput'],
54
+			10,
55
+			4
56
+		);
57
+	}
58 58
 
59 59
 
60
-    /**
61
-     * Gets the list of countries for the form input
62
-     *
63
-     * @param array|null           $countries_list deprecated prop from an old hook
64
-     * @param EE_Question|null     $question
65
-     * @param EE_Registration|null $registration
66
-     * @param EE_Answer|null       $answer deprecated prop from an old hook
67
-     * @return array 2d keys are country IDs, values are their names
68
-     * @throws EE_Error
69
-     * @throws ReflectionException
70
-     */
71
-    public function forLegacyFormInput(
72
-        array $countries_list = null,
73
-        EE_Question $question = null,
74
-        EE_Registration $registration = null,
75
-        EE_Answer $answer = null
76
-    ): array {
77
-        if (! isset($this->country_options[ $this->action ])) {
78
-            $this->generateLegacyCountryOptions($question, $registration);
79
-        }
80
-        return $this->country_options[ $this->action ];
81
-    }
60
+	/**
61
+	 * Gets the list of countries for the form input
62
+	 *
63
+	 * @param array|null           $countries_list deprecated prop from an old hook
64
+	 * @param EE_Question|null     $question
65
+	 * @param EE_Registration|null $registration
66
+	 * @param EE_Answer|null       $answer deprecated prop from an old hook
67
+	 * @return array 2d keys are country IDs, values are their names
68
+	 * @throws EE_Error
69
+	 * @throws ReflectionException
70
+	 */
71
+	public function forLegacyFormInput(
72
+		array $countries_list = null,
73
+		EE_Question $question = null,
74
+		EE_Registration $registration = null,
75
+		EE_Answer $answer = null
76
+	): array {
77
+		if (! isset($this->country_options[ $this->action ])) {
78
+			$this->generateLegacyCountryOptions($question, $registration);
79
+		}
80
+		return $this->country_options[ $this->action ];
81
+	}
82 82
 
83 83
 
84
-    /**
85
-     * @param EE_Question|null     $question
86
-     * @param EE_Registration|null $registration
87
-     * @throws EE_Error
88
-     * @throws ReflectionException
89
-     */
90
-    private function generateLegacyCountryOptions(EE_Question $question = null, EE_Registration $registration = null)
91
-    {
92
-        // get possibly cached list of countries
93
-        $countries = $this->action === 'process_reg_step'
94
-            ? $this->country_model->get_all_countries()
95
-            : $this->country_model->get_all_active_countries();
96
-        // start with an empty option
97
-        $country_options = ['' => ''];
98
-        if (! empty($countries)) {
99
-            foreach ($countries as $country) {
100
-                if ($country instanceof EE_Country) {
101
-                    $country_options[ $country->ID() ] = $country->name();
102
-                }
103
-            }
104
-        }
105
-        if ($question instanceof EE_Question && $registration instanceof EE_Registration) {
106
-            $answer = $this->answer_model->get_one(
107
-                [['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
108
-            );
109
-        } else {
110
-            $answer = EE_Answer::new_instance();
111
-        }
112
-        $this->country_options[ $this->action ] = apply_filters(
113
-            'FHEE__EventEspresso_core_domain_services_registration_form_v1_CountryOptions__generateLegacyCountryOptions__country_options',
114
-            $country_options,
115
-            $registration,
116
-            $question,
117
-            $answer,
118
-            $this
119
-        );
120
-    }
84
+	/**
85
+	 * @param EE_Question|null     $question
86
+	 * @param EE_Registration|null $registration
87
+	 * @throws EE_Error
88
+	 * @throws ReflectionException
89
+	 */
90
+	private function generateLegacyCountryOptions(EE_Question $question = null, EE_Registration $registration = null)
91
+	{
92
+		// get possibly cached list of countries
93
+		$countries = $this->action === 'process_reg_step'
94
+			? $this->country_model->get_all_countries()
95
+			: $this->country_model->get_all_active_countries();
96
+		// start with an empty option
97
+		$country_options = ['' => ''];
98
+		if (! empty($countries)) {
99
+			foreach ($countries as $country) {
100
+				if ($country instanceof EE_Country) {
101
+					$country_options[ $country->ID() ] = $country->name();
102
+				}
103
+			}
104
+		}
105
+		if ($question instanceof EE_Question && $registration instanceof EE_Registration) {
106
+			$answer = $this->answer_model->get_one(
107
+				[['QST_ID' => $question->ID(), 'REG_ID' => $registration->ID()]]
108
+			);
109
+		} else {
110
+			$answer = EE_Answer::new_instance();
111
+		}
112
+		$this->country_options[ $this->action ] = apply_filters(
113
+			'FHEE__EventEspresso_core_domain_services_registration_form_v1_CountryOptions__generateLegacyCountryOptions__country_options',
114
+			$country_options,
115
+			$registration,
116
+			$question,
117
+			$answer,
118
+			$this
119
+		);
120
+	}
121 121
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -74,10 +74,10 @@  discard block
 block discarded – undo
74 74
         EE_Registration $registration = null,
75 75
         EE_Answer $answer = null
76 76
     ): array {
77
-        if (! isset($this->country_options[ $this->action ])) {
77
+        if ( ! isset($this->country_options[$this->action])) {
78 78
             $this->generateLegacyCountryOptions($question, $registration);
79 79
         }
80
-        return $this->country_options[ $this->action ];
80
+        return $this->country_options[$this->action];
81 81
     }
82 82
 
83 83
 
@@ -95,10 +95,10 @@  discard block
 block discarded – undo
95 95
             : $this->country_model->get_all_active_countries();
96 96
         // start with an empty option
97 97
         $country_options = ['' => ''];
98
-        if (! empty($countries)) {
98
+        if ( ! empty($countries)) {
99 99
             foreach ($countries as $country) {
100 100
                 if ($country instanceof EE_Country) {
101
-                    $country_options[ $country->ID() ] = $country->name();
101
+                    $country_options[$country->ID()] = $country->name();
102 102
                 }
103 103
             }
104 104
         }
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
         } else {
110 110
             $answer = EE_Answer::new_instance();
111 111
         }
112
-        $this->country_options[ $this->action ] = apply_filters(
112
+        $this->country_options[$this->action] = apply_filters(
113 113
             'FHEE__EventEspresso_core_domain_services_registration_form_v1_CountryOptions__generateLegacyCountryOptions__country_options',
114 114
             $country_options,
115 115
             $registration,
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/AutoCopyAttendeeInfoForm.php 2 patches
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -8,21 +8,21 @@
 block discarded – undo
8 8
 class AutoCopyAttendeeInfoForm extends EE_Form_Section_HTML
9 9
 {
10 10
 
11
-    /**
12
-     * CopyAttendeeInfoForm constructor.
13
-     */
14
-    public function __construct(string $slug)
15
-    {
16
-        parent::__construct(
17
-            EEH_Template::locate_template(
18
-                SPCO_REG_STEPS_PATH . $slug . '/_auto_copy_attendee_info.template.php',
19
-                apply_filters(
20
-                    'FHEE__EventEspresso_core_domain_services_registration_form_v1_AutoCopyAttendeeInfoForm__construct__template_args',
21
-                    []
22
-                ),
23
-                true,
24
-                true
25
-            )
26
-        );
27
-    }
11
+	/**
12
+	 * CopyAttendeeInfoForm constructor.
13
+	 */
14
+	public function __construct(string $slug)
15
+	{
16
+		parent::__construct(
17
+			EEH_Template::locate_template(
18
+				SPCO_REG_STEPS_PATH . $slug . '/_auto_copy_attendee_info.template.php',
19
+				apply_filters(
20
+					'FHEE__EventEspresso_core_domain_services_registration_form_v1_AutoCopyAttendeeInfoForm__construct__template_args',
21
+					[]
22
+				),
23
+				true,
24
+				true
25
+			)
26
+		);
27
+	}
28 28
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -15,7 +15,7 @@
 block discarded – undo
15 15
     {
16 16
         parent::__construct(
17 17
             EEH_Template::locate_template(
18
-                SPCO_REG_STEPS_PATH . $slug . '/_auto_copy_attendee_info.template.php',
18
+                SPCO_REG_STEPS_PATH.$slug.'/_auto_copy_attendee_info.template.php',
19 19
                 apply_filters(
20 20
                     'FHEE__EventEspresso_core_domain_services_registration_form_v1_AutoCopyAttendeeInfoForm__construct__template_args',
21 21
                     []
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegistrantForm.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
         $form_args = [];
87 87
         // verify that registration has valid event
88 88
         if ($registration->event() instanceof EE_Event) {
89
-            $field_name      = 'Event_Question_Group.' . $this->event_question_group_model->fieldNameForContext(
89
+            $field_name      = 'Event_Question_Group.'.$this->event_question_group_model->fieldNameForContext(
90 90
                 $registration->is_primary_registrant()
91 91
             );
92 92
             $question_groups = $registration->event()->question_groups(
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
             if ($question_groups) {
107 107
                 // array of params to pass to parent constructor
108 108
                 $form_args = [
109
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
109
+                    'html_id'         => 'ee-registration-'.$registration->reg_url_link(),
110 110
                     'html_class'      => 'ee-reg-form-attendee-dv',
111 111
                     'html_style'      => $this->reg_step->checkout->admin_request
112 112
                         ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
                             RegFormQuestionGroup::class,
133 133
                             [$registration, $question_group, $this->reg_step]
134 134
                         );
135
-                        $form_args['subsections'][ $question_group->identifier() ] = apply_filters(
135
+                        $form_args['subsections'][$question_group->identifier()] = apply_filters(
136 136
                             'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_group_reg_form',
137 137
                             $question_group_reg_form,
138 138
                             $registration,
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
         $attendee_nmbr++;
171 171
 
172 172
         // Increment the reg forms number if form is valid.
173
-        if (! empty($form_args)) {
173
+        if ( ! empty($form_args)) {
174 174
             $this->has_questions = true;
175 175
         }
176 176
 
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
         // generate hidden input
189 189
         return new EE_Hidden_Input(
190 190
             [
191
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
191
+                'html_id' => 'additional-attendee-reg-info-'.$registration->reg_url_link(),
192 192
                 'default' => true,
193 193
             ]
194 194
         );
Please login to merge, or discard this patch.
Indentation   +193 added lines, -193 removed lines patch added patch discarded remove patch
@@ -17,197 +17,197 @@
 block discarded – undo
17 17
 
18 18
 class RegistrantForm extends EE_Form_Section_Proper
19 19
 {
20
-    /**
21
-     * @var EE_SPCO_Reg_Step_Attendee_Information
22
-     */
23
-    public $reg_step;
24
-
25
-    /**
26
-     * @var EEM_Event_Question_Group
27
-     */
28
-    public $event_question_group_model;
29
-
30
-    /**
31
-     * @var bool
32
-     */
33
-    private $has_questions = false;
34
-
35
-
36
-    /**
37
-     * RegistrantForm constructor.
38
-     *
39
-     * @param EE_Registration          $registration
40
-     * @param bool                     $copy_attendee_info
41
-     * @param callable                 $enablePrintCopyInfo
42
-     * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
43
-     * @param EEM_Event_Question_Group $event_question_group_model
44
-     * @throws EE_Error
45
-     * @throws ReflectionException
46
-     */
47
-    public function __construct(
48
-        EE_Registration $registration,
49
-        bool $copy_attendee_info,
50
-        callable $enablePrintCopyInfo,
51
-        EE_SPCO_Reg_Step_Attendee_Information $reg_step,
52
-        EEM_Event_Question_Group $event_question_group_model
53
-    ) {
54
-        $this->reg_step = $reg_step;
55
-        $this->event_question_group_model = $event_question_group_model;
56
-        parent::__construct(
57
-            $this->generateFormArgs($registration, $copy_attendee_info, $enablePrintCopyInfo)
58
-        );
59
-    }
60
-
61
-
62
-    /**
63
-     * @return bool
64
-     */
65
-    public function hasQuestions(): bool
66
-    {
67
-        return $this->has_questions;
68
-    }
69
-
70
-
71
-    /**
72
-     * @param EE_Registration $registration
73
-     * @param bool            $copy_attendee_info
74
-     * @param callable        $enablePrintCopyInfo
75
-     * @return array
76
-     * @throws EE_Error
77
-     * @throws ReflectionException
78
-     */
79
-    private function generateFormArgs(
80
-        EE_Registration $registration,
81
-        bool $copy_attendee_info,
82
-        callable $enablePrintCopyInfo
83
-    ): array {
84
-        static $attendee_nmbr = 1;
85
-        $form_args = [];
86
-        // verify that registration has valid event
87
-        if ($registration->event() instanceof EE_Event) {
88
-            $field_name      = 'Event_Question_Group.' . $this->event_question_group_model->fieldNameForContext(
89
-                $registration->is_primary_registrant()
90
-            );
91
-            $question_groups = $registration->event()->question_groups(
92
-                apply_filters(
93
-                    'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_groups_query_parameters',
94
-                    [
95
-                        [
96
-                            'Event.EVT_ID' => $registration->event()->ID(),
97
-                            $field_name    => true,
98
-                            'QSG_deleted'  => false,
99
-                        ],
100
-                        'order_by' => ['QSG_order' => 'ASC'],
101
-                    ],
102
-                    $registration,
103
-                    $this
104
-                )
105
-            );
106
-            if ($question_groups) {
107
-                // array of params to pass to parent constructor
108
-                $form_args = [
109
-                    'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
110
-                    'html_class'      => 'ee-reg-form-attendee-dv',
111
-                    'html_style'      => $this->reg_step->checkout->admin_request
112
-                        ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
113
-                        : '',
114
-                    'subsections'     => [],
115
-                    'layout_strategy' => new EE_Fieldset_Section_Layout(
116
-                        [
117
-                            'legend_class' => 'spco-attendee-lgnd',
118
-                            'legend_text'  => sprintf(
119
-                                esc_html_x(
120
-                                    'Attendee %d',
121
-                                    'Attendee 123',
122
-                                    'event_espresso'
123
-                                ),
124
-                                $attendee_nmbr
125
-                            ),
126
-                        ]
127
-                    ),
128
-                ];
129
-                foreach ($question_groups as $question_group) {
130
-                    if ($question_group instanceof EE_Question_Group) {
131
-                        $question_group_reg_form = LoaderFactory::getNew(
132
-                            RegFormQuestionGroup::class,
133
-                            [$registration, $question_group, $this->reg_step]
134
-                        );
135
-                        $form_args['subsections'][ $question_group->identifier() ] = apply_filters(
136
-                            'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_group_reg_form',
137
-                            $question_group_reg_form,
138
-                            $registration,
139
-                            $question_group,
140
-                            $this
141
-                        );
142
-                    }
143
-                }
144
-                // add hidden input
145
-                $form_args['subsections']['additional_attendee_reg_info'] = $this->additionalAttendeeRegInfoInput(
146
-                    $registration
147
-                );
148
-
149
-                // If we have question groups for additional attendees, then display the copy options
150
-                $printCopyInfo = apply_filters(
151
-                    'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__printCopyInfo',
152
-                    $attendee_nmbr > 1 && $copy_attendee_info,
153
-                    $attendee_nmbr,
154
-                    $registration,
155
-                    $this
156
-                );
157
-                if ($printCopyInfo) {
158
-                    $enablePrintCopyInfo();
159
-                }
160
-
161
-
162
-                if ($registration->is_primary_registrant()) {
163
-                    // generate hidden input
164
-                    $form_args['subsections']['primary_registrant'] = $this->additionalPrimaryRegistrantInputs(
165
-                        $registration
166
-                    );
167
-                }
168
-            }
169
-        }
170
-        $attendee_nmbr++;
171
-
172
-        // Increment the reg forms number if form is valid.
173
-        if (! empty($form_args)) {
174
-            $this->has_questions = true;
175
-        }
176
-
177
-        return $form_args;
178
-    }
179
-
180
-
181
-    /**
182
-     * @param EE_Registration $registration
183
-     * @return EE_Form_Input_Base
184
-     * @throws EE_Error
185
-     */
186
-    private function additionalAttendeeRegInfoInput(EE_Registration $registration)
187
-    {
188
-        // generate hidden input
189
-        return new EE_Hidden_Input(
190
-            [
191
-                'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
192
-                'default' => true,
193
-            ]
194
-        );
195
-    }
196
-
197
-
198
-    /**
199
-     * @param EE_Registration $registration
200
-     * @return    EE_Form_Input_Base
201
-     * @throws EE_Error
202
-     */
203
-    private function additionalPrimaryRegistrantInputs(EE_Registration $registration)
204
-    {
205
-        // generate hidden input
206
-        return new EE_Hidden_Input(
207
-            [
208
-                'html_id' => 'primary_registrant',
209
-                'default' => $registration->reg_url_link(),
210
-            ]
211
-        );
212
-    }
20
+	/**
21
+	 * @var EE_SPCO_Reg_Step_Attendee_Information
22
+	 */
23
+	public $reg_step;
24
+
25
+	/**
26
+	 * @var EEM_Event_Question_Group
27
+	 */
28
+	public $event_question_group_model;
29
+
30
+	/**
31
+	 * @var bool
32
+	 */
33
+	private $has_questions = false;
34
+
35
+
36
+	/**
37
+	 * RegistrantForm constructor.
38
+	 *
39
+	 * @param EE_Registration          $registration
40
+	 * @param bool                     $copy_attendee_info
41
+	 * @param callable                 $enablePrintCopyInfo
42
+	 * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
43
+	 * @param EEM_Event_Question_Group $event_question_group_model
44
+	 * @throws EE_Error
45
+	 * @throws ReflectionException
46
+	 */
47
+	public function __construct(
48
+		EE_Registration $registration,
49
+		bool $copy_attendee_info,
50
+		callable $enablePrintCopyInfo,
51
+		EE_SPCO_Reg_Step_Attendee_Information $reg_step,
52
+		EEM_Event_Question_Group $event_question_group_model
53
+	) {
54
+		$this->reg_step = $reg_step;
55
+		$this->event_question_group_model = $event_question_group_model;
56
+		parent::__construct(
57
+			$this->generateFormArgs($registration, $copy_attendee_info, $enablePrintCopyInfo)
58
+		);
59
+	}
60
+
61
+
62
+	/**
63
+	 * @return bool
64
+	 */
65
+	public function hasQuestions(): bool
66
+	{
67
+		return $this->has_questions;
68
+	}
69
+
70
+
71
+	/**
72
+	 * @param EE_Registration $registration
73
+	 * @param bool            $copy_attendee_info
74
+	 * @param callable        $enablePrintCopyInfo
75
+	 * @return array
76
+	 * @throws EE_Error
77
+	 * @throws ReflectionException
78
+	 */
79
+	private function generateFormArgs(
80
+		EE_Registration $registration,
81
+		bool $copy_attendee_info,
82
+		callable $enablePrintCopyInfo
83
+	): array {
84
+		static $attendee_nmbr = 1;
85
+		$form_args = [];
86
+		// verify that registration has valid event
87
+		if ($registration->event() instanceof EE_Event) {
88
+			$field_name      = 'Event_Question_Group.' . $this->event_question_group_model->fieldNameForContext(
89
+				$registration->is_primary_registrant()
90
+			);
91
+			$question_groups = $registration->event()->question_groups(
92
+				apply_filters(
93
+					'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_groups_query_parameters',
94
+					[
95
+						[
96
+							'Event.EVT_ID' => $registration->event()->ID(),
97
+							$field_name    => true,
98
+							'QSG_deleted'  => false,
99
+						],
100
+						'order_by' => ['QSG_order' => 'ASC'],
101
+					],
102
+					$registration,
103
+					$this
104
+				)
105
+			);
106
+			if ($question_groups) {
107
+				// array of params to pass to parent constructor
108
+				$form_args = [
109
+					'html_id'         => 'ee-registration-' . $registration->reg_url_link(),
110
+					'html_class'      => 'ee-reg-form-attendee-dv',
111
+					'html_style'      => $this->reg_step->checkout->admin_request
112
+						? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;'
113
+						: '',
114
+					'subsections'     => [],
115
+					'layout_strategy' => new EE_Fieldset_Section_Layout(
116
+						[
117
+							'legend_class' => 'spco-attendee-lgnd',
118
+							'legend_text'  => sprintf(
119
+								esc_html_x(
120
+									'Attendee %d',
121
+									'Attendee 123',
122
+									'event_espresso'
123
+								),
124
+								$attendee_nmbr
125
+							),
126
+						]
127
+					),
128
+				];
129
+				foreach ($question_groups as $question_group) {
130
+					if ($question_group instanceof EE_Question_Group) {
131
+						$question_group_reg_form = LoaderFactory::getNew(
132
+							RegFormQuestionGroup::class,
133
+							[$registration, $question_group, $this->reg_step]
134
+						);
135
+						$form_args['subsections'][ $question_group->identifier() ] = apply_filters(
136
+							'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_group_reg_form',
137
+							$question_group_reg_form,
138
+							$registration,
139
+							$question_group,
140
+							$this
141
+						);
142
+					}
143
+				}
144
+				// add hidden input
145
+				$form_args['subsections']['additional_attendee_reg_info'] = $this->additionalAttendeeRegInfoInput(
146
+					$registration
147
+				);
148
+
149
+				// If we have question groups for additional attendees, then display the copy options
150
+				$printCopyInfo = apply_filters(
151
+					'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__printCopyInfo',
152
+					$attendee_nmbr > 1 && $copy_attendee_info,
153
+					$attendee_nmbr,
154
+					$registration,
155
+					$this
156
+				);
157
+				if ($printCopyInfo) {
158
+					$enablePrintCopyInfo();
159
+				}
160
+
161
+
162
+				if ($registration->is_primary_registrant()) {
163
+					// generate hidden input
164
+					$form_args['subsections']['primary_registrant'] = $this->additionalPrimaryRegistrantInputs(
165
+						$registration
166
+					);
167
+				}
168
+			}
169
+		}
170
+		$attendee_nmbr++;
171
+
172
+		// Increment the reg forms number if form is valid.
173
+		if (! empty($form_args)) {
174
+			$this->has_questions = true;
175
+		}
176
+
177
+		return $form_args;
178
+	}
179
+
180
+
181
+	/**
182
+	 * @param EE_Registration $registration
183
+	 * @return EE_Form_Input_Base
184
+	 * @throws EE_Error
185
+	 */
186
+	private function additionalAttendeeRegInfoInput(EE_Registration $registration)
187
+	{
188
+		// generate hidden input
189
+		return new EE_Hidden_Input(
190
+			[
191
+				'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(),
192
+				'default' => true,
193
+			]
194
+		);
195
+	}
196
+
197
+
198
+	/**
199
+	 * @param EE_Registration $registration
200
+	 * @return    EE_Form_Input_Base
201
+	 * @throws EE_Error
202
+	 */
203
+	private function additionalPrimaryRegistrantInputs(EE_Registration $registration)
204
+	{
205
+		// generate hidden input
206
+		return new EE_Hidden_Input(
207
+			[
208
+				'html_id' => 'primary_registrant',
209
+				'default' => $registration->reg_url_link(),
210
+			]
211
+		);
212
+	}
213 213
 }
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/StateOptions.php 2 patches
Indentation   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -12,97 +12,97 @@
 block discarded – undo
12 12
 
13 13
 class StateOptions
14 14
 {
15
-    /**
16
-     * the action being performed on the current step
17
-     *
18
-     * @var string
19
-     */
20
-    public $action = '';
15
+	/**
16
+	 * the action being performed on the current step
17
+	 *
18
+	 * @var string
19
+	 */
20
+	public $action = '';
21 21
 
22
-    /**
23
-     * @var EEM_State
24
-     */
25
-    public $state_model;
22
+	/**
23
+	 * @var EEM_State
24
+	 */
25
+	public $state_model;
26 26
 
27
-    /**
28
-     * @var [][]
29
-     */
30
-    private $state_options = [];
27
+	/**
28
+	 * @var [][]
29
+	 */
30
+	private $state_options = [];
31 31
 
32 32
 
33
-    /**
34
-     * CountryOptions constructor.
35
-     *
36
-     * @param string    $action
37
-     * @param EEM_State $state_model
38
-     */
39
-    public function __construct(string $action, EEM_State $state_model)
40
-    {
41
-        $this->action      = $action;
42
-        $this->state_model = $state_model;
43
-        add_filter(
44
-            'FHEE__EE_Question__generate_form_input__state_options',
45
-            [$this, 'forLegacyFormInput'],
46
-            10,
47
-            4
48
-        );
49
-    }
33
+	/**
34
+	 * CountryOptions constructor.
35
+	 *
36
+	 * @param string    $action
37
+	 * @param EEM_State $state_model
38
+	 */
39
+	public function __construct(string $action, EEM_State $state_model)
40
+	{
41
+		$this->action      = $action;
42
+		$this->state_model = $state_model;
43
+		add_filter(
44
+			'FHEE__EE_Question__generate_form_input__state_options',
45
+			[$this, 'forLegacyFormInput'],
46
+			10,
47
+			4
48
+		);
49
+	}
50 50
 
51 51
 
52
-    /**
53
-     * Gets the list of states for the form input
54
-     *
55
-     * @param array|null           $states_list deprecated prop from an old hook
56
-     * @param EE_Question|null     $question
57
-     * @param EE_Registration|null $registration
58
-     * @param EE_Answer|null       $answer
59
-     * @return array 2d keys are state IDs, values are their names
60
-     * @throws EE_Error
61
-     * @throws ReflectionException
62
-     */
63
-    public function forLegacyFormInput(
64
-        array $states_list = null,
65
-        EE_Question $question = null,
66
-        EE_Registration $registration = null,
67
-        EE_Answer $answer = null
68
-    ): array {
69
-        if (! isset($this->state_options[ $this->action ])) {
70
-            $this->generateLegacyStateOptions($question, $registration, $answer);
71
-        }
72
-        return $this->state_options[ $this->action ];
73
-    }
52
+	/**
53
+	 * Gets the list of states for the form input
54
+	 *
55
+	 * @param array|null           $states_list deprecated prop from an old hook
56
+	 * @param EE_Question|null     $question
57
+	 * @param EE_Registration|null $registration
58
+	 * @param EE_Answer|null       $answer
59
+	 * @return array 2d keys are state IDs, values are their names
60
+	 * @throws EE_Error
61
+	 * @throws ReflectionException
62
+	 */
63
+	public function forLegacyFormInput(
64
+		array $states_list = null,
65
+		EE_Question $question = null,
66
+		EE_Registration $registration = null,
67
+		EE_Answer $answer = null
68
+	): array {
69
+		if (! isset($this->state_options[ $this->action ])) {
70
+			$this->generateLegacyStateOptions($question, $registration, $answer);
71
+		}
72
+		return $this->state_options[ $this->action ];
73
+	}
74 74
 
75 75
 
76
-    /**
77
-     * @param EE_Question|null     $question
78
-     * @param EE_Registration|null $registration
79
-     * @param EE_Answer|null       $answer
80
-     * @throws EE_Error
81
-     * @throws ReflectionException
82
-     */
83
-    private function generateLegacyStateOptions(
84
-        EE_Question $question = null,
85
-        EE_Registration $registration = null,
86
-        EE_Answer $answer = null
87
-    ) {
88
-        $state_options = ['' => ['' => '']];
89
-        $states        = $this->action === 'process_reg_step'
90
-            ? $this->state_model->get_all_states()
91
-            : $this->state_model->get_all_active_states();
92
-        if (! empty($states)) {
93
-            foreach ($states as $state) {
94
-                if ($state instanceof EE_State) {
95
-                    $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
96
-                }
97
-            }
98
-        }
99
-        $this->state_options[ $this->action ] = apply_filters(
100
-            'FHEE__EventEspresso_core_domain_services_registration_form_v1_StateOptions__generateLegacyStateOptions__state_options',
101
-            $state_options,
102
-            $registration,
103
-            $question,
104
-            $answer,
105
-            $this
106
-        );
107
-    }
76
+	/**
77
+	 * @param EE_Question|null     $question
78
+	 * @param EE_Registration|null $registration
79
+	 * @param EE_Answer|null       $answer
80
+	 * @throws EE_Error
81
+	 * @throws ReflectionException
82
+	 */
83
+	private function generateLegacyStateOptions(
84
+		EE_Question $question = null,
85
+		EE_Registration $registration = null,
86
+		EE_Answer $answer = null
87
+	) {
88
+		$state_options = ['' => ['' => '']];
89
+		$states        = $this->action === 'process_reg_step'
90
+			? $this->state_model->get_all_states()
91
+			: $this->state_model->get_all_active_states();
92
+		if (! empty($states)) {
93
+			foreach ($states as $state) {
94
+				if ($state instanceof EE_State) {
95
+					$state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
96
+				}
97
+			}
98
+		}
99
+		$this->state_options[ $this->action ] = apply_filters(
100
+			'FHEE__EventEspresso_core_domain_services_registration_form_v1_StateOptions__generateLegacyStateOptions__state_options',
101
+			$state_options,
102
+			$registration,
103
+			$question,
104
+			$answer,
105
+			$this
106
+		);
107
+	}
108 108
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -66,10 +66,10 @@  discard block
 block discarded – undo
66 66
         EE_Registration $registration = null,
67 67
         EE_Answer $answer = null
68 68
     ): array {
69
-        if (! isset($this->state_options[ $this->action ])) {
69
+        if ( ! isset($this->state_options[$this->action])) {
70 70
             $this->generateLegacyStateOptions($question, $registration, $answer);
71 71
         }
72
-        return $this->state_options[ $this->action ];
72
+        return $this->state_options[$this->action];
73 73
     }
74 74
 
75 75
 
@@ -89,14 +89,14 @@  discard block
 block discarded – undo
89 89
         $states        = $this->action === 'process_reg_step'
90 90
             ? $this->state_model->get_all_states()
91 91
             : $this->state_model->get_all_active_states();
92
-        if (! empty($states)) {
92
+        if ( ! empty($states)) {
93 93
             foreach ($states as $state) {
94 94
                 if ($state instanceof EE_State) {
95
-                    $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name();
95
+                    $state_options[$state->country()->name()][$state->ID()] = $state->name();
96 96
                 }
97 97
             }
98 98
         }
99
-        $this->state_options[ $this->action ] = apply_filters(
99
+        $this->state_options[$this->action] = apply_filters(
100 100
             'FHEE__EventEspresso_core_domain_services_registration_form_v1_StateOptions__generateLegacyStateOptions__state_options',
101 101
             $state_options,
102 102
             $registration,
Please login to merge, or discard this patch.