Completed
Branch BUG/php-8-issues (c4ea88)
by
unknown
11:33 queued 09:09
created
core/libraries/rest_api/controllers/model/Base.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
      */
51 51
     public function getModelVersionInfo()
52 52
     {
53
-        if (! $this->model_version_info) {
53
+        if ( ! $this->model_version_info) {
54 54
             throw new EE_Error(
55 55
                 sprintf(
56 56
                     esc_html__(
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
      */
96 96
     protected function validateModel($model_name)
97 97
     {
98
-        if (! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
98
+        if ( ! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
99 99
             throw new RestException(
100 100
                 'endpoint_parsing_error',
101 101
                 sprintf(
Please login to merge, or discard this patch.
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -18,95 +18,95 @@
 block discarded – undo
18 18
  */
19 19
 class Base extends Controller_Base
20 20
 {
21
-    /**
22
-     * Holds reference to the model version info, which knows the requested version
23
-     *
24
-     * @var ModelVersionInfo
25
-     */
26
-    protected $model_version_info;
21
+	/**
22
+	 * Holds reference to the model version info, which knows the requested version
23
+	 *
24
+	 * @var ModelVersionInfo
25
+	 */
26
+	protected $model_version_info;
27 27
 
28 28
 
29 29
 
30
-    /**
31
-     * Sets the version the user requested
32
-     *
33
-     * @param string $version eg '4.8'
34
-     */
35
-    public function setRequestedVersion($version)
36
-    {
37
-        parent::setRequestedVersion($version);
38
-        $this->model_version_info = new ModelVersionInfo($version);
39
-    }
30
+	/**
31
+	 * Sets the version the user requested
32
+	 *
33
+	 * @param string $version eg '4.8'
34
+	 */
35
+	public function setRequestedVersion($version)
36
+	{
37
+		parent::setRequestedVersion($version);
38
+		$this->model_version_info = new ModelVersionInfo($version);
39
+	}
40 40
 
41 41
 
42 42
 
43
-    /**
44
-     * Gets the object that should be used for getting any info from the models,
45
-     * because it's takes the requested and current core version into account
46
-     *
47
-     * @return \EventEspresso\core\libraries\rest_api\ModelVersionInfo
48
-     * @throws EE_Error
49
-     */
50
-    public function getModelVersionInfo()
51
-    {
52
-        if (! $this->model_version_info) {
53
-            throw new EE_Error(
54
-                sprintf(
55
-                    esc_html__(
56
-                        'Cannot use model version info before setting the requested version in the controller',
57
-                        'event_espresso'
58
-                    )
59
-                )
60
-            );
61
-        }
62
-        return $this->model_version_info;
63
-    }
43
+	/**
44
+	 * Gets the object that should be used for getting any info from the models,
45
+	 * because it's takes the requested and current core version into account
46
+	 *
47
+	 * @return \EventEspresso\core\libraries\rest_api\ModelVersionInfo
48
+	 * @throws EE_Error
49
+	 */
50
+	public function getModelVersionInfo()
51
+	{
52
+		if (! $this->model_version_info) {
53
+			throw new EE_Error(
54
+				sprintf(
55
+					esc_html__(
56
+						'Cannot use model version info before setting the requested version in the controller',
57
+						'event_espresso'
58
+					)
59
+				)
60
+			);
61
+		}
62
+		return $this->model_version_info;
63
+	}
64 64
 
65 65
 
66 66
 
67
-    /**
68
-     * Determines if $object is of one of the classes of $classes. Similar to
69
-     * in_array(), except this checks if $object is a subclass of the classnames provided
70
-     * in $classnames
71
-     *
72
-     * @param object $object
73
-     * @param array  $classnames
74
-     * @return boolean
75
-     */
76
-    public function isSubclassOfOne($object, $classnames)
77
-    {
78
-        foreach ($classnames as $classname) {
79
-            if (is_a($object, $classname)) {
80
-                return true;
81
-            }
82
-        }
83
-        return false;
84
-    }
67
+	/**
68
+	 * Determines if $object is of one of the classes of $classes. Similar to
69
+	 * in_array(), except this checks if $object is a subclass of the classnames provided
70
+	 * in $classnames
71
+	 *
72
+	 * @param object $object
73
+	 * @param array  $classnames
74
+	 * @return boolean
75
+	 */
76
+	public function isSubclassOfOne($object, $classnames)
77
+	{
78
+		foreach ($classnames as $classname) {
79
+			if (is_a($object, $classname)) {
80
+				return true;
81
+			}
82
+		}
83
+		return false;
84
+	}
85 85
 
86
-    /**
87
-     * Verifies the model name provided was valid. If so, returns the model (as an object). Otherwise, throws an
88
-     * exception. Must be called after `setRequestedVersion()`.
89
-     * @since 4.9.76.p
90
-     * @param $model_name
91
-     * @return EEM_Base
92
-     * @throws EE_Error
93
-     * @throws RestException
94
-     */
95
-    protected function validateModel($model_name)
96
-    {
97
-        if (! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
98
-            throw new RestException(
99
-                'endpoint_parsing_error',
100
-                sprintf(
101
-                    esc_html__(
102
-                        'There is no model for endpoint %s. Please contact event espresso support',
103
-                        'event_espresso'
104
-                    ),
105
-                    $model_name
106
-                )
107
-            );
108
-        }
109
-        return $this->getModelVersionInfo()->loadModel($model_name);
110
-    }
86
+	/**
87
+	 * Verifies the model name provided was valid. If so, returns the model (as an object). Otherwise, throws an
88
+	 * exception. Must be called after `setRequestedVersion()`.
89
+	 * @since 4.9.76.p
90
+	 * @param $model_name
91
+	 * @return EEM_Base
92
+	 * @throws EE_Error
93
+	 * @throws RestException
94
+	 */
95
+	protected function validateModel($model_name)
96
+	{
97
+		if (! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
98
+			throw new RestException(
99
+				'endpoint_parsing_error',
100
+				sprintf(
101
+					esc_html__(
102
+						'There is no model for endpoint %s. Please contact event espresso support',
103
+						'event_espresso'
104
+					),
105
+					$model_name
106
+				)
107
+			);
108
+		}
109
+		return $this->getModelVersionInfo()->loadModel($model_name);
110
+	}
111 111
 }
112 112
 // End of file Base.php
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/model/Read.php 2 patches
Spacing   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
             LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
87 87
         try {
88 88
             $controller->setRequestedVersion($version);
89
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
89
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
90 90
                 return $controller->sendResponse(
91 91
                     new WP_Error(
92 92
                         'endpoint_parsing_error',
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
             LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
129 129
         try {
130 130
             $controller->setRequestedVersion($version);
131
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
131
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
132 132
                 return [];
133 133
             }
134 134
             // get the model for this version
@@ -192,11 +192,11 @@  discard block
 block discarded – undo
192 192
      */
193 193
     protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema)
194 194
     {
195
-        if (isset($schema['properties'][ $field_name ]['default'])) {
196
-            if (is_array($schema['properties'][ $field_name ]['default'])) {
197
-                foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
195
+        if (isset($schema['properties'][$field_name]['default'])) {
196
+            if (is_array($schema['properties'][$field_name]['default'])) {
197
+                foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
198 198
                     if ($default_key === 'raw') {
199
-                        $schema['properties'][ $field_name ]['default'][ $default_key ] =
199
+                        $schema['properties'][$field_name]['default'][$default_key] =
200 200
                             ModelDataTranslator::prepareFieldValueForJson(
201 201
                                 $field,
202 202
                                 $default_value,
@@ -205,9 +205,9 @@  discard block
 block discarded – undo
205 205
                     }
206 206
                 }
207 207
             } else {
208
-                $schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
208
+                $schema['properties'][$field_name]['default'] = ModelDataTranslator::prepareFieldValueForJson(
209 209
                     $field,
210
-                    $schema['properties'][ $field_name ]['default'],
210
+                    $schema['properties'][$field_name]['default'],
211 211
                     $this->getModelVersionInfo()->requestedVersion()
212 212
                 );
213 213
             }
@@ -229,9 +229,9 @@  discard block
 block discarded – undo
229 229
     protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema)
230 230
     {
231 231
         if ($field instanceof EE_Datetime_Field) {
232
-            $schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
232
+            $schema['properties'][$field_name.'_gmt'] = $field->getSchema();
233 233
             // modify the description
234
-            $schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
234
+            $schema['properties'][$field_name.'_gmt']['description'] = sprintf(
235 235
                 esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
236 236
                 wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
237 237
             );
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
             LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
281 281
         try {
282 282
             $controller->setRequestedVersion($version);
283
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
283
+            if ( ! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
284 284
                 return $controller->sendResponse(
285 285
                     new WP_Error(
286 286
                         'endpoint_parsing_error',
@@ -360,7 +360,7 @@  discard block
 block discarded – undo
360 360
     public function getEntitiesFromModel($model, $request)
361 361
     {
362 362
         $query_params = $this->createModelQueryParams($model, $request->get_params());
363
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
363
+        if ( ! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
364 364
             $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
365 365
             throw new RestException(
366 366
                 sprintf('rest_%s_cannot_list', $model_name_plural),
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
                 ['status' => 403]
373 373
             );
374 374
         }
375
-        if (! $request->get_header('no_rest_headers')) {
375
+        if ( ! $request->get_header('no_rest_headers')) {
376 376
             $this->setHeadersFromQueryParams($model, $query_params);
377 377
         }
378 378
         /** @type array $results */
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
         $context       = $this->validateContext($request->get_param('caps'));
414 414
         $model         = $relation->get_this_model();
415 415
         $related_model = $relation->get_other_model();
416
-        if (! isset($primary_model_query_params[0])) {
416
+        if ( ! isset($primary_model_query_params[0])) {
417 417
             $primary_model_query_params[0] = [];
418 418
         }
419 419
         // check if they can access the 1st model object
@@ -477,13 +477,13 @@  discard block
 block discarded – undo
477 477
         );
478 478
         $query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
479 479
         foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
480
-            $query_params[0][ $relation->get_this_model()->get_this_model_name()
480
+            $query_params[0][$relation->get_this_model()->get_this_model_name()
481 481
                               . '.'
482
-                              . $where_condition_key ] = $where_condition_value;
482
+                              . $where_condition_key] = $where_condition_value;
483 483
         }
484 484
         $query_params['default_where_conditions'] = 'none';
485 485
         $query_params['caps']                     = $context;
486
-        if (! $request->get_header('no_rest_headers')) {
486
+        if ( ! $request->get_header('no_rest_headers')) {
487 487
             $this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
488 488
         }
489 489
         /** @type array $results */
@@ -503,7 +503,7 @@  discard block
 block discarded – undo
503 503
                     $result,
504 504
                     $request
505 505
                 );
506
-                $joined_result     = array_merge($join_model_result, $nice_result);
506
+                $joined_result = array_merge($join_model_result, $nice_result);
507 507
                 // but keep the meta stuff from the main model
508 508
                 if (isset($nice_result['meta'])) {
509 509
                     $joined_result['meta'] = $nice_result['meta'];
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
      */
536 536
     public function getEntitiesFromRelation($id, $relation, $request)
537 537
     {
538
-        if (! $relation->get_this_model()->has_primary_key_field()) {
538
+        if ( ! $relation->get_this_model()->has_primary_key_field()) {
539 539
             throw new EE_Error(
540 540
                 sprintf(
541 541
                     esc_html__(
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
             Capabilities::getMissingPermissionsString($model, $query_params['caps'])
583 583
         );
584 584
         // normally the limit to a 2-part array, where the 2nd item is the limit
585
-        if (! isset($query_params['limit'])) {
585
+        if ( ! isset($query_params['limit'])) {
586 586
             $query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
587 587
         }
588 588
         if (is_array($query_params['limit'])) {
@@ -621,7 +621,7 @@  discard block
 block discarded – undo
621 621
      */
622 622
     public function createEntityFromWpdbResult($model, $db_row, $rest_request, $deprecated = null)
623 623
     {
624
-        if (! $rest_request instanceof WP_REST_Request) {
624
+        if ( ! $rest_request instanceof WP_REST_Request) {
625 625
             // ok so this was called in the old style, where the 3rd arg was
626 626
             // $include, and the 4th arg was $context
627 627
             // now setup the request just to avoid fatal errors, although we won't be able
@@ -698,7 +698,7 @@  discard block
 block discarded – undo
698 698
             $rest_request,
699 699
             $this
700 700
         );
701
-        if (! $current_user_full_access_to_entity) {
701
+        if ( ! $current_user_full_access_to_entity) {
702 702
             $result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
703 703
                 $entity_array,
704 704
                 $model,
@@ -733,7 +733,7 @@  discard block
 block discarded – undo
733 733
      */
734 734
     protected function addProtectedProperty(EEM_Base $model, $results_so_far, $protected)
735 735
     {
736
-        if (! $model->hasPassword() || ! $protected) {
736
+        if ( ! $model->hasPassword() || ! $protected) {
737 737
             return $results_so_far;
738 738
         }
739 739
         $password_field  = $model->getPasswordField();
@@ -782,8 +782,8 @@  discard block
 block discarded – undo
782 782
         if ($do_chevy_shuffle) {
783 783
             global $post;
784 784
             $old_post = $post;
785
-            $post     = get_post($result[ $model->primary_key_name() ]);
786
-            if (! $post instanceof WP_Post) {
785
+            $post     = get_post($result[$model->primary_key_name()]);
786
+            if ( ! $post instanceof WP_Post) {
787 787
                 // well that's weird, because $result is what we JUST fetched from the database
788 788
                 throw new RestException(
789 789
                     'error_fetching_post_from_database_results',
@@ -793,7 +793,7 @@  discard block
 block discarded – undo
793 793
                     )
794 794
                 );
795 795
             }
796
-            $model_object_classname          = 'EE_' . $model->get_this_model_name();
796
+            $model_object_classname          = 'EE_'.$model->get_this_model_name();
797 797
             $post->{$model_object_classname} = EE_Registry::instance()->load_class(
798 798
                 $model_object_classname,
799 799
                 $result,
@@ -804,14 +804,14 @@  discard block
 block discarded – undo
804 804
         foreach ($result as $field_name => $field_value) {
805 805
             $field_obj = $model->field_settings_for($field_name);
806 806
             if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
807
-                unset($result[ $field_name ]);
807
+                unset($result[$field_name]);
808 808
             } elseif (
809 809
                 $this->isSubclassOfOne(
810 810
                     $field_obj,
811 811
                     $this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
812 812
                 )
813 813
             ) {
814
-                $result[ $field_name ] = [
814
+                $result[$field_name] = [
815 815
                     'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
816 816
                     'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
817 817
                 ];
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
                     $this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
822 822
                 )
823 823
             ) {
824
-                $result[ $field_name ] = [
824
+                $result[$field_name] = [
825 825
                     'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
826 826
                     'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
827 827
                 ];
@@ -852,10 +852,10 @@  discard block
 block discarded – undo
852 852
                         $this->getModelVersionInfo()->requestedVersion()
853 853
                     );
854 854
                 }
855
-                $result[ $field_name . '_gmt' ] = $gmt_date;
856
-                $result[ $field_name ]          = $local_date;
855
+                $result[$field_name.'_gmt'] = $gmt_date;
856
+                $result[$field_name]          = $local_date;
857 857
             } else {
858
-                $result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
858
+                $result[$field_name] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
859 859
             }
860 860
         }
861 861
         if ($do_chevy_shuffle) {
@@ -910,7 +910,7 @@  discard block
 block discarded – undo
910 910
     protected function addExtraFields(EEM_Base $model, $db_row, $entity_array)
911 911
     {
912 912
         if ($model instanceof EEM_CPT_Base) {
913
-            $entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
913
+            $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
914 914
         }
915 915
         return $entity_array;
916 916
     }
@@ -937,7 +937,7 @@  discard block
 block discarded – undo
937 937
                     'href' => $this->getVersionedLinkTo(
938 938
                         EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
939 939
                         . '/'
940
-                        . $entity_array[ $model->primary_key_name() ]
940
+                        . $entity_array[$model->primary_key_name()]
941 941
                     ),
942 942
                 ],
943 943
             ];
@@ -954,12 +954,12 @@  discard block
 block discarded – undo
954 954
             foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
955 955
                 $related_model_part                                                      =
956 956
                     Read::getRelatedEntityName($relation_name, $relation_obj);
957
-                $links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = [
957
+                $links[EED_Core_Rest_Api::ee_api_link_namespace.$related_model_part] = [
958 958
                     [
959 959
                         'href'   => $this->getVersionedLinkTo(
960 960
                             EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
961 961
                             . '/'
962
-                            . $entity_array[ $model->primary_key_name() ]
962
+                            . $entity_array[$model->primary_key_name()]
963 963
                             . '/'
964 964
                             . $related_model_part
965 965
                         ),
@@ -993,12 +993,12 @@  discard block
 block discarded – undo
993 993
         $included_items_protected = false
994 994
     ) {
995 995
         // if $db_row not included, hope the entity array has what we need
996
-        if (! $db_row) {
996
+        if ( ! $db_row) {
997 997
             $db_row = $entity_array;
998 998
         }
999 999
         $relation_settings = $this->getModelVersionInfo()->relationSettings($model);
1000 1000
         foreach ($relation_settings as $relation_name => $relation_obj) {
1001
-            $related_fields_to_include   = $this->explodeAndGetItemsPrefixedWith(
1001
+            $related_fields_to_include = $this->explodeAndGetItemsPrefixedWith(
1002 1002
                 $rest_request->get_param('include'),
1003 1003
                 $relation_name
1004 1004
             );
@@ -1026,7 +1026,7 @@  discard block
 block discarded – undo
1026 1026
                         $model->deduce_fields_n_values_from_cols_n_values($db_row)
1027 1027
                     )
1028 1028
                 );
1029
-                if (! $included_items_protected) {
1029
+                if ( ! $included_items_protected) {
1030 1030
                     try {
1031 1031
                         $related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1032 1032
                             $primary_model_query_params,
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
                             ? null
1048 1048
                             : [];
1049 1049
                 }
1050
-                $entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1050
+                $entity_array[Read::getRelatedEntityName($relation_name, $relation_obj)] = $related_results;
1051 1051
             }
1052 1052
         }
1053 1053
         return $entity_array;
@@ -1131,13 +1131,13 @@  discard block
 block discarded – undo
1131 1131
                 $schema = $this->fields_calculator->getJsonSchemaForModel($model);
1132 1132
                 if (
1133 1133
                     $row_is_protected
1134
-                    && isset($schema['properties'][ $field_to_calculate ]['protected'])
1135
-                    && $schema['properties'][ $field_to_calculate ]['protected']
1134
+                    && isset($schema['properties'][$field_to_calculate]['protected'])
1135
+                    && $schema['properties'][$field_to_calculate]['protected']
1136 1136
                 ) {
1137 1137
                     $calculated_value   = null;
1138 1138
                     $protected_fields[] = $field_to_calculate;
1139
-                    if ($schema['properties'][ $field_to_calculate ]['type']) {
1140
-                        switch ($schema['properties'][ $field_to_calculate ]['type']) {
1139
+                    if ($schema['properties'][$field_to_calculate]['type']) {
1140
+                        switch ($schema['properties'][$field_to_calculate]['type']) {
1141 1141
                             case 'boolean':
1142 1142
                                 $calculated_value = false;
1143 1143
                                 break;
@@ -1252,7 +1252,7 @@  discard block
 block discarded – undo
1252 1252
      */
1253 1253
     public function validateContext($context)
1254 1254
     {
1255
-        if (! $context) {
1255
+        if ( ! $context) {
1256 1256
             $context = EEM_Base::caps_read;
1257 1257
         }
1258 1258
         $valid_contexts = EEM_Base::valid_cap_contexts();
@@ -1277,7 +1277,7 @@  discard block
 block discarded – undo
1277 1277
             EEM_Base::default_where_conditions_minimum_all,
1278 1278
             EEM_Base::default_where_conditions_minimum_others,
1279 1279
         ];
1280
-        if (! $default_query_params) {
1280
+        if ( ! $default_query_params) {
1281 1281
             $default_query_params = EEM_Base::default_where_conditions_all;
1282 1282
         }
1283 1283
         if (
@@ -1363,14 +1363,14 @@  discard block
 block discarded – undo
1363 1363
         }
1364 1364
         if (isset($query_params['limit'])) {
1365 1365
             // limit should be either a string like '23' or '23,43', or an array with two items in it
1366
-            if (! is_array($query_params['limit'])) {
1366
+            if ( ! is_array($query_params['limit'])) {
1367 1367
                 $limit_array = explode(',', (string) $query_params['limit']);
1368 1368
             } else {
1369 1369
                 $limit_array = $query_params['limit'];
1370 1370
             }
1371 1371
             $sanitized_limit = [];
1372 1372
             foreach ($limit_array as $limit_part) {
1373
-                if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1373
+                if ($this->debug_mode && ( ! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1374 1374
                     throw new EE_Error(
1375 1375
                         sprintf(
1376 1376
                             esc_html__(
@@ -1428,7 +1428,7 @@  discard block
 block discarded – undo
1428 1428
     {
1429 1429
         $model_ready_query_params = [];
1430 1430
         foreach ($query_params as $key => $value) {
1431
-            $model_ready_query_params[ $key ] = is_array($value)
1431
+            $model_ready_query_params[$key] = is_array($value)
1432 1432
                 ? $this->prepareRestQueryParamsKeyForModels($model, $value)
1433 1433
                 : $value;
1434 1434
         }
@@ -1447,9 +1447,9 @@  discard block
 block discarded – undo
1447 1447
         $model_ready_query_params = [];
1448 1448
         foreach ($query_params as $key => $value) {
1449 1449
             if (is_array($value)) {
1450
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1450
+                $model_ready_query_params[$key] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1451 1451
             } else {
1452
-                $model_ready_query_params[ $key ] = $value;
1452
+                $model_ready_query_params[$key] = $value;
1453 1453
             }
1454 1454
         }
1455 1455
         return $model_ready_query_params;
@@ -1481,17 +1481,17 @@  discard block
 block discarded – undo
1481 1481
         foreach ($exploded_contents as $item) {
1482 1482
             $item = trim($item);
1483 1483
             // if no prefix was provided, so we look for items with no "." in them
1484
-            if (! $prefix) {
1484
+            if ( ! $prefix) {
1485 1485
                 // does this item have a period?
1486 1486
                 if (strpos($item, '.') === false) {
1487 1487
                     // if not, then its what we're looking for
1488 1488
                     $contents_with_prefix[] = $item;
1489 1489
                 }
1490
-            } elseif (strpos($item, $prefix . '.') === 0) {
1490
+            } elseif (strpos($item, $prefix.'.') === 0) {
1491 1491
                 // this item has the prefix and a period, grab it
1492 1492
                 $contents_with_prefix[] = substr(
1493 1493
                     $item,
1494
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1494
+                    strpos($item, $prefix.'.') + strlen($prefix.'.')
1495 1495
                 );
1496 1496
             } elseif ($item === $prefix) {
1497 1497
                 // this item is JUST the prefix
@@ -1533,9 +1533,9 @@  discard block
 block discarded – undo
1533 1533
         if ($model_name) {
1534 1534
             foreach ($includes as $field_to_include) {
1535 1535
                 $field_to_include = trim($field_to_include);
1536
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1536
+                if (strpos($field_to_include, $model_name.'.') === 0) {
1537 1537
                     // found the model name at the exact start
1538
-                    $field_sans_model_name         = str_replace($model_name . '.', '', $field_to_include);
1538
+                    $field_sans_model_name         = str_replace($model_name.'.', '', $field_to_include);
1539 1539
                     $extracted_fields_to_include[] = $field_sans_model_name;
1540 1540
                 } elseif ($field_to_include == $model_name) {
1541 1541
                     $extracted_fields_to_include[] = '*';
@@ -1578,7 +1578,7 @@  discard block
 block discarded – undo
1578 1578
         $restricted_query_params['caps'] = $context;
1579 1579
         $this->setDebugInfo('model query params', $restricted_query_params);
1580 1580
         $model_rows = $model->get_all_wpdb_results($restricted_query_params);
1581
-        if (! empty($model_rows)) {
1581
+        if ( ! empty($model_rows)) {
1582 1582
             return $this->createEntityFromWpdbResult(
1583 1583
                 $model,
1584 1584
                 reset($model_rows),
@@ -1590,7 +1590,7 @@  discard block
 block discarded – undo
1590 1590
             if ($model->exists($query_params)) {
1591 1591
                 // you got shafted- it existed but we didn't want to tell you!
1592 1592
                 throw new RestException(
1593
-                    'rest_user_cannot_' . $context,
1593
+                    'rest_user_cannot_'.$context,
1594 1594
                     sprintf(
1595 1595
                         esc_html__('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1596 1596
                         $context,
@@ -1644,14 +1644,14 @@  discard block
 block discarded – undo
1644 1644
         // if this entity requires a password, they better give it and it better be right!
1645 1645
         if (
1646 1646
             $model->hasPassword()
1647
-            && $model_row[ $model->getPasswordField()->get_qualified_column() ] !== ''
1647
+            && $model_row[$model->getPasswordField()->get_qualified_column()] !== ''
1648 1648
         ) {
1649 1649
             if (empty($request['password'])) {
1650 1650
                 throw new RestPasswordRequiredException();
1651 1651
             }
1652 1652
             if (
1653 1653
                 ! hash_equals(
1654
-                    $model_row[ $model->getPasswordField()->get_qualified_column() ],
1654
+                    $model_row[$model->getPasswordField()->get_qualified_column()],
1655 1655
                     $request['password']
1656 1656
                 )
1657 1657
             ) {
@@ -1665,12 +1665,12 @@  discard block
 block discarded – undo
1665 1665
             $password_supplied = $request->get_param('password');
1666 1666
             if (empty($password_supplied)) {
1667 1667
                 $query_params['exclude_protected'] = true;
1668
-                if (! $model->exists($query_params)) {
1668
+                if ( ! $model->exists($query_params)) {
1669 1669
                     throw new RestPasswordRequiredException();
1670 1670
                 }
1671 1671
             } else {
1672
-                $query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1673
-                if (! $model->exists($query_params)) {
1672
+                $query_params[0][$model->modelChainAndPassword()] = $password_supplied;
1673
+                if ( ! $model->exists($query_params)) {
1674 1674
                     throw new RestPasswordIncorrectException();
1675 1675
                 }
1676 1676
             }
Please login to merge, or discard this patch.
Indentation   +1625 added lines, -1625 removed lines patch added patch discarded remove patch
@@ -49,1629 +49,1629 @@
 block discarded – undo
49 49
  */
50 50
 class Read extends Base
51 51
 {
52
-    /**
53
-     * @var CalculatedModelFields
54
-     */
55
-    protected $fields_calculator;
56
-
57
-
58
-    /**
59
-     * Read constructor.
60
-     *
61
-     * @param CalculatedModelFields $fields_calculator
62
-     */
63
-    public function __construct(CalculatedModelFields $fields_calculator)
64
-    {
65
-        parent::__construct();
66
-        $this->fields_calculator = $fields_calculator;
67
-    }
68
-
69
-
70
-    /**
71
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
72
-     *
73
-     * @param WP_REST_Request $request
74
-     * @param string          $version
75
-     * @param string          $model_name
76
-     * @return WP_REST_Response|WP_Error
77
-     * @throws InvalidArgumentException
78
-     * @throws InvalidDataTypeException
79
-     * @throws InvalidInterfaceException
80
-     */
81
-    public static function handleRequestGetAll(WP_REST_Request $request, $version, $model_name)
82
-    {
83
-        $controller =
84
-            LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
85
-        try {
86
-            $controller->setRequestedVersion($version);
87
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
88
-                return $controller->sendResponse(
89
-                    new WP_Error(
90
-                        'endpoint_parsing_error',
91
-                        sprintf(
92
-                            esc_html__(
93
-                                'There is no model for endpoint %s. Please contact event espresso support',
94
-                                'event_espresso'
95
-                            ),
96
-                            $model_name
97
-                        )
98
-                    )
99
-                );
100
-            }
101
-            return $controller->sendResponse(
102
-                $controller->getEntitiesFromModel(
103
-                    $controller->getModelVersionInfo()->loadModel($model_name),
104
-                    $request
105
-                )
106
-            );
107
-        } catch (Exception $e) {
108
-            return $controller->sendResponse($e);
109
-        }
110
-    }
111
-
112
-
113
-    /**
114
-     * Prepares and returns schema for any OPTIONS request.
115
-     *
116
-     * @param string $version    The API endpoint version being used.
117
-     * @param string $model_name Something like `Event` or `Registration`
118
-     * @return array
119
-     * @throws InvalidArgumentException
120
-     * @throws InvalidDataTypeException
121
-     * @throws InvalidInterfaceException
122
-     */
123
-    public static function handleSchemaRequest($version, $model_name)
124
-    {
125
-        $controller =
126
-            LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
127
-        try {
128
-            $controller->setRequestedVersion($version);
129
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
130
-                return [];
131
-            }
132
-            // get the model for this version
133
-            $model        = $controller->getModelVersionInfo()->loadModel($model_name);
134
-            $model_schema = new JsonModelSchema(
135
-                $model,
136
-                LoaderFactory::getLoader()->getShared('EventEspresso\core\libraries\rest_api\CalculatedModelFields')
137
-            );
138
-            return $model_schema->getModelSchemaForRelations(
139
-                $controller->getModelVersionInfo()->relationSettings($model),
140
-                $controller->customizeSchemaForRestResponse(
141
-                    $model,
142
-                    $model_schema->getModelSchemaForFields(
143
-                        $controller->getModelVersionInfo()->fieldsOnModelInThisVersion($model),
144
-                        $model_schema->getInitialSchemaStructure()
145
-                    )
146
-                )
147
-            );
148
-        } catch (Exception $e) {
149
-            return [];
150
-        }
151
-    }
152
-
153
-
154
-    /**
155
-     * This loops through each field in the given schema for the model and does the following:
156
-     * - add any extra fields that are REST API specific and related to existing fields.
157
-     * - transform default values into the correct format for a REST API response.
158
-     *
159
-     * @param EEM_Base $model
160
-     * @param array    $schema
161
-     * @return array  The final schema.
162
-     * @throws EE_Error
163
-     * @throws EE_Error
164
-     */
165
-    protected function customizeSchemaForRestResponse(EEM_Base $model, array $schema)
166
-    {
167
-        foreach ($this->getModelVersionInfo()->fieldsOnModelInThisVersion($model) as $field_name => $field) {
168
-            $schema = $this->translateDefaultsForRestResponse(
169
-                $field_name,
170
-                $field,
171
-                $this->maybeAddExtraFieldsToSchema($field_name, $field, $schema)
172
-            );
173
-        }
174
-        return $schema;
175
-    }
176
-
177
-
178
-    /**
179
-     * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
180
-     * response.
181
-     *
182
-     * @param                      $field_name
183
-     * @param EE_Model_Field_Base  $field
184
-     * @param array                $schema
185
-     * @return array
186
-     * @throws RestException  if a default value has a PHP object, which we should never do
187
-     *                                  (but if we did, let's know about it ASAP, so let the exception bubble up)
188
-     * @throws EE_Error
189
-     *
190
-     */
191
-    protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema)
192
-    {
193
-        if (isset($schema['properties'][ $field_name ]['default'])) {
194
-            if (is_array($schema['properties'][ $field_name ]['default'])) {
195
-                foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
196
-                    if ($default_key === 'raw') {
197
-                        $schema['properties'][ $field_name ]['default'][ $default_key ] =
198
-                            ModelDataTranslator::prepareFieldValueForJson(
199
-                                $field,
200
-                                $default_value,
201
-                                $this->getModelVersionInfo()->requestedVersion()
202
-                            );
203
-                    }
204
-                }
205
-            } else {
206
-                $schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
207
-                    $field,
208
-                    $schema['properties'][ $field_name ]['default'],
209
-                    $this->getModelVersionInfo()->requestedVersion()
210
-                );
211
-            }
212
-        }
213
-        return $schema;
214
-    }
215
-
216
-
217
-    /**
218
-     * Adds additional fields to the schema
219
-     * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
220
-     * needs to be added to the schema.
221
-     *
222
-     * @param                      $field_name
223
-     * @param EE_Model_Field_Base  $field
224
-     * @param array                $schema
225
-     * @return array
226
-     */
227
-    protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema)
228
-    {
229
-        if ($field instanceof EE_Datetime_Field) {
230
-            $schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
231
-            // modify the description
232
-            $schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
233
-                esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
234
-                wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
235
-            );
236
-        }
237
-        return $schema;
238
-    }
239
-
240
-
241
-    /**
242
-     * Used to figure out the route from the request when a `WP_REST_Request` object is not available
243
-     *
244
-     * @return string
245
-     */
246
-    protected function getRouteFromRequest()
247
-    {
248
-        if (
249
-            isset($GLOBALS['wp'])
250
-            && $GLOBALS['wp'] instanceof WP
251
-            && isset($GLOBALS['wp']->query_vars['rest_route'])
252
-        ) {
253
-            return $GLOBALS['wp']->query_vars['rest_route'];
254
-        } else {
255
-            /** @var RequestInterface $request */
256
-            $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
257
-            return $request->serverParamIsSet('PATH_INFO')
258
-                ? $request->getServerParam('PATH_INFO')
259
-                : '/';
260
-        }
261
-    }
262
-
263
-
264
-    /**
265
-     * Gets a single entity related to the model indicated in the path and its id
266
-     *
267
-     * @param WP_REST_Request $request
268
-     * @param string          $version
269
-     * @param string          $model_name
270
-     * @return WP_REST_Response|WP_Error
271
-     * @throws InvalidDataTypeException
272
-     * @throws InvalidInterfaceException
273
-     * @throws InvalidArgumentException
274
-     */
275
-    public static function handleRequestGetOne(WP_REST_Request $request, $version, $model_name)
276
-    {
277
-        $controller =
278
-            LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
279
-        try {
280
-            $controller->setRequestedVersion($version);
281
-            if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
282
-                return $controller->sendResponse(
283
-                    new WP_Error(
284
-                        'endpoint_parsing_error',
285
-                        sprintf(
286
-                            esc_html__(
287
-                                'There is no model for endpoint %s. Please contact event espresso support',
288
-                                'event_espresso'
289
-                            ),
290
-                            $model_name
291
-                        )
292
-                    )
293
-                );
294
-            }
295
-            return $controller->sendResponse(
296
-                $controller->getEntityFromModel(
297
-                    $controller->getModelVersionInfo()->loadModel($model_name),
298
-                    $request
299
-                )
300
-            );
301
-        } catch (Exception $e) {
302
-            return $controller->sendResponse($e);
303
-        }
304
-    }
305
-
306
-
307
-    /**
308
-     * Gets all the related entities (or if its a belongs-to relation just the one)
309
-     * to the item with the given id
310
-     *
311
-     * @param WP_REST_Request $request
312
-     * @param string          $version
313
-     * @param string          $model_name
314
-     * @param string          $related_model_name
315
-     * @return WP_REST_Response|WP_Error
316
-     * @throws InvalidDataTypeException
317
-     * @throws InvalidInterfaceException
318
-     * @throws InvalidArgumentException
319
-     */
320
-    public static function handleRequestGetRelated(
321
-        WP_REST_Request $request,
322
-        $version,
323
-        $model_name,
324
-        $related_model_name
325
-    ) {
326
-        $controller =
327
-            LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
328
-        try {
329
-            $controller->setRequestedVersion($version);
330
-            $main_model = $controller->validateModel($model_name);
331
-            $controller->validateModel($related_model_name);
332
-            return $controller->sendResponse(
333
-                $controller->getEntitiesFromRelation(
334
-                    $request->get_param('id'),
335
-                    $main_model->related_settings_for($related_model_name),
336
-                    $request
337
-                )
338
-            );
339
-        } catch (Exception $e) {
340
-            return $controller->sendResponse($e);
341
-        }
342
-    }
343
-
344
-
345
-    /**
346
-     * Gets a collection for the given model and filters
347
-     *
348
-     * @param EEM_Base        $model
349
-     * @param WP_REST_Request $request
350
-     * @return array
351
-     * @throws EE_Error
352
-     * @throws InvalidArgumentException
353
-     * @throws InvalidDataTypeException
354
-     * @throws InvalidInterfaceException
355
-     * @throws ReflectionException
356
-     * @throws RestException
357
-     */
358
-    public function getEntitiesFromModel($model, $request)
359
-    {
360
-        $query_params = $this->createModelQueryParams($model, $request->get_params());
361
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
362
-            $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
363
-            throw new RestException(
364
-                sprintf('rest_%s_cannot_list', $model_name_plural),
365
-                sprintf(
366
-                    esc_html__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
367
-                    $model_name_plural,
368
-                    Capabilities::getMissingPermissionsString($model, $query_params['caps'])
369
-                ),
370
-                ['status' => 403]
371
-            );
372
-        }
373
-        if (! $request->get_header('no_rest_headers')) {
374
-            $this->setHeadersFromQueryParams($model, $query_params);
375
-        }
376
-        /** @type array $results */
377
-        $results      = $model->get_all_wpdb_results($query_params);
378
-        $nice_results = [];
379
-        foreach ($results as $result) {
380
-            $nice_results[] = $this->createEntityFromWpdbResult(
381
-                $model,
382
-                $result,
383
-                $request
384
-            );
385
-        }
386
-        return $nice_results;
387
-    }
388
-
389
-
390
-    /**
391
-     * Gets the collection for given relation object
392
-     * The same as Read::get_entities_from_model(), except if the relation
393
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
394
-     * the join-model-object into the results
395
-     *
396
-     * @param array                  $primary_model_query_params  query params for finding the item from which
397
-     *                                                            relations will be based
398
-     * @param EE_Model_Relation_Base $relation
399
-     * @param WP_REST_Request        $request
400
-     * @return array
401
-     * @throws EE_Error
402
-     * @throws InvalidArgumentException
403
-     * @throws InvalidDataTypeException
404
-     * @throws InvalidInterfaceException
405
-     * @throws ReflectionException
406
-     * @throws RestException
407
-     * @throws ModelConfigurationException
408
-     */
409
-    protected function getEntitiesFromRelationUsingModelQueryParams($primary_model_query_params, $relation, $request)
410
-    {
411
-        $context       = $this->validateContext($request->get_param('caps'));
412
-        $model         = $relation->get_this_model();
413
-        $related_model = $relation->get_other_model();
414
-        if (! isset($primary_model_query_params[0])) {
415
-            $primary_model_query_params[0] = [];
416
-        }
417
-        // check if they can access the 1st model object
418
-        $primary_model_query_params = [
419
-            0       => $primary_model_query_params[0],
420
-            'limit' => 1,
421
-        ];
422
-        if ($model instanceof EEM_Soft_Delete_Base) {
423
-            $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included(
424
-                $primary_model_query_params
425
-            );
426
-        }
427
-        $restricted_query_params          = $primary_model_query_params;
428
-        $restricted_query_params['caps']  = $context;
429
-        $restricted_query_params['limit'] = 1;
430
-        $this->setDebugInfo('main model query params', $restricted_query_params);
431
-        $this->setDebugInfo('missing caps', Capabilities::getMissingPermissionsString($related_model, $context));
432
-        $primary_model_rows = $model->get_all_wpdb_results($restricted_query_params);
433
-        $primary_model_row  = null;
434
-        if (is_array($primary_model_rows)) {
435
-            $primary_model_row = reset($primary_model_rows);
436
-        }
437
-        if (
438
-            ! (
439
-                $primary_model_row
440
-                && Capabilities::currentUserHasPartialAccessTo($related_model, $context)
441
-            )
442
-        ) {
443
-            if ($relation instanceof EE_Belongs_To_Relation) {
444
-                $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
445
-            } else {
446
-                $related_model_name_maybe_plural = EEH_Inflector::pluralize_and_lower(
447
-                    $related_model->get_this_model_name()
448
-                );
449
-            }
450
-            throw new RestException(
451
-                sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
452
-                sprintf(
453
-                    esc_html__(
454
-                        'Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
455
-                        'event_espresso'
456
-                    ),
457
-                    $related_model_name_maybe_plural,
458
-                    $relation->get_this_model()->get_this_model_name(),
459
-                    implode(
460
-                        ',',
461
-                        array_keys(
462
-                            Capabilities::getMissingPermissions($related_model, $context)
463
-                        )
464
-                    )
465
-                ),
466
-                ['status' => 403]
467
-            );
468
-        }
469
-
470
-        $this->checkPassword(
471
-            $model,
472
-            $primary_model_row,
473
-            $restricted_query_params,
474
-            $request
475
-        );
476
-        $query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
477
-        foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
478
-            $query_params[0][ $relation->get_this_model()->get_this_model_name()
479
-                              . '.'
480
-                              . $where_condition_key ] = $where_condition_value;
481
-        }
482
-        $query_params['default_where_conditions'] = 'none';
483
-        $query_params['caps']                     = $context;
484
-        if (! $request->get_header('no_rest_headers')) {
485
-            $this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
486
-        }
487
-        /** @type array $results */
488
-        $results      = $relation->get_other_model()->get_all_wpdb_results($query_params);
489
-        $nice_results = [];
490
-        foreach ($results as $result) {
491
-            $nice_result = $this->createEntityFromWpdbResult(
492
-                $relation->get_other_model(),
493
-                $result,
494
-                $request
495
-            );
496
-            if ($relation instanceof EE_HABTM_Relation) {
497
-                // put the unusual stuff (properties from the HABTM relation) first, and make sure
498
-                // if there are conflicts we prefer the properties from the main model
499
-                $join_model_result = $this->createEntityFromWpdbResult(
500
-                    $relation->get_join_model(),
501
-                    $result,
502
-                    $request
503
-                );
504
-                $joined_result     = array_merge($join_model_result, $nice_result);
505
-                // but keep the meta stuff from the main model
506
-                if (isset($nice_result['meta'])) {
507
-                    $joined_result['meta'] = $nice_result['meta'];
508
-                }
509
-                $nice_result = $joined_result;
510
-            }
511
-            $nice_results[] = $nice_result;
512
-        }
513
-        if ($relation instanceof EE_Belongs_To_Relation) {
514
-            return array_shift($nice_results);
515
-        } else {
516
-            return $nice_results;
517
-        }
518
-    }
519
-
520
-
521
-    /**
522
-     * Gets the collection for given relation object
523
-     * The same as Read::get_entities_from_model(), except if the relation
524
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
525
-     * the join-model-object into the results
526
-     *
527
-     * @param string                 $id the ID of the thing we are fetching related stuff from
528
-     * @param EE_Model_Relation_Base $relation
529
-     * @param WP_REST_Request        $request
530
-     * @return array
531
-     * @throws EE_Error
532
-     * @throws ReflectionException
533
-     */
534
-    public function getEntitiesFromRelation($id, $relation, $request)
535
-    {
536
-        if (! $relation->get_this_model()->has_primary_key_field()) {
537
-            throw new EE_Error(
538
-                sprintf(
539
-                    esc_html__(
540
-                    // @codingStandardsIgnoreStart
541
-                        'Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
542
-                        // @codingStandardsIgnoreEnd
543
-                        'event_espresso'
544
-                    ),
545
-                    $relation->get_this_model()->get_this_model_name()
546
-                )
547
-            );
548
-        }
549
-        // can we edit that main item?
550
-        // if not, show nothing but an error
551
-        // otherwise, please proceed
552
-        return $this->getEntitiesFromRelationUsingModelQueryParams(
553
-            [
554
-                [
555
-                    $relation->get_this_model()->primary_key_name() => $id,
556
-                ],
557
-            ],
558
-            $relation,
559
-            $request
560
-        );
561
-    }
562
-
563
-
564
-    /**
565
-     * Sets the headers that are based on the model and query params,
566
-     * like the total records. This should only be called on the original request
567
-     * from the client, not on subsequent internal
568
-     *
569
-     * @param EEM_Base $model
570
-     * @param array    $query_params
571
-     * @return void
572
-     * @throws EE_Error
573
-     * @throws EE_Error
574
-     */
575
-    protected function setHeadersFromQueryParams($model, $query_params)
576
-    {
577
-        $this->setDebugInfo('model query params', $query_params);
578
-        $this->setDebugInfo(
579
-            'missing caps',
580
-            Capabilities::getMissingPermissionsString($model, $query_params['caps'])
581
-        );
582
-        // normally the limit to a 2-part array, where the 2nd item is the limit
583
-        if (! isset($query_params['limit'])) {
584
-            $query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
585
-        }
586
-        if (is_array($query_params['limit'])) {
587
-            $limit_parts = $query_params['limit'];
588
-        } else {
589
-            $limit_parts = explode(',', $query_params['limit']);
590
-            if (count($limit_parts) == 1) {
591
-                $limit_parts = [0, $limit_parts[0]];
592
-            }
593
-        }
594
-        // remove the group by and having parts of the query, as those will
595
-        // make the sql query return an array of values, instead of just a single value
596
-        unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
597
-        $count = $model->count($query_params, null, true);
598
-        $pages = $count / $limit_parts[1];
599
-        $this->setResponseHeader('Total', $count, false);
600
-        $this->setResponseHeader('PageSize', $limit_parts[1], false);
601
-        $this->setResponseHeader('TotalPages', ceil($pages), false);
602
-    }
603
-
604
-
605
-    /**
606
-     * Changes database results into REST API entities
607
-     *
608
-     * @param EEM_Base        $model
609
-     * @param array           $db_row     like results from $wpdb->get_results()
610
-     * @param WP_REST_Request $rest_request
611
-     * @param string          $deprecated no longer used
612
-     * @return array ready for being converted into json for sending to client
613
-     * @throws EE_Error
614
-     * @throws RestException
615
-     * @throws InvalidDataTypeException
616
-     * @throws InvalidInterfaceException
617
-     * @throws InvalidArgumentException
618
-     * @throws ReflectionException
619
-     */
620
-    public function createEntityFromWpdbResult($model, $db_row, $rest_request, $deprecated = null)
621
-    {
622
-        if (! $rest_request instanceof WP_REST_Request) {
623
-            // ok so this was called in the old style, where the 3rd arg was
624
-            // $include, and the 4th arg was $context
625
-            // now setup the request just to avoid fatal errors, although we won't be able
626
-            // to truly make use of it because it's kinda devoid of info
627
-            $rest_request = new WP_REST_Request();
628
-            $rest_request->set_param('include', $rest_request);
629
-            $rest_request->set_param('caps', $deprecated);
630
-        }
631
-        if ($rest_request->get_param('caps') == null) {
632
-            $rest_request->set_param('caps', EEM_Base::caps_read);
633
-        }
634
-        $current_user_full_access_to_entity = $model->currentUserCan(
635
-            EEM_Base::caps_read_admin,
636
-            $model->deduce_fields_n_values_from_cols_n_values($db_row)
637
-        );
638
-        $entity_array                       = $this->createBareEntityFromWpdbResults($model, $db_row);
639
-        $entity_array                       = $this->addExtraFields($model, $db_row, $entity_array);
640
-        $entity_array['_links']             = $this->getEntityLinks($model, $db_row, $entity_array);
641
-        // when it's a regular read request for a model with a password and the password wasn't provided
642
-        // remove the password protected fields
643
-        $has_protected_fields = false;
644
-        try {
645
-            $this->checkPassword(
646
-                $model,
647
-                $db_row,
648
-                $model->alter_query_params_to_restrict_by_ID(
649
-                    $model->get_index_primary_key_string(
650
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
651
-                    )
652
-                ),
653
-                $rest_request
654
-            );
655
-        } catch (RestPasswordRequiredException $e) {
656
-            if ($model->hasPassword()) {
657
-                // just remove protected fields
658
-                $has_protected_fields = true;
659
-                $entity_array         = Capabilities::filterOutPasswordProtectedFields(
660
-                    $entity_array,
661
-                    $model,
662
-                    $this->getModelVersionInfo()
663
-                );
664
-            } else {
665
-                // that's a problem. None of this should be accessible if no password was provided
666
-                throw $e;
667
-            }
668
-        }
669
-
670
-        $entity_array['_calculated_fields'] =
671
-            $this->getEntityCalculations($model, $db_row, $rest_request, $has_protected_fields);
672
-        $entity_array                       = apply_filters(
673
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
674
-            $entity_array,
675
-            $model,
676
-            $rest_request->get_param('caps'),
677
-            $rest_request,
678
-            $this
679
-        );
680
-        // add an empty protected property for now. If it's still around after we remove everything the request didn't
681
-        // want, we'll populate it then. k?
682
-        $entity_array['_protected'] = [];
683
-        // remove any properties the request didn't want. This way _protected won't bother mentioning them
684
-        $entity_array = $this->includeOnlyRequestedProperties($model, $rest_request, $entity_array);
685
-        $entity_array =
686
-            $this->includeRequestedModels($model, $rest_request, $entity_array, $db_row, $has_protected_fields);
687
-        // if they still wanted the _protected property, add it.
688
-        if (isset($entity_array['_protected'])) {
689
-            $entity_array = $this->addProtectedProperty($model, $entity_array, $has_protected_fields);
690
-        }
691
-        $entity_array = apply_filters(
692
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
693
-            $entity_array,
694
-            $model,
695
-            $rest_request->get_param('caps'),
696
-            $rest_request,
697
-            $this
698
-        );
699
-        if (! $current_user_full_access_to_entity) {
700
-            $result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
701
-                $entity_array,
702
-                $model,
703
-                $rest_request->get_param('caps'),
704
-                $this->getModelVersionInfo()
705
-            );
706
-        } else {
707
-            $result_without_inaccessible_fields = $entity_array;
708
-        }
709
-        $this->setDebugInfo(
710
-            'inaccessible fields',
711
-            array_keys(array_diff_key((array) $entity_array, (array) $result_without_inaccessible_fields))
712
-        );
713
-        return apply_filters(
714
-            'FHEE__Read__create_entity_from_wpdb_results__entity_return',
715
-            $result_without_inaccessible_fields,
716
-            $model,
717
-            $rest_request->get_param('caps')
718
-        );
719
-    }
720
-
721
-
722
-    /**
723
-     * Returns an array describing which fields can be protected, and which actually were removed this request
724
-     *
725
-     * @param EEM_Base $model
726
-     * @param array    $results_so_far
727
-     * @param bool     $protected
728
-     * @return array results
729
-     * @throws EE_Error
730
-     * @since 4.9.74.p
731
-     */
732
-    protected function addProtectedProperty(EEM_Base $model, $results_so_far, $protected)
733
-    {
734
-        if (! $model->hasPassword() || ! $protected) {
735
-            return $results_so_far;
736
-        }
737
-        $password_field  = $model->getPasswordField();
738
-        $all_protected   = array_merge(
739
-            [$password_field->get_name()],
740
-            $password_field->protectedFields()
741
-        );
742
-        $fields_included = array_keys($results_so_far);
743
-        $fields_included = array_intersect(
744
-            $all_protected,
745
-            $fields_included
746
-        );
747
-        foreach ($fields_included as $field_name) {
748
-            $results_so_far['_protected'][] = $field_name;
749
-        }
750
-        return $results_so_far;
751
-    }
752
-
753
-
754
-    /**
755
-     * Creates a REST entity array (JSON object we're going to return in the response, but
756
-     * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
757
-     * from $wpdb->get_row( $sql, ARRAY_A)
758
-     *
759
-     * @param EEM_Base $model
760
-     * @param array    $db_row
761
-     * @return array entity mostly ready for converting to JSON and sending in the response
762
-     * @throws EE_Error
763
-     * @throws ReflectionException
764
-     * @throws RestException
765
-     */
766
-    protected function createBareEntityFromWpdbResults(EEM_Base $model, $db_row)
767
-    {
768
-        $result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
769
-        $result = array_intersect_key(
770
-            $result,
771
-            $this->getModelVersionInfo()->fieldsOnModelInThisVersion($model)
772
-        );
773
-        // if this is a CPT, we need to set the global $post to it,
774
-        // otherwise shortcodes etc won't work properly while rendering it
775
-        if ($model instanceof EEM_CPT_Base) {
776
-            $do_chevy_shuffle = true;
777
-        } else {
778
-            $do_chevy_shuffle = false;
779
-        }
780
-        if ($do_chevy_shuffle) {
781
-            global $post;
782
-            $old_post = $post;
783
-            $post     = get_post($result[ $model->primary_key_name() ]);
784
-            if (! $post instanceof WP_Post) {
785
-                // well that's weird, because $result is what we JUST fetched from the database
786
-                throw new RestException(
787
-                    'error_fetching_post_from_database_results',
788
-                    esc_html__(
789
-                        'An item was retrieved from the database but it\'s not a WP_Post like it should be.',
790
-                        'event_espresso'
791
-                    )
792
-                );
793
-            }
794
-            $model_object_classname          = 'EE_' . $model->get_this_model_name();
795
-            $post->{$model_object_classname} = EE_Registry::instance()->load_class(
796
-                $model_object_classname,
797
-                $result,
798
-                false,
799
-                false
800
-            );
801
-        }
802
-        foreach ($result as $field_name => $field_value) {
803
-            $field_obj = $model->field_settings_for($field_name);
804
-            if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
805
-                unset($result[ $field_name ]);
806
-            } elseif (
807
-                $this->isSubclassOfOne(
808
-                    $field_obj,
809
-                    $this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
810
-                )
811
-            ) {
812
-                $result[ $field_name ] = [
813
-                    'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
814
-                    'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
815
-                ];
816
-            } elseif (
817
-                $this->isSubclassOfOne(
818
-                    $field_obj,
819
-                    $this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
820
-                )
821
-            ) {
822
-                $result[ $field_name ] = [
823
-                    'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
824
-                    'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
825
-                ];
826
-            } elseif ($field_obj instanceof EE_Datetime_Field) {
827
-                $field_value = $field_obj->prepare_for_set_from_db($field_value);
828
-                // if the value is null, but we're not supposed to permit null, then set to the field's default
829
-                if (is_null($field_value)) {
830
-                    $field_value = $field_obj->getDefaultDateTimeObj();
831
-                }
832
-                if (is_null($field_value)) {
833
-                    $gmt_date = $local_date = ModelDataTranslator::prepareFieldValuesForJson(
834
-                        $field_obj,
835
-                        $field_value,
836
-                        $this->getModelVersionInfo()->requestedVersion()
837
-                    );
838
-                } else {
839
-                    $timezone = $field_value->getTimezone();
840
-                    EEH_DTT_Helper::setTimezone($field_value, new DateTimeZone('UTC'));
841
-                    $gmt_date = ModelDataTranslator::prepareFieldValuesForJson(
842
-                        $field_obj,
843
-                        $field_value,
844
-                        $this->getModelVersionInfo()->requestedVersion()
845
-                    );
846
-                    EEH_DTT_Helper::setTimezone($field_value, $timezone);
847
-                    $local_date = ModelDataTranslator::prepareFieldValuesForJson(
848
-                        $field_obj,
849
-                        $field_value,
850
-                        $this->getModelVersionInfo()->requestedVersion()
851
-                    );
852
-                }
853
-                $result[ $field_name . '_gmt' ] = $gmt_date;
854
-                $result[ $field_name ]          = $local_date;
855
-            } else {
856
-                $result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
857
-            }
858
-        }
859
-        if ($do_chevy_shuffle) {
860
-            $post = $old_post;
861
-        }
862
-        return $result;
863
-    }
864
-
865
-
866
-    /**
867
-     * Takes a value all the way from the DB representation, to the model object's representation, to the
868
-     * user-facing PHP representation, to the REST API representation. (Assumes you've already taken from the DB
869
-     * representation using $field_obj->prepare_for_set_from_db())
870
-     *
871
-     * @param EE_Model_Field_Base $field_obj
872
-     * @param mixed               $value  as it's stored on a model object
873
-     * @param string              $format valid values are 'normal' (default), 'pretty', 'datetime_obj'
874
-     * @return array
875
-     * @throws RestException if $value contains a PHP object
876
-     * @throws EE_Error
877
-     */
878
-    protected function prepareFieldObjValueForJson(EE_Model_Field_Base $field_obj, $value, $format = 'normal')
879
-    {
880
-        $value = $field_obj->prepare_for_set_from_db($value);
881
-        switch ($format) {
882
-            case 'pretty':
883
-                $value = $field_obj->prepare_for_pretty_echoing($value);
884
-                break;
885
-            case 'normal':
886
-            default:
887
-                $value = $field_obj->prepare_for_get($value);
888
-                break;
889
-        }
890
-        return ModelDataTranslator::prepareFieldValuesForJson(
891
-            $field_obj,
892
-            $value,
893
-            $this->getModelVersionInfo()->requestedVersion()
894
-        );
895
-    }
896
-
897
-
898
-    /**
899
-     * Adds a few extra fields to the entity response
900
-     *
901
-     * @param EEM_Base $model
902
-     * @param array    $db_row
903
-     * @param array    $entity_array
904
-     * @return array modified entity
905
-     * @throws EE_Error
906
-     * @throws EE_Error
907
-     */
908
-    protected function addExtraFields(EEM_Base $model, $db_row, $entity_array)
909
-    {
910
-        if ($model instanceof EEM_CPT_Base) {
911
-            $entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
912
-        }
913
-        return $entity_array;
914
-    }
915
-
916
-
917
-    /**
918
-     * Gets links we want to add to the response
919
-     *
920
-     * @param EEM_Base        $model
921
-     * @param array           $db_row
922
-     * @param array           $entity_array
923
-     * @return array the _links item in the entity
924
-     * @throws EE_Error
925
-     * @throws EE_Error
926
-     * @global WP_REST_Server $wp_rest_server
927
-     */
928
-    protected function getEntityLinks($model, $db_row, $entity_array)
929
-    {
930
-        // add basic links
931
-        $links = [];
932
-        if ($model->has_primary_key_field()) {
933
-            $links['self'] = [
934
-                [
935
-                    'href' => $this->getVersionedLinkTo(
936
-                        EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
937
-                        . '/'
938
-                        . $entity_array[ $model->primary_key_name() ]
939
-                    ),
940
-                ],
941
-            ];
942
-        }
943
-        $links['collection'] = [
944
-            [
945
-                'href' => $this->getVersionedLinkTo(
946
-                    EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
947
-                ),
948
-            ],
949
-        ];
950
-        // add links to related models
951
-        if ($model->has_primary_key_field()) {
952
-            foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
953
-                $related_model_part                                                      =
954
-                    Read::getRelatedEntityName($relation_name, $relation_obj);
955
-                $links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = [
956
-                    [
957
-                        'href'   => $this->getVersionedLinkTo(
958
-                            EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
959
-                            . '/'
960
-                            . $entity_array[ $model->primary_key_name() ]
961
-                            . '/'
962
-                            . $related_model_part
963
-                        ),
964
-                        'single' => $relation_obj instanceof EE_Belongs_To_Relation,
965
-                    ],
966
-                ];
967
-            }
968
-        }
969
-        return $links;
970
-    }
971
-
972
-
973
-    /**
974
-     * Adds the included models indicated in the request to the entity provided
975
-     *
976
-     * @param EEM_Base        $model
977
-     * @param WP_REST_Request $rest_request
978
-     * @param array           $entity_array
979
-     * @param array           $db_row
980
-     * @param boolean         $included_items_protected if the original item is password protected, don't include any
981
-     *                                                  related models.
982
-     * @return array the modified entity
983
-     * @throws EE_Error
984
-     * @throws ReflectionException
985
-     */
986
-    protected function includeRequestedModels(
987
-        EEM_Base $model,
988
-        WP_REST_Request $rest_request,
989
-        $entity_array,
990
-        $db_row = [],
991
-        $included_items_protected = false
992
-    ) {
993
-        // if $db_row not included, hope the entity array has what we need
994
-        if (! $db_row) {
995
-            $db_row = $entity_array;
996
-        }
997
-        $relation_settings = $this->getModelVersionInfo()->relationSettings($model);
998
-        foreach ($relation_settings as $relation_name => $relation_obj) {
999
-            $related_fields_to_include   = $this->explodeAndGetItemsPrefixedWith(
1000
-                $rest_request->get_param('include'),
1001
-                $relation_name
1002
-            );
1003
-            $related_fields_to_calculate = $this->explodeAndGetItemsPrefixedWith(
1004
-                $rest_request->get_param('calculate'),
1005
-                $relation_name
1006
-            );
1007
-            // did they specify they wanted to include a related model, or
1008
-            // specific fields from a related model?
1009
-            // or did they specify to calculate a field from a related model?
1010
-            if ($related_fields_to_include || $related_fields_to_calculate) {
1011
-                // if so, we should include at least some part of the related model
1012
-                $pretend_related_request = new WP_REST_Request();
1013
-                $pretend_related_request->set_query_params(
1014
-                    [
1015
-                        'caps'      => $rest_request->get_param('caps'),
1016
-                        'include'   => $related_fields_to_include,
1017
-                        'calculate' => $related_fields_to_calculate,
1018
-                        'password'  => $rest_request->get_param('password'),
1019
-                    ]
1020
-                );
1021
-                $pretend_related_request->add_header('no_rest_headers', true);
1022
-                $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
1023
-                    $model->get_index_primary_key_string(
1024
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
1025
-                    )
1026
-                );
1027
-                if (! $included_items_protected) {
1028
-                    try {
1029
-                        $related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1030
-                            $primary_model_query_params,
1031
-                            $relation_obj,
1032
-                            $pretend_related_request
1033
-                        );
1034
-                    } catch (RestException $e) {
1035
-                        $related_results = null;
1036
-                    }
1037
-                } else {
1038
-                    // they're protected, hide them.
1039
-                    $related_results              = null;
1040
-                    $entity_array['_protected'][] = Read::getRelatedEntityName($relation_name, $relation_obj);
1041
-                }
1042
-                if ($related_results instanceof WP_Error || $related_results === null) {
1043
-                    $related_results =
1044
-                        $relation_obj instanceof EE_Belongs_To_Relation
1045
-                            ? null
1046
-                            : [];
1047
-                }
1048
-                $entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1049
-            }
1050
-        }
1051
-        return $entity_array;
1052
-    }
1053
-
1054
-
1055
-    /**
1056
-     * If the user has requested only specific properties (including meta properties like _links or _protected)
1057
-     * remove everything else.
1058
-     *
1059
-     * @param EEM_Base        $model
1060
-     * @param WP_REST_Request $rest_request
1061
-     * @param                 $entity_array
1062
-     * @return array
1063
-     * @throws EE_Error
1064
-     * @since 4.9.74.p
1065
-     */
1066
-    protected function includeOnlyRequestedProperties(
1067
-        EEM_Base $model,
1068
-        WP_REST_Request $rest_request,
1069
-        $entity_array
1070
-    ) {
1071
-
1072
-        $includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1073
-        $includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1074
-        // if they passed in * or didn't specify any includes, return everything
1075
-        if (
1076
-            ! in_array('*', $includes_for_this_model)
1077
-            && ! empty($includes_for_this_model)
1078
-        ) {
1079
-            if ($model->has_primary_key_field()) {
1080
-                // always include the primary key. ya just gotta know that at least
1081
-                $includes_for_this_model[] = $model->primary_key_name();
1082
-            }
1083
-            if ($this->explodeAndGetItemsPrefixedWith($rest_request->get_param('calculate'), '')) {
1084
-                $includes_for_this_model[] = '_calculated_fields';
1085
-            }
1086
-            $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
1087
-        }
1088
-        return $entity_array;
1089
-    }
1090
-
1091
-
1092
-    /**
1093
-     * Returns a new array with all the names of models removed. Eg
1094
-     * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
1095
-     *
1096
-     * @param array $arr
1097
-     * @return array
1098
-     */
1099
-    private function removeModelNamesFromArray($arr)
1100
-    {
1101
-        return array_diff($arr, array_keys(EE_Registry::instance()->non_abstract_db_models));
1102
-    }
1103
-
1104
-
1105
-    /**
1106
-     * Gets the calculated fields for the response
1107
-     *
1108
-     * @param EEM_Base        $model
1109
-     * @param array           $wpdb_row
1110
-     * @param WP_REST_Request $rest_request
1111
-     * @param boolean         $row_is_protected whether this row is password protected or not
1112
-     * @return stdClass the _calculations item in the entity
1113
-     * @throws RestException if a default value has a PHP object, which should never do (and if we
1114
-     * @throws EE_Error
1115
-     *                                          did, let's know about it ASAP, so let the exception bubble up)
1116
-     */
1117
-    protected function getEntityCalculations($model, $wpdb_row, $rest_request, $row_is_protected = false)
1118
-    {
1119
-        $calculated_fields = $this->explodeAndGetItemsPrefixedWith(
1120
-            $rest_request->get_param('calculate'),
1121
-            ''
1122
-        );
1123
-        // note: setting calculate=* doesn't do anything
1124
-        $calculated_fields_to_return = new stdClass();
1125
-        $protected_fields            = [];
1126
-        foreach ($calculated_fields as $field_to_calculate) {
1127
-            try {
1128
-                // it's password protected, so they shouldn't be able to read this. Remove the value
1129
-                $schema = $this->fields_calculator->getJsonSchemaForModel($model);
1130
-                if (
1131
-                    $row_is_protected
1132
-                    && isset($schema['properties'][ $field_to_calculate ]['protected'])
1133
-                    && $schema['properties'][ $field_to_calculate ]['protected']
1134
-                ) {
1135
-                    $calculated_value   = null;
1136
-                    $protected_fields[] = $field_to_calculate;
1137
-                    if ($schema['properties'][ $field_to_calculate ]['type']) {
1138
-                        switch ($schema['properties'][ $field_to_calculate ]['type']) {
1139
-                            case 'boolean':
1140
-                                $calculated_value = false;
1141
-                                break;
1142
-                            case 'integer':
1143
-                                $calculated_value = 0;
1144
-                                break;
1145
-                            case 'string':
1146
-                                $calculated_value = '';
1147
-                                break;
1148
-                            case 'array':
1149
-                                $calculated_value = [];
1150
-                                break;
1151
-                            case 'object':
1152
-                                $calculated_value = new stdClass();
1153
-                                break;
1154
-                        }
1155
-                    }
1156
-                } else {
1157
-                    $calculated_value = ModelDataTranslator::prepareFieldValueForJson(
1158
-                        null,
1159
-                        $this->fields_calculator->retrieveCalculatedFieldValue(
1160
-                            $model,
1161
-                            $field_to_calculate,
1162
-                            $wpdb_row,
1163
-                            $rest_request,
1164
-                            $this
1165
-                        ),
1166
-                        $this->getModelVersionInfo()->requestedVersion()
1167
-                    );
1168
-                }
1169
-                $calculated_fields_to_return->{$field_to_calculate} = $calculated_value;
1170
-            } catch (RestException $e) {
1171
-                // if we don't have permission to read it, just leave it out. but let devs know about the problem
1172
-                $this->setResponseHeader(
1173
-                    'Notices-Field-Calculation-Errors['
1174
-                    . $e->getStringCode()
1175
-                    . ']['
1176
-                    . $model->get_this_model_name()
1177
-                    . ']['
1178
-                    . $field_to_calculate
1179
-                    . ']',
1180
-                    $e->getMessage(),
1181
-                    true
1182
-                );
1183
-            }
1184
-        }
1185
-        $calculated_fields_to_return->_protected = $protected_fields;
1186
-        return $calculated_fields_to_return;
1187
-    }
1188
-
1189
-
1190
-    /**
1191
-     * Gets the full URL to the resource, taking the requested version into account
1192
-     *
1193
-     * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
1194
-     * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
1195
-     * @throws EE_Error
1196
-     * @throws EE_Error
1197
-     */
1198
-    public function getVersionedLinkTo($link_part_after_version_and_slash)
1199
-    {
1200
-        return rest_url(
1201
-            EED_Core_Rest_Api::get_versioned_route_to(
1202
-                $link_part_after_version_and_slash,
1203
-                $this->getModelVersionInfo()->requestedVersion()
1204
-            )
1205
-        );
1206
-    }
1207
-
1208
-
1209
-    /**
1210
-     * Gets the correct lowercase name for the relation in the API according
1211
-     * to the relation's type
1212
-     *
1213
-     * @param string                 $relation_name
1214
-     * @param EE_Model_Relation_Base $relation_obj
1215
-     * @return string
1216
-     */
1217
-    public static function getRelatedEntityName($relation_name, $relation_obj)
1218
-    {
1219
-        if ($relation_obj instanceof EE_Belongs_To_Relation) {
1220
-            return strtolower($relation_name);
1221
-        } else {
1222
-            return EEH_Inflector::pluralize_and_lower($relation_name);
1223
-        }
1224
-    }
1225
-
1226
-
1227
-    /**
1228
-     * Gets the one model object with the specified id for the specified model
1229
-     *
1230
-     * @param EEM_Base        $model
1231
-     * @param WP_REST_Request $request
1232
-     * @return array
1233
-     * @throws EE_Error
1234
-     * @throws EE_Error
1235
-     * @throws ReflectionException
1236
-     */
1237
-    public function getEntityFromModel($model, $request)
1238
-    {
1239
-        $context = $this->validateContext($request->get_param('caps'));
1240
-        return $this->getOneOrReportPermissionError($model, $request, $context);
1241
-    }
1242
-
1243
-
1244
-    /**
1245
-     * If a context is provided which isn't valid, maybe it was added in a future
1246
-     * version so just treat it as a default read
1247
-     *
1248
-     * @param string $context
1249
-     * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
1250
-     */
1251
-    public function validateContext($context)
1252
-    {
1253
-        if (! $context) {
1254
-            $context = EEM_Base::caps_read;
1255
-        }
1256
-        $valid_contexts = EEM_Base::valid_cap_contexts();
1257
-        if (in_array($context, $valid_contexts)) {
1258
-            return $context;
1259
-        } else {
1260
-            return EEM_Base::caps_read;
1261
-        }
1262
-    }
1263
-
1264
-
1265
-    /**
1266
-     * Verifies the passed in value is an allowable default where conditions value.
1267
-     *
1268
-     * @param $default_query_params
1269
-     * @return string
1270
-     */
1271
-    public function validateDefaultQueryParams($default_query_params)
1272
-    {
1273
-        $valid_default_where_conditions_for_api_calls = [
1274
-            EEM_Base::default_where_conditions_all,
1275
-            EEM_Base::default_where_conditions_minimum_all,
1276
-            EEM_Base::default_where_conditions_minimum_others,
1277
-        ];
1278
-        if (! $default_query_params) {
1279
-            $default_query_params = EEM_Base::default_where_conditions_all;
1280
-        }
1281
-        if (
1282
-            in_array(
1283
-                $default_query_params,
1284
-                $valid_default_where_conditions_for_api_calls,
1285
-                true
1286
-            )
1287
-        ) {
1288
-            return $default_query_params;
1289
-        }
1290
-        return EEM_Base::default_where_conditions_all;
1291
-    }
1292
-
1293
-
1294
-    /**
1295
-     * Translates API filter get parameter into model query params @see
1296
-     * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions.
1297
-     * Note: right now the query parameter keys for fields (and related fields) can be left as-is, but it's quite
1298
-     * possible this will change someday. Also, this method's contents might be candidate for moving to
1299
-     * Model_Data_Translator
1300
-     *
1301
-     * @param EEM_Base $model
1302
-     * @param array    $query_params
1303
-     * @return array model query params (@see
1304
-     *               https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions)
1305
-     *               or FALSE to indicate that absolutely no results should be returned
1306
-     * @throws EE_Error
1307
-     * @throws RestException
1308
-     */
1309
-    public function createModelQueryParams($model, $query_params)
1310
-    {
1311
-        $model_query_params = [];
1312
-        if (isset($query_params['where'])) {
1313
-            $model_query_params[0] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1314
-                $query_params['where'],
1315
-                $model,
1316
-                $this->getModelVersionInfo()->requestedVersion()
1317
-            );
1318
-        }
1319
-        if (isset($query_params['order_by'])) {
1320
-            $order_by = $query_params['order_by'];
1321
-        } elseif (isset($query_params['orderby'])) {
1322
-            $order_by = $query_params['orderby'];
1323
-        } else {
1324
-            $order_by = null;
1325
-        }
1326
-        if ($order_by !== null) {
1327
-            if (is_array($order_by)) {
1328
-                $order_by = ModelDataTranslator::prepareFieldNamesInArrayKeysFromJson($order_by);
1329
-            } else {
1330
-                // it's a single item
1331
-                $order_by = ModelDataTranslator::prepareFieldNameFromJson($order_by);
1332
-            }
1333
-            $model_query_params['order_by'] = $order_by;
1334
-        }
1335
-        if (isset($query_params['group_by'])) {
1336
-            $group_by = $query_params['group_by'];
1337
-        } elseif (isset($query_params['groupby'])) {
1338
-            $group_by = $query_params['groupby'];
1339
-        } else {
1340
-            $group_by = array_keys($model->get_combined_primary_key_fields());
1341
-        }
1342
-        // make sure they're all real names
1343
-        if (is_array($group_by)) {
1344
-            $group_by = ModelDataTranslator::prepareFieldNamesFromJson($group_by);
1345
-        }
1346
-        if ($group_by !== null) {
1347
-            $model_query_params['group_by'] = $group_by;
1348
-        }
1349
-        if (isset($query_params['having'])) {
1350
-            $model_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1351
-                $query_params['having'],
1352
-                $model,
1353
-                $this->getModelVersionInfo()->requestedVersion()
1354
-            );
1355
-        }
1356
-        if (isset($query_params['order'])) {
1357
-            $model_query_params['order'] = $query_params['order'];
1358
-        }
1359
-        if (isset($query_params['mine'])) {
1360
-            $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1361
-        }
1362
-        if (isset($query_params['limit'])) {
1363
-            // limit should be either a string like '23' or '23,43', or an array with two items in it
1364
-            if (! is_array($query_params['limit'])) {
1365
-                $limit_array = explode(',', (string) $query_params['limit']);
1366
-            } else {
1367
-                $limit_array = $query_params['limit'];
1368
-            }
1369
-            $sanitized_limit = [];
1370
-            foreach ($limit_array as $limit_part) {
1371
-                if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1372
-                    throw new EE_Error(
1373
-                        sprintf(
1374
-                            esc_html__(
1375
-                            // @codingStandardsIgnoreStart
1376
-                                '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.',
1377
-                                // @codingStandardsIgnoreEnd
1378
-                                'event_espresso'
1379
-                            ),
1380
-                            wp_json_encode($query_params['limit'])
1381
-                        )
1382
-                    );
1383
-                }
1384
-                $sanitized_limit[] = (int) $limit_part;
1385
-            }
1386
-            $model_query_params['limit'] = implode(',', $sanitized_limit);
1387
-        } else {
1388
-            $model_query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
1389
-        }
1390
-        if (isset($query_params['caps'])) {
1391
-            $model_query_params['caps'] = $this->validateContext($query_params['caps']);
1392
-        } else {
1393
-            $model_query_params['caps'] = EEM_Base::caps_read;
1394
-        }
1395
-        if (isset($query_params['default_where_conditions'])) {
1396
-            $model_query_params['default_where_conditions'] = $this->validateDefaultQueryParams(
1397
-                $query_params['default_where_conditions']
1398
-            );
1399
-        }
1400
-        // if this is a model protected by a password on another model, exclude the password protected
1401
-        // entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1402
-        // though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1403
-        if (
1404
-            ! $model->hasPassword()
1405
-            && $model->restrictedByRelatedModelPassword()
1406
-            && $model_query_params['caps'] === EEM_Base::caps_read
1407
-        ) {
1408
-            if (empty($query_params['password'])) {
1409
-                $model_query_params['exclude_protected'] = true;
1410
-            }
1411
-        }
1412
-
1413
-        return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_params, $model);
1414
-    }
1415
-
1416
-
1417
-    /**
1418
-     * Changes the REST-style query params for use in the models
1419
-     *
1420
-     * @param EEM_Base $model
1421
-     * @param array    $query_params sub-array from @see EEM_Base::get_all()
1422
-     * @return array
1423
-     * @deprecated
1424
-     */
1425
-    public function prepareRestQueryParamsKeyForModels($model, $query_params)
1426
-    {
1427
-        $model_ready_query_params = [];
1428
-        foreach ($query_params as $key => $value) {
1429
-            $model_ready_query_params[ $key ] = is_array($value)
1430
-                ? $this->prepareRestQueryParamsKeyForModels($model, $value)
1431
-                : $value;
1432
-        }
1433
-        return $model_ready_query_params;
1434
-    }
1435
-
1436
-
1437
-    /**
1438
-     * @param $model
1439
-     * @param $query_params
1440
-     * @return array
1441
-     * @deprecated instead use ModelDataTranslator::prepareFieldValuesFromJson()
1442
-     */
1443
-    public function prepareRestQueryParamsValuesForModels($model, $query_params)
1444
-    {
1445
-        $model_ready_query_params = [];
1446
-        foreach ($query_params as $key => $value) {
1447
-            if (is_array($value)) {
1448
-                $model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1449
-            } else {
1450
-                $model_ready_query_params[ $key ] = $value;
1451
-            }
1452
-        }
1453
-        return $model_ready_query_params;
1454
-    }
1455
-
1456
-
1457
-    /**
1458
-     * Explodes the string on commas, and only returns items with $prefix followed by a period.
1459
-     * If no prefix is specified, returns items with no period.
1460
-     *
1461
-     * @param string|array $string_to_explode eg "jibba,jabba, blah, blah, blah" or array('jibba', 'jabba' )
1462
-     * @param string       $prefix            "Event" or "foobar"
1463
-     * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1464
-     *                                        we only return strings starting with that and a period; if no prefix was
1465
-     *                                        specified we return all items containing NO periods
1466
-     */
1467
-    public function explodeAndGetItemsPrefixedWith($string_to_explode, $prefix)
1468
-    {
1469
-        if (is_string($string_to_explode)) {
1470
-            $exploded_contents = explode(',', $string_to_explode);
1471
-        } elseif (is_array($string_to_explode)) {
1472
-            $exploded_contents = $string_to_explode;
1473
-        } else {
1474
-            $exploded_contents = [];
1475
-        }
1476
-        // if the string was empty, we want an empty array
1477
-        $exploded_contents    = array_filter($exploded_contents);
1478
-        $contents_with_prefix = [];
1479
-        foreach ($exploded_contents as $item) {
1480
-            $item = trim($item);
1481
-            // if no prefix was provided, so we look for items with no "." in them
1482
-            if (! $prefix) {
1483
-                // does this item have a period?
1484
-                if (strpos($item, '.') === false) {
1485
-                    // if not, then its what we're looking for
1486
-                    $contents_with_prefix[] = $item;
1487
-                }
1488
-            } elseif (strpos($item, $prefix . '.') === 0) {
1489
-                // this item has the prefix and a period, grab it
1490
-                $contents_with_prefix[] = substr(
1491
-                    $item,
1492
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1493
-                );
1494
-            } elseif ($item === $prefix) {
1495
-                // this item is JUST the prefix
1496
-                // so let's grab everything after, which is a blank string
1497
-                $contents_with_prefix[] = '';
1498
-            }
1499
-        }
1500
-        return $contents_with_prefix;
1501
-    }
1502
-
1503
-
1504
-    /**
1505
-     * @param string $include_string @see Read:handle_request_get_all
1506
-     * @param string $model_name
1507
-     * @return array of fields for this model. If $model_name is provided, then
1508
-     *                               the fields for that model, with the model's name removed from each.
1509
-     *                               If $include_string was blank or '*' returns an empty array
1510
-     * @throws EE_Error
1511
-     * @throws EE_Error
1512
-     * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1513
-     *                               Deprecated because its return values were really quite confusing- sometimes it
1514
-     *                               returned an empty array (when the include string was blank or '*') or sometimes it
1515
-     *                               returned array('*') (when you provided a model and a model of that kind was
1516
-     *                               found). Parses the $include_string so we fetch all the field names relating to
1517
-     *                               THIS model
1518
-     *                               (ie have NO period in them), or for the provided model (ie start with the model
1519
-     *                               name and then a period).
1520
-     */
1521
-    public function extractIncludesForThisModel($include_string, $model_name = null)
1522
-    {
1523
-        if (is_array($include_string)) {
1524
-            $include_string = implode(',', $include_string);
1525
-        }
1526
-        if ($include_string === '*' || $include_string === '') {
1527
-            return [];
1528
-        }
1529
-        $includes                    = explode(',', $include_string);
1530
-        $extracted_fields_to_include = [];
1531
-        if ($model_name) {
1532
-            foreach ($includes as $field_to_include) {
1533
-                $field_to_include = trim($field_to_include);
1534
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1535
-                    // found the model name at the exact start
1536
-                    $field_sans_model_name         = str_replace($model_name . '.', '', $field_to_include);
1537
-                    $extracted_fields_to_include[] = $field_sans_model_name;
1538
-                } elseif ($field_to_include == $model_name) {
1539
-                    $extracted_fields_to_include[] = '*';
1540
-                }
1541
-            }
1542
-        } else {
1543
-            // look for ones with no period
1544
-            foreach ($includes as $field_to_include) {
1545
-                $field_to_include = trim($field_to_include);
1546
-                if (
1547
-                    strpos($field_to_include, '.') === false
1548
-                    && ! $this->getModelVersionInfo()->isModelNameInThisVersion($field_to_include)
1549
-                ) {
1550
-                    $extracted_fields_to_include[] = $field_to_include;
1551
-                }
1552
-            }
1553
-        }
1554
-        return $extracted_fields_to_include;
1555
-    }
1556
-
1557
-
1558
-    /**
1559
-     * Gets the single item using the model according to the request in the context given, otherwise
1560
-     * returns that it's inaccessible to the current user
1561
-     *
1562
-     * @param EEM_Base        $model
1563
-     * @param WP_REST_Request $request
1564
-     * @param null            $context
1565
-     * @return array
1566
-     * @throws EE_Error
1567
-     * @throws ReflectionException
1568
-     */
1569
-    public function getOneOrReportPermissionError(EEM_Base $model, WP_REST_Request $request, $context = null)
1570
-    {
1571
-        $query_params = [[$model->primary_key_name() => $request->get_param('id')], 'limit' => 1];
1572
-        if ($model instanceof EEM_Soft_Delete_Base) {
1573
-            $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
1574
-        }
1575
-        $restricted_query_params         = $query_params;
1576
-        $restricted_query_params['caps'] = $context;
1577
-        $this->setDebugInfo('model query params', $restricted_query_params);
1578
-        $model_rows = $model->get_all_wpdb_results($restricted_query_params);
1579
-        if (! empty($model_rows)) {
1580
-            return $this->createEntityFromWpdbResult(
1581
-                $model,
1582
-                reset($model_rows),
1583
-                $request
1584
-            );
1585
-        } else {
1586
-            // ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
1587
-            $lowercase_model_name = strtolower($model->get_this_model_name());
1588
-            if ($model->exists($query_params)) {
1589
-                // you got shafted- it existed but we didn't want to tell you!
1590
-                throw new RestException(
1591
-                    'rest_user_cannot_' . $context,
1592
-                    sprintf(
1593
-                        esc_html__('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1594
-                        $context,
1595
-                        $lowercase_model_name,
1596
-                        Capabilities::getMissingPermissionsString(
1597
-                            $model,
1598
-                            $context
1599
-                        )
1600
-                    ),
1601
-                    ['status' => 403]
1602
-                );
1603
-            } else {
1604
-                // it's not you. It just doesn't exist
1605
-                throw new RestException(
1606
-                    sprintf('rest_%s_invalid_id', $lowercase_model_name),
1607
-                    sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
1608
-                    ['status' => 404]
1609
-                );
1610
-            }
1611
-        }
1612
-    }
1613
-
1614
-
1615
-    /**
1616
-     * Checks that if this content requires a password to be read, that it's been provided and is correct.
1617
-     *
1618
-     * @param EEM_Base        $model
1619
-     * @param array           $model_row
1620
-     * @param array           $query_params Adds 'default_where_conditions' => 'minimum'
1621
-     *                                      to ensure we don't confuse trashed with password protected.
1622
-     * @param WP_REST_Request $request
1623
-     * @throws EE_Error
1624
-     * @throws InvalidArgumentException
1625
-     * @throws InvalidDataTypeException
1626
-     * @throws InvalidInterfaceException
1627
-     * @throws RestPasswordRequiredException
1628
-     * @throws RestPasswordIncorrectException
1629
-     * @throws ModelConfigurationException
1630
-     * @throws ReflectionException
1631
-     * @since 4.9.74.p
1632
-     */
1633
-    protected function checkPassword(EEM_Base $model, $model_row, $query_params, WP_REST_Request $request)
1634
-    {
1635
-        $query_params['default_where_conditions'] = 'minimum';
1636
-        // stuff is only "protected" for front-end requests. Elsewhere, you either get full permission to access the object
1637
-        // or you don't.
1638
-        $request_caps = $request->get_param('caps');
1639
-        if (isset($request_caps) && $request_caps !== EEM_Base::caps_read) {
1640
-            return;
1641
-        }
1642
-        // if this entity requires a password, they better give it and it better be right!
1643
-        if (
1644
-            $model->hasPassword()
1645
-            && $model_row[ $model->getPasswordField()->get_qualified_column() ] !== ''
1646
-        ) {
1647
-            if (empty($request['password'])) {
1648
-                throw new RestPasswordRequiredException();
1649
-            }
1650
-            if (
1651
-                ! hash_equals(
1652
-                    $model_row[ $model->getPasswordField()->get_qualified_column() ],
1653
-                    $request['password']
1654
-                )
1655
-            ) {
1656
-                throw new RestPasswordIncorrectException();
1657
-            }
1658
-        } elseif (
1659
-            // wait! maybe this content is password protected
1660
-            $model->restrictedByRelatedModelPassword()
1661
-            && $request->get_param('caps') === EEM_Base::caps_read
1662
-        ) {
1663
-            $password_supplied = $request->get_param('password');
1664
-            if (empty($password_supplied)) {
1665
-                $query_params['exclude_protected'] = true;
1666
-                if (! $model->exists($query_params)) {
1667
-                    throw new RestPasswordRequiredException();
1668
-                }
1669
-            } else {
1670
-                $query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1671
-                if (! $model->exists($query_params)) {
1672
-                    throw new RestPasswordIncorrectException();
1673
-                }
1674
-            }
1675
-        }
1676
-    }
52
+	/**
53
+	 * @var CalculatedModelFields
54
+	 */
55
+	protected $fields_calculator;
56
+
57
+
58
+	/**
59
+	 * Read constructor.
60
+	 *
61
+	 * @param CalculatedModelFields $fields_calculator
62
+	 */
63
+	public function __construct(CalculatedModelFields $fields_calculator)
64
+	{
65
+		parent::__construct();
66
+		$this->fields_calculator = $fields_calculator;
67
+	}
68
+
69
+
70
+	/**
71
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
72
+	 *
73
+	 * @param WP_REST_Request $request
74
+	 * @param string          $version
75
+	 * @param string          $model_name
76
+	 * @return WP_REST_Response|WP_Error
77
+	 * @throws InvalidArgumentException
78
+	 * @throws InvalidDataTypeException
79
+	 * @throws InvalidInterfaceException
80
+	 */
81
+	public static function handleRequestGetAll(WP_REST_Request $request, $version, $model_name)
82
+	{
83
+		$controller =
84
+			LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
85
+		try {
86
+			$controller->setRequestedVersion($version);
87
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
88
+				return $controller->sendResponse(
89
+					new WP_Error(
90
+						'endpoint_parsing_error',
91
+						sprintf(
92
+							esc_html__(
93
+								'There is no model for endpoint %s. Please contact event espresso support',
94
+								'event_espresso'
95
+							),
96
+							$model_name
97
+						)
98
+					)
99
+				);
100
+			}
101
+			return $controller->sendResponse(
102
+				$controller->getEntitiesFromModel(
103
+					$controller->getModelVersionInfo()->loadModel($model_name),
104
+					$request
105
+				)
106
+			);
107
+		} catch (Exception $e) {
108
+			return $controller->sendResponse($e);
109
+		}
110
+	}
111
+
112
+
113
+	/**
114
+	 * Prepares and returns schema for any OPTIONS request.
115
+	 *
116
+	 * @param string $version    The API endpoint version being used.
117
+	 * @param string $model_name Something like `Event` or `Registration`
118
+	 * @return array
119
+	 * @throws InvalidArgumentException
120
+	 * @throws InvalidDataTypeException
121
+	 * @throws InvalidInterfaceException
122
+	 */
123
+	public static function handleSchemaRequest($version, $model_name)
124
+	{
125
+		$controller =
126
+			LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
127
+		try {
128
+			$controller->setRequestedVersion($version);
129
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
130
+				return [];
131
+			}
132
+			// get the model for this version
133
+			$model        = $controller->getModelVersionInfo()->loadModel($model_name);
134
+			$model_schema = new JsonModelSchema(
135
+				$model,
136
+				LoaderFactory::getLoader()->getShared('EventEspresso\core\libraries\rest_api\CalculatedModelFields')
137
+			);
138
+			return $model_schema->getModelSchemaForRelations(
139
+				$controller->getModelVersionInfo()->relationSettings($model),
140
+				$controller->customizeSchemaForRestResponse(
141
+					$model,
142
+					$model_schema->getModelSchemaForFields(
143
+						$controller->getModelVersionInfo()->fieldsOnModelInThisVersion($model),
144
+						$model_schema->getInitialSchemaStructure()
145
+					)
146
+				)
147
+			);
148
+		} catch (Exception $e) {
149
+			return [];
150
+		}
151
+	}
152
+
153
+
154
+	/**
155
+	 * This loops through each field in the given schema for the model and does the following:
156
+	 * - add any extra fields that are REST API specific and related to existing fields.
157
+	 * - transform default values into the correct format for a REST API response.
158
+	 *
159
+	 * @param EEM_Base $model
160
+	 * @param array    $schema
161
+	 * @return array  The final schema.
162
+	 * @throws EE_Error
163
+	 * @throws EE_Error
164
+	 */
165
+	protected function customizeSchemaForRestResponse(EEM_Base $model, array $schema)
166
+	{
167
+		foreach ($this->getModelVersionInfo()->fieldsOnModelInThisVersion($model) as $field_name => $field) {
168
+			$schema = $this->translateDefaultsForRestResponse(
169
+				$field_name,
170
+				$field,
171
+				$this->maybeAddExtraFieldsToSchema($field_name, $field, $schema)
172
+			);
173
+		}
174
+		return $schema;
175
+	}
176
+
177
+
178
+	/**
179
+	 * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
180
+	 * response.
181
+	 *
182
+	 * @param                      $field_name
183
+	 * @param EE_Model_Field_Base  $field
184
+	 * @param array                $schema
185
+	 * @return array
186
+	 * @throws RestException  if a default value has a PHP object, which we should never do
187
+	 *                                  (but if we did, let's know about it ASAP, so let the exception bubble up)
188
+	 * @throws EE_Error
189
+	 *
190
+	 */
191
+	protected function translateDefaultsForRestResponse($field_name, EE_Model_Field_Base $field, array $schema)
192
+	{
193
+		if (isset($schema['properties'][ $field_name ]['default'])) {
194
+			if (is_array($schema['properties'][ $field_name ]['default'])) {
195
+				foreach ($schema['properties'][ $field_name ]['default'] as $default_key => $default_value) {
196
+					if ($default_key === 'raw') {
197
+						$schema['properties'][ $field_name ]['default'][ $default_key ] =
198
+							ModelDataTranslator::prepareFieldValueForJson(
199
+								$field,
200
+								$default_value,
201
+								$this->getModelVersionInfo()->requestedVersion()
202
+							);
203
+					}
204
+				}
205
+			} else {
206
+				$schema['properties'][ $field_name ]['default'] = ModelDataTranslator::prepareFieldValueForJson(
207
+					$field,
208
+					$schema['properties'][ $field_name ]['default'],
209
+					$this->getModelVersionInfo()->requestedVersion()
210
+				);
211
+			}
212
+		}
213
+		return $schema;
214
+	}
215
+
216
+
217
+	/**
218
+	 * Adds additional fields to the schema
219
+	 * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
220
+	 * needs to be added to the schema.
221
+	 *
222
+	 * @param                      $field_name
223
+	 * @param EE_Model_Field_Base  $field
224
+	 * @param array                $schema
225
+	 * @return array
226
+	 */
227
+	protected function maybeAddExtraFieldsToSchema($field_name, EE_Model_Field_Base $field, array $schema)
228
+	{
229
+		if ($field instanceof EE_Datetime_Field) {
230
+			$schema['properties'][ $field_name . '_gmt' ] = $field->getSchema();
231
+			// modify the description
232
+			$schema['properties'][ $field_name . '_gmt' ]['description'] = sprintf(
233
+				esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
234
+				wp_specialchars_decode($field->get_nicename(), ENT_QUOTES)
235
+			);
236
+		}
237
+		return $schema;
238
+	}
239
+
240
+
241
+	/**
242
+	 * Used to figure out the route from the request when a `WP_REST_Request` object is not available
243
+	 *
244
+	 * @return string
245
+	 */
246
+	protected function getRouteFromRequest()
247
+	{
248
+		if (
249
+			isset($GLOBALS['wp'])
250
+			&& $GLOBALS['wp'] instanceof WP
251
+			&& isset($GLOBALS['wp']->query_vars['rest_route'])
252
+		) {
253
+			return $GLOBALS['wp']->query_vars['rest_route'];
254
+		} else {
255
+			/** @var RequestInterface $request */
256
+			$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
257
+			return $request->serverParamIsSet('PATH_INFO')
258
+				? $request->getServerParam('PATH_INFO')
259
+				: '/';
260
+		}
261
+	}
262
+
263
+
264
+	/**
265
+	 * Gets a single entity related to the model indicated in the path and its id
266
+	 *
267
+	 * @param WP_REST_Request $request
268
+	 * @param string          $version
269
+	 * @param string          $model_name
270
+	 * @return WP_REST_Response|WP_Error
271
+	 * @throws InvalidDataTypeException
272
+	 * @throws InvalidInterfaceException
273
+	 * @throws InvalidArgumentException
274
+	 */
275
+	public static function handleRequestGetOne(WP_REST_Request $request, $version, $model_name)
276
+	{
277
+		$controller =
278
+			LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
279
+		try {
280
+			$controller->setRequestedVersion($version);
281
+			if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
282
+				return $controller->sendResponse(
283
+					new WP_Error(
284
+						'endpoint_parsing_error',
285
+						sprintf(
286
+							esc_html__(
287
+								'There is no model for endpoint %s. Please contact event espresso support',
288
+								'event_espresso'
289
+							),
290
+							$model_name
291
+						)
292
+					)
293
+				);
294
+			}
295
+			return $controller->sendResponse(
296
+				$controller->getEntityFromModel(
297
+					$controller->getModelVersionInfo()->loadModel($model_name),
298
+					$request
299
+				)
300
+			);
301
+		} catch (Exception $e) {
302
+			return $controller->sendResponse($e);
303
+		}
304
+	}
305
+
306
+
307
+	/**
308
+	 * Gets all the related entities (or if its a belongs-to relation just the one)
309
+	 * to the item with the given id
310
+	 *
311
+	 * @param WP_REST_Request $request
312
+	 * @param string          $version
313
+	 * @param string          $model_name
314
+	 * @param string          $related_model_name
315
+	 * @return WP_REST_Response|WP_Error
316
+	 * @throws InvalidDataTypeException
317
+	 * @throws InvalidInterfaceException
318
+	 * @throws InvalidArgumentException
319
+	 */
320
+	public static function handleRequestGetRelated(
321
+		WP_REST_Request $request,
322
+		$version,
323
+		$model_name,
324
+		$related_model_name
325
+	) {
326
+		$controller =
327
+			LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
328
+		try {
329
+			$controller->setRequestedVersion($version);
330
+			$main_model = $controller->validateModel($model_name);
331
+			$controller->validateModel($related_model_name);
332
+			return $controller->sendResponse(
333
+				$controller->getEntitiesFromRelation(
334
+					$request->get_param('id'),
335
+					$main_model->related_settings_for($related_model_name),
336
+					$request
337
+				)
338
+			);
339
+		} catch (Exception $e) {
340
+			return $controller->sendResponse($e);
341
+		}
342
+	}
343
+
344
+
345
+	/**
346
+	 * Gets a collection for the given model and filters
347
+	 *
348
+	 * @param EEM_Base        $model
349
+	 * @param WP_REST_Request $request
350
+	 * @return array
351
+	 * @throws EE_Error
352
+	 * @throws InvalidArgumentException
353
+	 * @throws InvalidDataTypeException
354
+	 * @throws InvalidInterfaceException
355
+	 * @throws ReflectionException
356
+	 * @throws RestException
357
+	 */
358
+	public function getEntitiesFromModel($model, $request)
359
+	{
360
+		$query_params = $this->createModelQueryParams($model, $request->get_params());
361
+		if (! Capabilities::currentUserHasPartialAccessTo($model, $query_params['caps'])) {
362
+			$model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
363
+			throw new RestException(
364
+				sprintf('rest_%s_cannot_list', $model_name_plural),
365
+				sprintf(
366
+					esc_html__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
367
+					$model_name_plural,
368
+					Capabilities::getMissingPermissionsString($model, $query_params['caps'])
369
+				),
370
+				['status' => 403]
371
+			);
372
+		}
373
+		if (! $request->get_header('no_rest_headers')) {
374
+			$this->setHeadersFromQueryParams($model, $query_params);
375
+		}
376
+		/** @type array $results */
377
+		$results      = $model->get_all_wpdb_results($query_params);
378
+		$nice_results = [];
379
+		foreach ($results as $result) {
380
+			$nice_results[] = $this->createEntityFromWpdbResult(
381
+				$model,
382
+				$result,
383
+				$request
384
+			);
385
+		}
386
+		return $nice_results;
387
+	}
388
+
389
+
390
+	/**
391
+	 * Gets the collection for given relation object
392
+	 * The same as Read::get_entities_from_model(), except if the relation
393
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
394
+	 * the join-model-object into the results
395
+	 *
396
+	 * @param array                  $primary_model_query_params  query params for finding the item from which
397
+	 *                                                            relations will be based
398
+	 * @param EE_Model_Relation_Base $relation
399
+	 * @param WP_REST_Request        $request
400
+	 * @return array
401
+	 * @throws EE_Error
402
+	 * @throws InvalidArgumentException
403
+	 * @throws InvalidDataTypeException
404
+	 * @throws InvalidInterfaceException
405
+	 * @throws ReflectionException
406
+	 * @throws RestException
407
+	 * @throws ModelConfigurationException
408
+	 */
409
+	protected function getEntitiesFromRelationUsingModelQueryParams($primary_model_query_params, $relation, $request)
410
+	{
411
+		$context       = $this->validateContext($request->get_param('caps'));
412
+		$model         = $relation->get_this_model();
413
+		$related_model = $relation->get_other_model();
414
+		if (! isset($primary_model_query_params[0])) {
415
+			$primary_model_query_params[0] = [];
416
+		}
417
+		// check if they can access the 1st model object
418
+		$primary_model_query_params = [
419
+			0       => $primary_model_query_params[0],
420
+			'limit' => 1,
421
+		];
422
+		if ($model instanceof EEM_Soft_Delete_Base) {
423
+			$primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included(
424
+				$primary_model_query_params
425
+			);
426
+		}
427
+		$restricted_query_params          = $primary_model_query_params;
428
+		$restricted_query_params['caps']  = $context;
429
+		$restricted_query_params['limit'] = 1;
430
+		$this->setDebugInfo('main model query params', $restricted_query_params);
431
+		$this->setDebugInfo('missing caps', Capabilities::getMissingPermissionsString($related_model, $context));
432
+		$primary_model_rows = $model->get_all_wpdb_results($restricted_query_params);
433
+		$primary_model_row  = null;
434
+		if (is_array($primary_model_rows)) {
435
+			$primary_model_row = reset($primary_model_rows);
436
+		}
437
+		if (
438
+			! (
439
+				$primary_model_row
440
+				&& Capabilities::currentUserHasPartialAccessTo($related_model, $context)
441
+			)
442
+		) {
443
+			if ($relation instanceof EE_Belongs_To_Relation) {
444
+				$related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
445
+			} else {
446
+				$related_model_name_maybe_plural = EEH_Inflector::pluralize_and_lower(
447
+					$related_model->get_this_model_name()
448
+				);
449
+			}
450
+			throw new RestException(
451
+				sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
452
+				sprintf(
453
+					esc_html__(
454
+						'Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
455
+						'event_espresso'
456
+					),
457
+					$related_model_name_maybe_plural,
458
+					$relation->get_this_model()->get_this_model_name(),
459
+					implode(
460
+						',',
461
+						array_keys(
462
+							Capabilities::getMissingPermissions($related_model, $context)
463
+						)
464
+					)
465
+				),
466
+				['status' => 403]
467
+			);
468
+		}
469
+
470
+		$this->checkPassword(
471
+			$model,
472
+			$primary_model_row,
473
+			$restricted_query_params,
474
+			$request
475
+		);
476
+		$query_params = $this->createModelQueryParams($relation->get_other_model(), $request->get_params());
477
+		foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
478
+			$query_params[0][ $relation->get_this_model()->get_this_model_name()
479
+							  . '.'
480
+							  . $where_condition_key ] = $where_condition_value;
481
+		}
482
+		$query_params['default_where_conditions'] = 'none';
483
+		$query_params['caps']                     = $context;
484
+		if (! $request->get_header('no_rest_headers')) {
485
+			$this->setHeadersFromQueryParams($relation->get_other_model(), $query_params);
486
+		}
487
+		/** @type array $results */
488
+		$results      = $relation->get_other_model()->get_all_wpdb_results($query_params);
489
+		$nice_results = [];
490
+		foreach ($results as $result) {
491
+			$nice_result = $this->createEntityFromWpdbResult(
492
+				$relation->get_other_model(),
493
+				$result,
494
+				$request
495
+			);
496
+			if ($relation instanceof EE_HABTM_Relation) {
497
+				// put the unusual stuff (properties from the HABTM relation) first, and make sure
498
+				// if there are conflicts we prefer the properties from the main model
499
+				$join_model_result = $this->createEntityFromWpdbResult(
500
+					$relation->get_join_model(),
501
+					$result,
502
+					$request
503
+				);
504
+				$joined_result     = array_merge($join_model_result, $nice_result);
505
+				// but keep the meta stuff from the main model
506
+				if (isset($nice_result['meta'])) {
507
+					$joined_result['meta'] = $nice_result['meta'];
508
+				}
509
+				$nice_result = $joined_result;
510
+			}
511
+			$nice_results[] = $nice_result;
512
+		}
513
+		if ($relation instanceof EE_Belongs_To_Relation) {
514
+			return array_shift($nice_results);
515
+		} else {
516
+			return $nice_results;
517
+		}
518
+	}
519
+
520
+
521
+	/**
522
+	 * Gets the collection for given relation object
523
+	 * The same as Read::get_entities_from_model(), except if the relation
524
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
525
+	 * the join-model-object into the results
526
+	 *
527
+	 * @param string                 $id the ID of the thing we are fetching related stuff from
528
+	 * @param EE_Model_Relation_Base $relation
529
+	 * @param WP_REST_Request        $request
530
+	 * @return array
531
+	 * @throws EE_Error
532
+	 * @throws ReflectionException
533
+	 */
534
+	public function getEntitiesFromRelation($id, $relation, $request)
535
+	{
536
+		if (! $relation->get_this_model()->has_primary_key_field()) {
537
+			throw new EE_Error(
538
+				sprintf(
539
+					esc_html__(
540
+					// @codingStandardsIgnoreStart
541
+						'Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
542
+						// @codingStandardsIgnoreEnd
543
+						'event_espresso'
544
+					),
545
+					$relation->get_this_model()->get_this_model_name()
546
+				)
547
+			);
548
+		}
549
+		// can we edit that main item?
550
+		// if not, show nothing but an error
551
+		// otherwise, please proceed
552
+		return $this->getEntitiesFromRelationUsingModelQueryParams(
553
+			[
554
+				[
555
+					$relation->get_this_model()->primary_key_name() => $id,
556
+				],
557
+			],
558
+			$relation,
559
+			$request
560
+		);
561
+	}
562
+
563
+
564
+	/**
565
+	 * Sets the headers that are based on the model and query params,
566
+	 * like the total records. This should only be called on the original request
567
+	 * from the client, not on subsequent internal
568
+	 *
569
+	 * @param EEM_Base $model
570
+	 * @param array    $query_params
571
+	 * @return void
572
+	 * @throws EE_Error
573
+	 * @throws EE_Error
574
+	 */
575
+	protected function setHeadersFromQueryParams($model, $query_params)
576
+	{
577
+		$this->setDebugInfo('model query params', $query_params);
578
+		$this->setDebugInfo(
579
+			'missing caps',
580
+			Capabilities::getMissingPermissionsString($model, $query_params['caps'])
581
+		);
582
+		// normally the limit to a 2-part array, where the 2nd item is the limit
583
+		if (! isset($query_params['limit'])) {
584
+			$query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
585
+		}
586
+		if (is_array($query_params['limit'])) {
587
+			$limit_parts = $query_params['limit'];
588
+		} else {
589
+			$limit_parts = explode(',', $query_params['limit']);
590
+			if (count($limit_parts) == 1) {
591
+				$limit_parts = [0, $limit_parts[0]];
592
+			}
593
+		}
594
+		// remove the group by and having parts of the query, as those will
595
+		// make the sql query return an array of values, instead of just a single value
596
+		unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
597
+		$count = $model->count($query_params, null, true);
598
+		$pages = $count / $limit_parts[1];
599
+		$this->setResponseHeader('Total', $count, false);
600
+		$this->setResponseHeader('PageSize', $limit_parts[1], false);
601
+		$this->setResponseHeader('TotalPages', ceil($pages), false);
602
+	}
603
+
604
+
605
+	/**
606
+	 * Changes database results into REST API entities
607
+	 *
608
+	 * @param EEM_Base        $model
609
+	 * @param array           $db_row     like results from $wpdb->get_results()
610
+	 * @param WP_REST_Request $rest_request
611
+	 * @param string          $deprecated no longer used
612
+	 * @return array ready for being converted into json for sending to client
613
+	 * @throws EE_Error
614
+	 * @throws RestException
615
+	 * @throws InvalidDataTypeException
616
+	 * @throws InvalidInterfaceException
617
+	 * @throws InvalidArgumentException
618
+	 * @throws ReflectionException
619
+	 */
620
+	public function createEntityFromWpdbResult($model, $db_row, $rest_request, $deprecated = null)
621
+	{
622
+		if (! $rest_request instanceof WP_REST_Request) {
623
+			// ok so this was called in the old style, where the 3rd arg was
624
+			// $include, and the 4th arg was $context
625
+			// now setup the request just to avoid fatal errors, although we won't be able
626
+			// to truly make use of it because it's kinda devoid of info
627
+			$rest_request = new WP_REST_Request();
628
+			$rest_request->set_param('include', $rest_request);
629
+			$rest_request->set_param('caps', $deprecated);
630
+		}
631
+		if ($rest_request->get_param('caps') == null) {
632
+			$rest_request->set_param('caps', EEM_Base::caps_read);
633
+		}
634
+		$current_user_full_access_to_entity = $model->currentUserCan(
635
+			EEM_Base::caps_read_admin,
636
+			$model->deduce_fields_n_values_from_cols_n_values($db_row)
637
+		);
638
+		$entity_array                       = $this->createBareEntityFromWpdbResults($model, $db_row);
639
+		$entity_array                       = $this->addExtraFields($model, $db_row, $entity_array);
640
+		$entity_array['_links']             = $this->getEntityLinks($model, $db_row, $entity_array);
641
+		// when it's a regular read request for a model with a password and the password wasn't provided
642
+		// remove the password protected fields
643
+		$has_protected_fields = false;
644
+		try {
645
+			$this->checkPassword(
646
+				$model,
647
+				$db_row,
648
+				$model->alter_query_params_to_restrict_by_ID(
649
+					$model->get_index_primary_key_string(
650
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
651
+					)
652
+				),
653
+				$rest_request
654
+			);
655
+		} catch (RestPasswordRequiredException $e) {
656
+			if ($model->hasPassword()) {
657
+				// just remove protected fields
658
+				$has_protected_fields = true;
659
+				$entity_array         = Capabilities::filterOutPasswordProtectedFields(
660
+					$entity_array,
661
+					$model,
662
+					$this->getModelVersionInfo()
663
+				);
664
+			} else {
665
+				// that's a problem. None of this should be accessible if no password was provided
666
+				throw $e;
667
+			}
668
+		}
669
+
670
+		$entity_array['_calculated_fields'] =
671
+			$this->getEntityCalculations($model, $db_row, $rest_request, $has_protected_fields);
672
+		$entity_array                       = apply_filters(
673
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
674
+			$entity_array,
675
+			$model,
676
+			$rest_request->get_param('caps'),
677
+			$rest_request,
678
+			$this
679
+		);
680
+		// add an empty protected property for now. If it's still around after we remove everything the request didn't
681
+		// want, we'll populate it then. k?
682
+		$entity_array['_protected'] = [];
683
+		// remove any properties the request didn't want. This way _protected won't bother mentioning them
684
+		$entity_array = $this->includeOnlyRequestedProperties($model, $rest_request, $entity_array);
685
+		$entity_array =
686
+			$this->includeRequestedModels($model, $rest_request, $entity_array, $db_row, $has_protected_fields);
687
+		// if they still wanted the _protected property, add it.
688
+		if (isset($entity_array['_protected'])) {
689
+			$entity_array = $this->addProtectedProperty($model, $entity_array, $has_protected_fields);
690
+		}
691
+		$entity_array = apply_filters(
692
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
693
+			$entity_array,
694
+			$model,
695
+			$rest_request->get_param('caps'),
696
+			$rest_request,
697
+			$this
698
+		);
699
+		if (! $current_user_full_access_to_entity) {
700
+			$result_without_inaccessible_fields = Capabilities::filterOutInaccessibleEntityFields(
701
+				$entity_array,
702
+				$model,
703
+				$rest_request->get_param('caps'),
704
+				$this->getModelVersionInfo()
705
+			);
706
+		} else {
707
+			$result_without_inaccessible_fields = $entity_array;
708
+		}
709
+		$this->setDebugInfo(
710
+			'inaccessible fields',
711
+			array_keys(array_diff_key((array) $entity_array, (array) $result_without_inaccessible_fields))
712
+		);
713
+		return apply_filters(
714
+			'FHEE__Read__create_entity_from_wpdb_results__entity_return',
715
+			$result_without_inaccessible_fields,
716
+			$model,
717
+			$rest_request->get_param('caps')
718
+		);
719
+	}
720
+
721
+
722
+	/**
723
+	 * Returns an array describing which fields can be protected, and which actually were removed this request
724
+	 *
725
+	 * @param EEM_Base $model
726
+	 * @param array    $results_so_far
727
+	 * @param bool     $protected
728
+	 * @return array results
729
+	 * @throws EE_Error
730
+	 * @since 4.9.74.p
731
+	 */
732
+	protected function addProtectedProperty(EEM_Base $model, $results_so_far, $protected)
733
+	{
734
+		if (! $model->hasPassword() || ! $protected) {
735
+			return $results_so_far;
736
+		}
737
+		$password_field  = $model->getPasswordField();
738
+		$all_protected   = array_merge(
739
+			[$password_field->get_name()],
740
+			$password_field->protectedFields()
741
+		);
742
+		$fields_included = array_keys($results_so_far);
743
+		$fields_included = array_intersect(
744
+			$all_protected,
745
+			$fields_included
746
+		);
747
+		foreach ($fields_included as $field_name) {
748
+			$results_so_far['_protected'][] = $field_name;
749
+		}
750
+		return $results_so_far;
751
+	}
752
+
753
+
754
+	/**
755
+	 * Creates a REST entity array (JSON object we're going to return in the response, but
756
+	 * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
757
+	 * from $wpdb->get_row( $sql, ARRAY_A)
758
+	 *
759
+	 * @param EEM_Base $model
760
+	 * @param array    $db_row
761
+	 * @return array entity mostly ready for converting to JSON and sending in the response
762
+	 * @throws EE_Error
763
+	 * @throws ReflectionException
764
+	 * @throws RestException
765
+	 */
766
+	protected function createBareEntityFromWpdbResults(EEM_Base $model, $db_row)
767
+	{
768
+		$result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
769
+		$result = array_intersect_key(
770
+			$result,
771
+			$this->getModelVersionInfo()->fieldsOnModelInThisVersion($model)
772
+		);
773
+		// if this is a CPT, we need to set the global $post to it,
774
+		// otherwise shortcodes etc won't work properly while rendering it
775
+		if ($model instanceof EEM_CPT_Base) {
776
+			$do_chevy_shuffle = true;
777
+		} else {
778
+			$do_chevy_shuffle = false;
779
+		}
780
+		if ($do_chevy_shuffle) {
781
+			global $post;
782
+			$old_post = $post;
783
+			$post     = get_post($result[ $model->primary_key_name() ]);
784
+			if (! $post instanceof WP_Post) {
785
+				// well that's weird, because $result is what we JUST fetched from the database
786
+				throw new RestException(
787
+					'error_fetching_post_from_database_results',
788
+					esc_html__(
789
+						'An item was retrieved from the database but it\'s not a WP_Post like it should be.',
790
+						'event_espresso'
791
+					)
792
+				);
793
+			}
794
+			$model_object_classname          = 'EE_' . $model->get_this_model_name();
795
+			$post->{$model_object_classname} = EE_Registry::instance()->load_class(
796
+				$model_object_classname,
797
+				$result,
798
+				false,
799
+				false
800
+			);
801
+		}
802
+		foreach ($result as $field_name => $field_value) {
803
+			$field_obj = $model->field_settings_for($field_name);
804
+			if ($this->isSubclassOfOne($field_obj, $this->getModelVersionInfo()->fieldsIgnored())) {
805
+				unset($result[ $field_name ]);
806
+			} elseif (
807
+				$this->isSubclassOfOne(
808
+					$field_obj,
809
+					$this->getModelVersionInfo()->fieldsThatHaveRenderedFormat()
810
+				)
811
+			) {
812
+				$result[ $field_name ] = [
813
+					'raw'      => $this->prepareFieldObjValueForJson($field_obj, $field_value),
814
+					'rendered' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
815
+				];
816
+			} elseif (
817
+				$this->isSubclassOfOne(
818
+					$field_obj,
819
+					$this->getModelVersionInfo()->fieldsThatHavePrettyFormat()
820
+				)
821
+			) {
822
+				$result[ $field_name ] = [
823
+					'raw'    => $this->prepareFieldObjValueForJson($field_obj, $field_value),
824
+					'pretty' => $this->prepareFieldObjValueForJson($field_obj, $field_value, 'pretty'),
825
+				];
826
+			} elseif ($field_obj instanceof EE_Datetime_Field) {
827
+				$field_value = $field_obj->prepare_for_set_from_db($field_value);
828
+				// if the value is null, but we're not supposed to permit null, then set to the field's default
829
+				if (is_null($field_value)) {
830
+					$field_value = $field_obj->getDefaultDateTimeObj();
831
+				}
832
+				if (is_null($field_value)) {
833
+					$gmt_date = $local_date = ModelDataTranslator::prepareFieldValuesForJson(
834
+						$field_obj,
835
+						$field_value,
836
+						$this->getModelVersionInfo()->requestedVersion()
837
+					);
838
+				} else {
839
+					$timezone = $field_value->getTimezone();
840
+					EEH_DTT_Helper::setTimezone($field_value, new DateTimeZone('UTC'));
841
+					$gmt_date = ModelDataTranslator::prepareFieldValuesForJson(
842
+						$field_obj,
843
+						$field_value,
844
+						$this->getModelVersionInfo()->requestedVersion()
845
+					);
846
+					EEH_DTT_Helper::setTimezone($field_value, $timezone);
847
+					$local_date = ModelDataTranslator::prepareFieldValuesForJson(
848
+						$field_obj,
849
+						$field_value,
850
+						$this->getModelVersionInfo()->requestedVersion()
851
+					);
852
+				}
853
+				$result[ $field_name . '_gmt' ] = $gmt_date;
854
+				$result[ $field_name ]          = $local_date;
855
+			} else {
856
+				$result[ $field_name ] = $this->prepareFieldObjValueForJson($field_obj, $field_value);
857
+			}
858
+		}
859
+		if ($do_chevy_shuffle) {
860
+			$post = $old_post;
861
+		}
862
+		return $result;
863
+	}
864
+
865
+
866
+	/**
867
+	 * Takes a value all the way from the DB representation, to the model object's representation, to the
868
+	 * user-facing PHP representation, to the REST API representation. (Assumes you've already taken from the DB
869
+	 * representation using $field_obj->prepare_for_set_from_db())
870
+	 *
871
+	 * @param EE_Model_Field_Base $field_obj
872
+	 * @param mixed               $value  as it's stored on a model object
873
+	 * @param string              $format valid values are 'normal' (default), 'pretty', 'datetime_obj'
874
+	 * @return array
875
+	 * @throws RestException if $value contains a PHP object
876
+	 * @throws EE_Error
877
+	 */
878
+	protected function prepareFieldObjValueForJson(EE_Model_Field_Base $field_obj, $value, $format = 'normal')
879
+	{
880
+		$value = $field_obj->prepare_for_set_from_db($value);
881
+		switch ($format) {
882
+			case 'pretty':
883
+				$value = $field_obj->prepare_for_pretty_echoing($value);
884
+				break;
885
+			case 'normal':
886
+			default:
887
+				$value = $field_obj->prepare_for_get($value);
888
+				break;
889
+		}
890
+		return ModelDataTranslator::prepareFieldValuesForJson(
891
+			$field_obj,
892
+			$value,
893
+			$this->getModelVersionInfo()->requestedVersion()
894
+		);
895
+	}
896
+
897
+
898
+	/**
899
+	 * Adds a few extra fields to the entity response
900
+	 *
901
+	 * @param EEM_Base $model
902
+	 * @param array    $db_row
903
+	 * @param array    $entity_array
904
+	 * @return array modified entity
905
+	 * @throws EE_Error
906
+	 * @throws EE_Error
907
+	 */
908
+	protected function addExtraFields(EEM_Base $model, $db_row, $entity_array)
909
+	{
910
+		if ($model instanceof EEM_CPT_Base) {
911
+			$entity_array['link'] = get_permalink($db_row[ $model->get_primary_key_field()->get_qualified_column() ]);
912
+		}
913
+		return $entity_array;
914
+	}
915
+
916
+
917
+	/**
918
+	 * Gets links we want to add to the response
919
+	 *
920
+	 * @param EEM_Base        $model
921
+	 * @param array           $db_row
922
+	 * @param array           $entity_array
923
+	 * @return array the _links item in the entity
924
+	 * @throws EE_Error
925
+	 * @throws EE_Error
926
+	 * @global WP_REST_Server $wp_rest_server
927
+	 */
928
+	protected function getEntityLinks($model, $db_row, $entity_array)
929
+	{
930
+		// add basic links
931
+		$links = [];
932
+		if ($model->has_primary_key_field()) {
933
+			$links['self'] = [
934
+				[
935
+					'href' => $this->getVersionedLinkTo(
936
+						EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
937
+						. '/'
938
+						. $entity_array[ $model->primary_key_name() ]
939
+					),
940
+				],
941
+			];
942
+		}
943
+		$links['collection'] = [
944
+			[
945
+				'href' => $this->getVersionedLinkTo(
946
+					EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
947
+				),
948
+			],
949
+		];
950
+		// add links to related models
951
+		if ($model->has_primary_key_field()) {
952
+			foreach ($this->getModelVersionInfo()->relationSettings($model) as $relation_name => $relation_obj) {
953
+				$related_model_part                                                      =
954
+					Read::getRelatedEntityName($relation_name, $relation_obj);
955
+				$links[ EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part ] = [
956
+					[
957
+						'href'   => $this->getVersionedLinkTo(
958
+							EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
959
+							. '/'
960
+							. $entity_array[ $model->primary_key_name() ]
961
+							. '/'
962
+							. $related_model_part
963
+						),
964
+						'single' => $relation_obj instanceof EE_Belongs_To_Relation,
965
+					],
966
+				];
967
+			}
968
+		}
969
+		return $links;
970
+	}
971
+
972
+
973
+	/**
974
+	 * Adds the included models indicated in the request to the entity provided
975
+	 *
976
+	 * @param EEM_Base        $model
977
+	 * @param WP_REST_Request $rest_request
978
+	 * @param array           $entity_array
979
+	 * @param array           $db_row
980
+	 * @param boolean         $included_items_protected if the original item is password protected, don't include any
981
+	 *                                                  related models.
982
+	 * @return array the modified entity
983
+	 * @throws EE_Error
984
+	 * @throws ReflectionException
985
+	 */
986
+	protected function includeRequestedModels(
987
+		EEM_Base $model,
988
+		WP_REST_Request $rest_request,
989
+		$entity_array,
990
+		$db_row = [],
991
+		$included_items_protected = false
992
+	) {
993
+		// if $db_row not included, hope the entity array has what we need
994
+		if (! $db_row) {
995
+			$db_row = $entity_array;
996
+		}
997
+		$relation_settings = $this->getModelVersionInfo()->relationSettings($model);
998
+		foreach ($relation_settings as $relation_name => $relation_obj) {
999
+			$related_fields_to_include   = $this->explodeAndGetItemsPrefixedWith(
1000
+				$rest_request->get_param('include'),
1001
+				$relation_name
1002
+			);
1003
+			$related_fields_to_calculate = $this->explodeAndGetItemsPrefixedWith(
1004
+				$rest_request->get_param('calculate'),
1005
+				$relation_name
1006
+			);
1007
+			// did they specify they wanted to include a related model, or
1008
+			// specific fields from a related model?
1009
+			// or did they specify to calculate a field from a related model?
1010
+			if ($related_fields_to_include || $related_fields_to_calculate) {
1011
+				// if so, we should include at least some part of the related model
1012
+				$pretend_related_request = new WP_REST_Request();
1013
+				$pretend_related_request->set_query_params(
1014
+					[
1015
+						'caps'      => $rest_request->get_param('caps'),
1016
+						'include'   => $related_fields_to_include,
1017
+						'calculate' => $related_fields_to_calculate,
1018
+						'password'  => $rest_request->get_param('password'),
1019
+					]
1020
+				);
1021
+				$pretend_related_request->add_header('no_rest_headers', true);
1022
+				$primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
1023
+					$model->get_index_primary_key_string(
1024
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
1025
+					)
1026
+				);
1027
+				if (! $included_items_protected) {
1028
+					try {
1029
+						$related_results = $this->getEntitiesFromRelationUsingModelQueryParams(
1030
+							$primary_model_query_params,
1031
+							$relation_obj,
1032
+							$pretend_related_request
1033
+						);
1034
+					} catch (RestException $e) {
1035
+						$related_results = null;
1036
+					}
1037
+				} else {
1038
+					// they're protected, hide them.
1039
+					$related_results              = null;
1040
+					$entity_array['_protected'][] = Read::getRelatedEntityName($relation_name, $relation_obj);
1041
+				}
1042
+				if ($related_results instanceof WP_Error || $related_results === null) {
1043
+					$related_results =
1044
+						$relation_obj instanceof EE_Belongs_To_Relation
1045
+							? null
1046
+							: [];
1047
+				}
1048
+				$entity_array[ Read::getRelatedEntityName($relation_name, $relation_obj) ] = $related_results;
1049
+			}
1050
+		}
1051
+		return $entity_array;
1052
+	}
1053
+
1054
+
1055
+	/**
1056
+	 * If the user has requested only specific properties (including meta properties like _links or _protected)
1057
+	 * remove everything else.
1058
+	 *
1059
+	 * @param EEM_Base        $model
1060
+	 * @param WP_REST_Request $rest_request
1061
+	 * @param                 $entity_array
1062
+	 * @return array
1063
+	 * @throws EE_Error
1064
+	 * @since 4.9.74.p
1065
+	 */
1066
+	protected function includeOnlyRequestedProperties(
1067
+		EEM_Base $model,
1068
+		WP_REST_Request $rest_request,
1069
+		$entity_array
1070
+	) {
1071
+
1072
+		$includes_for_this_model = $this->explodeAndGetItemsPrefixedWith($rest_request->get_param('include'), '');
1073
+		$includes_for_this_model = $this->removeModelNamesFromArray($includes_for_this_model);
1074
+		// if they passed in * or didn't specify any includes, return everything
1075
+		if (
1076
+			! in_array('*', $includes_for_this_model)
1077
+			&& ! empty($includes_for_this_model)
1078
+		) {
1079
+			if ($model->has_primary_key_field()) {
1080
+				// always include the primary key. ya just gotta know that at least
1081
+				$includes_for_this_model[] = $model->primary_key_name();
1082
+			}
1083
+			if ($this->explodeAndGetItemsPrefixedWith($rest_request->get_param('calculate'), '')) {
1084
+				$includes_for_this_model[] = '_calculated_fields';
1085
+			}
1086
+			$entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
1087
+		}
1088
+		return $entity_array;
1089
+	}
1090
+
1091
+
1092
+	/**
1093
+	 * Returns a new array with all the names of models removed. Eg
1094
+	 * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
1095
+	 *
1096
+	 * @param array $arr
1097
+	 * @return array
1098
+	 */
1099
+	private function removeModelNamesFromArray($arr)
1100
+	{
1101
+		return array_diff($arr, array_keys(EE_Registry::instance()->non_abstract_db_models));
1102
+	}
1103
+
1104
+
1105
+	/**
1106
+	 * Gets the calculated fields for the response
1107
+	 *
1108
+	 * @param EEM_Base        $model
1109
+	 * @param array           $wpdb_row
1110
+	 * @param WP_REST_Request $rest_request
1111
+	 * @param boolean         $row_is_protected whether this row is password protected or not
1112
+	 * @return stdClass the _calculations item in the entity
1113
+	 * @throws RestException if a default value has a PHP object, which should never do (and if we
1114
+	 * @throws EE_Error
1115
+	 *                                          did, let's know about it ASAP, so let the exception bubble up)
1116
+	 */
1117
+	protected function getEntityCalculations($model, $wpdb_row, $rest_request, $row_is_protected = false)
1118
+	{
1119
+		$calculated_fields = $this->explodeAndGetItemsPrefixedWith(
1120
+			$rest_request->get_param('calculate'),
1121
+			''
1122
+		);
1123
+		// note: setting calculate=* doesn't do anything
1124
+		$calculated_fields_to_return = new stdClass();
1125
+		$protected_fields            = [];
1126
+		foreach ($calculated_fields as $field_to_calculate) {
1127
+			try {
1128
+				// it's password protected, so they shouldn't be able to read this. Remove the value
1129
+				$schema = $this->fields_calculator->getJsonSchemaForModel($model);
1130
+				if (
1131
+					$row_is_protected
1132
+					&& isset($schema['properties'][ $field_to_calculate ]['protected'])
1133
+					&& $schema['properties'][ $field_to_calculate ]['protected']
1134
+				) {
1135
+					$calculated_value   = null;
1136
+					$protected_fields[] = $field_to_calculate;
1137
+					if ($schema['properties'][ $field_to_calculate ]['type']) {
1138
+						switch ($schema['properties'][ $field_to_calculate ]['type']) {
1139
+							case 'boolean':
1140
+								$calculated_value = false;
1141
+								break;
1142
+							case 'integer':
1143
+								$calculated_value = 0;
1144
+								break;
1145
+							case 'string':
1146
+								$calculated_value = '';
1147
+								break;
1148
+							case 'array':
1149
+								$calculated_value = [];
1150
+								break;
1151
+							case 'object':
1152
+								$calculated_value = new stdClass();
1153
+								break;
1154
+						}
1155
+					}
1156
+				} else {
1157
+					$calculated_value = ModelDataTranslator::prepareFieldValueForJson(
1158
+						null,
1159
+						$this->fields_calculator->retrieveCalculatedFieldValue(
1160
+							$model,
1161
+							$field_to_calculate,
1162
+							$wpdb_row,
1163
+							$rest_request,
1164
+							$this
1165
+						),
1166
+						$this->getModelVersionInfo()->requestedVersion()
1167
+					);
1168
+				}
1169
+				$calculated_fields_to_return->{$field_to_calculate} = $calculated_value;
1170
+			} catch (RestException $e) {
1171
+				// if we don't have permission to read it, just leave it out. but let devs know about the problem
1172
+				$this->setResponseHeader(
1173
+					'Notices-Field-Calculation-Errors['
1174
+					. $e->getStringCode()
1175
+					. ']['
1176
+					. $model->get_this_model_name()
1177
+					. ']['
1178
+					. $field_to_calculate
1179
+					. ']',
1180
+					$e->getMessage(),
1181
+					true
1182
+				);
1183
+			}
1184
+		}
1185
+		$calculated_fields_to_return->_protected = $protected_fields;
1186
+		return $calculated_fields_to_return;
1187
+	}
1188
+
1189
+
1190
+	/**
1191
+	 * Gets the full URL to the resource, taking the requested version into account
1192
+	 *
1193
+	 * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
1194
+	 * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
1195
+	 * @throws EE_Error
1196
+	 * @throws EE_Error
1197
+	 */
1198
+	public function getVersionedLinkTo($link_part_after_version_and_slash)
1199
+	{
1200
+		return rest_url(
1201
+			EED_Core_Rest_Api::get_versioned_route_to(
1202
+				$link_part_after_version_and_slash,
1203
+				$this->getModelVersionInfo()->requestedVersion()
1204
+			)
1205
+		);
1206
+	}
1207
+
1208
+
1209
+	/**
1210
+	 * Gets the correct lowercase name for the relation in the API according
1211
+	 * to the relation's type
1212
+	 *
1213
+	 * @param string                 $relation_name
1214
+	 * @param EE_Model_Relation_Base $relation_obj
1215
+	 * @return string
1216
+	 */
1217
+	public static function getRelatedEntityName($relation_name, $relation_obj)
1218
+	{
1219
+		if ($relation_obj instanceof EE_Belongs_To_Relation) {
1220
+			return strtolower($relation_name);
1221
+		} else {
1222
+			return EEH_Inflector::pluralize_and_lower($relation_name);
1223
+		}
1224
+	}
1225
+
1226
+
1227
+	/**
1228
+	 * Gets the one model object with the specified id for the specified model
1229
+	 *
1230
+	 * @param EEM_Base        $model
1231
+	 * @param WP_REST_Request $request
1232
+	 * @return array
1233
+	 * @throws EE_Error
1234
+	 * @throws EE_Error
1235
+	 * @throws ReflectionException
1236
+	 */
1237
+	public function getEntityFromModel($model, $request)
1238
+	{
1239
+		$context = $this->validateContext($request->get_param('caps'));
1240
+		return $this->getOneOrReportPermissionError($model, $request, $context);
1241
+	}
1242
+
1243
+
1244
+	/**
1245
+	 * If a context is provided which isn't valid, maybe it was added in a future
1246
+	 * version so just treat it as a default read
1247
+	 *
1248
+	 * @param string $context
1249
+	 * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
1250
+	 */
1251
+	public function validateContext($context)
1252
+	{
1253
+		if (! $context) {
1254
+			$context = EEM_Base::caps_read;
1255
+		}
1256
+		$valid_contexts = EEM_Base::valid_cap_contexts();
1257
+		if (in_array($context, $valid_contexts)) {
1258
+			return $context;
1259
+		} else {
1260
+			return EEM_Base::caps_read;
1261
+		}
1262
+	}
1263
+
1264
+
1265
+	/**
1266
+	 * Verifies the passed in value is an allowable default where conditions value.
1267
+	 *
1268
+	 * @param $default_query_params
1269
+	 * @return string
1270
+	 */
1271
+	public function validateDefaultQueryParams($default_query_params)
1272
+	{
1273
+		$valid_default_where_conditions_for_api_calls = [
1274
+			EEM_Base::default_where_conditions_all,
1275
+			EEM_Base::default_where_conditions_minimum_all,
1276
+			EEM_Base::default_where_conditions_minimum_others,
1277
+		];
1278
+		if (! $default_query_params) {
1279
+			$default_query_params = EEM_Base::default_where_conditions_all;
1280
+		}
1281
+		if (
1282
+			in_array(
1283
+				$default_query_params,
1284
+				$valid_default_where_conditions_for_api_calls,
1285
+				true
1286
+			)
1287
+		) {
1288
+			return $default_query_params;
1289
+		}
1290
+		return EEM_Base::default_where_conditions_all;
1291
+	}
1292
+
1293
+
1294
+	/**
1295
+	 * Translates API filter get parameter into model query params @see
1296
+	 * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions.
1297
+	 * Note: right now the query parameter keys for fields (and related fields) can be left as-is, but it's quite
1298
+	 * possible this will change someday. Also, this method's contents might be candidate for moving to
1299
+	 * Model_Data_Translator
1300
+	 *
1301
+	 * @param EEM_Base $model
1302
+	 * @param array    $query_params
1303
+	 * @return array model query params (@see
1304
+	 *               https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions)
1305
+	 *               or FALSE to indicate that absolutely no results should be returned
1306
+	 * @throws EE_Error
1307
+	 * @throws RestException
1308
+	 */
1309
+	public function createModelQueryParams($model, $query_params)
1310
+	{
1311
+		$model_query_params = [];
1312
+		if (isset($query_params['where'])) {
1313
+			$model_query_params[0] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1314
+				$query_params['where'],
1315
+				$model,
1316
+				$this->getModelVersionInfo()->requestedVersion()
1317
+			);
1318
+		}
1319
+		if (isset($query_params['order_by'])) {
1320
+			$order_by = $query_params['order_by'];
1321
+		} elseif (isset($query_params['orderby'])) {
1322
+			$order_by = $query_params['orderby'];
1323
+		} else {
1324
+			$order_by = null;
1325
+		}
1326
+		if ($order_by !== null) {
1327
+			if (is_array($order_by)) {
1328
+				$order_by = ModelDataTranslator::prepareFieldNamesInArrayKeysFromJson($order_by);
1329
+			} else {
1330
+				// it's a single item
1331
+				$order_by = ModelDataTranslator::prepareFieldNameFromJson($order_by);
1332
+			}
1333
+			$model_query_params['order_by'] = $order_by;
1334
+		}
1335
+		if (isset($query_params['group_by'])) {
1336
+			$group_by = $query_params['group_by'];
1337
+		} elseif (isset($query_params['groupby'])) {
1338
+			$group_by = $query_params['groupby'];
1339
+		} else {
1340
+			$group_by = array_keys($model->get_combined_primary_key_fields());
1341
+		}
1342
+		// make sure they're all real names
1343
+		if (is_array($group_by)) {
1344
+			$group_by = ModelDataTranslator::prepareFieldNamesFromJson($group_by);
1345
+		}
1346
+		if ($group_by !== null) {
1347
+			$model_query_params['group_by'] = $group_by;
1348
+		}
1349
+		if (isset($query_params['having'])) {
1350
+			$model_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForModels(
1351
+				$query_params['having'],
1352
+				$model,
1353
+				$this->getModelVersionInfo()->requestedVersion()
1354
+			);
1355
+		}
1356
+		if (isset($query_params['order'])) {
1357
+			$model_query_params['order'] = $query_params['order'];
1358
+		}
1359
+		if (isset($query_params['mine'])) {
1360
+			$model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1361
+		}
1362
+		if (isset($query_params['limit'])) {
1363
+			// limit should be either a string like '23' or '23,43', or an array with two items in it
1364
+			if (! is_array($query_params['limit'])) {
1365
+				$limit_array = explode(',', (string) $query_params['limit']);
1366
+			} else {
1367
+				$limit_array = $query_params['limit'];
1368
+			}
1369
+			$sanitized_limit = [];
1370
+			foreach ($limit_array as $limit_part) {
1371
+				if ($this->debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1372
+					throw new EE_Error(
1373
+						sprintf(
1374
+							esc_html__(
1375
+							// @codingStandardsIgnoreStart
1376
+								'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.',
1377
+								// @codingStandardsIgnoreEnd
1378
+								'event_espresso'
1379
+							),
1380
+							wp_json_encode($query_params['limit'])
1381
+						)
1382
+					);
1383
+				}
1384
+				$sanitized_limit[] = (int) $limit_part;
1385
+			}
1386
+			$model_query_params['limit'] = implode(',', $sanitized_limit);
1387
+		} else {
1388
+			$model_query_params['limit'] = EED_Core_Rest_Api::get_default_query_limit();
1389
+		}
1390
+		if (isset($query_params['caps'])) {
1391
+			$model_query_params['caps'] = $this->validateContext($query_params['caps']);
1392
+		} else {
1393
+			$model_query_params['caps'] = EEM_Base::caps_read;
1394
+		}
1395
+		if (isset($query_params['default_where_conditions'])) {
1396
+			$model_query_params['default_where_conditions'] = $this->validateDefaultQueryParams(
1397
+				$query_params['default_where_conditions']
1398
+			);
1399
+		}
1400
+		// if this is a model protected by a password on another model, exclude the password protected
1401
+		// entities by default. But if they passed in a password, try to show them all. If the password is wrong,
1402
+		// though, they'll get an error (see Read::createEntityFromWpdbResult() which calls Read::checkPassword)
1403
+		if (
1404
+			! $model->hasPassword()
1405
+			&& $model->restrictedByRelatedModelPassword()
1406
+			&& $model_query_params['caps'] === EEM_Base::caps_read
1407
+		) {
1408
+			if (empty($query_params['password'])) {
1409
+				$model_query_params['exclude_protected'] = true;
1410
+			}
1411
+		}
1412
+
1413
+		return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_params, $model);
1414
+	}
1415
+
1416
+
1417
+	/**
1418
+	 * Changes the REST-style query params for use in the models
1419
+	 *
1420
+	 * @param EEM_Base $model
1421
+	 * @param array    $query_params sub-array from @see EEM_Base::get_all()
1422
+	 * @return array
1423
+	 * @deprecated
1424
+	 */
1425
+	public function prepareRestQueryParamsKeyForModels($model, $query_params)
1426
+	{
1427
+		$model_ready_query_params = [];
1428
+		foreach ($query_params as $key => $value) {
1429
+			$model_ready_query_params[ $key ] = is_array($value)
1430
+				? $this->prepareRestQueryParamsKeyForModels($model, $value)
1431
+				: $value;
1432
+		}
1433
+		return $model_ready_query_params;
1434
+	}
1435
+
1436
+
1437
+	/**
1438
+	 * @param $model
1439
+	 * @param $query_params
1440
+	 * @return array
1441
+	 * @deprecated instead use ModelDataTranslator::prepareFieldValuesFromJson()
1442
+	 */
1443
+	public function prepareRestQueryParamsValuesForModels($model, $query_params)
1444
+	{
1445
+		$model_ready_query_params = [];
1446
+		foreach ($query_params as $key => $value) {
1447
+			if (is_array($value)) {
1448
+				$model_ready_query_params[ $key ] = $this->prepareRestQueryParamsValuesForModels($model, $value);
1449
+			} else {
1450
+				$model_ready_query_params[ $key ] = $value;
1451
+			}
1452
+		}
1453
+		return $model_ready_query_params;
1454
+	}
1455
+
1456
+
1457
+	/**
1458
+	 * Explodes the string on commas, and only returns items with $prefix followed by a period.
1459
+	 * If no prefix is specified, returns items with no period.
1460
+	 *
1461
+	 * @param string|array $string_to_explode eg "jibba,jabba, blah, blah, blah" or array('jibba', 'jabba' )
1462
+	 * @param string       $prefix            "Event" or "foobar"
1463
+	 * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1464
+	 *                                        we only return strings starting with that and a period; if no prefix was
1465
+	 *                                        specified we return all items containing NO periods
1466
+	 */
1467
+	public function explodeAndGetItemsPrefixedWith($string_to_explode, $prefix)
1468
+	{
1469
+		if (is_string($string_to_explode)) {
1470
+			$exploded_contents = explode(',', $string_to_explode);
1471
+		} elseif (is_array($string_to_explode)) {
1472
+			$exploded_contents = $string_to_explode;
1473
+		} else {
1474
+			$exploded_contents = [];
1475
+		}
1476
+		// if the string was empty, we want an empty array
1477
+		$exploded_contents    = array_filter($exploded_contents);
1478
+		$contents_with_prefix = [];
1479
+		foreach ($exploded_contents as $item) {
1480
+			$item = trim($item);
1481
+			// if no prefix was provided, so we look for items with no "." in them
1482
+			if (! $prefix) {
1483
+				// does this item have a period?
1484
+				if (strpos($item, '.') === false) {
1485
+					// if not, then its what we're looking for
1486
+					$contents_with_prefix[] = $item;
1487
+				}
1488
+			} elseif (strpos($item, $prefix . '.') === 0) {
1489
+				// this item has the prefix and a period, grab it
1490
+				$contents_with_prefix[] = substr(
1491
+					$item,
1492
+					strpos($item, $prefix . '.') + strlen($prefix . '.')
1493
+				);
1494
+			} elseif ($item === $prefix) {
1495
+				// this item is JUST the prefix
1496
+				// so let's grab everything after, which is a blank string
1497
+				$contents_with_prefix[] = '';
1498
+			}
1499
+		}
1500
+		return $contents_with_prefix;
1501
+	}
1502
+
1503
+
1504
+	/**
1505
+	 * @param string $include_string @see Read:handle_request_get_all
1506
+	 * @param string $model_name
1507
+	 * @return array of fields for this model. If $model_name is provided, then
1508
+	 *                               the fields for that model, with the model's name removed from each.
1509
+	 *                               If $include_string was blank or '*' returns an empty array
1510
+	 * @throws EE_Error
1511
+	 * @throws EE_Error
1512
+	 * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1513
+	 *                               Deprecated because its return values were really quite confusing- sometimes it
1514
+	 *                               returned an empty array (when the include string was blank or '*') or sometimes it
1515
+	 *                               returned array('*') (when you provided a model and a model of that kind was
1516
+	 *                               found). Parses the $include_string so we fetch all the field names relating to
1517
+	 *                               THIS model
1518
+	 *                               (ie have NO period in them), or for the provided model (ie start with the model
1519
+	 *                               name and then a period).
1520
+	 */
1521
+	public function extractIncludesForThisModel($include_string, $model_name = null)
1522
+	{
1523
+		if (is_array($include_string)) {
1524
+			$include_string = implode(',', $include_string);
1525
+		}
1526
+		if ($include_string === '*' || $include_string === '') {
1527
+			return [];
1528
+		}
1529
+		$includes                    = explode(',', $include_string);
1530
+		$extracted_fields_to_include = [];
1531
+		if ($model_name) {
1532
+			foreach ($includes as $field_to_include) {
1533
+				$field_to_include = trim($field_to_include);
1534
+				if (strpos($field_to_include, $model_name . '.') === 0) {
1535
+					// found the model name at the exact start
1536
+					$field_sans_model_name         = str_replace($model_name . '.', '', $field_to_include);
1537
+					$extracted_fields_to_include[] = $field_sans_model_name;
1538
+				} elseif ($field_to_include == $model_name) {
1539
+					$extracted_fields_to_include[] = '*';
1540
+				}
1541
+			}
1542
+		} else {
1543
+			// look for ones with no period
1544
+			foreach ($includes as $field_to_include) {
1545
+				$field_to_include = trim($field_to_include);
1546
+				if (
1547
+					strpos($field_to_include, '.') === false
1548
+					&& ! $this->getModelVersionInfo()->isModelNameInThisVersion($field_to_include)
1549
+				) {
1550
+					$extracted_fields_to_include[] = $field_to_include;
1551
+				}
1552
+			}
1553
+		}
1554
+		return $extracted_fields_to_include;
1555
+	}
1556
+
1557
+
1558
+	/**
1559
+	 * Gets the single item using the model according to the request in the context given, otherwise
1560
+	 * returns that it's inaccessible to the current user
1561
+	 *
1562
+	 * @param EEM_Base        $model
1563
+	 * @param WP_REST_Request $request
1564
+	 * @param null            $context
1565
+	 * @return array
1566
+	 * @throws EE_Error
1567
+	 * @throws ReflectionException
1568
+	 */
1569
+	public function getOneOrReportPermissionError(EEM_Base $model, WP_REST_Request $request, $context = null)
1570
+	{
1571
+		$query_params = [[$model->primary_key_name() => $request->get_param('id')], 'limit' => 1];
1572
+		if ($model instanceof EEM_Soft_Delete_Base) {
1573
+			$query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
1574
+		}
1575
+		$restricted_query_params         = $query_params;
1576
+		$restricted_query_params['caps'] = $context;
1577
+		$this->setDebugInfo('model query params', $restricted_query_params);
1578
+		$model_rows = $model->get_all_wpdb_results($restricted_query_params);
1579
+		if (! empty($model_rows)) {
1580
+			return $this->createEntityFromWpdbResult(
1581
+				$model,
1582
+				reset($model_rows),
1583
+				$request
1584
+			);
1585
+		} else {
1586
+			// ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
1587
+			$lowercase_model_name = strtolower($model->get_this_model_name());
1588
+			if ($model->exists($query_params)) {
1589
+				// you got shafted- it existed but we didn't want to tell you!
1590
+				throw new RestException(
1591
+					'rest_user_cannot_' . $context,
1592
+					sprintf(
1593
+						esc_html__('Sorry, you cannot %1$s this %2$s. Missing permissions are: %3$s', 'event_espresso'),
1594
+						$context,
1595
+						$lowercase_model_name,
1596
+						Capabilities::getMissingPermissionsString(
1597
+							$model,
1598
+							$context
1599
+						)
1600
+					),
1601
+					['status' => 403]
1602
+				);
1603
+			} else {
1604
+				// it's not you. It just doesn't exist
1605
+				throw new RestException(
1606
+					sprintf('rest_%s_invalid_id', $lowercase_model_name),
1607
+					sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
1608
+					['status' => 404]
1609
+				);
1610
+			}
1611
+		}
1612
+	}
1613
+
1614
+
1615
+	/**
1616
+	 * Checks that if this content requires a password to be read, that it's been provided and is correct.
1617
+	 *
1618
+	 * @param EEM_Base        $model
1619
+	 * @param array           $model_row
1620
+	 * @param array           $query_params Adds 'default_where_conditions' => 'minimum'
1621
+	 *                                      to ensure we don't confuse trashed with password protected.
1622
+	 * @param WP_REST_Request $request
1623
+	 * @throws EE_Error
1624
+	 * @throws InvalidArgumentException
1625
+	 * @throws InvalidDataTypeException
1626
+	 * @throws InvalidInterfaceException
1627
+	 * @throws RestPasswordRequiredException
1628
+	 * @throws RestPasswordIncorrectException
1629
+	 * @throws ModelConfigurationException
1630
+	 * @throws ReflectionException
1631
+	 * @since 4.9.74.p
1632
+	 */
1633
+	protected function checkPassword(EEM_Base $model, $model_row, $query_params, WP_REST_Request $request)
1634
+	{
1635
+		$query_params['default_where_conditions'] = 'minimum';
1636
+		// stuff is only "protected" for front-end requests. Elsewhere, you either get full permission to access the object
1637
+		// or you don't.
1638
+		$request_caps = $request->get_param('caps');
1639
+		if (isset($request_caps) && $request_caps !== EEM_Base::caps_read) {
1640
+			return;
1641
+		}
1642
+		// if this entity requires a password, they better give it and it better be right!
1643
+		if (
1644
+			$model->hasPassword()
1645
+			&& $model_row[ $model->getPasswordField()->get_qualified_column() ] !== ''
1646
+		) {
1647
+			if (empty($request['password'])) {
1648
+				throw new RestPasswordRequiredException();
1649
+			}
1650
+			if (
1651
+				! hash_equals(
1652
+					$model_row[ $model->getPasswordField()->get_qualified_column() ],
1653
+					$request['password']
1654
+				)
1655
+			) {
1656
+				throw new RestPasswordIncorrectException();
1657
+			}
1658
+		} elseif (
1659
+			// wait! maybe this content is password protected
1660
+			$model->restrictedByRelatedModelPassword()
1661
+			&& $request->get_param('caps') === EEM_Base::caps_read
1662
+		) {
1663
+			$password_supplied = $request->get_param('password');
1664
+			if (empty($password_supplied)) {
1665
+				$query_params['exclude_protected'] = true;
1666
+				if (! $model->exists($query_params)) {
1667
+					throw new RestPasswordRequiredException();
1668
+				}
1669
+			} else {
1670
+				$query_params[0][ $model->modelChainAndPassword() ] = $password_supplied;
1671
+				if (! $model->exists($query_params)) {
1672
+					throw new RestPasswordIncorrectException();
1673
+				}
1674
+			}
1675
+		}
1676
+	}
1677 1677
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/model/Write.php 2 patches
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -134,9 +134,9 @@  discard block
 block discarded – undo
134 134
     {
135 135
         Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
136 136
         $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
137
-        if (! current_user_can($default_cap_to_check_for)) {
137
+        if ( ! current_user_can($default_cap_to_check_for)) {
138 138
             throw new RestException(
139
-                'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
139
+                'rest_cannot_create_'.EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
140 140
                 sprintf(
141 141
                     esc_html__(
142 142
                     // @codingStandardsIgnoreStart
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
         );
165 165
         $model_obj->save();
166 166
         $new_id = $model_obj->ID();
167
-        if (! $new_id) {
167
+        if ( ! $new_id) {
168 168
             throw new RestException(
169 169
                 'rest_insertion_failed',
170 170
                 sprintf(esc_html__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name())
@@ -186,9 +186,9 @@  discard block
 block discarded – undo
186 186
     {
187 187
         Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
188 188
         $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
189
-        if (! current_user_can($default_cap_to_check_for)) {
189
+        if ( ! current_user_can($default_cap_to_check_for)) {
190 190
             throw new RestException(
191
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
191
+                'rest_cannot_edit_'.EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
192 192
                 sprintf(
193 193
                     esc_html__(
194 194
                     // @codingStandardsIgnoreStart
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
             );
203 203
         }
204 204
         $obj_id = $request->get_param('id');
205
-        if (! $obj_id) {
205
+        if ( ! $obj_id) {
206 206
             throw new RestException(
207 207
                 'rest_edit_failed',
208 208
                 sprintf(esc_html__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name())
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
             true
216 216
         );
217 217
         $model_obj = $model->get_one_by_ID($obj_id);
218
-        if (! $model_obj instanceof EE_Base_Class) {
218
+        if ( ! $model_obj instanceof EE_Base_Class) {
219 219
             $lowercase_model_name = strtolower($model->get_this_model_name());
220 220
             throw new RestException(
221 221
                 sprintf('rest_%s_invalid_id', $lowercase_model_name),
@@ -240,9 +240,9 @@  discard block
 block discarded – undo
240 240
     {
241 241
         Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete');
242 242
         $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
243
-        if (! current_user_can($default_cap_to_check_for)) {
243
+        if ( ! current_user_can($default_cap_to_check_for)) {
244 244
             throw new RestException(
245
-                'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
245
+                'rest_cannot_delete_'.EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
246 246
                 sprintf(
247 247
                     esc_html__(
248 248
                     // @codingStandardsIgnoreStart
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
         $obj_id = $request->get_param('id');
259 259
         // this is where we would apply more fine-grained caps
260 260
         $model_obj = $model->get_one_by_ID($obj_id);
261
-        if (! $model_obj instanceof EE_Base_Class) {
261
+        if ( ! $model_obj instanceof EE_Base_Class) {
262 262
             $lowercase_model_name = strtolower($model->get_this_model_name());
263 263
             throw new RestException(
264 264
                 sprintf('rest_%s_invalid_id', $lowercase_model_name),
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
             } else {
317 317
                 $raw_value = $model_obj->get_raw($field_name);
318 318
             }
319
-            $simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value);
319
+            $simulated_db_row[$field_obj->get_qualified_column()] = $field_obj->prepare_for_use_in_db($raw_value);
320 320
         }
321 321
         $read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
322 322
         $read_controller->setRequestedVersion($this->getRequestedVersion());
@@ -447,7 +447,7 @@  discard block
 block discarded – undo
447 447
                     )
448 448
                 )
449 449
             );
450
-            $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
450
+            $response['join'][strtolower($relation->get_join_model()->get_this_model_name())] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
451 451
         }
452 452
         return $response;
453 453
     }
@@ -495,7 +495,7 @@  discard block
 block discarded – undo
495 495
     {
496 496
         // This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know
497 497
         // up-front that it doesn't.)
498
-        if (!empty($request->get_body_params())) {
498
+        if ( ! empty($request->get_body_params())) {
499 499
             $body_params = $request->get_body_params();
500 500
             throw new RestException(
501 501
                 'invalid_field',
@@ -537,9 +537,9 @@  discard block
 block discarded – undo
537 537
                 )
538 538
             );
539 539
             if ($join_model_obj instanceof EE_Base_Class) {
540
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
540
+                $response['join'][strtolower($relation->get_join_model()->get_this_model_name())] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
541 541
             } else {
542
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null;
542
+                $response['join'][strtolower($relation->get_join_model()->get_this_model_name())] = null;
543 543
             }
544 544
         }
545 545
         return $response;
@@ -564,9 +564,9 @@  discard block
 block discarded – undo
564 564
         // Check generic caps. For now, we're only allowing access to this endpoint to full admins.
565 565
         Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
566 566
         $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
567
-        if (! current_user_can($default_cap_to_check_for)) {
567
+        if ( ! current_user_can($default_cap_to_check_for)) {
568 568
             throw new RestException(
569
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
569
+                'rest_cannot_edit_'.EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
570 570
                 sprintf(
571 571
                     esc_html__(
572 572
                         // @codingStandardsIgnoreStart
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
         $model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
584 584
         // For now, we require the other model object to exist too. This might be relaxed later.
585 585
         $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id'));
586
-        return array($model_obj,$other_obj);
586
+        return array($model_obj, $other_obj);
587 587
     }
588 588
 
589 589
     /**
Please login to merge, or discard this patch.
Indentation   +546 added lines, -546 removed lines patch added patch discarded remove patch
@@ -37,573 +37,573 @@
 block discarded – undo
37 37
  */
38 38
 class Write extends Base
39 39
 {
40
-    public function __construct()
41
-    {
42
-        parent::__construct();
43
-        EE_Registry::instance()->load_helper('Inflector');
44
-    }
40
+	public function __construct()
41
+	{
42
+		parent::__construct();
43
+		EE_Registry::instance()->load_helper('Inflector');
44
+	}
45 45
 
46 46
 
47
-    /**
48
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
49
-     *
50
-     * @param WP_REST_Request $request
51
-     * @param string          $version
52
-     * @param string          $model_name
53
-     * @return WP_REST_Response|\WP_Error
54
-     */
55
-    public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name)
56
-    {
57
-        $controller = new Write();
58
-        try {
59
-            $controller->setRequestedVersion($version);
60
-            return $controller->sendResponse(
61
-                $controller->insert(
62
-                    $controller->getModelVersionInfo()->loadModel($model_name),
63
-                    $request
64
-                )
65
-            );
66
-        } catch (Exception $e) {
67
-            return $controller->sendResponse($e);
68
-        }
69
-    }
47
+	/**
48
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
49
+	 *
50
+	 * @param WP_REST_Request $request
51
+	 * @param string          $version
52
+	 * @param string          $model_name
53
+	 * @return WP_REST_Response|\WP_Error
54
+	 */
55
+	public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name)
56
+	{
57
+		$controller = new Write();
58
+		try {
59
+			$controller->setRequestedVersion($version);
60
+			return $controller->sendResponse(
61
+				$controller->insert(
62
+					$controller->getModelVersionInfo()->loadModel($model_name),
63
+					$request
64
+				)
65
+			);
66
+		} catch (Exception $e) {
67
+			return $controller->sendResponse($e);
68
+		}
69
+	}
70 70
 
71 71
 
72
-    /**
73
-     * Handles a request from \WP_REST_Server to update an EE model
74
-     *
75
-     * @param WP_REST_Request $request
76
-     * @param string          $version
77
-     * @param string          $model_name
78
-     * @return WP_REST_Response|\WP_Error
79
-     */
80
-    public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name)
81
-    {
82
-        $controller = new Write();
83
-        try {
84
-            $controller->setRequestedVersion($version);
85
-            return $controller->sendResponse(
86
-                $controller->update(
87
-                    $controller->getModelVersionInfo()->loadModel($model_name),
88
-                    $request
89
-                )
90
-            );
91
-        } catch (Exception $e) {
92
-            return $controller->sendResponse($e);
93
-        }
94
-    }
72
+	/**
73
+	 * Handles a request from \WP_REST_Server to update an EE model
74
+	 *
75
+	 * @param WP_REST_Request $request
76
+	 * @param string          $version
77
+	 * @param string          $model_name
78
+	 * @return WP_REST_Response|\WP_Error
79
+	 */
80
+	public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name)
81
+	{
82
+		$controller = new Write();
83
+		try {
84
+			$controller->setRequestedVersion($version);
85
+			return $controller->sendResponse(
86
+				$controller->update(
87
+					$controller->getModelVersionInfo()->loadModel($model_name),
88
+					$request
89
+				)
90
+			);
91
+		} catch (Exception $e) {
92
+			return $controller->sendResponse($e);
93
+		}
94
+	}
95 95
 
96 96
 
97
-    /**
98
-     * Deletes a single model object and returns it. Unless
99
-     *
100
-     * @param WP_REST_Request $request
101
-     * @param string          $version
102
-     * @param string          $model_name
103
-     * @return WP_REST_Response|\WP_Error
104
-     */
105
-    public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name)
106
-    {
107
-        $controller = new Write();
108
-        try {
109
-            $controller->setRequestedVersion($version);
110
-            return $controller->sendResponse(
111
-                $controller->delete(
112
-                    $controller->getModelVersionInfo()->loadModel($model_name),
113
-                    $request
114
-                )
115
-            );
116
-        } catch (Exception $e) {
117
-            return $controller->sendResponse($e);
118
-        }
119
-    }
97
+	/**
98
+	 * Deletes a single model object and returns it. Unless
99
+	 *
100
+	 * @param WP_REST_Request $request
101
+	 * @param string          $version
102
+	 * @param string          $model_name
103
+	 * @return WP_REST_Response|\WP_Error
104
+	 */
105
+	public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name)
106
+	{
107
+		$controller = new Write();
108
+		try {
109
+			$controller->setRequestedVersion($version);
110
+			return $controller->sendResponse(
111
+				$controller->delete(
112
+					$controller->getModelVersionInfo()->loadModel($model_name),
113
+					$request
114
+				)
115
+			);
116
+		} catch (Exception $e) {
117
+			return $controller->sendResponse($e);
118
+		}
119
+	}
120 120
 
121 121
 
122
-    /**
123
-     * Inserts a new model object according to the $request
124
-     *
125
-     * @param EEM_Base        $model
126
-     * @param WP_REST_Request $request
127
-     * @return array
128
-     * @throws EE_Error
129
-     * @throws RestException
130
-     */
131
-    public function insert(EEM_Base $model, WP_REST_Request $request)
132
-    {
133
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
134
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
135
-        if (! current_user_can($default_cap_to_check_for)) {
136
-            throw new RestException(
137
-                'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
138
-                sprintf(
139
-                    esc_html__(
140
-                    // @codingStandardsIgnoreStart
141
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.',
142
-                        // @codingStandardsIgnoreEnd
143
-                        'event_espresso'
144
-                    ),
145
-                    $default_cap_to_check_for
146
-                ),
147
-                array('status' => 403)
148
-            );
149
-        }
150
-        $submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params());
151
-        $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
152
-            $submitted_json_data,
153
-            $model,
154
-            $this->getModelVersionInfo()->requestedVersion(),
155
-            true
156
-        );
157
-        $model_obj = EE_Registry::instance()->load_class(
158
-            $model->get_this_model_name(),
159
-            array($model_data, $model->get_timezone()),
160
-            false,
161
-            false
162
-        );
163
-        $model_obj->save();
164
-        $new_id = $model_obj->ID();
165
-        if (! $new_id) {
166
-            throw new RestException(
167
-                'rest_insertion_failed',
168
-                sprintf(esc_html__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name())
169
-            );
170
-        }
171
-        return $this->returnModelObjAsJsonResponse($model_obj, $request);
172
-    }
122
+	/**
123
+	 * Inserts a new model object according to the $request
124
+	 *
125
+	 * @param EEM_Base        $model
126
+	 * @param WP_REST_Request $request
127
+	 * @return array
128
+	 * @throws EE_Error
129
+	 * @throws RestException
130
+	 */
131
+	public function insert(EEM_Base $model, WP_REST_Request $request)
132
+	{
133
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
134
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
135
+		if (! current_user_can($default_cap_to_check_for)) {
136
+			throw new RestException(
137
+				'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
138
+				sprintf(
139
+					esc_html__(
140
+					// @codingStandardsIgnoreStart
141
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.',
142
+						// @codingStandardsIgnoreEnd
143
+						'event_espresso'
144
+					),
145
+					$default_cap_to_check_for
146
+				),
147
+				array('status' => 403)
148
+			);
149
+		}
150
+		$submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params());
151
+		$model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
152
+			$submitted_json_data,
153
+			$model,
154
+			$this->getModelVersionInfo()->requestedVersion(),
155
+			true
156
+		);
157
+		$model_obj = EE_Registry::instance()->load_class(
158
+			$model->get_this_model_name(),
159
+			array($model_data, $model->get_timezone()),
160
+			false,
161
+			false
162
+		);
163
+		$model_obj->save();
164
+		$new_id = $model_obj->ID();
165
+		if (! $new_id) {
166
+			throw new RestException(
167
+				'rest_insertion_failed',
168
+				sprintf(esc_html__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name())
169
+			);
170
+		}
171
+		return $this->returnModelObjAsJsonResponse($model_obj, $request);
172
+	}
173 173
 
174 174
 
175
-    /**
176
-     * Updates an existing model object according to the $request
177
-     *
178
-     * @param EEM_Base        $model
179
-     * @param WP_REST_Request $request
180
-     * @return array
181
-     * @throws EE_Error
182
-     */
183
-    public function update(EEM_Base $model, WP_REST_Request $request)
184
-    {
185
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
186
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
187
-        if (! current_user_can($default_cap_to_check_for)) {
188
-            throw new RestException(
189
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
190
-                sprintf(
191
-                    esc_html__(
192
-                    // @codingStandardsIgnoreStart
193
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.',
194
-                        // @codingStandardsIgnoreEnd
195
-                        'event_espresso'
196
-                    ),
197
-                    $default_cap_to_check_for
198
-                ),
199
-                array('status' => 403)
200
-            );
201
-        }
202
-        $obj_id = $request->get_param('id');
203
-        if (! $obj_id) {
204
-            throw new RestException(
205
-                'rest_edit_failed',
206
-                sprintf(esc_html__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name())
207
-            );
208
-        }
209
-        $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
210
-            $this->getBodyParams($request),
211
-            $model,
212
-            $this->getModelVersionInfo()->requestedVersion(),
213
-            true
214
-        );
215
-        $model_obj = $model->get_one_by_ID($obj_id);
216
-        if (! $model_obj instanceof EE_Base_Class) {
217
-            $lowercase_model_name = strtolower($model->get_this_model_name());
218
-            throw new RestException(
219
-                sprintf('rest_%s_invalid_id', $lowercase_model_name),
220
-                sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
221
-                array('status' => 404)
222
-            );
223
-        }
224
-        $model_obj->save($model_data);
225
-        return $this->returnModelObjAsJsonResponse($model_obj, $request);
226
-    }
175
+	/**
176
+	 * Updates an existing model object according to the $request
177
+	 *
178
+	 * @param EEM_Base        $model
179
+	 * @param WP_REST_Request $request
180
+	 * @return array
181
+	 * @throws EE_Error
182
+	 */
183
+	public function update(EEM_Base $model, WP_REST_Request $request)
184
+	{
185
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
186
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
187
+		if (! current_user_can($default_cap_to_check_for)) {
188
+			throw new RestException(
189
+				'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
190
+				sprintf(
191
+					esc_html__(
192
+					// @codingStandardsIgnoreStart
193
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.',
194
+						// @codingStandardsIgnoreEnd
195
+						'event_espresso'
196
+					),
197
+					$default_cap_to_check_for
198
+				),
199
+				array('status' => 403)
200
+			);
201
+		}
202
+		$obj_id = $request->get_param('id');
203
+		if (! $obj_id) {
204
+			throw new RestException(
205
+				'rest_edit_failed',
206
+				sprintf(esc_html__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name())
207
+			);
208
+		}
209
+		$model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
210
+			$this->getBodyParams($request),
211
+			$model,
212
+			$this->getModelVersionInfo()->requestedVersion(),
213
+			true
214
+		);
215
+		$model_obj = $model->get_one_by_ID($obj_id);
216
+		if (! $model_obj instanceof EE_Base_Class) {
217
+			$lowercase_model_name = strtolower($model->get_this_model_name());
218
+			throw new RestException(
219
+				sprintf('rest_%s_invalid_id', $lowercase_model_name),
220
+				sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
221
+				array('status' => 404)
222
+			);
223
+		}
224
+		$model_obj->save($model_data);
225
+		return $this->returnModelObjAsJsonResponse($model_obj, $request);
226
+	}
227 227
 
228 228
 
229
-    /**
230
-     * Updates an existing model object according to the $request
231
-     *
232
-     * @param EEM_Base        $model
233
-     * @param WP_REST_Request $request
234
-     * @return array of either the soft-deleted item, or
235
-     * @throws EE_Error
236
-     */
237
-    public function delete(EEM_Base $model, WP_REST_Request $request)
238
-    {
239
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete');
240
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
241
-        if (! current_user_can($default_cap_to_check_for)) {
242
-            throw new RestException(
243
-                'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
244
-                sprintf(
245
-                    esc_html__(
246
-                    // @codingStandardsIgnoreStart
247
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.',
248
-                        // @codingStandardsIgnoreEnd
249
-                        'event_espresso'
250
-                    ),
251
-                    $default_cap_to_check_for
252
-                ),
253
-                array('status' => 403)
254
-            );
255
-        }
256
-        $obj_id = $request->get_param('id');
257
-        // this is where we would apply more fine-grained caps
258
-        $model_obj = $model->get_one_by_ID($obj_id);
259
-        if (! $model_obj instanceof EE_Base_Class) {
260
-            $lowercase_model_name = strtolower($model->get_this_model_name());
261
-            throw new RestException(
262
-                sprintf('rest_%s_invalid_id', $lowercase_model_name),
263
-                sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
264
-                array('status' => 404)
265
-            );
266
-        }
267
-        $requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN);
268
-        $requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN);
269
-        if ($requested_permanent_delete) {
270
-            $previous = $this->returnModelObjAsJsonResponse($model_obj, $request);
271
-            $deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking);
272
-            return array(
273
-                'deleted'  => $deleted,
274
-                'previous' => $previous,
275
-            );
276
-        } else {
277
-            if ($model instanceof EEM_Soft_Delete_Base) {
278
-                $model->delete_by_ID($obj_id, $requested_allow_blocking);
279
-                return $this->returnModelObjAsJsonResponse($model_obj, $request);
280
-            } else {
281
-                throw new RestException(
282
-                    'rest_trash_not_supported',
283
-                    501,
284
-                    sprintf(
285
-                        esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'),
286
-                        EEH_Inflector::pluralize($model->get_this_model_name())
287
-                    )
288
-                );
289
-            }
290
-        }
291
-    }
229
+	/**
230
+	 * Updates an existing model object according to the $request
231
+	 *
232
+	 * @param EEM_Base        $model
233
+	 * @param WP_REST_Request $request
234
+	 * @return array of either the soft-deleted item, or
235
+	 * @throws EE_Error
236
+	 */
237
+	public function delete(EEM_Base $model, WP_REST_Request $request)
238
+	{
239
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete');
240
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
241
+		if (! current_user_can($default_cap_to_check_for)) {
242
+			throw new RestException(
243
+				'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
244
+				sprintf(
245
+					esc_html__(
246
+					// @codingStandardsIgnoreStart
247
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.',
248
+						// @codingStandardsIgnoreEnd
249
+						'event_espresso'
250
+					),
251
+					$default_cap_to_check_for
252
+				),
253
+				array('status' => 403)
254
+			);
255
+		}
256
+		$obj_id = $request->get_param('id');
257
+		// this is where we would apply more fine-grained caps
258
+		$model_obj = $model->get_one_by_ID($obj_id);
259
+		if (! $model_obj instanceof EE_Base_Class) {
260
+			$lowercase_model_name = strtolower($model->get_this_model_name());
261
+			throw new RestException(
262
+				sprintf('rest_%s_invalid_id', $lowercase_model_name),
263
+				sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
264
+				array('status' => 404)
265
+			);
266
+		}
267
+		$requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN);
268
+		$requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN);
269
+		if ($requested_permanent_delete) {
270
+			$previous = $this->returnModelObjAsJsonResponse($model_obj, $request);
271
+			$deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking);
272
+			return array(
273
+				'deleted'  => $deleted,
274
+				'previous' => $previous,
275
+			);
276
+		} else {
277
+			if ($model instanceof EEM_Soft_Delete_Base) {
278
+				$model->delete_by_ID($obj_id, $requested_allow_blocking);
279
+				return $this->returnModelObjAsJsonResponse($model_obj, $request);
280
+			} else {
281
+				throw new RestException(
282
+					'rest_trash_not_supported',
283
+					501,
284
+					sprintf(
285
+						esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'),
286
+						EEH_Inflector::pluralize($model->get_this_model_name())
287
+					)
288
+				);
289
+			}
290
+		}
291
+	}
292 292
 
293 293
 
294
-    /**
295
-     * Returns an array ready to be converted into a JSON response, based solely on the model object
296
-     *
297
-     * @param EE_Base_Class   $model_obj
298
-     * @param WP_REST_Request $request
299
-     * @return array ready for a response
300
-     */
301
-    protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request)
302
-    {
303
-        $model = $model_obj->get_model();
304
-        // create an array exactly like the wpdb results row,
305
-        // so we can pass it to controllers/model/Read::create_entity_from_wpdb_result()
306
-        $simulated_db_row = array();
307
-        foreach ($model->field_settings(true) as $field_name => $field_obj) {
308
-            // we need to reconstruct the normal wpdb results, including the db-only fields
309
-            // like a secondary table's primary key. The models expect those (but don't care what value they have)
310
-            if ($field_obj instanceof EE_DB_Only_Field_Base) {
311
-                $raw_value = true;
312
-            } elseif ($field_obj instanceof EE_Datetime_Field) {
313
-                $raw_value = $model_obj->get_DateTime_object($field_name);
314
-            } else {
315
-                $raw_value = $model_obj->get_raw($field_name);
316
-            }
317
-            $simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value);
318
-        }
319
-        $read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
320
-        $read_controller->setRequestedVersion($this->getRequestedVersion());
321
-        // the simulates request really doesn't need any info downstream
322
-        $simulated_request = new WP_REST_Request('GET');
323
-        // set the caps context on the simulated according to the original request.
324
-        switch ($request->get_method()) {
325
-            case 'POST':
326
-            case 'PUT':
327
-                $caps_context = EEM_Base::caps_edit;
328
-                break;
329
-            case 'DELETE':
330
-                $caps_context = EEM_Base::caps_delete;
331
-                break;
332
-            default:
333
-                $caps_context = EEM_Base::caps_read_admin;
334
-        }
335
-        $simulated_request->set_param('caps', $caps_context);
336
-        return $read_controller->createEntityFromWpdbResult(
337
-            $model_obj->get_model(),
338
-            $simulated_db_row,
339
-            $simulated_request
340
-        );
341
-    }
294
+	/**
295
+	 * Returns an array ready to be converted into a JSON response, based solely on the model object
296
+	 *
297
+	 * @param EE_Base_Class   $model_obj
298
+	 * @param WP_REST_Request $request
299
+	 * @return array ready for a response
300
+	 */
301
+	protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request)
302
+	{
303
+		$model = $model_obj->get_model();
304
+		// create an array exactly like the wpdb results row,
305
+		// so we can pass it to controllers/model/Read::create_entity_from_wpdb_result()
306
+		$simulated_db_row = array();
307
+		foreach ($model->field_settings(true) as $field_name => $field_obj) {
308
+			// we need to reconstruct the normal wpdb results, including the db-only fields
309
+			// like a secondary table's primary key. The models expect those (but don't care what value they have)
310
+			if ($field_obj instanceof EE_DB_Only_Field_Base) {
311
+				$raw_value = true;
312
+			} elseif ($field_obj instanceof EE_Datetime_Field) {
313
+				$raw_value = $model_obj->get_DateTime_object($field_name);
314
+			} else {
315
+				$raw_value = $model_obj->get_raw($field_name);
316
+			}
317
+			$simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value);
318
+		}
319
+		$read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
320
+		$read_controller->setRequestedVersion($this->getRequestedVersion());
321
+		// the simulates request really doesn't need any info downstream
322
+		$simulated_request = new WP_REST_Request('GET');
323
+		// set the caps context on the simulated according to the original request.
324
+		switch ($request->get_method()) {
325
+			case 'POST':
326
+			case 'PUT':
327
+				$caps_context = EEM_Base::caps_edit;
328
+				break;
329
+			case 'DELETE':
330
+				$caps_context = EEM_Base::caps_delete;
331
+				break;
332
+			default:
333
+				$caps_context = EEM_Base::caps_read_admin;
334
+		}
335
+		$simulated_request->set_param('caps', $caps_context);
336
+		return $read_controller->createEntityFromWpdbResult(
337
+			$model_obj->get_model(),
338
+			$simulated_db_row,
339
+			$simulated_request
340
+		);
341
+	}
342 342
 
343 343
 
344
-    /**
345
-     * Gets the item affected by this request
346
-     *
347
-     * @param EEM_Base        $model
348
-     * @param WP_REST_Request $request
349
-     * @param  int|string     $obj_id
350
-     * @return \WP_Error|array
351
-     */
352
-    protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id)
353
-    {
354
-        $requested_version = $this->getRequestedVersion($request->get_route());
355
-        $get_request = new WP_REST_Request(
356
-            'GET',
357
-            EED_Core_Rest_Api::ee_api_namespace
358
-            . $requested_version
359
-            . '/'
360
-            . EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
361
-            . '/'
362
-            . $obj_id
363
-        );
364
-        $get_request->set_url_params(
365
-            array(
366
-                'id'      => $obj_id,
367
-                'include' => $request->get_param('include'),
368
-            )
369
-        );
370
-        $read_controller = new Read();
371
-        $read_controller->setRequestedVersion($this->getRequestedVersion());
372
-        return $read_controller->getEntityFromModel($model, $get_request);
373
-    }
344
+	/**
345
+	 * Gets the item affected by this request
346
+	 *
347
+	 * @param EEM_Base        $model
348
+	 * @param WP_REST_Request $request
349
+	 * @param  int|string     $obj_id
350
+	 * @return \WP_Error|array
351
+	 */
352
+	protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id)
353
+	{
354
+		$requested_version = $this->getRequestedVersion($request->get_route());
355
+		$get_request = new WP_REST_Request(
356
+			'GET',
357
+			EED_Core_Rest_Api::ee_api_namespace
358
+			. $requested_version
359
+			. '/'
360
+			. EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
361
+			. '/'
362
+			. $obj_id
363
+		);
364
+		$get_request->set_url_params(
365
+			array(
366
+				'id'      => $obj_id,
367
+				'include' => $request->get_param('include'),
368
+			)
369
+		);
370
+		$read_controller = new Read();
371
+		$read_controller->setRequestedVersion($this->getRequestedVersion());
372
+		return $read_controller->getEntityFromModel($model, $get_request);
373
+	}
374 374
 
375
-    /**
376
-     * Adds a relation between the specified models (if it doesn't already exist.)
377
-     * @since 4.9.76.p
378
-     * @param WP_REST_Request $request
379
-     * @return WP_REST_Response
380
-     */
381
-    public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
382
-    {
383
-        $controller = new Write();
384
-        try {
385
-            $controller->setRequestedVersion($version);
386
-            $main_model = $controller->validateModel($model_name);
387
-            $controller->validateModel($related_model_name);
388
-            return $controller->sendResponse(
389
-                $controller->addRelation(
390
-                    $main_model,
391
-                    $main_model->related_settings_for($related_model_name),
392
-                    $request
393
-                )
394
-            );
395
-        } catch (Exception $e) {
396
-            return $controller->sendResponse($e);
397
-        }
398
-    }
375
+	/**
376
+	 * Adds a relation between the specified models (if it doesn't already exist.)
377
+	 * @since 4.9.76.p
378
+	 * @param WP_REST_Request $request
379
+	 * @return WP_REST_Response
380
+	 */
381
+	public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
382
+	{
383
+		$controller = new Write();
384
+		try {
385
+			$controller->setRequestedVersion($version);
386
+			$main_model = $controller->validateModel($model_name);
387
+			$controller->validateModel($related_model_name);
388
+			return $controller->sendResponse(
389
+				$controller->addRelation(
390
+					$main_model,
391
+					$main_model->related_settings_for($related_model_name),
392
+					$request
393
+				)
394
+			);
395
+		} catch (Exception $e) {
396
+			return $controller->sendResponse($e);
397
+		}
398
+	}
399 399
 
400
-    /**
401
-     * Adds a relation between the two model specified model objects.
402
-     * @since 4.9.76.p
403
-     * @param EEM_Base $model
404
-     * @param EE_Model_Relation_Base $relation
405
-     * @param WP_REST_Request $request
406
-     * @return array
407
-     * @throws EE_Error
408
-     * @throws InvalidArgumentException
409
-     * @throws InvalidDataTypeException
410
-     * @throws InvalidInterfaceException
411
-     * @throws RestException
412
-     * @throws DomainException
413
-     */
414
-    public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
415
-    {
416
-        list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
417
-        $extra_params = array();
418
-        if ($relation instanceof EE_HABTM_Relation) {
419
-            $extra_params = array_intersect_key(
420
-                ModelDataTranslator::prepareConditionsQueryParamsForModels(
421
-                    $request->get_body_params(),
422
-                    $relation->get_join_model(),
423
-                    $this->getModelVersionInfo()->requestedVersion(),
424
-                    true
425
-                ),
426
-                $relation->getNonKeyFields()
427
-            );
428
-        }
429
-        // Add a relation.
430
-        $related_obj = $model_obj->_add_relation_to(
431
-            $other_obj,
432
-            $relation->get_other_model()->get_this_model_name(),
433
-            $extra_params
434
-        );
435
-        $response = array(
436
-            strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
437
-            strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
438
-        );
439
-        if ($relation instanceof EE_HABTM_Relation) {
440
-            $join_model_obj = $relation->get_join_model()->get_one(
441
-                array(
442
-                    array(
443
-                        $relation->get_join_model()->get_foreign_key_to($model->get_this_model_name())->get_name() => $model_obj->ID(),
444
-                        $relation->get_join_model()->get_foreign_key_to($relation->get_other_model()->get_this_model_name())->get_name() => $related_obj->ID()
445
-                    )
446
-                )
447
-            );
448
-            $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
449
-        }
450
-        return $response;
451
-    }
400
+	/**
401
+	 * Adds a relation between the two model specified model objects.
402
+	 * @since 4.9.76.p
403
+	 * @param EEM_Base $model
404
+	 * @param EE_Model_Relation_Base $relation
405
+	 * @param WP_REST_Request $request
406
+	 * @return array
407
+	 * @throws EE_Error
408
+	 * @throws InvalidArgumentException
409
+	 * @throws InvalidDataTypeException
410
+	 * @throws InvalidInterfaceException
411
+	 * @throws RestException
412
+	 * @throws DomainException
413
+	 */
414
+	public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
415
+	{
416
+		list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
417
+		$extra_params = array();
418
+		if ($relation instanceof EE_HABTM_Relation) {
419
+			$extra_params = array_intersect_key(
420
+				ModelDataTranslator::prepareConditionsQueryParamsForModels(
421
+					$request->get_body_params(),
422
+					$relation->get_join_model(),
423
+					$this->getModelVersionInfo()->requestedVersion(),
424
+					true
425
+				),
426
+				$relation->getNonKeyFields()
427
+			);
428
+		}
429
+		// Add a relation.
430
+		$related_obj = $model_obj->_add_relation_to(
431
+			$other_obj,
432
+			$relation->get_other_model()->get_this_model_name(),
433
+			$extra_params
434
+		);
435
+		$response = array(
436
+			strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
437
+			strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
438
+		);
439
+		if ($relation instanceof EE_HABTM_Relation) {
440
+			$join_model_obj = $relation->get_join_model()->get_one(
441
+				array(
442
+					array(
443
+						$relation->get_join_model()->get_foreign_key_to($model->get_this_model_name())->get_name() => $model_obj->ID(),
444
+						$relation->get_join_model()->get_foreign_key_to($relation->get_other_model()->get_this_model_name())->get_name() => $related_obj->ID()
445
+					)
446
+				)
447
+			);
448
+			$response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
449
+		}
450
+		return $response;
451
+	}
452 452
 
453 453
 
454
-    /**
455
-     * Removes the relation between the specified models (if it exists).
456
-     * @since 4.9.76.p
457
-     * @param WP_REST_Request $request
458
-     * @return WP_REST_Response
459
-     */
460
-    public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
461
-    {
462
-        $controller = new Write();
463
-        try {
464
-            $controller->setRequestedVersion($version);
465
-            $main_model = $controller->getModelVersionInfo()->loadModel($model_name);
466
-            return $controller->sendResponse(
467
-                $controller->removeRelation(
468
-                    $main_model,
469
-                    $main_model->related_settings_for($related_model_name),
470
-                    $request
471
-                )
472
-            );
473
-        } catch (Exception $e) {
474
-            return $controller->sendResponse($e);
475
-        }
476
-    }
454
+	/**
455
+	 * Removes the relation between the specified models (if it exists).
456
+	 * @since 4.9.76.p
457
+	 * @param WP_REST_Request $request
458
+	 * @return WP_REST_Response
459
+	 */
460
+	public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
461
+	{
462
+		$controller = new Write();
463
+		try {
464
+			$controller->setRequestedVersion($version);
465
+			$main_model = $controller->getModelVersionInfo()->loadModel($model_name);
466
+			return $controller->sendResponse(
467
+				$controller->removeRelation(
468
+					$main_model,
469
+					$main_model->related_settings_for($related_model_name),
470
+					$request
471
+				)
472
+			);
473
+		} catch (Exception $e) {
474
+			return $controller->sendResponse($e);
475
+		}
476
+	}
477 477
 
478
-    /**
479
-     * Adds a relation between the two model specified model objects.
480
-     * @since 4.9.76.p
481
-     * @param EEM_Base $model
482
-     * @param EE_Model_Relation_Base $relation
483
-     * @param WP_REST_Request $request
484
-     * @return array
485
-     * @throws DomainException
486
-     * @throws EE_Error
487
-     * @throws InvalidArgumentException
488
-     * @throws InvalidDataTypeException
489
-     * @throws InvalidInterfaceException
490
-     * @throws RestException
491
-     */
492
-    public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
493
-    {
494
-        // This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know
495
-        // up-front that it doesn't.)
496
-        if (!empty($request->get_body_params())) {
497
-            $body_params = $request->get_body_params();
498
-            throw new RestException(
499
-                'invalid_field',
500
-                sprintf(
501
-                    esc_html__('This endpoint doesn\'t accept post body arguments, you sent in %1$s', 'event_espresso'),
502
-                    implode(array_keys($body_params))
503
-                )
504
-            );
505
-        }
506
-        list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
507
-        // Remember the old relation, if it used a join entry.
508
-        $join_model_obj = null;
509
-        if ($relation instanceof EE_HABTM_Relation) {
510
-            $join_model_obj = $relation->get_join_model()->get_one(
511
-                array(
512
-                    array(
513
-                        $model->primary_key_name() => $model_obj->ID(),
514
-                        $relation->get_other_model()->primary_key_name() => $other_obj->ID()
515
-                    )
516
-                )
517
-            );
518
-        }
519
-        // Remove the relation.
520
-        $related_obj = $model_obj->_remove_relation_to(
521
-            $other_obj,
522
-            $relation->get_other_model()->get_this_model_name()
523
-        );
524
-        $response = array(
525
-            strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
526
-            strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
527
-        );
528
-        if ($relation instanceof EE_HABTM_Relation) {
529
-            $join_model_obj_after_removal = $relation->get_join_model()->get_one(
530
-                array(
531
-                    array(
532
-                        $model->primary_key_name() => $model_obj->ID(),
533
-                        $relation->get_other_model()->primary_key_name() => $other_obj->ID()
534
-                    )
535
-                )
536
-            );
537
-            if ($join_model_obj instanceof EE_Base_Class) {
538
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
539
-            } else {
540
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null;
541
-            }
542
-        }
543
-        return $response;
544
-    }
478
+	/**
479
+	 * Adds a relation between the two model specified model objects.
480
+	 * @since 4.9.76.p
481
+	 * @param EEM_Base $model
482
+	 * @param EE_Model_Relation_Base $relation
483
+	 * @param WP_REST_Request $request
484
+	 * @return array
485
+	 * @throws DomainException
486
+	 * @throws EE_Error
487
+	 * @throws InvalidArgumentException
488
+	 * @throws InvalidDataTypeException
489
+	 * @throws InvalidInterfaceException
490
+	 * @throws RestException
491
+	 */
492
+	public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
493
+	{
494
+		// This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know
495
+		// up-front that it doesn't.)
496
+		if (!empty($request->get_body_params())) {
497
+			$body_params = $request->get_body_params();
498
+			throw new RestException(
499
+				'invalid_field',
500
+				sprintf(
501
+					esc_html__('This endpoint doesn\'t accept post body arguments, you sent in %1$s', 'event_espresso'),
502
+					implode(array_keys($body_params))
503
+				)
504
+			);
505
+		}
506
+		list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
507
+		// Remember the old relation, if it used a join entry.
508
+		$join_model_obj = null;
509
+		if ($relation instanceof EE_HABTM_Relation) {
510
+			$join_model_obj = $relation->get_join_model()->get_one(
511
+				array(
512
+					array(
513
+						$model->primary_key_name() => $model_obj->ID(),
514
+						$relation->get_other_model()->primary_key_name() => $other_obj->ID()
515
+					)
516
+				)
517
+			);
518
+		}
519
+		// Remove the relation.
520
+		$related_obj = $model_obj->_remove_relation_to(
521
+			$other_obj,
522
+			$relation->get_other_model()->get_this_model_name()
523
+		);
524
+		$response = array(
525
+			strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
526
+			strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
527
+		);
528
+		if ($relation instanceof EE_HABTM_Relation) {
529
+			$join_model_obj_after_removal = $relation->get_join_model()->get_one(
530
+				array(
531
+					array(
532
+						$model->primary_key_name() => $model_obj->ID(),
533
+						$relation->get_other_model()->primary_key_name() => $other_obj->ID()
534
+					)
535
+				)
536
+			);
537
+			if ($join_model_obj instanceof EE_Base_Class) {
538
+				$response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
539
+			} else {
540
+				$response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null;
541
+			}
542
+		}
543
+		return $response;
544
+	}
545 545
 
546
-    /**
547
-     * Gets the model objects indicated by the model, relation object, and request.
548
-     * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist.
549
-     * However, this behaviour may change, as we may add support for simultaneously creating and relating data.
550
-     * @since 4.9.76.p
551
-     * @param EEM_Base $model
552
-     * @param EE_Model_Relation_Base $relation
553
-     * @param WP_REST_Request $request
554
-     * @return array {
555
-     * @type EE_Base_Class $model_obj
556
-     * @type EE_Base_Class|null $other_model_obj
557
-     * }
558
-     * @throws RestException
559
-     */
560
-    protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
561
-    {
562
-        // Check generic caps. For now, we're only allowing access to this endpoint to full admins.
563
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
564
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
565
-        if (! current_user_can($default_cap_to_check_for)) {
566
-            throw new RestException(
567
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
568
-                sprintf(
569
-                    esc_html__(
570
-                        // @codingStandardsIgnoreStart
571
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.',
572
-                        // @codingStandardsIgnoreEnd
573
-                        'event_espresso'
574
-                    ),
575
-                    $default_cap_to_check_for
576
-                ),
577
-                array('status' => 403)
578
-            );
579
-        }
580
-        // Get the main model object.
581
-        $model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
582
-        // For now, we require the other model object to exist too. This might be relaxed later.
583
-        $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id'));
584
-        return array($model_obj,$other_obj);
585
-    }
546
+	/**
547
+	 * Gets the model objects indicated by the model, relation object, and request.
548
+	 * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist.
549
+	 * However, this behaviour may change, as we may add support for simultaneously creating and relating data.
550
+	 * @since 4.9.76.p
551
+	 * @param EEM_Base $model
552
+	 * @param EE_Model_Relation_Base $relation
553
+	 * @param WP_REST_Request $request
554
+	 * @return array {
555
+	 * @type EE_Base_Class $model_obj
556
+	 * @type EE_Base_Class|null $other_model_obj
557
+	 * }
558
+	 * @throws RestException
559
+	 */
560
+	protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
561
+	{
562
+		// Check generic caps. For now, we're only allowing access to this endpoint to full admins.
563
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
564
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
565
+		if (! current_user_can($default_cap_to_check_for)) {
566
+			throw new RestException(
567
+				'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
568
+				sprintf(
569
+					esc_html__(
570
+						// @codingStandardsIgnoreStart
571
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.',
572
+						// @codingStandardsIgnoreEnd
573
+						'event_espresso'
574
+					),
575
+					$default_cap_to_check_for
576
+				),
577
+				array('status' => 403)
578
+			);
579
+		}
580
+		// Get the main model object.
581
+		$model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
582
+		// For now, we require the other model object to exist too. This might be relaxed later.
583
+		$other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id'));
584
+		return array($model_obj,$other_obj);
585
+	}
586 586
 
587
-    /**
588
-     * Gets the model with that ID or throws a REST exception.
589
-     * @since 4.9.76.p
590
-     * @param EEM_Base $model
591
-     * @param $id
592
-     * @return EE_Base_Class
593
-     * @throws RestException
594
-     */
595
-    protected function getOneOrThrowException(EEM_Base $model, $id)
596
-    {
597
-        $model_obj = $model->get_one_by_ID($id);
598
-        // @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint.
599
-        if ($model_obj instanceof EE_Base_Class) {
600
-            return $model_obj;
601
-        }
602
-        $lowercase_model_name = strtolower($model->get_this_model_name());
603
-        throw new RestException(
604
-            sprintf('rest_%s_invalid_id', $lowercase_model_name),
605
-            sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
606
-            array('status' => 404)
607
-        );
608
-    }
587
+	/**
588
+	 * Gets the model with that ID or throws a REST exception.
589
+	 * @since 4.9.76.p
590
+	 * @param EEM_Base $model
591
+	 * @param $id
592
+	 * @return EE_Base_Class
593
+	 * @throws RestException
594
+	 */
595
+	protected function getOneOrThrowException(EEM_Base $model, $id)
596
+	{
597
+		$model_obj = $model->get_one_by_ID($id);
598
+		// @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint.
599
+		if ($model_obj instanceof EE_Base_Class) {
600
+			return $model_obj;
601
+		}
602
+		$lowercase_model_name = strtolower($model->get_this_model_name());
603
+		throw new RestException(
604
+			sprintf('rest_%s_invalid_id', $lowercase_model_name),
605
+			sprintf(esc_html__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
606
+			array('status' => 404)
607
+		);
608
+	}
609 609
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/changes/ChangesInBase.php 2 patches
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -37,74 +37,74 @@
 block discarded – undo
37 37
 abstract class ChangesInBase
38 38
 {
39 39
 
40
-    /**
41
-     * The version that these changes happened
42
-     *
43
-     * @var string
44
-     */
45
-    protected $version = null;
40
+	/**
41
+	 * The version that these changes happened
42
+	 *
43
+	 * @var string
44
+	 */
45
+	protected $version = null;
46 46
 
47 47
 
48
-    /**
49
-     * Called when an EE4 REST API request is made to an earlier version than
50
-     * what is indicated in this class' name.
51
-     * Uses WordPress' add_filter and add_action to modify the EE4 REST API's response
52
-     * so that regardless of what version of EE4 core is running, API clients
53
-     * will have a consistent response
54
-     *
55
-     * @return void
56
-     */
57
-    abstract public function setHooks();
48
+	/**
49
+	 * Called when an EE4 REST API request is made to an earlier version than
50
+	 * what is indicated in this class' name.
51
+	 * Uses WordPress' add_filter and add_action to modify the EE4 REST API's response
52
+	 * so that regardless of what version of EE4 core is running, API clients
53
+	 * will have a consistent response
54
+	 *
55
+	 * @return void
56
+	 */
57
+	abstract public function setHooks();
58 58
 
59 59
 
60
-    /**
61
-     * Returns whether or not this class' name indicates its hooks should
62
-     * apply when a request comes in for $requested_version. A class can use
63
-     * other conditions when determining whether to perform their callbacks or not,
64
-     * but this will typically be enough
65
-     *
66
-     * @param string $requested_version eg "4.8.33"
67
-     * @return boolean true: this class' name indicates its filters and actions
68
-     *                                  should take effect. False: this class' name indicates it shouldn't do anything
69
-     */
70
-    public function appliesToVersion($requested_version)
71
-    {
72
-        if ($this->version() > $requested_version) {
73
-            return true;
74
-        }
75
-        return false;
76
-    }
60
+	/**
61
+	 * Returns whether or not this class' name indicates its hooks should
62
+	 * apply when a request comes in for $requested_version. A class can use
63
+	 * other conditions when determining whether to perform their callbacks or not,
64
+	 * but this will typically be enough
65
+	 *
66
+	 * @param string $requested_version eg "4.8.33"
67
+	 * @return boolean true: this class' name indicates its filters and actions
68
+	 *                                  should take effect. False: this class' name indicates it shouldn't do anything
69
+	 */
70
+	public function appliesToVersion($requested_version)
71
+	{
72
+		if ($this->version() > $requested_version) {
73
+			return true;
74
+		}
75
+		return false;
76
+	}
77 77
 
78 78
 
79
-    /**
80
-     * Gets the EE core version when this changes were made to the rest api.
81
-     * Any requests to earlier versions should have modifications made to them
82
-     * by the callbacks of this class.
83
-     *
84
-     * @return string eg "4.8.33"
85
-     * @throws EE_Error
86
-     */
87
-    public function version()
88
-    {
89
-        if ($this->version === null) {
90
-            $matches = array();
91
-            $regex = '~ChangesIn(\d)(\d\d)(\d\d)$~';
92
-            $success = preg_match(
93
-                $regex,
94
-                get_class($this),
95
-                $matches
96
-            );
97
-            if (! $success) {
98
-                throw new EE_Error(
99
-                    sprintf(
100
-                        esc_html__('The class %1$s was misnamed. It name should match the regex "%2$s"', 'event_espresso'),
101
-                        get_class($this),
102
-                        $regex
103
-                    )
104
-                );
105
-            }
106
-            $this->version = (int) $matches[1] . '.' . (int) $matches[2] . '.' . (int) $matches[3];
107
-        }
108
-        return $this->version;
109
-    }
79
+	/**
80
+	 * Gets the EE core version when this changes were made to the rest api.
81
+	 * Any requests to earlier versions should have modifications made to them
82
+	 * by the callbacks of this class.
83
+	 *
84
+	 * @return string eg "4.8.33"
85
+	 * @throws EE_Error
86
+	 */
87
+	public function version()
88
+	{
89
+		if ($this->version === null) {
90
+			$matches = array();
91
+			$regex = '~ChangesIn(\d)(\d\d)(\d\d)$~';
92
+			$success = preg_match(
93
+				$regex,
94
+				get_class($this),
95
+				$matches
96
+			);
97
+			if (! $success) {
98
+				throw new EE_Error(
99
+					sprintf(
100
+						esc_html__('The class %1$s was misnamed. It name should match the regex "%2$s"', 'event_espresso'),
101
+						get_class($this),
102
+						$regex
103
+					)
104
+				);
105
+			}
106
+			$this->version = (int) $matches[1] . '.' . (int) $matches[2] . '.' . (int) $matches[3];
107
+		}
108
+		return $this->version;
109
+	}
110 110
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
                 get_class($this),
95 95
                 $matches
96 96
             );
97
-            if (! $success) {
97
+            if ( ! $success) {
98 98
                 throw new EE_Error(
99 99
                     sprintf(
100 100
                         esc_html__('The class %1$s was misnamed. It name should match the regex "%2$s"', 'event_espresso'),
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
                     )
104 104
                 );
105 105
             }
106
-            $this->version = (int) $matches[1] . '.' . (int) $matches[2] . '.' . (int) $matches[3];
106
+            $this->version = (int) $matches[1].'.'.(int) $matches[2].'.'.(int) $matches[3];
107 107
         }
108 108
         return $this->version;
109 109
     }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Datetime.php 2 patches
Indentation   +200 added lines, -200 removed lines patch added patch discarded remove patch
@@ -17,214 +17,214 @@
 block discarded – undo
17 17
 
18 18
 class Datetime extends DatetimeCalculationBase
19 19
 {
20
-    /**
21
-     * @var EEM_Datetime
22
-     */
23
-    protected $datetime_model;
20
+	/**
21
+	 * @var EEM_Datetime
22
+	 */
23
+	protected $datetime_model;
24 24
 
25
-    /**
26
-     * @var EEM_Registration
27
-     */
28
-    protected $registration_model;
29
-    public function __construct(EEM_Datetime $datetime_model, EEM_Registration $registration_model)
30
-    {
31
-        $this->datetime_model = $datetime_model;
32
-        $this->registration_model = $registration_model;
33
-    }
25
+	/**
26
+	 * @var EEM_Registration
27
+	 */
28
+	protected $registration_model;
29
+	public function __construct(EEM_Datetime $datetime_model, EEM_Registration $registration_model)
30
+	{
31
+		$this->datetime_model = $datetime_model;
32
+		$this->registration_model = $registration_model;
33
+	}
34 34
 
35
-    /**
36
-     * Calculates the total spaces available on the datetime, taking into account
37
-     * ticket limits too.
38
-     *
39
-     * @see EE_Datetime::spaces_remaining( true )
40
-     * @param array            $wpdb_row
41
-     * @param WP_REST_Request $request
42
-     * @param DatetimeControllerBase  $controller
43
-     * @return int
44
-     * @throws EE_Error
45
-     * @throws InvalidDataTypeException
46
-     * @throws InvalidInterfaceException
47
-     * @throws InvalidArgumentException
48
-     * @throws ReflectionException
49
-     */
50
-    public function spacesRemainingConsideringTickets($wpdb_row, $request, $controller)
51
-    {
52
-        if (is_array($wpdb_row) && isset($wpdb_row['Datetime.DTT_ID'])) {
53
-            $dtt_obj = $this->datetime_model->get_one_by_ID($wpdb_row['Datetime.DTT_ID']);
54
-        } else {
55
-            $dtt_obj = null;
56
-        }
57
-        if ($dtt_obj instanceof EE_Datetime) {
58
-            return $dtt_obj->spaces_remaining(true);
59
-        }
60
-        throw new EE_Error(
61
-            sprintf(
62
-                esc_html__(
63
-                // @codingStandardsIgnoreStart
64
-                    'Cannot calculate spaces_remaining_considering_tickets because the datetime with ID %1$s (from database row %2$s) was not found',
65
-                    // @codingStandardsIgnoreEnd
66
-                    'event_espresso'
67
-                ),
68
-                $wpdb_row['Datetime.DTT_ID'],
69
-                print_r($wpdb_row, true)
70
-            )
71
-        );
72
-    }
35
+	/**
36
+	 * Calculates the total spaces available on the datetime, taking into account
37
+	 * ticket limits too.
38
+	 *
39
+	 * @see EE_Datetime::spaces_remaining( true )
40
+	 * @param array            $wpdb_row
41
+	 * @param WP_REST_Request $request
42
+	 * @param DatetimeControllerBase  $controller
43
+	 * @return int
44
+	 * @throws EE_Error
45
+	 * @throws InvalidDataTypeException
46
+	 * @throws InvalidInterfaceException
47
+	 * @throws InvalidArgumentException
48
+	 * @throws ReflectionException
49
+	 */
50
+	public function spacesRemainingConsideringTickets($wpdb_row, $request, $controller)
51
+	{
52
+		if (is_array($wpdb_row) && isset($wpdb_row['Datetime.DTT_ID'])) {
53
+			$dtt_obj = $this->datetime_model->get_one_by_ID($wpdb_row['Datetime.DTT_ID']);
54
+		} else {
55
+			$dtt_obj = null;
56
+		}
57
+		if ($dtt_obj instanceof EE_Datetime) {
58
+			return $dtt_obj->spaces_remaining(true);
59
+		}
60
+		throw new EE_Error(
61
+			sprintf(
62
+				esc_html__(
63
+				// @codingStandardsIgnoreStart
64
+					'Cannot calculate spaces_remaining_considering_tickets because the datetime with ID %1$s (from database row %2$s) was not found',
65
+					// @codingStandardsIgnoreEnd
66
+					'event_espresso'
67
+				),
68
+				$wpdb_row['Datetime.DTT_ID'],
69
+				print_r($wpdb_row, true)
70
+			)
71
+		);
72
+	}
73 73
 
74 74
 
75
-    /**
76
-     * Counts registrations who have checked into this datetime
77
-     *
78
-     * @param array           $wpdb_row
79
-     * @param WP_REST_Request $request
80
-     * @param DatetimeControllerBase $controller
81
-     * @return int
82
-     * @throws EE_Error
83
-     * @throws InvalidArgumentException
84
-     * @throws InvalidDataTypeException
85
-     * @throws InvalidInterfaceException
86
-     * @throws RestException
87
-     */
88
-    public function registrationsCheckedInCount($wpdb_row, $request, $controller)
89
-    {
90
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
91
-            throw new EE_Error(
92
-                sprintf(
93
-                    esc_html__(
94
-                    // @codingStandardsIgnoreStart
95
-                        'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
96
-                        // @codingStandardsIgnoreEnd
97
-                        'event_espresso'
98
-                    ),
99
-                    print_r($wpdb_row, true)
100
-                )
101
-            );
102
-        }
103
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
104
-        return $this->registration_model
105
-                               ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], true);
106
-    }
75
+	/**
76
+	 * Counts registrations who have checked into this datetime
77
+	 *
78
+	 * @param array           $wpdb_row
79
+	 * @param WP_REST_Request $request
80
+	 * @param DatetimeControllerBase $controller
81
+	 * @return int
82
+	 * @throws EE_Error
83
+	 * @throws InvalidArgumentException
84
+	 * @throws InvalidDataTypeException
85
+	 * @throws InvalidInterfaceException
86
+	 * @throws RestException
87
+	 */
88
+	public function registrationsCheckedInCount($wpdb_row, $request, $controller)
89
+	{
90
+		if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
91
+			throw new EE_Error(
92
+				sprintf(
93
+					esc_html__(
94
+					// @codingStandardsIgnoreStart
95
+						'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
96
+						// @codingStandardsIgnoreEnd
97
+						'event_espresso'
98
+					),
99
+					print_r($wpdb_row, true)
100
+				)
101
+			);
102
+		}
103
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
104
+		return $this->registration_model
105
+							   ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], true);
106
+	}
107 107
 
108 108
 
109
-    /**
110
-     * Counts registrations who have checked out of this datetime
111
-     *
112
-     * @param array           $wpdb_row
113
-     * @param WP_REST_Request $request
114
-     * @param DatetimeControllerBase $controller
115
-     * @return int
116
-     * @throws EE_Error
117
-     * @throws InvalidArgumentException
118
-     * @throws InvalidDataTypeException
119
-     * @throws InvalidInterfaceException
120
-     * @throws RestException
121
-     */
122
-    public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
123
-    {
124
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
125
-            throw new EE_Error(
126
-                sprintf(
127
-                    esc_html__(
128
-                    // @codingStandardsIgnoreStart
129
-                        'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
130
-                        // @codingStandardsIgnoreEnd
131
-                        'event_espresso'
132
-                    ),
133
-                    print_r($wpdb_row, true)
134
-                )
135
-            );
136
-        }
137
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
138
-        return $this->registration_model
139
-                               ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], false);
140
-    }
109
+	/**
110
+	 * Counts registrations who have checked out of this datetime
111
+	 *
112
+	 * @param array           $wpdb_row
113
+	 * @param WP_REST_Request $request
114
+	 * @param DatetimeControllerBase $controller
115
+	 * @return int
116
+	 * @throws EE_Error
117
+	 * @throws InvalidArgumentException
118
+	 * @throws InvalidDataTypeException
119
+	 * @throws InvalidInterfaceException
120
+	 * @throws RestException
121
+	 */
122
+	public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
123
+	{
124
+		if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
125
+			throw new EE_Error(
126
+				sprintf(
127
+					esc_html__(
128
+					// @codingStandardsIgnoreStart
129
+						'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
130
+						// @codingStandardsIgnoreEnd
131
+						'event_espresso'
132
+					),
133
+					print_r($wpdb_row, true)
134
+				)
135
+			);
136
+		}
137
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
138
+		return $this->registration_model
139
+							   ->count_registrations_checked_into_datetime($wpdb_row['Datetime.DTT_ID'], false);
140
+	}
141 141
 
142 142
 
143
-    /**
144
-     * Counts the number of pending-payment registrations for this event (regardless
145
-     * of how many datetimes each registrations' ticket purchase is for)
146
-     *
147
-     * @param array           $wpdb_row
148
-     * @param WP_REST_Request $request
149
-     * @param DatetimeControllerBase $controller
150
-     * @return int
151
-     * @throws EE_Error
152
-     * @throws InvalidArgumentException
153
-     * @throws InvalidDataTypeException
154
-     * @throws InvalidInterfaceException
155
-     * @throws RestException
156
-     */
157
-    public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
158
-    {
159
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
160
-            throw new EE_Error(
161
-                sprintf(
162
-                    esc_html__(
163
-                    // @codingStandardsIgnoreStart
164
-                        'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
165
-                        // @codingStandardsIgnoreEnd
166
-                        'event_espresso'
167
-                    ),
168
-                    print_r($wpdb_row, true)
169
-                )
170
-            );
171
-        }
172
-        $this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
173
-        return $this->registration_model->count(
174
-            array(
175
-                array(
176
-                    'Ticket.Datetime.DTT_ID' => $wpdb_row['Datetime.DTT_ID'],
177
-                    'STS_ID'                 => EEM_Registration::status_id_pending_payment,
178
-                ),
179
-            ),
180
-            'REG_ID',
181
-            true
182
-        );
183
-    }
143
+	/**
144
+	 * Counts the number of pending-payment registrations for this event (regardless
145
+	 * of how many datetimes each registrations' ticket purchase is for)
146
+	 *
147
+	 * @param array           $wpdb_row
148
+	 * @param WP_REST_Request $request
149
+	 * @param DatetimeControllerBase $controller
150
+	 * @return int
151
+	 * @throws EE_Error
152
+	 * @throws InvalidArgumentException
153
+	 * @throws InvalidDataTypeException
154
+	 * @throws InvalidInterfaceException
155
+	 * @throws RestException
156
+	 */
157
+	public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
158
+	{
159
+		if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
160
+			throw new EE_Error(
161
+				sprintf(
162
+					esc_html__(
163
+					// @codingStandardsIgnoreStart
164
+						'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Datetime.DTT_ID"',
165
+						// @codingStandardsIgnoreEnd
166
+						'event_espresso'
167
+					),
168
+					print_r($wpdb_row, true)
169
+				)
170
+			);
171
+		}
172
+		$this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
173
+		return $this->registration_model->count(
174
+			array(
175
+				array(
176
+					'Ticket.Datetime.DTT_ID' => $wpdb_row['Datetime.DTT_ID'],
177
+					'STS_ID'                 => EEM_Registration::status_id_pending_payment,
178
+				),
179
+			),
180
+			'REG_ID',
181
+			true
182
+		);
183
+	}
184 184
 
185 185
 
186
-    /**
187
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
188
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
189
-     *
190
-     * @since 4.9.68.p
191
-     * @return array
192
-     */
193
-    public function schemaForCalculations()
194
-    {
195
-        return array(
196
-            'spaces_remaining_considering_tickets' => array(
197
-                'description' => esc_html__(
198
-                    'Calculates the total spaces available on the datetime, taking into account ticket limits too.',
199
-                    'event_espresso'
200
-                ),
201
-                'type' => 'number',
202
-                'protected' => true,
203
-            ),
204
-            'registrations_checked_in_count' => array(
205
-                'description' => esc_html__(
206
-                    'Counts registrations who have checked into this datetime.',
207
-                    'event_espresso'
208
-                ),
209
-                'type' => 'number',
210
-                'protected' => true,
211
-            ),
212
-            'registrations_checked_out_count' => array(
213
-                'description' => esc_html__(
214
-                    'Counts registrations who have checked out of this datetime.',
215
-                    'event_espresso'
216
-                ),
217
-                'type' => 'number',
218
-                'protected' => true,
219
-            ),
220
-            'spots_taken_pending_payment' => array(
221
-                'description' => esc_html__(
222
-                    'The count of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for',
223
-                    'event_espresso'
224
-                ),
225
-                'type' => 'number',
226
-                'protected' => true,
227
-            ),
228
-        );
229
-    }
186
+	/**
187
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
188
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
189
+	 *
190
+	 * @since 4.9.68.p
191
+	 * @return array
192
+	 */
193
+	public function schemaForCalculations()
194
+	{
195
+		return array(
196
+			'spaces_remaining_considering_tickets' => array(
197
+				'description' => esc_html__(
198
+					'Calculates the total spaces available on the datetime, taking into account ticket limits too.',
199
+					'event_espresso'
200
+				),
201
+				'type' => 'number',
202
+				'protected' => true,
203
+			),
204
+			'registrations_checked_in_count' => array(
205
+				'description' => esc_html__(
206
+					'Counts registrations who have checked into this datetime.',
207
+					'event_espresso'
208
+				),
209
+				'type' => 'number',
210
+				'protected' => true,
211
+			),
212
+			'registrations_checked_out_count' => array(
213
+				'description' => esc_html__(
214
+					'Counts registrations who have checked out of this datetime.',
215
+					'event_espresso'
216
+				),
217
+				'type' => 'number',
218
+				'protected' => true,
219
+			),
220
+			'spots_taken_pending_payment' => array(
221
+				'description' => esc_html__(
222
+					'The count of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for',
223
+					'event_espresso'
224
+				),
225
+				'type' => 'number',
226
+				'protected' => true,
227
+			),
228
+		);
229
+	}
230 230
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
      */
88 88
     public function registrationsCheckedInCount($wpdb_row, $request, $controller)
89 89
     {
90
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
90
+        if ( ! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
91 91
             throw new EE_Error(
92 92
                 sprintf(
93 93
                     esc_html__(
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
      */
122 122
     public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
123 123
     {
124
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
124
+        if ( ! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
125 125
             throw new EE_Error(
126 126
                 sprintf(
127 127
                     esc_html__(
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
      */
157 157
     public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
158 158
     {
159
-        if (! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
159
+        if ( ! is_array($wpdb_row) || ! isset($wpdb_row['Datetime.DTT_ID'])) {
160 160
             throw new EE_Error(
161 161
                 sprintf(
162 162
                     esc_html__(
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Event.php 2 patches
Indentation   +567 added lines, -567 removed lines patch added patch discarded remove patch
@@ -26,571 +26,571 @@
 block discarded – undo
26 26
  */
27 27
 class Event extends EventCalculationBase
28 28
 {
29
-    /**
30
-     * @var EEM_Event
31
-     */
32
-    protected $event_model;
33
-
34
-    /**
35
-     * @var EEM_Registration
36
-     */
37
-    protected $registration_model;
38
-    public function __construct(EEM_Event $event_model, EEM_Registration $registration_model)
39
-    {
40
-        $this->event_model = $event_model;
41
-        $this->registration_model = $registration_model;
42
-    }
43
-
44
-    /**
45
-     * Calculates the total spaces on the event (not subtracting sales, but taking
46
-     * sales into account; so this is the optimum sales that CAN still be achieved)
47
-     * See EE_Event::total_available_spaces( true );
48
-     *
49
-     * @param array               $wpdb_row
50
-     * @param WP_REST_Request     $request
51
-     * @param EventControllerBase $controller
52
-     * @return int
53
-     * @throws EE_Error
54
-     * @throws DomainException
55
-     * @throws InvalidDataTypeException
56
-     * @throws InvalidInterfaceException
57
-     * @throws UnexpectedEntityException
58
-     * @throws InvalidArgumentException
59
-     */
60
-    public function optimumSalesAtStart($wpdb_row, $request, $controller)
61
-    {
62
-        $event_obj = null;
63
-        if (Event::wpdbRowHasEventId($wpdb_row)) {
64
-            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
65
-        }
66
-        if ($event_obj instanceof EE_Event) {
67
-            return $event_obj->total_available_spaces();
68
-        }
69
-        throw new EE_Error(
70
-            sprintf(
71
-                esc_html__(
72
-                // @codingStandardsIgnoreStart
73
-                    'Cannot calculate optimum_sales_at_start because the event with ID %1$s (from database row %2$s) was not found',
74
-                    // @codingStandardsIgnoreEnd
75
-                    'event_espresso'
76
-                ),
77
-                $wpdb_row['Event_CPT.ID'],
78
-                print_r($wpdb_row, true)
79
-            )
80
-        );
81
-    }
82
-
83
-
84
-    /**
85
-     * Calculates the total spaces on the event (ignoring all sales; so this is the optimum
86
-     * sales that COULD have been achieved)
87
-     * See EE_Event::total_available_spaces( true );
88
-     *
89
-     * @param array               $wpdb_row
90
-     * @param WP_REST_Request     $request
91
-     * @param EventControllerBase $controller
92
-     * @return int
93
-     * @throws DomainException
94
-     * @throws EE_Error
95
-     * @throws InvalidArgumentException
96
-     * @throws InvalidDataTypeException
97
-     * @throws InvalidInterfaceException
98
-     * @throws UnexpectedEntityException
99
-     */
100
-    public function optimumSalesNow($wpdb_row, $request, $controller)
101
-    {
102
-        $event_obj = null;
103
-        if (Event::wpdbRowHasEventId($wpdb_row)) {
104
-            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
105
-        }
106
-        if ($event_obj instanceof EE_Event) {
107
-            return $event_obj->total_available_spaces(true);
108
-        }
109
-        throw new EE_Error(
110
-            sprintf(
111
-                esc_html__(
112
-                // @codingStandardsIgnoreStart
113
-                    'Cannot calculate optimum_sales_now because the event with ID %1$s (from database row %2$s) was not found',
114
-                    // @codingStandardsIgnoreEnd
115
-                    'event_espresso'
116
-                ),
117
-                $wpdb_row['Event_CPT.ID'],
118
-                print_r($wpdb_row, true)
119
-            )
120
-        );
121
-    }
122
-
123
-
124
-    /**
125
-     * Like optimum_sales_now, but minus total sales so far.
126
-     * See EE_Event::spaces_remaining_for_sale( true );
127
-     *
128
-     * @param array               $wpdb_row
129
-     * @param WP_REST_Request     $request
130
-     * @param EventControllerBase $controller
131
-     * @return int
132
-     * @throws DomainException
133
-     * @throws EE_Error
134
-     * @throws InvalidArgumentException
135
-     * @throws InvalidDataTypeException
136
-     * @throws InvalidInterfaceException
137
-     * @throws UnexpectedEntityException
138
-     */
139
-    public function spacesRemaining($wpdb_row, $request, $controller)
140
-    {
141
-        $event_obj = null;
142
-        if (Event::wpdbRowHasEventId($wpdb_row)) {
143
-            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
144
-        }
145
-        if ($event_obj instanceof EE_Event) {
146
-            return $event_obj->spaces_remaining_for_sale();
147
-        }
148
-        throw new EE_Error(
149
-            sprintf(
150
-                esc_html__(
151
-                // @codingStandardsIgnoreStart
152
-                    'Cannot calculate spaces_remaining because the event with ID %1$s (from database row %2$s) was not found',
153
-                    // @codingStandardsIgnoreEnd
154
-                    'event_espresso'
155
-                ),
156
-                $wpdb_row['Event_CPT.ID'],
157
-                print_r($wpdb_row, true)
158
-            )
159
-        );
160
-    }
161
-
162
-
163
-    /**
164
-     * Counts the number of approved registrations for this event (regardless
165
-     * of how many datetimes each registrations' ticket purchase is for)
166
-     *
167
-     * @param array               $wpdb_row
168
-     * @param WP_REST_Request     $request
169
-     * @param EventControllerBase $controller
170
-     * @return int
171
-     * @throws EE_Error
172
-     * @throws InvalidArgumentException
173
-     * @throws InvalidDataTypeException
174
-     * @throws InvalidInterfaceException
175
-     */
176
-    public function spotsTaken($wpdb_row, $request, $controller)
177
-    {
178
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
179
-            throw new EE_Error(
180
-                sprintf(
181
-                    esc_html__(
182
-                    // @codingStandardsIgnoreStart
183
-                        'Cannot calculate spots_taken because the database row %1$s does not have a valid entry for "Event_CPT.ID"',
184
-                        // @codingStandardsIgnoreEnd
185
-                        'event_espresso'
186
-                    ),
187
-                    print_r($wpdb_row, true)
188
-                )
189
-            );
190
-        }
191
-        return $this->registration_model->count(
192
-            array(
193
-                array(
194
-                    'EVT_ID' => $wpdb_row['Event_CPT.ID'],
195
-                    'STS_ID' => EEM_Registration::status_id_approved,
196
-                ),
197
-            ),
198
-            'REG_ID',
199
-            true
200
-        );
201
-    }
202
-
203
-
204
-    /**
205
-     * Counts the number of pending-payment registrations for this event (regardless
206
-     * of how many datetimes each registrations' ticket purchase is for)
207
-     *
208
-     * @param array               $wpdb_row
209
-     * @param WP_REST_Request     $request
210
-     * @param EventControllerBase $controller
211
-     * @return int
212
-     * @throws EE_Error
213
-     * @throws InvalidArgumentException
214
-     * @throws InvalidDataTypeException
215
-     * @throws InvalidInterfaceException
216
-     * @throws RestException
217
-     */
218
-    public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
219
-    {
220
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
221
-            throw new EE_Error(
222
-                sprintf(
223
-                    esc_html__(
224
-                    // @codingStandardsIgnoreStart
225
-                        'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Event_CPT.ID"',
226
-                        // @codingStandardsIgnoreEnd
227
-                        'event_espresso'
228
-                    ),
229
-                    print_r($wpdb_row, true)
230
-                )
231
-            );
232
-        }
233
-        $this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
234
-        return $this->registration_model->count(
235
-            array(
236
-                array(
237
-                    'EVT_ID' => $wpdb_row['Event_CPT.ID'],
238
-                    'STS_ID' => EEM_Registration::status_id_pending_payment,
239
-                ),
240
-            ),
241
-            'REG_ID',
242
-            true
243
-        );
244
-    }
245
-
246
-
247
-    /**
248
-     * Counts all the registrations who have checked into one of this events' datetimes
249
-     * See EE_Event::total_available_spaces( false );
250
-     *
251
-     * @param array               $wpdb_row
252
-     * @param WP_REST_Request     $request
253
-     * @param EventControllerBase $controller
254
-     * @return int|null if permission denied
255
-     * @throws EE_Error
256
-     * @throws InvalidArgumentException
257
-     * @throws InvalidDataTypeException
258
-     * @throws InvalidInterfaceException
259
-     * @throws RestException
260
-     */
261
-    public function registrationsCheckedInCount($wpdb_row, $request, $controller)
262
-    {
263
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
264
-            throw new EE_Error(
265
-                sprintf(
266
-                    esc_html__(
267
-                    // @codingStandardsIgnoreStart
268
-                        'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
269
-                        // @codingStandardsIgnoreEnd
270
-                        'event_espresso'
271
-                    ),
272
-                    print_r($wpdb_row, true)
273
-                )
274
-            );
275
-        }
276
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
277
-        return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], true);
278
-    }
279
-
280
-
281
-    /**
282
-     * Counts all the registrations who have checked out of one of this events' datetimes
283
-     * See EE_Event::total_available_spaces( false );
284
-     *
285
-     * @param array               $wpdb_row
286
-     * @param WP_REST_Request     $request
287
-     * @param EventControllerBase $controller
288
-     * @return int
289
-     * @throws EE_Error
290
-     * @throws InvalidArgumentException
291
-     * @throws InvalidDataTypeException
292
-     * @throws InvalidInterfaceException
293
-     * @throws RestException
294
-     */
295
-    public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
296
-    {
297
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
298
-            throw new EE_Error(
299
-                sprintf(
300
-                    esc_html__(
301
-                    // @codingStandardsIgnoreStart
302
-                        'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
303
-                        // @codingStandardsIgnoreEnd
304
-                        'event_espresso'
305
-                    ),
306
-                    print_r($wpdb_row, true)
307
-                )
308
-            );
309
-        }
310
-        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
311
-        return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], false);
312
-    }
313
-
314
-
315
-    /**
316
-     * Gets the thumbnail image
317
-     *
318
-     * @param array               $wpdb_row
319
-     * @param WP_REST_Request     $request
320
-     * @param EventControllerBase $controller
321
-     * @return array
322
-     * @throws EE_Error
323
-     */
324
-    public function imageThumbnail($wpdb_row, $request, $controller)
325
-    {
326
-        return self::calculateImageData($wpdb_row, 'thumbnail');
327
-    }
328
-
329
-
330
-    /**
331
-     * Gets the medium image
332
-     *
333
-     * @param array               $wpdb_row
334
-     * @param WP_REST_Request     $request
335
-     * @param EventControllerBase $controller
336
-     * @return array
337
-     * @throws EE_Error
338
-     */
339
-    public function imageMedium($wpdb_row, $request, $controller)
340
-    {
341
-        return self::calculateImageData($wpdb_row, 'medium');
342
-    }
343
-
344
-
345
-    /**
346
-     * Gets the medium-large image
347
-     *
348
-     * @param array               $wpdb_row
349
-     * @param WP_REST_Request     $request
350
-     * @param EventControllerBase $controller
351
-     * @return array
352
-     * @throws EE_Error
353
-     */
354
-    public function imageMediumLarge($wpdb_row, $request, $controller)
355
-    {
356
-        return self::calculateImageData($wpdb_row, 'medium_large');
357
-    }
358
-
359
-
360
-    /**
361
-     * Gets the large image
362
-     *
363
-     * @param array               $wpdb_row
364
-     * @param WP_REST_Request     $request
365
-     * @param EventControllerBase $controller
366
-     * @return array
367
-     * @throws EE_Error
368
-     */
369
-    public function imageLarge($wpdb_row, $request, $controller)
370
-    {
371
-        return self::calculateImageData($wpdb_row, 'large');
372
-    }
373
-
374
-
375
-    /**
376
-     * Gets the post-thumbnail image
377
-     *
378
-     * @param array               $wpdb_row
379
-     * @param WP_REST_Request     $request
380
-     * @param EventControllerBase $controller
381
-     * @return array
382
-     * @throws EE_Error
383
-     */
384
-    public function imagePostThumbnail($wpdb_row, $request, $controller)
385
-    {
386
-        return self::calculateImageData($wpdb_row, 'post-thumbnail');
387
-    }
388
-
389
-
390
-    /**
391
-     * Gets the full size image
392
-     *
393
-     * @param array               $wpdb_row
394
-     * @param WP_REST_Request     $request
395
-     * @param EventControllerBase $controller
396
-     * @return array
397
-     * @throws EE_Error
398
-     */
399
-    public function imageFull($wpdb_row, $request, $controller)
400
-    {
401
-        return self::calculateImageData($wpdb_row, 'full');
402
-    }
403
-
404
-
405
-    /**
406
-     * Gets image specs and formats them for the display in the API,
407
-     * according to the image size requested
408
-     *
409
-     * @param array  $wpdb_row
410
-     * @param string $image_size one of these: thumbnail, medium, medium_large, large, post-thumbnail, full
411
-     * @return array|false if no such image exists. If array it will have keys 'url', 'width', 'height' and 'original'
412
-     * @throws EE_Error
413
-     */
414
-    protected function calculateImageData($wpdb_row, $image_size)
415
-    {
416
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
417
-            throw new EE_Error(
418
-                sprintf(
419
-                    esc_html__(
420
-                    // @codingStandardsIgnoreStart
421
-                        'Cannot calculate image because the database row %1$s does not have an entry for "Event_CPT.ID"',
422
-                        // @codingStandardsIgnoreEnd
423
-                        'event_espresso'
424
-                    ),
425
-                    print_r($wpdb_row, true)
426
-                )
427
-            );
428
-        }
429
-        $EVT_ID = $wpdb_row['Event_CPT.ID'];
430
-        $attachment_id = get_post_thumbnail_id($EVT_ID);
431
-        $data = wp_get_attachment_image_src($attachment_id, $image_size);
432
-        if (! $data) {
433
-            return null;
434
-        }
435
-        $generated = true;
436
-        if (isset($data[3])) {
437
-            $generated = $data[3];
438
-        }
439
-        return array(
440
-            'url'       => $data[0],
441
-            'width'     => $data[1],
442
-            'height'    => $data[2],
443
-            'generated' => $generated,
444
-        );
445
-    }
446
-
447
-
448
-    /**
449
-     * Returns true if the array of data contains 'Event_CPT.ID'. False otherwise
450
-     *
451
-     * @param array $wpdb_row
452
-     * @return bool
453
-     */
454
-    protected function wpdbRowHasEventId($wpdb_row)
455
-    {
456
-        return (is_array($wpdb_row) && isset($wpdb_row['Event_CPT.ID']) && absint($wpdb_row['Event_CPT.ID']));
457
-    }
458
-
459
-
460
-    /**
461
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
462
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
463
-     *
464
-     * @since 4.9.68.p
465
-     * @return array
466
-     */
467
-    public function schemaForCalculations()
468
-    {
469
-        $image_object_properties = array(
470
-            'url'       => array(
471
-                'type' => 'string',
472
-            ),
473
-            'width'     => array(
474
-                'type' => 'number',
475
-            ),
476
-            'height'    => array(
477
-                'type' => 'number',
478
-            ),
479
-            'generated' => array(
480
-                'type' => 'boolean',
481
-            ),
482
-        );
483
-        return array(
484
-            'optimum_sales_at_start'          => array(
485
-                'description' => esc_html__(
486
-                    'The total spaces on the event (not subtracting sales, but taking sales into account; so this is the optimum sales that CAN still be achieved.',
487
-                    'event_espresso'
488
-                ),
489
-                'type'        => 'number',
490
-                'protected' => true,
491
-            ),
492
-            'optimum_sales_now'               => array(
493
-                'description' => esc_html__(
494
-                    'The total spaces on the event (ignoring all sales; so this is the optimum sales that could have been achieved.',
495
-                    'event_espresso'
496
-                ),
497
-                'type'        => 'number',
498
-                'protected' => true,
499
-            ),
500
-            'spaces_remaining'                => array(
501
-                'description' => esc_html__(
502
-                    'The optimum_sales_number result, minus total sales so far.',
503
-                    'event_espresso'
504
-                ),
505
-                'type'        => 'number',
506
-                'protected' => true,
507
-            ),
508
-            'spots_taken'                     => array(
509
-                'description' => esc_html__(
510
-                    'The number of approved registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
511
-                    'event_espresso'
512
-                ),
513
-                'type'        => 'number',
514
-                'protected' => true,
515
-            ),
516
-            'spots_taken_pending_payment'     => array(
517
-                'description' => esc_html__(
518
-                    'The number of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
519
-                    'event_espresso'
520
-                ),
521
-                'type'        => 'number',
522
-                'protected' => true,
523
-            ),
524
-            'registrations_checked_in_count'  => array(
525
-                'description' => esc_html__(
526
-                    'The count of all the registrations who have checked into one of this event\'s datetimes.',
527
-                    'event_espresso'
528
-                ),
529
-                'type'        => 'number',
530
-                'protected' => true,
531
-            ),
532
-            'registrations_checked_out_count' => array(
533
-                'description' => esc_html__(
534
-                    'The count of all registrations who have checked out of one of this event\'s datetimes.',
535
-                    'event_espresso'
536
-                ),
537
-                'type'        => 'number',
538
-                'protected' => true,
539
-            ),
540
-            'image_thumbnail'                 => array(
541
-                'description'          => esc_html__(
542
-                    'The thumbnail image data.',
543
-                    'event_espresso'
544
-                ),
545
-                'type'                 => 'object',
546
-                'properties'           => $image_object_properties,
547
-                'additionalProperties' => false,
548
-            ),
549
-            'image_medium'                    => array(
550
-                'description'          => esc_html__(
551
-                    'The medium image data.',
552
-                    'event_espresso'
553
-                ),
554
-                'type'                 => 'object',
555
-                'properties'           => $image_object_properties,
556
-                'additionalProperties' => false,
557
-            ),
558
-            'image_medium_large'              => array(
559
-                'description'          => esc_html__(
560
-                    'The medium-large image data.',
561
-                    'event_espresso'
562
-                ),
563
-                'type'                 => 'object',
564
-                'properties'           => $image_object_properties,
565
-                'additionalProperties' => false,
566
-            ),
567
-            'image_large'                     => array(
568
-                'description'          => esc_html__(
569
-                    'The large image data.',
570
-                    'event_espresso'
571
-                ),
572
-                'type'                 => 'object',
573
-                'properties'           => $image_object_properties,
574
-                'additionalProperties' => false,
575
-            ),
576
-            'image_post_thumbnail'            => array(
577
-                'description'          => esc_html__(
578
-                    'The post-thumbnail image data.',
579
-                    'event_espresso'
580
-                ),
581
-                'type'                 => 'object',
582
-                'properties'           => $image_object_properties,
583
-                'additionalProperties' => false,
584
-            ),
585
-            'image_full'                      => array(
586
-                'description'          => esc_html__(
587
-                    'The full size image data',
588
-                    'event_espresso'
589
-                ),
590
-                'type'                 => 'object',
591
-                'properties'           => $image_object_properties,
592
-                'additionalProperties' => false,
593
-            ),
594
-        );
595
-    }
29
+	/**
30
+	 * @var EEM_Event
31
+	 */
32
+	protected $event_model;
33
+
34
+	/**
35
+	 * @var EEM_Registration
36
+	 */
37
+	protected $registration_model;
38
+	public function __construct(EEM_Event $event_model, EEM_Registration $registration_model)
39
+	{
40
+		$this->event_model = $event_model;
41
+		$this->registration_model = $registration_model;
42
+	}
43
+
44
+	/**
45
+	 * Calculates the total spaces on the event (not subtracting sales, but taking
46
+	 * sales into account; so this is the optimum sales that CAN still be achieved)
47
+	 * See EE_Event::total_available_spaces( true );
48
+	 *
49
+	 * @param array               $wpdb_row
50
+	 * @param WP_REST_Request     $request
51
+	 * @param EventControllerBase $controller
52
+	 * @return int
53
+	 * @throws EE_Error
54
+	 * @throws DomainException
55
+	 * @throws InvalidDataTypeException
56
+	 * @throws InvalidInterfaceException
57
+	 * @throws UnexpectedEntityException
58
+	 * @throws InvalidArgumentException
59
+	 */
60
+	public function optimumSalesAtStart($wpdb_row, $request, $controller)
61
+	{
62
+		$event_obj = null;
63
+		if (Event::wpdbRowHasEventId($wpdb_row)) {
64
+			$event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
65
+		}
66
+		if ($event_obj instanceof EE_Event) {
67
+			return $event_obj->total_available_spaces();
68
+		}
69
+		throw new EE_Error(
70
+			sprintf(
71
+				esc_html__(
72
+				// @codingStandardsIgnoreStart
73
+					'Cannot calculate optimum_sales_at_start because the event with ID %1$s (from database row %2$s) was not found',
74
+					// @codingStandardsIgnoreEnd
75
+					'event_espresso'
76
+				),
77
+				$wpdb_row['Event_CPT.ID'],
78
+				print_r($wpdb_row, true)
79
+			)
80
+		);
81
+	}
82
+
83
+
84
+	/**
85
+	 * Calculates the total spaces on the event (ignoring all sales; so this is the optimum
86
+	 * sales that COULD have been achieved)
87
+	 * See EE_Event::total_available_spaces( true );
88
+	 *
89
+	 * @param array               $wpdb_row
90
+	 * @param WP_REST_Request     $request
91
+	 * @param EventControllerBase $controller
92
+	 * @return int
93
+	 * @throws DomainException
94
+	 * @throws EE_Error
95
+	 * @throws InvalidArgumentException
96
+	 * @throws InvalidDataTypeException
97
+	 * @throws InvalidInterfaceException
98
+	 * @throws UnexpectedEntityException
99
+	 */
100
+	public function optimumSalesNow($wpdb_row, $request, $controller)
101
+	{
102
+		$event_obj = null;
103
+		if (Event::wpdbRowHasEventId($wpdb_row)) {
104
+			$event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
105
+		}
106
+		if ($event_obj instanceof EE_Event) {
107
+			return $event_obj->total_available_spaces(true);
108
+		}
109
+		throw new EE_Error(
110
+			sprintf(
111
+				esc_html__(
112
+				// @codingStandardsIgnoreStart
113
+					'Cannot calculate optimum_sales_now because the event with ID %1$s (from database row %2$s) was not found',
114
+					// @codingStandardsIgnoreEnd
115
+					'event_espresso'
116
+				),
117
+				$wpdb_row['Event_CPT.ID'],
118
+				print_r($wpdb_row, true)
119
+			)
120
+		);
121
+	}
122
+
123
+
124
+	/**
125
+	 * Like optimum_sales_now, but minus total sales so far.
126
+	 * See EE_Event::spaces_remaining_for_sale( true );
127
+	 *
128
+	 * @param array               $wpdb_row
129
+	 * @param WP_REST_Request     $request
130
+	 * @param EventControllerBase $controller
131
+	 * @return int
132
+	 * @throws DomainException
133
+	 * @throws EE_Error
134
+	 * @throws InvalidArgumentException
135
+	 * @throws InvalidDataTypeException
136
+	 * @throws InvalidInterfaceException
137
+	 * @throws UnexpectedEntityException
138
+	 */
139
+	public function spacesRemaining($wpdb_row, $request, $controller)
140
+	{
141
+		$event_obj = null;
142
+		if (Event::wpdbRowHasEventId($wpdb_row)) {
143
+			$event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
144
+		}
145
+		if ($event_obj instanceof EE_Event) {
146
+			return $event_obj->spaces_remaining_for_sale();
147
+		}
148
+		throw new EE_Error(
149
+			sprintf(
150
+				esc_html__(
151
+				// @codingStandardsIgnoreStart
152
+					'Cannot calculate spaces_remaining because the event with ID %1$s (from database row %2$s) was not found',
153
+					// @codingStandardsIgnoreEnd
154
+					'event_espresso'
155
+				),
156
+				$wpdb_row['Event_CPT.ID'],
157
+				print_r($wpdb_row, true)
158
+			)
159
+		);
160
+	}
161
+
162
+
163
+	/**
164
+	 * Counts the number of approved registrations for this event (regardless
165
+	 * of how many datetimes each registrations' ticket purchase is for)
166
+	 *
167
+	 * @param array               $wpdb_row
168
+	 * @param WP_REST_Request     $request
169
+	 * @param EventControllerBase $controller
170
+	 * @return int
171
+	 * @throws EE_Error
172
+	 * @throws InvalidArgumentException
173
+	 * @throws InvalidDataTypeException
174
+	 * @throws InvalidInterfaceException
175
+	 */
176
+	public function spotsTaken($wpdb_row, $request, $controller)
177
+	{
178
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
179
+			throw new EE_Error(
180
+				sprintf(
181
+					esc_html__(
182
+					// @codingStandardsIgnoreStart
183
+						'Cannot calculate spots_taken because the database row %1$s does not have a valid entry for "Event_CPT.ID"',
184
+						// @codingStandardsIgnoreEnd
185
+						'event_espresso'
186
+					),
187
+					print_r($wpdb_row, true)
188
+				)
189
+			);
190
+		}
191
+		return $this->registration_model->count(
192
+			array(
193
+				array(
194
+					'EVT_ID' => $wpdb_row['Event_CPT.ID'],
195
+					'STS_ID' => EEM_Registration::status_id_approved,
196
+				),
197
+			),
198
+			'REG_ID',
199
+			true
200
+		);
201
+	}
202
+
203
+
204
+	/**
205
+	 * Counts the number of pending-payment registrations for this event (regardless
206
+	 * of how many datetimes each registrations' ticket purchase is for)
207
+	 *
208
+	 * @param array               $wpdb_row
209
+	 * @param WP_REST_Request     $request
210
+	 * @param EventControllerBase $controller
211
+	 * @return int
212
+	 * @throws EE_Error
213
+	 * @throws InvalidArgumentException
214
+	 * @throws InvalidDataTypeException
215
+	 * @throws InvalidInterfaceException
216
+	 * @throws RestException
217
+	 */
218
+	public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
219
+	{
220
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
221
+			throw new EE_Error(
222
+				sprintf(
223
+					esc_html__(
224
+					// @codingStandardsIgnoreStart
225
+						'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Event_CPT.ID"',
226
+						// @codingStandardsIgnoreEnd
227
+						'event_espresso'
228
+					),
229
+					print_r($wpdb_row, true)
230
+				)
231
+			);
232
+		}
233
+		$this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
234
+		return $this->registration_model->count(
235
+			array(
236
+				array(
237
+					'EVT_ID' => $wpdb_row['Event_CPT.ID'],
238
+					'STS_ID' => EEM_Registration::status_id_pending_payment,
239
+				),
240
+			),
241
+			'REG_ID',
242
+			true
243
+		);
244
+	}
245
+
246
+
247
+	/**
248
+	 * Counts all the registrations who have checked into one of this events' datetimes
249
+	 * See EE_Event::total_available_spaces( false );
250
+	 *
251
+	 * @param array               $wpdb_row
252
+	 * @param WP_REST_Request     $request
253
+	 * @param EventControllerBase $controller
254
+	 * @return int|null if permission denied
255
+	 * @throws EE_Error
256
+	 * @throws InvalidArgumentException
257
+	 * @throws InvalidDataTypeException
258
+	 * @throws InvalidInterfaceException
259
+	 * @throws RestException
260
+	 */
261
+	public function registrationsCheckedInCount($wpdb_row, $request, $controller)
262
+	{
263
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
264
+			throw new EE_Error(
265
+				sprintf(
266
+					esc_html__(
267
+					// @codingStandardsIgnoreStart
268
+						'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
269
+						// @codingStandardsIgnoreEnd
270
+						'event_espresso'
271
+					),
272
+					print_r($wpdb_row, true)
273
+				)
274
+			);
275
+		}
276
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
277
+		return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], true);
278
+	}
279
+
280
+
281
+	/**
282
+	 * Counts all the registrations who have checked out of one of this events' datetimes
283
+	 * See EE_Event::total_available_spaces( false );
284
+	 *
285
+	 * @param array               $wpdb_row
286
+	 * @param WP_REST_Request     $request
287
+	 * @param EventControllerBase $controller
288
+	 * @return int
289
+	 * @throws EE_Error
290
+	 * @throws InvalidArgumentException
291
+	 * @throws InvalidDataTypeException
292
+	 * @throws InvalidInterfaceException
293
+	 * @throws RestException
294
+	 */
295
+	public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
296
+	{
297
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
298
+			throw new EE_Error(
299
+				sprintf(
300
+					esc_html__(
301
+					// @codingStandardsIgnoreStart
302
+						'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
303
+						// @codingStandardsIgnoreEnd
304
+						'event_espresso'
305
+					),
306
+					print_r($wpdb_row, true)
307
+				)
308
+			);
309
+		}
310
+		$this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
311
+		return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], false);
312
+	}
313
+
314
+
315
+	/**
316
+	 * Gets the thumbnail image
317
+	 *
318
+	 * @param array               $wpdb_row
319
+	 * @param WP_REST_Request     $request
320
+	 * @param EventControllerBase $controller
321
+	 * @return array
322
+	 * @throws EE_Error
323
+	 */
324
+	public function imageThumbnail($wpdb_row, $request, $controller)
325
+	{
326
+		return self::calculateImageData($wpdb_row, 'thumbnail');
327
+	}
328
+
329
+
330
+	/**
331
+	 * Gets the medium image
332
+	 *
333
+	 * @param array               $wpdb_row
334
+	 * @param WP_REST_Request     $request
335
+	 * @param EventControllerBase $controller
336
+	 * @return array
337
+	 * @throws EE_Error
338
+	 */
339
+	public function imageMedium($wpdb_row, $request, $controller)
340
+	{
341
+		return self::calculateImageData($wpdb_row, 'medium');
342
+	}
343
+
344
+
345
+	/**
346
+	 * Gets the medium-large image
347
+	 *
348
+	 * @param array               $wpdb_row
349
+	 * @param WP_REST_Request     $request
350
+	 * @param EventControllerBase $controller
351
+	 * @return array
352
+	 * @throws EE_Error
353
+	 */
354
+	public function imageMediumLarge($wpdb_row, $request, $controller)
355
+	{
356
+		return self::calculateImageData($wpdb_row, 'medium_large');
357
+	}
358
+
359
+
360
+	/**
361
+	 * Gets the large image
362
+	 *
363
+	 * @param array               $wpdb_row
364
+	 * @param WP_REST_Request     $request
365
+	 * @param EventControllerBase $controller
366
+	 * @return array
367
+	 * @throws EE_Error
368
+	 */
369
+	public function imageLarge($wpdb_row, $request, $controller)
370
+	{
371
+		return self::calculateImageData($wpdb_row, 'large');
372
+	}
373
+
374
+
375
+	/**
376
+	 * Gets the post-thumbnail image
377
+	 *
378
+	 * @param array               $wpdb_row
379
+	 * @param WP_REST_Request     $request
380
+	 * @param EventControllerBase $controller
381
+	 * @return array
382
+	 * @throws EE_Error
383
+	 */
384
+	public function imagePostThumbnail($wpdb_row, $request, $controller)
385
+	{
386
+		return self::calculateImageData($wpdb_row, 'post-thumbnail');
387
+	}
388
+
389
+
390
+	/**
391
+	 * Gets the full size image
392
+	 *
393
+	 * @param array               $wpdb_row
394
+	 * @param WP_REST_Request     $request
395
+	 * @param EventControllerBase $controller
396
+	 * @return array
397
+	 * @throws EE_Error
398
+	 */
399
+	public function imageFull($wpdb_row, $request, $controller)
400
+	{
401
+		return self::calculateImageData($wpdb_row, 'full');
402
+	}
403
+
404
+
405
+	/**
406
+	 * Gets image specs and formats them for the display in the API,
407
+	 * according to the image size requested
408
+	 *
409
+	 * @param array  $wpdb_row
410
+	 * @param string $image_size one of these: thumbnail, medium, medium_large, large, post-thumbnail, full
411
+	 * @return array|false if no such image exists. If array it will have keys 'url', 'width', 'height' and 'original'
412
+	 * @throws EE_Error
413
+	 */
414
+	protected function calculateImageData($wpdb_row, $image_size)
415
+	{
416
+		if (! Event::wpdbRowHasEventId($wpdb_row)) {
417
+			throw new EE_Error(
418
+				sprintf(
419
+					esc_html__(
420
+					// @codingStandardsIgnoreStart
421
+						'Cannot calculate image because the database row %1$s does not have an entry for "Event_CPT.ID"',
422
+						// @codingStandardsIgnoreEnd
423
+						'event_espresso'
424
+					),
425
+					print_r($wpdb_row, true)
426
+				)
427
+			);
428
+		}
429
+		$EVT_ID = $wpdb_row['Event_CPT.ID'];
430
+		$attachment_id = get_post_thumbnail_id($EVT_ID);
431
+		$data = wp_get_attachment_image_src($attachment_id, $image_size);
432
+		if (! $data) {
433
+			return null;
434
+		}
435
+		$generated = true;
436
+		if (isset($data[3])) {
437
+			$generated = $data[3];
438
+		}
439
+		return array(
440
+			'url'       => $data[0],
441
+			'width'     => $data[1],
442
+			'height'    => $data[2],
443
+			'generated' => $generated,
444
+		);
445
+	}
446
+
447
+
448
+	/**
449
+	 * Returns true if the array of data contains 'Event_CPT.ID'. False otherwise
450
+	 *
451
+	 * @param array $wpdb_row
452
+	 * @return bool
453
+	 */
454
+	protected function wpdbRowHasEventId($wpdb_row)
455
+	{
456
+		return (is_array($wpdb_row) && isset($wpdb_row['Event_CPT.ID']) && absint($wpdb_row['Event_CPT.ID']));
457
+	}
458
+
459
+
460
+	/**
461
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
462
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
463
+	 *
464
+	 * @since 4.9.68.p
465
+	 * @return array
466
+	 */
467
+	public function schemaForCalculations()
468
+	{
469
+		$image_object_properties = array(
470
+			'url'       => array(
471
+				'type' => 'string',
472
+			),
473
+			'width'     => array(
474
+				'type' => 'number',
475
+			),
476
+			'height'    => array(
477
+				'type' => 'number',
478
+			),
479
+			'generated' => array(
480
+				'type' => 'boolean',
481
+			),
482
+		);
483
+		return array(
484
+			'optimum_sales_at_start'          => array(
485
+				'description' => esc_html__(
486
+					'The total spaces on the event (not subtracting sales, but taking sales into account; so this is the optimum sales that CAN still be achieved.',
487
+					'event_espresso'
488
+				),
489
+				'type'        => 'number',
490
+				'protected' => true,
491
+			),
492
+			'optimum_sales_now'               => array(
493
+				'description' => esc_html__(
494
+					'The total spaces on the event (ignoring all sales; so this is the optimum sales that could have been achieved.',
495
+					'event_espresso'
496
+				),
497
+				'type'        => 'number',
498
+				'protected' => true,
499
+			),
500
+			'spaces_remaining'                => array(
501
+				'description' => esc_html__(
502
+					'The optimum_sales_number result, minus total sales so far.',
503
+					'event_espresso'
504
+				),
505
+				'type'        => 'number',
506
+				'protected' => true,
507
+			),
508
+			'spots_taken'                     => array(
509
+				'description' => esc_html__(
510
+					'The number of approved registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
511
+					'event_espresso'
512
+				),
513
+				'type'        => 'number',
514
+				'protected' => true,
515
+			),
516
+			'spots_taken_pending_payment'     => array(
517
+				'description' => esc_html__(
518
+					'The number of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
519
+					'event_espresso'
520
+				),
521
+				'type'        => 'number',
522
+				'protected' => true,
523
+			),
524
+			'registrations_checked_in_count'  => array(
525
+				'description' => esc_html__(
526
+					'The count of all the registrations who have checked into one of this event\'s datetimes.',
527
+					'event_espresso'
528
+				),
529
+				'type'        => 'number',
530
+				'protected' => true,
531
+			),
532
+			'registrations_checked_out_count' => array(
533
+				'description' => esc_html__(
534
+					'The count of all registrations who have checked out of one of this event\'s datetimes.',
535
+					'event_espresso'
536
+				),
537
+				'type'        => 'number',
538
+				'protected' => true,
539
+			),
540
+			'image_thumbnail'                 => array(
541
+				'description'          => esc_html__(
542
+					'The thumbnail image data.',
543
+					'event_espresso'
544
+				),
545
+				'type'                 => 'object',
546
+				'properties'           => $image_object_properties,
547
+				'additionalProperties' => false,
548
+			),
549
+			'image_medium'                    => array(
550
+				'description'          => esc_html__(
551
+					'The medium image data.',
552
+					'event_espresso'
553
+				),
554
+				'type'                 => 'object',
555
+				'properties'           => $image_object_properties,
556
+				'additionalProperties' => false,
557
+			),
558
+			'image_medium_large'              => array(
559
+				'description'          => esc_html__(
560
+					'The medium-large image data.',
561
+					'event_espresso'
562
+				),
563
+				'type'                 => 'object',
564
+				'properties'           => $image_object_properties,
565
+				'additionalProperties' => false,
566
+			),
567
+			'image_large'                     => array(
568
+				'description'          => esc_html__(
569
+					'The large image data.',
570
+					'event_espresso'
571
+				),
572
+				'type'                 => 'object',
573
+				'properties'           => $image_object_properties,
574
+				'additionalProperties' => false,
575
+			),
576
+			'image_post_thumbnail'            => array(
577
+				'description'          => esc_html__(
578
+					'The post-thumbnail image data.',
579
+					'event_espresso'
580
+				),
581
+				'type'                 => 'object',
582
+				'properties'           => $image_object_properties,
583
+				'additionalProperties' => false,
584
+			),
585
+			'image_full'                      => array(
586
+				'description'          => esc_html__(
587
+					'The full size image data',
588
+					'event_espresso'
589
+				),
590
+				'type'                 => 'object',
591
+				'properties'           => $image_object_properties,
592
+				'additionalProperties' => false,
593
+			),
594
+		);
595
+	}
596 596
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
      */
176 176
     public function spotsTaken($wpdb_row, $request, $controller)
177 177
     {
178
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
178
+        if ( ! Event::wpdbRowHasEventId($wpdb_row)) {
179 179
             throw new EE_Error(
180 180
                 sprintf(
181 181
                     esc_html__(
@@ -217,7 +217,7 @@  discard block
 block discarded – undo
217 217
      */
218 218
     public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
219 219
     {
220
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
220
+        if ( ! Event::wpdbRowHasEventId($wpdb_row)) {
221 221
             throw new EE_Error(
222 222
                 sprintf(
223 223
                     esc_html__(
@@ -260,7 +260,7 @@  discard block
 block discarded – undo
260 260
      */
261 261
     public function registrationsCheckedInCount($wpdb_row, $request, $controller)
262 262
     {
263
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
263
+        if ( ! Event::wpdbRowHasEventId($wpdb_row)) {
264 264
             throw new EE_Error(
265 265
                 sprintf(
266 266
                     esc_html__(
@@ -294,7 +294,7 @@  discard block
 block discarded – undo
294 294
      */
295 295
     public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
296 296
     {
297
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
297
+        if ( ! Event::wpdbRowHasEventId($wpdb_row)) {
298 298
             throw new EE_Error(
299 299
                 sprintf(
300 300
                     esc_html__(
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
      */
414 414
     protected function calculateImageData($wpdb_row, $image_size)
415 415
     {
416
-        if (! Event::wpdbRowHasEventId($wpdb_row)) {
416
+        if ( ! Event::wpdbRowHasEventId($wpdb_row)) {
417 417
             throw new EE_Error(
418 418
                 sprintf(
419 419
                     esc_html__(
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
         $EVT_ID = $wpdb_row['Event_CPT.ID'];
430 430
         $attachment_id = get_post_thumbnail_id($EVT_ID);
431 431
         $data = wp_get_attachment_image_src($attachment_id, $image_size);
432
-        if (! $data) {
432
+        if ( ! $data) {
433 433
             return null;
434 434
         }
435 435
         $generated = true;
Please login to merge, or discard this patch.
line_item_display/EE_Receipt_Line_Item_Display_Strategy.strategy.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -15,88 +15,88 @@
 block discarded – undo
15 15
  * ------------------------------------------------------------------------
16 16
  */
17 17
  /**
18
- *
19
- * Class EE_Receipt_Line_Item_Display_Strategy
20
- *
21
- * Description
22
- *
23
- * @package         Event Espresso
24
- * @subpackage    core
25
- * @author              Brent Christensen
26
- *
27
- *
28
- */
18
+  *
19
+  * Class EE_Receipt_Line_Item_Display_Strategy
20
+  *
21
+  * Description
22
+  *
23
+  * @package         Event Espresso
24
+  * @subpackage    core
25
+  * @author              Brent Christensen
26
+  *
27
+  *
28
+  */
29 29
 
30 30
 class EE_Receipt_Line_Item_Display_Strategy implements EEI_Line_Item_Display
31 31
 {
32 32
 
33
-    /**
34
-     * @param EE_Line_Item $line_item
35
-     * @param array        $options
36
-     * @return mixed
37
-     */
38
-    public function display_line_item(EE_Line_Item $line_item, $options = array())
39
-    {
33
+	/**
34
+	 * @param EE_Line_Item $line_item
35
+	 * @param array        $options
36
+	 * @return mixed
37
+	 */
38
+	public function display_line_item(EE_Line_Item $line_item, $options = array())
39
+	{
40 40
 
41
-        $html = '';
42
-        // set some default options and merge with incoming
43
-        $default_options = array(
44
-            'show_desc' => true,
45
-            'odd' => false
46
-        );
47
-        $options = array_merge($default_options, (array) $options);
48
-        switch ($line_item->type()) {
49
-            case EEM_Line_Item::type_total:
50
-                // loop thru children
51
-                foreach ($line_item->children() as $child_line_item) {
52
-                    // recursively feed children back into this method
41
+		$html = '';
42
+		// set some default options and merge with incoming
43
+		$default_options = array(
44
+			'show_desc' => true,
45
+			'odd' => false
46
+		);
47
+		$options = array_merge($default_options, (array) $options);
48
+		switch ($line_item->type()) {
49
+			case EEM_Line_Item::type_total:
50
+				// loop thru children
51
+				foreach ($line_item->children() as $child_line_item) {
52
+					// recursively feed children back into this method
53 53
 //                  $html .= $this->display_line_item( $child_line_item, $options );
54
-                }
54
+				}
55 55
 //              $html .= $this->_separator_row( $options );
56 56
 //              $html .= $this->_total_row( $line_item, esc_html__('Total', 'event_espresso'), $options );
57
-                break;
57
+				break;
58 58
 
59 59
 
60
-            case EEM_Line_Item::type_sub_total:
61
-                // loop thru children
62
-                foreach ($line_item->children() as $child_line_item) {
63
-                    // recursively feed children back into this method
60
+			case EEM_Line_Item::type_sub_total:
61
+				// loop thru children
62
+				foreach ($line_item->children() as $child_line_item) {
63
+					// recursively feed children back into this method
64 64
 //                  $html .= $this->display_line_item( $child_line_item, $options );
65
-                }
65
+				}
66 66
 //              $html .= $this->_total_row( $line_item, esc_html__('Sub-Total', 'event_espresso'), $options );
67
-                break;
67
+				break;
68 68
 
69 69
 
70
-            case EEM_Line_Item::type_tax_sub_total:
71
-                // loop thru children
72
-                foreach ($line_item->children() as $child_line_item) {
73
-                    // recursively feed children back into this method
70
+			case EEM_Line_Item::type_tax_sub_total:
71
+				// loop thru children
72
+				foreach ($line_item->children() as $child_line_item) {
73
+					// recursively feed children back into this method
74 74
 //                  $html .= $this->display_line_item( $child_line_item, $options );
75
-                }
75
+				}
76 76
 //              $html .= $this->_total_row( $line_item, esc_html__('Tax Total', 'event_espresso'), $options );
77
-                break;
77
+				break;
78 78
 
79 79
 
80
-            case EEM_Line_Item::type_line_item:
81
-                // item row
80
+			case EEM_Line_Item::type_line_item:
81
+				// item row
82 82
 //              $html .= $this->_item_row( $line_item, $options );
83
-                // got any kids?
84
-                foreach ($line_item->children() as $child_line_item) {
83
+				// got any kids?
84
+				foreach ($line_item->children() as $child_line_item) {
85 85
 //                  $this->display_line_item( $child_line_item, $options );
86
-                }
87
-                break;
86
+				}
87
+				break;
88 88
 
89 89
 
90
-            case EEM_Line_Item::type_sub_line_item:
90
+			case EEM_Line_Item::type_sub_line_item:
91 91
 //              $html .= $this->_sub_item_row( $line_item, $options );
92
-                break;
92
+				break;
93 93
 
94 94
 
95
-            case EEM_Line_Item::type_tax:
95
+			case EEM_Line_Item::type_tax:
96 96
 //              $html .= $this->_tax_row( $line_item, $options );
97
-                break;
98
-        }
97
+				break;
98
+		}
99 99
 
100
-        return $html;
101
-    }
100
+		return $html;
101
+	}
102 102
 }
Please login to merge, or discard this patch.
line_item_display/EE_Admin_Table_Line_Item_Display_Strategy.strategy.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -118,7 +118,7 @@  discard block
 block discarded – undo
118 118
                 $html .= $this->_taxes_html;
119 119
                 $html .= $this->_total_row($line_item, $options);
120 120
                 if ($options['use_table_wrapper']) {
121
-                    $html = $this->_table_header($options) . $html . $this->_table_footer($options);
121
+                    $html = $this->_table_header($options).$html.$this->_table_footer($options);
122 122
                 }
123 123
                 break;
124 124
         }
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
      */
158 158
     protected function _table_footer($options)
159 159
     {
160
-        return EEH_HTML::tbodyx() .  EEH_HTML::tablex();
160
+        return EEH_HTML::tbodyx().EEH_HTML::tablex();
161 161
     }
162 162
 
163 163
 
@@ -188,16 +188,16 @@  discard block
 block discarded – undo
188 188
 
189 189
 
190 190
         $name_html = $line_item_related_object instanceof EEI_Line_Item_Object ? $line_item_related_object->name() : $line_item->name();
191
-        $name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>' : $name_html;
191
+        $name_html = $name_link ? '<a href="'.$name_link.'">'.$name_html.'</a>' : $name_html;
192 192
         $name_html .= $line_item->is_taxable() ? ' *' : '';
193 193
         // maybe preface with icon?
194
-        $name_html = $line_item_related_object instanceof EEI_Has_Icon ? $line_item_related_object->get_icon() . $name_html : $name_html;
195
-        $name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
196
-        $name_html .=  sprintf(
194
+        $name_html = $line_item_related_object instanceof EEI_Has_Icon ? $line_item_related_object->get_icon().$name_html : $name_html;
195
+        $name_html = '<span class="ee-line-item-name linked">'.$name_html.'</span><br>';
196
+        $name_html .= sprintf(
197 197
             _x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'),
198 198
             '<span class="ee-line-item-related-parent-object">',
199 199
             $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->OBJ_type_i18n() : esc_html__('Item:', 'event_espresso'),
200
-            $parent_related_object_link ? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>' : $parent_related_object_name,
200
+            $parent_related_object_link ? '<a href="'.$parent_related_object_link.'">'.$parent_related_object_name.'</a>' : $parent_related_object_name,
201 201
             '</span>'
202 202
         );
203 203
 
@@ -214,13 +214,13 @@  discard block
 block discarded – undo
214 214
         $type_html .= $this->_get_cancellations($line_item);
215 215
         $type_html .= $line_item->OBJ_type() ? '<br />' : '';
216 216
         $code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
217
-        $type_html .= ! empty($code) ? '<span class="ee-line-item-id">' . sprintf(esc_html__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
217
+        $type_html .= ! empty($code) ? '<span class="ee-line-item-id">'.sprintf(esc_html__('Code: %s', 'event_espresso'), $code).'</span>' : '';
218 218
         $html .= EEH_HTML::td($type_html, '', 'jst-left');
219 219
 
220 220
 
221 221
         // Amount Column
222 222
         if ($line_item->is_percent()) {
223
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
223
+            $html .= EEH_HTML::td($line_item->percent().'%', '', 'jst-rght');
224 224
         } else {
225 225
             $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
226 226
         }
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
         // start of row
296 296
         $html = EEH_HTML::tr('', 'admin-primary-mbox-taxes-tr');
297 297
         // name th
298
-        $html .= EEH_HTML::th($line_item->name() . '(' . $line_item->get_pretty('LIN_percent') . '%)', '', 'jst-rght', '', ' colspan="4"');
298
+        $html .= EEH_HTML::th($line_item->name().'('.$line_item->get_pretty('LIN_percent').'%)', '', 'jst-rght', '', ' colspan="4"');
299 299
         // total th
300 300
         $html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
301 301
         // end of row
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
         // start of row
335 335
         $html = EEH_HTML::tr('', '', 'admin-primary-mbox-total-tr');
336 336
         // Total th label
337
-        $total_label = sprintf(esc_html__('Transaction Total %s', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
337
+        $total_label = sprintf(esc_html__('Transaction Total %s', 'event_espresso'), '('.EE_Registry::instance()->CFG->currency->code.')');
338 338
         $html .= EEH_HTML::th($total_label, '', 'jst-rght', '', ' colspan="4"');
339 339
         // total th
340 340
 
Please login to merge, or discard this patch.
Indentation   +328 added lines, -328 removed lines patch added patch discarded remove patch
@@ -13,332 +13,332 @@
 block discarded – undo
13 13
 
14 14
 class EE_Admin_Table_Line_Item_Display_Strategy implements EEI_Line_Item_Display
15 15
 {
16
-    /**
17
-     * whether to display the taxes row or not
18
-     * @type bool $_show_taxes
19
-     */
20
-    protected $_show_taxes = false;
21
-
22
-    /**
23
-     * html for any tax rows
24
-     * @type string $_show_taxes
25
-     */
26
-    protected $_taxes_html = '';
27
-
28
-
29
-    /**
30
-     * total amount including tax we can bill for at this time
31
-     * @type float $_grand_total
32
-     */
33
-    protected $_grand_total = 0.00;
34
-
35
-
36
-
37
-    /**
38
-     * @return float
39
-     */
40
-    public function grand_total()
41
-    {
42
-        return $this->_grand_total;
43
-    }
44
-
45
-
46
-
47
-    /**
48
-     * This is used to output a single
49
-     * @param EE_Line_Item $line_item
50
-     * @param array        $options
51
-     * @return mixed
52
-     */
53
-    public function display_line_item(EE_Line_Item $line_item, $options = array())
54
-    {
55
-
56
-        $html = '';
57
-        // set some default options and merge with incoming
58
-        $default_options = array(
59
-            'odd' => true,
60
-            'use_table_wrapper' => true,
61
-            'table_css_class' => 'admin-primary-mbox-tbl',
62
-            'taxes_tr_css_class' => 'admin-primary-mbox-taxes-tr',
63
-            'total_tr_css_class' => 'admin-primary-mbox-total-tr'
64
-        );
65
-        $options = array_merge($default_options, (array) $options);
66
-
67
-        switch ($line_item->type()) {
68
-            case EEM_Line_Item::type_line_item:
69
-                // item row
70
-                $html .= $this->_item_row($line_item, $options);
71
-                break;
72
-
73
-            case EEM_Line_Item::type_sub_line_item:
74
-                $html .= $this->_sub_item_row($line_item, $options);
75
-                break;
76
-
77
-            case EEM_Line_Item::type_sub_total:
78
-                if ($line_item->quantity() === 0) {
79
-                    return $html;
80
-                }
81
-                // loop through children
82
-                $child_line_items = $line_item->children();
83
-                // loop through children
84
-                foreach ($child_line_items as $child_line_item) {
85
-                    // recursively feed children back into this method
86
-                    $html .= $this->display_line_item($child_line_item, $options);
87
-                }
88
-                $html .= $this->_sub_total_row($line_item, $options);
89
-                break;
90
-
91
-            case EEM_Line_Item::type_tax:
92
-                if ($this->_show_taxes) {
93
-                    $this->_taxes_html .= $this->_tax_row($line_item, $options);
94
-                }
95
-                break;
96
-
97
-            case EEM_Line_Item::type_tax_sub_total:
98
-                foreach ($line_item->children() as $child_line_item) {
99
-                    if ($child_line_item->type() == EEM_Line_Item::type_tax) {
100
-                        $this->display_line_item($child_line_item, $options);
101
-                    }
102
-                }
103
-                break;
104
-
105
-            case EEM_Line_Item::type_total:
106
-                // determine whether to display taxes or not
107
-                $this->_show_taxes = $line_item->get_total_tax() > 0 ? true : false;
108
-                // get all child line items
109
-                $children = $line_item->children();
110
-
111
-                // loop thru all non-tax child line items
112
-                foreach ($children as $child_line_item) {
113
-                        $html .= $this->display_line_item($child_line_item, $options);
114
-                }
115
-
116
-                $html .= $this->_taxes_html;
117
-                $html .= $this->_total_row($line_item, $options);
118
-                if ($options['use_table_wrapper']) {
119
-                    $html = $this->_table_header($options) . $html . $this->_table_footer($options);
120
-                }
121
-                break;
122
-        }
123
-
124
-        return $html;
125
-    }
126
-
127
-
128
-
129
-    /**
130
-     * Table header for display.
131
-     * @since   4.8
132
-     * @param array $options
133
-     * @return string
134
-     */
135
-    protected function _table_header($options)
136
-    {
137
-        $html = EEH_HTML::table('', '', $options['table_css_class']);
138
-        $html .= EEH_HTML::thead();
139
-        $html .= EEH_HTML::tr();
140
-        $html .= EEH_HTML::th(esc_html__('Name', 'event_espresso'), '', 'jst-left');
141
-        $html .= EEH_HTML::th(esc_html__('Type', 'event_espresso'), '', 'jst-left');
142
-        $html .= EEH_HTML::th(esc_html__('Amount', 'event_espresso'), '', 'jst-cntr');
143
-        $html .= EEH_HTML::th(esc_html__('Qty', 'event_espresso'), '', 'jst-cntr');
144
-        $html .= EEH_HTML::th(esc_html__('Line Total', 'event_espresso'), '', 'jst-cntr');
145
-        $html .= EEH_HTML::tbody();
146
-        return $html;
147
-    }
148
-
149
-
150
-    /**
151
-     * Table footer for display
152
-     * @since 4.8
153
-     * @param array $options array of options for the table.
154
-     * @return string
155
-     */
156
-    protected function _table_footer($options)
157
-    {
158
-        return EEH_HTML::tbodyx() .  EEH_HTML::tablex();
159
-    }
160
-
161
-
162
-
163
-    /**
164
-     *    _item_row
165
-     *
166
-     * @param EE_Line_Item $line_item
167
-     * @param array        $options
168
-     * @return mixed
169
-     */
170
-    protected function _item_row(EE_Line_Item $line_item, $options = array())
171
-    {
172
-        $line_item_related_object = $line_item->get_object();
173
-        $parent_line_item_related_object = $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->get_object() : null;
174
-        // start of row
175
-        $row_class = $options['odd'] ? 'item odd' : 'item';
176
-        $html = EEH_HTML::tr('', '', $row_class);
177
-
178
-
179
-        // Name Column
180
-        $name_link = $line_item_related_object instanceof EEI_Admin_Links ? $line_item_related_object->get_admin_details_link() : '';
181
-
182
-        // related object scope.
183
-        $parent_related_object_name = $parent_line_item_related_object instanceof EEI_Line_Item_Object ? $parent_line_item_related_object->name() : '';
184
-        $parent_related_object_name = empty($parent_related_object_name) && $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->name() : $parent_related_object_name;
185
-        $parent_related_object_link = $parent_line_item_related_object instanceof EEI_Admin_Links ? $parent_line_item_related_object->get_admin_details_link() : '';
186
-
187
-
188
-        $name_html = $line_item_related_object instanceof EEI_Line_Item_Object ? $line_item_related_object->name() : $line_item->name();
189
-        $name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>' : $name_html;
190
-        $name_html .= $line_item->is_taxable() ? ' *' : '';
191
-        // maybe preface with icon?
192
-        $name_html = $line_item_related_object instanceof EEI_Has_Icon ? $line_item_related_object->get_icon() . $name_html : $name_html;
193
-        $name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
194
-        $name_html .=  sprintf(
195
-            _x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'),
196
-            '<span class="ee-line-item-related-parent-object">',
197
-            $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->OBJ_type_i18n() : esc_html__('Item:', 'event_espresso'),
198
-            $parent_related_object_link ? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>' : $parent_related_object_name,
199
-            '</span>'
200
-        );
201
-
202
-        $name_html = apply_filters(
203
-            'FHEE__EE_Admin_Table_Line_Item_Display_Strategy___item_row__name_html',
204
-            $name_html,
205
-            $line_item,
206
-            $options
207
-        );
208
-
209
-        $html .= EEH_HTML::td($name_html, '', 'jst-left');
210
-        // Type Column
211
-        $type_html = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() : '';
212
-        $type_html .= $this->_get_cancellations($line_item);
213
-        $type_html .= $line_item->OBJ_type() ? '<br />' : '';
214
-        $code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
215
-        $type_html .= ! empty($code) ? '<span class="ee-line-item-id">' . sprintf(esc_html__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
216
-        $html .= EEH_HTML::td($type_html, '', 'jst-left');
217
-
218
-
219
-        // Amount Column
220
-        if ($line_item->is_percent()) {
221
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
222
-        } else {
223
-            $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
224
-        }
225
-
226
-        // QTY column
227
-        $html .= EEH_HTML::td($line_item->quantity(), '', 'jst-rght');
228
-
229
-        // total column
230
-        $html .= EEH_HTML::td(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
231
-
232
-        // finish things off and return
233
-        $html .= EEH_HTML::trx();
234
-        return $html;
235
-    }
236
-
237
-
238
-
239
-    /**
240
-     *    _get_cancellations
241
-     *
242
-     * @param EE_Line_Item $line_item
243
-     * @return string
244
-     */
245
-    protected function _get_cancellations(EE_Line_Item $line_item)
246
-    {
247
-        $html = '';
248
-        $cancellations = $line_item->get_cancellations();
249
-        $cancellation = reset($cancellations);
250
-        // \EEH_Debug_Tools::printr( $cancellation, '$cancellation', __FILE__, __LINE__ );
251
-        if ($cancellation instanceof EE_Line_Item) {
252
-            $html .= ' <span class="ee-line-item-id">';
253
-            $html .= sprintf(
254
-                _n(
255
-                    '(%1$s Cancellation)',
256
-                    '(%1$s Cancellations)',
257
-                    $cancellation->quantity(),
258
-                    'event_espresso'
259
-                ),
260
-                $cancellation->quantity()
261
-            );
262
-            $html .= '</span>';
263
-        }
264
-        return $html;
265
-    }
266
-
267
-
268
-
269
-    /**
270
-     *  _sub_item_row
271
-     *
272
-     * @param EE_Line_Item $line_item
273
-     * @param array        $options
274
-     * @return mixed
275
-     */
276
-    protected function _sub_item_row(EE_Line_Item $line_item, $options = array())
277
-    {
278
-        // for now we're not showing sub-items
279
-        return '';
280
-    }
281
-
282
-
283
-
284
-    /**
285
-     *  _tax_row
286
-     *
287
-     * @param EE_Line_Item $line_item
288
-     * @param array        $options
289
-     * @return mixed
290
-     */
291
-    protected function _tax_row(EE_Line_Item $line_item, $options = array())
292
-    {
293
-        // start of row
294
-        $html = EEH_HTML::tr('', 'admin-primary-mbox-taxes-tr');
295
-        // name th
296
-        $html .= EEH_HTML::th($line_item->name() . '(' . $line_item->get_pretty('LIN_percent') . '%)', '', 'jst-rght', '', ' colspan="4"');
297
-        // total th
298
-        $html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
299
-        // end of row
300
-        $html .= EEH_HTML::trx();
301
-        return $html;
302
-    }
303
-
304
-
305
-
306
-
307
-    /**
308
-     *  _total_row
309
-     *
310
-     * @param EE_Line_Item $line_item
311
-     * @param string       $text
312
-     * @param array        $options
313
-     * @return mixed
314
-     */
315
-    protected function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
316
-    {
317
-        // currently not showing subtotal row
318
-        return '';
319
-    }
320
-
321
-
322
-
323
-    /**
324
-     *  _total_row
325
-     *
326
-     * @param EE_Line_Item $line_item
327
-     * @param array        $options
328
-     * @return mixed
329
-     */
330
-    protected function _total_row(EE_Line_Item $line_item, $options = array())
331
-    {
332
-        // start of row
333
-        $html = EEH_HTML::tr('', '', 'admin-primary-mbox-total-tr');
334
-        // Total th label
335
-        $total_label = sprintf(esc_html__('Transaction Total %s', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
336
-        $html .= EEH_HTML::th($total_label, '', 'jst-rght', '', ' colspan="4"');
337
-        // total th
338
-
339
-        $html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
340
-        // end of row
341
-        $html .= EEH_HTML::trx();
342
-        return $html;
343
-    }
16
+	/**
17
+	 * whether to display the taxes row or not
18
+	 * @type bool $_show_taxes
19
+	 */
20
+	protected $_show_taxes = false;
21
+
22
+	/**
23
+	 * html for any tax rows
24
+	 * @type string $_show_taxes
25
+	 */
26
+	protected $_taxes_html = '';
27
+
28
+
29
+	/**
30
+	 * total amount including tax we can bill for at this time
31
+	 * @type float $_grand_total
32
+	 */
33
+	protected $_grand_total = 0.00;
34
+
35
+
36
+
37
+	/**
38
+	 * @return float
39
+	 */
40
+	public function grand_total()
41
+	{
42
+		return $this->_grand_total;
43
+	}
44
+
45
+
46
+
47
+	/**
48
+	 * This is used to output a single
49
+	 * @param EE_Line_Item $line_item
50
+	 * @param array        $options
51
+	 * @return mixed
52
+	 */
53
+	public function display_line_item(EE_Line_Item $line_item, $options = array())
54
+	{
55
+
56
+		$html = '';
57
+		// set some default options and merge with incoming
58
+		$default_options = array(
59
+			'odd' => true,
60
+			'use_table_wrapper' => true,
61
+			'table_css_class' => 'admin-primary-mbox-tbl',
62
+			'taxes_tr_css_class' => 'admin-primary-mbox-taxes-tr',
63
+			'total_tr_css_class' => 'admin-primary-mbox-total-tr'
64
+		);
65
+		$options = array_merge($default_options, (array) $options);
66
+
67
+		switch ($line_item->type()) {
68
+			case EEM_Line_Item::type_line_item:
69
+				// item row
70
+				$html .= $this->_item_row($line_item, $options);
71
+				break;
72
+
73
+			case EEM_Line_Item::type_sub_line_item:
74
+				$html .= $this->_sub_item_row($line_item, $options);
75
+				break;
76
+
77
+			case EEM_Line_Item::type_sub_total:
78
+				if ($line_item->quantity() === 0) {
79
+					return $html;
80
+				}
81
+				// loop through children
82
+				$child_line_items = $line_item->children();
83
+				// loop through children
84
+				foreach ($child_line_items as $child_line_item) {
85
+					// recursively feed children back into this method
86
+					$html .= $this->display_line_item($child_line_item, $options);
87
+				}
88
+				$html .= $this->_sub_total_row($line_item, $options);
89
+				break;
90
+
91
+			case EEM_Line_Item::type_tax:
92
+				if ($this->_show_taxes) {
93
+					$this->_taxes_html .= $this->_tax_row($line_item, $options);
94
+				}
95
+				break;
96
+
97
+			case EEM_Line_Item::type_tax_sub_total:
98
+				foreach ($line_item->children() as $child_line_item) {
99
+					if ($child_line_item->type() == EEM_Line_Item::type_tax) {
100
+						$this->display_line_item($child_line_item, $options);
101
+					}
102
+				}
103
+				break;
104
+
105
+			case EEM_Line_Item::type_total:
106
+				// determine whether to display taxes or not
107
+				$this->_show_taxes = $line_item->get_total_tax() > 0 ? true : false;
108
+				// get all child line items
109
+				$children = $line_item->children();
110
+
111
+				// loop thru all non-tax child line items
112
+				foreach ($children as $child_line_item) {
113
+						$html .= $this->display_line_item($child_line_item, $options);
114
+				}
115
+
116
+				$html .= $this->_taxes_html;
117
+				$html .= $this->_total_row($line_item, $options);
118
+				if ($options['use_table_wrapper']) {
119
+					$html = $this->_table_header($options) . $html . $this->_table_footer($options);
120
+				}
121
+				break;
122
+		}
123
+
124
+		return $html;
125
+	}
126
+
127
+
128
+
129
+	/**
130
+	 * Table header for display.
131
+	 * @since   4.8
132
+	 * @param array $options
133
+	 * @return string
134
+	 */
135
+	protected function _table_header($options)
136
+	{
137
+		$html = EEH_HTML::table('', '', $options['table_css_class']);
138
+		$html .= EEH_HTML::thead();
139
+		$html .= EEH_HTML::tr();
140
+		$html .= EEH_HTML::th(esc_html__('Name', 'event_espresso'), '', 'jst-left');
141
+		$html .= EEH_HTML::th(esc_html__('Type', 'event_espresso'), '', 'jst-left');
142
+		$html .= EEH_HTML::th(esc_html__('Amount', 'event_espresso'), '', 'jst-cntr');
143
+		$html .= EEH_HTML::th(esc_html__('Qty', 'event_espresso'), '', 'jst-cntr');
144
+		$html .= EEH_HTML::th(esc_html__('Line Total', 'event_espresso'), '', 'jst-cntr');
145
+		$html .= EEH_HTML::tbody();
146
+		return $html;
147
+	}
148
+
149
+
150
+	/**
151
+	 * Table footer for display
152
+	 * @since 4.8
153
+	 * @param array $options array of options for the table.
154
+	 * @return string
155
+	 */
156
+	protected function _table_footer($options)
157
+	{
158
+		return EEH_HTML::tbodyx() .  EEH_HTML::tablex();
159
+	}
160
+
161
+
162
+
163
+	/**
164
+	 *    _item_row
165
+	 *
166
+	 * @param EE_Line_Item $line_item
167
+	 * @param array        $options
168
+	 * @return mixed
169
+	 */
170
+	protected function _item_row(EE_Line_Item $line_item, $options = array())
171
+	{
172
+		$line_item_related_object = $line_item->get_object();
173
+		$parent_line_item_related_object = $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->get_object() : null;
174
+		// start of row
175
+		$row_class = $options['odd'] ? 'item odd' : 'item';
176
+		$html = EEH_HTML::tr('', '', $row_class);
177
+
178
+
179
+		// Name Column
180
+		$name_link = $line_item_related_object instanceof EEI_Admin_Links ? $line_item_related_object->get_admin_details_link() : '';
181
+
182
+		// related object scope.
183
+		$parent_related_object_name = $parent_line_item_related_object instanceof EEI_Line_Item_Object ? $parent_line_item_related_object->name() : '';
184
+		$parent_related_object_name = empty($parent_related_object_name) && $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->name() : $parent_related_object_name;
185
+		$parent_related_object_link = $parent_line_item_related_object instanceof EEI_Admin_Links ? $parent_line_item_related_object->get_admin_details_link() : '';
186
+
187
+
188
+		$name_html = $line_item_related_object instanceof EEI_Line_Item_Object ? $line_item_related_object->name() : $line_item->name();
189
+		$name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>' : $name_html;
190
+		$name_html .= $line_item->is_taxable() ? ' *' : '';
191
+		// maybe preface with icon?
192
+		$name_html = $line_item_related_object instanceof EEI_Has_Icon ? $line_item_related_object->get_icon() . $name_html : $name_html;
193
+		$name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
194
+		$name_html .=  sprintf(
195
+			_x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'),
196
+			'<span class="ee-line-item-related-parent-object">',
197
+			$line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->OBJ_type_i18n() : esc_html__('Item:', 'event_espresso'),
198
+			$parent_related_object_link ? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>' : $parent_related_object_name,
199
+			'</span>'
200
+		);
201
+
202
+		$name_html = apply_filters(
203
+			'FHEE__EE_Admin_Table_Line_Item_Display_Strategy___item_row__name_html',
204
+			$name_html,
205
+			$line_item,
206
+			$options
207
+		);
208
+
209
+		$html .= EEH_HTML::td($name_html, '', 'jst-left');
210
+		// Type Column
211
+		$type_html = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() : '';
212
+		$type_html .= $this->_get_cancellations($line_item);
213
+		$type_html .= $line_item->OBJ_type() ? '<br />' : '';
214
+		$code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
215
+		$type_html .= ! empty($code) ? '<span class="ee-line-item-id">' . sprintf(esc_html__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
216
+		$html .= EEH_HTML::td($type_html, '', 'jst-left');
217
+
218
+
219
+		// Amount Column
220
+		if ($line_item->is_percent()) {
221
+			$html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
222
+		} else {
223
+			$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
224
+		}
225
+
226
+		// QTY column
227
+		$html .= EEH_HTML::td($line_item->quantity(), '', 'jst-rght');
228
+
229
+		// total column
230
+		$html .= EEH_HTML::td(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
231
+
232
+		// finish things off and return
233
+		$html .= EEH_HTML::trx();
234
+		return $html;
235
+	}
236
+
237
+
238
+
239
+	/**
240
+	 *    _get_cancellations
241
+	 *
242
+	 * @param EE_Line_Item $line_item
243
+	 * @return string
244
+	 */
245
+	protected function _get_cancellations(EE_Line_Item $line_item)
246
+	{
247
+		$html = '';
248
+		$cancellations = $line_item->get_cancellations();
249
+		$cancellation = reset($cancellations);
250
+		// \EEH_Debug_Tools::printr( $cancellation, '$cancellation', __FILE__, __LINE__ );
251
+		if ($cancellation instanceof EE_Line_Item) {
252
+			$html .= ' <span class="ee-line-item-id">';
253
+			$html .= sprintf(
254
+				_n(
255
+					'(%1$s Cancellation)',
256
+					'(%1$s Cancellations)',
257
+					$cancellation->quantity(),
258
+					'event_espresso'
259
+				),
260
+				$cancellation->quantity()
261
+			);
262
+			$html .= '</span>';
263
+		}
264
+		return $html;
265
+	}
266
+
267
+
268
+
269
+	/**
270
+	 *  _sub_item_row
271
+	 *
272
+	 * @param EE_Line_Item $line_item
273
+	 * @param array        $options
274
+	 * @return mixed
275
+	 */
276
+	protected function _sub_item_row(EE_Line_Item $line_item, $options = array())
277
+	{
278
+		// for now we're not showing sub-items
279
+		return '';
280
+	}
281
+
282
+
283
+
284
+	/**
285
+	 *  _tax_row
286
+	 *
287
+	 * @param EE_Line_Item $line_item
288
+	 * @param array        $options
289
+	 * @return mixed
290
+	 */
291
+	protected function _tax_row(EE_Line_Item $line_item, $options = array())
292
+	{
293
+		// start of row
294
+		$html = EEH_HTML::tr('', 'admin-primary-mbox-taxes-tr');
295
+		// name th
296
+		$html .= EEH_HTML::th($line_item->name() . '(' . $line_item->get_pretty('LIN_percent') . '%)', '', 'jst-rght', '', ' colspan="4"');
297
+		// total th
298
+		$html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
299
+		// end of row
300
+		$html .= EEH_HTML::trx();
301
+		return $html;
302
+	}
303
+
304
+
305
+
306
+
307
+	/**
308
+	 *  _total_row
309
+	 *
310
+	 * @param EE_Line_Item $line_item
311
+	 * @param string       $text
312
+	 * @param array        $options
313
+	 * @return mixed
314
+	 */
315
+	protected function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
316
+	{
317
+		// currently not showing subtotal row
318
+		return '';
319
+	}
320
+
321
+
322
+
323
+	/**
324
+	 *  _total_row
325
+	 *
326
+	 * @param EE_Line_Item $line_item
327
+	 * @param array        $options
328
+	 * @return mixed
329
+	 */
330
+	protected function _total_row(EE_Line_Item $line_item, $options = array())
331
+	{
332
+		// start of row
333
+		$html = EEH_HTML::tr('', '', 'admin-primary-mbox-total-tr');
334
+		// Total th label
335
+		$total_label = sprintf(esc_html__('Transaction Total %s', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
336
+		$html .= EEH_HTML::th($total_label, '', 'jst-rght', '', ' colspan="4"');
337
+		// total th
338
+
339
+		$html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
340
+		// end of row
341
+		$html .= EEH_HTML::trx();
342
+		return $html;
343
+	}
344 344
 }
Please login to merge, or discard this patch.
EE_Admin_Table_Registration_Line_Item_Display_Strategy.strategy.php 2 patches
Indentation   +187 added lines, -187 removed lines patch added patch discarded remove patch
@@ -14,191 +14,191 @@
 block discarded – undo
14 14
 class EE_Admin_Table_Registration_Line_Item_Display_Strategy extends EE_Admin_Table_Line_Item_Display_Strategy
15 15
 {
16 16
 
17
-    /**
18
-     * Table header for display.
19
-     * @since   4.8
20
-     * @param array $options
21
-     * @return string
22
-     */
23
-    protected function _table_header($options)
24
-    {
25
-        $html = EEH_HTML::table('', '', $options['table_css_class']);
26
-        $html .= EEH_HTML::thead();
27
-        $html .= EEH_HTML::tr();
28
-        $html .= EEH_HTML::th(esc_html__('Name', 'event_espresso'), '', 'jst-left');
29
-        $html .= EEH_HTML::th(esc_html__('Type', 'event_espresso'), '', 'jst-left');
30
-        $html .= EEH_HTML::th(esc_html__('Date(s)', 'event_espresso'), '', 'jst-left');
31
-        $html .= EEH_HTML::th(esc_html__('Amount', 'event_espresso'), '', 'jst-cntr');
32
-        $html .= EEH_HTML::tbody();
33
-        return $html;
34
-    }
35
-
36
-
37
-
38
-
39
-
40
-    /**
41
-     *    _item_row
42
-     *
43
-     * @param EE_Line_Item $line_item
44
-     * @param array        $options
45
-     * @return mixed
46
-     */
47
-    protected function _item_row(EE_Line_Item $line_item, $options = array())
48
-    {
49
-        $line_item_related_object = $line_item->get_object();
50
-        $parent_line_item_related_object = $line_item->parent() instanceof EE_Line_Item
51
-            ? $line_item->parent()->get_object()
52
-            : null;
53
-        // start of row
54
-        $row_class = $options['odd'] ? 'item odd' : 'item';
55
-        $html = EEH_HTML::tr('', '', $row_class);
56
-
57
-
58
-        // Name Column
59
-        $name_link = $line_item_related_object instanceof EEI_Admin_Links ? $line_item_related_object->get_admin_details_link() : '';
60
-
61
-        // related object scope.
62
-        $parent_related_object_name = $parent_line_item_related_object instanceof EEI_Line_Item_Object
63
-            ? $parent_line_item_related_object->name()
64
-            : '';
65
-        $parent_related_object_name = empty($parent_related_object_name) && $line_item->parent() instanceof EE_Line_Item
66
-            ? $line_item->parent()->name()
67
-            : $parent_related_object_name;
68
-        $parent_related_object_link = $parent_line_item_related_object instanceof EEI_Admin_Links
69
-            ? $parent_line_item_related_object->get_admin_details_link()
70
-            : '';
71
-
72
-
73
-        $name_html = $line_item_related_object instanceof EEI_Line_Item_Object
74
-            ? $line_item_related_object->name() : $line_item->name();
75
-        $name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>'
76
-            : $name_html;
77
-        $name_html .= $line_item->is_taxable() ? ' *' : '';
78
-        // maybe preface with icon?
79
-        $name_html = $line_item_related_object instanceof EEI_Has_Icon
80
-            ? $line_item_related_object->get_icon() . $name_html
81
-            : $name_html;
82
-        $name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
83
-        $name_html .=  sprintf(
84
-            _x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'),
85
-            '<span class="ee-line-item-related-parent-object">',
86
-            $line_item->parent() instanceof EE_Line_Item
87
-                ? $line_item->parent()->OBJ_type_i18n()
88
-                : esc_html__('Item:', 'event_espresso'),
89
-            $parent_related_object_link
90
-                ? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>'
91
-                : $parent_related_object_name,
92
-            '</span>'
93
-        );
94
-
95
-        $name_html = apply_filters(
96
-            'FHEE__EE_Admin_Table_Registration_Line_Item_Display_Strategy___item_row__name_html',
97
-            $name_html,
98
-            $line_item,
99
-            $options
100
-        );
101
-
102
-        $html .= EEH_HTML::td($name_html, '', 'jst-left');
103
-        // Type Column
104
-        $type_html = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() : '';
105
-        $type_html .= $this->_get_cancellations($line_item);
106
-        $type_html .= $line_item->OBJ_type() ? '<br />' : '';
107
-        $code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
108
-        $type_html .= ! empty($code) ? '<span class="ee-line-item-id">' . sprintf(esc_html__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
109
-        $html .= EEH_HTML::td($type_html, '', 'jst-left');
110
-
111
-        // Date column
112
-        $datetime_content = '';
113
-        if ($line_item_related_object instanceof EE_Ticket) {
114
-            $datetimes = $line_item_related_object->datetimes();
115
-            foreach ($datetimes as $datetime) {
116
-                if ($datetime instanceof EE_Datetime) {
117
-                    $datetime_content .= $datetime->get_dtt_display_name() . '<br>';
118
-                }
119
-            }
120
-        }
121
-        $html .= EEH_HTML::td($datetime_content, '', 'jst-left');
122
-
123
-        // Amount Column
124
-        if ($line_item->is_percent()) {
125
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
126
-        } else {
127
-            $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
128
-        }
129
-
130
-
131
-        // finish things off and return
132
-        $html .= EEH_HTML::trx();
133
-        return $html;
134
-    }
135
-
136
-
137
-
138
-    /**
139
-     *  _tax_row
140
-     *
141
-     * @param EE_Line_Item $line_item
142
-     * @param array        $options
143
-     * @return mixed
144
-     */
145
-    protected function _tax_row(EE_Line_Item $line_item, $options = array())
146
-    {
147
-        // start of row
148
-        $html = EEH_HTML::tr('', 'admin-primary-mbox-taxes-tr');
149
-        // name th
150
-        $html .= EEH_HTML::th($line_item->name() . '(' . $line_item->get_pretty('LIN_percent') . '%)', '', 'jst-rght', '', ' colspan="3"');
151
-        // total th
152
-        $html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
153
-        // end of row
154
-        $html .= EEH_HTML::trx();
155
-        return $html;
156
-    }
157
-
158
-
159
-
160
-
161
-
162
-    /**
163
-     *  _total_row
164
-     *
165
-     * @param EE_Line_Item $line_item
166
-     * @param array        $options
167
-     * @return mixed
168
-     */
169
-    protected function _total_row(EE_Line_Item $line_item, $options = array())
170
-    {
171
-
172
-        $registration = isset($options['EE_Registration']) ? $options['EE_Registration'] : null;
173
-        $registration_total = $registration instanceof EE_Registration ? $registration->pretty_final_price() : 0;
174
-        // if no valid registration object then we're not going to show the approximate text.
175
-        $total_match = $registration instanceof EE_Registration
176
-            ? $registration->final_price() === $line_item->total()
177
-            : true;
178
-
179
-        // start of row
180
-        $html = EEH_HTML::tr('', '', 'admin-primary-mbox-total-tr');
181
-        // Total th label
182
-        if ($total_match) {
183
-            $total_label = sprintf(esc_html__('This registration\'s total %s:', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
184
-        } else {
185
-            $total_label = sprintf(esc_html__('This registration\'s approximate total %s', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
186
-            $total_label .= '<br>';
187
-            $total_label .= '<p class="ee-footnote-text">'
188
-                            . sprintf(
189
-                                esc_html__('The registrations\' share of the transaction total is approximate because it might not be possible to evenly divide the transaction total among each registration, and so some registrations may need to pay a penny more than others.  This registration\'s final share is actually %1$s%2$s%3$s.', 'event_espresso'),
190
-                                '<strong>',
191
-                                $registration_total,
192
-                                '</strong>'
193
-                            )
194
-                            . '</p>';
195
-        }
196
-        $html .= EEH_HTML::th($total_label, '', 'jst-rght', '', ' colspan="3"');
197
-        // total th
198
-
199
-        $html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
200
-        // end of row
201
-        $html .= EEH_HTML::trx();
202
-        return $html;
203
-    }
17
+	/**
18
+	 * Table header for display.
19
+	 * @since   4.8
20
+	 * @param array $options
21
+	 * @return string
22
+	 */
23
+	protected function _table_header($options)
24
+	{
25
+		$html = EEH_HTML::table('', '', $options['table_css_class']);
26
+		$html .= EEH_HTML::thead();
27
+		$html .= EEH_HTML::tr();
28
+		$html .= EEH_HTML::th(esc_html__('Name', 'event_espresso'), '', 'jst-left');
29
+		$html .= EEH_HTML::th(esc_html__('Type', 'event_espresso'), '', 'jst-left');
30
+		$html .= EEH_HTML::th(esc_html__('Date(s)', 'event_espresso'), '', 'jst-left');
31
+		$html .= EEH_HTML::th(esc_html__('Amount', 'event_espresso'), '', 'jst-cntr');
32
+		$html .= EEH_HTML::tbody();
33
+		return $html;
34
+	}
35
+
36
+
37
+
38
+
39
+
40
+	/**
41
+	 *    _item_row
42
+	 *
43
+	 * @param EE_Line_Item $line_item
44
+	 * @param array        $options
45
+	 * @return mixed
46
+	 */
47
+	protected function _item_row(EE_Line_Item $line_item, $options = array())
48
+	{
49
+		$line_item_related_object = $line_item->get_object();
50
+		$parent_line_item_related_object = $line_item->parent() instanceof EE_Line_Item
51
+			? $line_item->parent()->get_object()
52
+			: null;
53
+		// start of row
54
+		$row_class = $options['odd'] ? 'item odd' : 'item';
55
+		$html = EEH_HTML::tr('', '', $row_class);
56
+
57
+
58
+		// Name Column
59
+		$name_link = $line_item_related_object instanceof EEI_Admin_Links ? $line_item_related_object->get_admin_details_link() : '';
60
+
61
+		// related object scope.
62
+		$parent_related_object_name = $parent_line_item_related_object instanceof EEI_Line_Item_Object
63
+			? $parent_line_item_related_object->name()
64
+			: '';
65
+		$parent_related_object_name = empty($parent_related_object_name) && $line_item->parent() instanceof EE_Line_Item
66
+			? $line_item->parent()->name()
67
+			: $parent_related_object_name;
68
+		$parent_related_object_link = $parent_line_item_related_object instanceof EEI_Admin_Links
69
+			? $parent_line_item_related_object->get_admin_details_link()
70
+			: '';
71
+
72
+
73
+		$name_html = $line_item_related_object instanceof EEI_Line_Item_Object
74
+			? $line_item_related_object->name() : $line_item->name();
75
+		$name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>'
76
+			: $name_html;
77
+		$name_html .= $line_item->is_taxable() ? ' *' : '';
78
+		// maybe preface with icon?
79
+		$name_html = $line_item_related_object instanceof EEI_Has_Icon
80
+			? $line_item_related_object->get_icon() . $name_html
81
+			: $name_html;
82
+		$name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
83
+		$name_html .=  sprintf(
84
+			_x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'),
85
+			'<span class="ee-line-item-related-parent-object">',
86
+			$line_item->parent() instanceof EE_Line_Item
87
+				? $line_item->parent()->OBJ_type_i18n()
88
+				: esc_html__('Item:', 'event_espresso'),
89
+			$parent_related_object_link
90
+				? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>'
91
+				: $parent_related_object_name,
92
+			'</span>'
93
+		);
94
+
95
+		$name_html = apply_filters(
96
+			'FHEE__EE_Admin_Table_Registration_Line_Item_Display_Strategy___item_row__name_html',
97
+			$name_html,
98
+			$line_item,
99
+			$options
100
+		);
101
+
102
+		$html .= EEH_HTML::td($name_html, '', 'jst-left');
103
+		// Type Column
104
+		$type_html = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() : '';
105
+		$type_html .= $this->_get_cancellations($line_item);
106
+		$type_html .= $line_item->OBJ_type() ? '<br />' : '';
107
+		$code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
108
+		$type_html .= ! empty($code) ? '<span class="ee-line-item-id">' . sprintf(esc_html__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
109
+		$html .= EEH_HTML::td($type_html, '', 'jst-left');
110
+
111
+		// Date column
112
+		$datetime_content = '';
113
+		if ($line_item_related_object instanceof EE_Ticket) {
114
+			$datetimes = $line_item_related_object->datetimes();
115
+			foreach ($datetimes as $datetime) {
116
+				if ($datetime instanceof EE_Datetime) {
117
+					$datetime_content .= $datetime->get_dtt_display_name() . '<br>';
118
+				}
119
+			}
120
+		}
121
+		$html .= EEH_HTML::td($datetime_content, '', 'jst-left');
122
+
123
+		// Amount Column
124
+		if ($line_item->is_percent()) {
125
+			$html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
126
+		} else {
127
+			$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
128
+		}
129
+
130
+
131
+		// finish things off and return
132
+		$html .= EEH_HTML::trx();
133
+		return $html;
134
+	}
135
+
136
+
137
+
138
+	/**
139
+	 *  _tax_row
140
+	 *
141
+	 * @param EE_Line_Item $line_item
142
+	 * @param array        $options
143
+	 * @return mixed
144
+	 */
145
+	protected function _tax_row(EE_Line_Item $line_item, $options = array())
146
+	{
147
+		// start of row
148
+		$html = EEH_HTML::tr('', 'admin-primary-mbox-taxes-tr');
149
+		// name th
150
+		$html .= EEH_HTML::th($line_item->name() . '(' . $line_item->get_pretty('LIN_percent') . '%)', '', 'jst-rght', '', ' colspan="3"');
151
+		// total th
152
+		$html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
153
+		// end of row
154
+		$html .= EEH_HTML::trx();
155
+		return $html;
156
+	}
157
+
158
+
159
+
160
+
161
+
162
+	/**
163
+	 *  _total_row
164
+	 *
165
+	 * @param EE_Line_Item $line_item
166
+	 * @param array        $options
167
+	 * @return mixed
168
+	 */
169
+	protected function _total_row(EE_Line_Item $line_item, $options = array())
170
+	{
171
+
172
+		$registration = isset($options['EE_Registration']) ? $options['EE_Registration'] : null;
173
+		$registration_total = $registration instanceof EE_Registration ? $registration->pretty_final_price() : 0;
174
+		// if no valid registration object then we're not going to show the approximate text.
175
+		$total_match = $registration instanceof EE_Registration
176
+			? $registration->final_price() === $line_item->total()
177
+			: true;
178
+
179
+		// start of row
180
+		$html = EEH_HTML::tr('', '', 'admin-primary-mbox-total-tr');
181
+		// Total th label
182
+		if ($total_match) {
183
+			$total_label = sprintf(esc_html__('This registration\'s total %s:', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
184
+		} else {
185
+			$total_label = sprintf(esc_html__('This registration\'s approximate total %s', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
186
+			$total_label .= '<br>';
187
+			$total_label .= '<p class="ee-footnote-text">'
188
+							. sprintf(
189
+								esc_html__('The registrations\' share of the transaction total is approximate because it might not be possible to evenly divide the transaction total among each registration, and so some registrations may need to pay a penny more than others.  This registration\'s final share is actually %1$s%2$s%3$s.', 'event_espresso'),
190
+								'<strong>',
191
+								$registration_total,
192
+								'</strong>'
193
+							)
194
+							. '</p>';
195
+		}
196
+		$html .= EEH_HTML::th($total_label, '', 'jst-rght', '', ' colspan="3"');
197
+		// total th
198
+
199
+		$html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
200
+		// end of row
201
+		$html .= EEH_HTML::trx();
202
+		return $html;
203
+	}
204 204
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -72,22 +72,22 @@  discard block
 block discarded – undo
72 72
 
73 73
         $name_html = $line_item_related_object instanceof EEI_Line_Item_Object
74 74
             ? $line_item_related_object->name() : $line_item->name();
75
-        $name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>'
75
+        $name_html = $name_link ? '<a href="'.$name_link.'">'.$name_html.'</a>'
76 76
             : $name_html;
77 77
         $name_html .= $line_item->is_taxable() ? ' *' : '';
78 78
         // maybe preface with icon?
79 79
         $name_html = $line_item_related_object instanceof EEI_Has_Icon
80
-            ? $line_item_related_object->get_icon() . $name_html
80
+            ? $line_item_related_object->get_icon().$name_html
81 81
             : $name_html;
82
-        $name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
83
-        $name_html .=  sprintf(
82
+        $name_html = '<span class="ee-line-item-name linked">'.$name_html.'</span><br>';
83
+        $name_html .= sprintf(
84 84
             _x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'),
85 85
             '<span class="ee-line-item-related-parent-object">',
86 86
             $line_item->parent() instanceof EE_Line_Item
87 87
                 ? $line_item->parent()->OBJ_type_i18n()
88 88
                 : esc_html__('Item:', 'event_espresso'),
89 89
             $parent_related_object_link
90
-                ? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>'
90
+                ? '<a href="'.$parent_related_object_link.'">'.$parent_related_object_name.'</a>'
91 91
                 : $parent_related_object_name,
92 92
             '</span>'
93 93
         );
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
         $type_html .= $this->_get_cancellations($line_item);
106 106
         $type_html .= $line_item->OBJ_type() ? '<br />' : '';
107 107
         $code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
108
-        $type_html .= ! empty($code) ? '<span class="ee-line-item-id">' . sprintf(esc_html__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
108
+        $type_html .= ! empty($code) ? '<span class="ee-line-item-id">'.sprintf(esc_html__('Code: %s', 'event_espresso'), $code).'</span>' : '';
109 109
         $html .= EEH_HTML::td($type_html, '', 'jst-left');
110 110
 
111 111
         // Date column
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
             $datetimes = $line_item_related_object->datetimes();
115 115
             foreach ($datetimes as $datetime) {
116 116
                 if ($datetime instanceof EE_Datetime) {
117
-                    $datetime_content .= $datetime->get_dtt_display_name() . '<br>';
117
+                    $datetime_content .= $datetime->get_dtt_display_name().'<br>';
118 118
                 }
119 119
             }
120 120
         }
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
 
123 123
         // Amount Column
124 124
         if ($line_item->is_percent()) {
125
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
125
+            $html .= EEH_HTML::td($line_item->percent().'%', '', 'jst-rght');
126 126
         } else {
127 127
             $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
128 128
         }
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
         // start of row
148 148
         $html = EEH_HTML::tr('', 'admin-primary-mbox-taxes-tr');
149 149
         // name th
150
-        $html .= EEH_HTML::th($line_item->name() . '(' . $line_item->get_pretty('LIN_percent') . '%)', '', 'jst-rght', '', ' colspan="3"');
150
+        $html .= EEH_HTML::th($line_item->name().'('.$line_item->get_pretty('LIN_percent').'%)', '', 'jst-rght', '', ' colspan="3"');
151 151
         // total th
152 152
         $html .= EEH_HTML::th(EEH_Template::format_currency($line_item->total(), false, false), '', 'jst-rght');
153 153
         // end of row
@@ -180,9 +180,9 @@  discard block
 block discarded – undo
180 180
         $html = EEH_HTML::tr('', '', 'admin-primary-mbox-total-tr');
181 181
         // Total th label
182 182
         if ($total_match) {
183
-            $total_label = sprintf(esc_html__('This registration\'s total %s:', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
183
+            $total_label = sprintf(esc_html__('This registration\'s total %s:', 'event_espresso'), '('.EE_Registry::instance()->CFG->currency->code.')');
184 184
         } else {
185
-            $total_label = sprintf(esc_html__('This registration\'s approximate total %s', 'event_espresso'), '(' . EE_Registry::instance()->CFG->currency->code . ')');
185
+            $total_label = sprintf(esc_html__('This registration\'s approximate total %s', 'event_espresso'), '('.EE_Registry::instance()->CFG->currency->code.')');
186 186
             $total_label .= '<br>';
187 187
             $total_label .= '<p class="ee-footnote-text">'
188 188
                             . sprintf(
Please login to merge, or discard this patch.