Completed
Branch BUG/reg-status-change-recursio... (fbd515)
by
unknown
09:28 queued 36s
created
core/libraries/rest_api/controllers/model/Write.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -456,7 +456,7 @@
 block discarded – undo
456 456
      * @param EEM_Base $model
457 457
      * @param EE_Model_Relation_Base $relation
458 458
      * @param WP_REST_Request $request
459
-     * @return array {
459
+     * @return EE_Base_Class[] {
460 460
      * @type EE_Base_Class $model_obj
461 461
      * @type EE_Base_Class|null $other_model_obj
462 462
      * }
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -11,7 +11,6 @@
 block discarded – undo
11 11
 use EventEspresso\core\services\loaders\LoaderFactory;
12 12
 use Exception;
13 13
 use InvalidArgumentException;
14
-use ReflectionException;
15 14
 use \WP_REST_Request;
16 15
 use \WP_REST_Response;
17 16
 use EventEspresso\core\libraries\rest_api\Capabilities;
Please login to merge, or discard this patch.
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(__('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(__('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());
@@ -434,7 +434,7 @@  discard block
 block discarded – undo
434 434
                     )
435 435
                 )
436 436
             );
437
-            $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
437
+            $response['join'][strtolower($relation->get_join_model()->get_this_model_name())] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
438 438
         }
439 439
         return $response;
440 440
     }
@@ -482,7 +482,7 @@  discard block
 block discarded – undo
482 482
     {
483 483
         // This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know
484 484
         // up-front that it doesn't.)
485
-        if (!empty($request->get_body_params())) {
485
+        if ( ! empty($request->get_body_params())) {
486 486
             $body_params = $request->get_body_params();
487 487
             throw new RestException(
488 488
                 'invalid_field',
@@ -524,9 +524,9 @@  discard block
 block discarded – undo
524 524
                 )
525 525
             );
526 526
             if ($join_model_obj instanceof EE_Base_Class) {
527
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
527
+                $response['join'][strtolower($relation->get_join_model()->get_this_model_name())] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
528 528
             } else {
529
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null;
529
+                $response['join'][strtolower($relation->get_join_model()->get_this_model_name())] = null;
530 530
             }
531 531
         }
532 532
         return $response;
@@ -551,9 +551,9 @@  discard block
 block discarded – undo
551 551
         // Check generic caps. For now, we're only allowing access to this endpoint to full admins.
552 552
         Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
553 553
         $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
554
-        if (! current_user_can($default_cap_to_check_for)) {
554
+        if ( ! current_user_can($default_cap_to_check_for)) {
555 555
             throw new RestException(
556
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
556
+                'rest_cannot_edit_'.EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
557 557
                 sprintf(
558 558
                     esc_html__(
559 559
                         // @codingStandardsIgnoreStart
@@ -570,7 +570,7 @@  discard block
 block discarded – undo
570 570
         $model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
571 571
         // For now, we require the other model object to exist too. This might be relaxed later.
572 572
         $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id'));
573
-        return array($model_obj,$other_obj);
573
+        return array($model_obj, $other_obj);
574 574
     }
575 575
 
576 576
     /**
Please login to merge, or discard this patch.
Indentation   +546 added lines, -546 removed lines patch added patch discarded remove patch
@@ -39,573 +39,573 @@
 block discarded – undo
39 39
 {
40 40
 
41 41
 
42
-    public function __construct()
43
-    {
44
-        parent::__construct();
45
-        EE_Registry::instance()->load_helper('Inflector');
46
-    }
42
+	public function __construct()
43
+	{
44
+		parent::__construct();
45
+		EE_Registry::instance()->load_helper('Inflector');
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
51
-     *
52
-     * @param WP_REST_Request $request
53
-     * @param string          $version
54
-     * @param string          $model_name
55
-     * @return WP_REST_Response|\WP_Error
56
-     */
57
-    public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name)
58
-    {
59
-        $controller = new Write();
60
-        try {
61
-            $controller->setRequestedVersion($version);
62
-            return $controller->sendResponse(
63
-                $controller->insert(
64
-                    $controller->getModelVersionInfo()->loadModel($model_name),
65
-                    $request
66
-                )
67
-            );
68
-        } catch (Exception $e) {
69
-            return $controller->sendResponse($e);
70
-        }
71
-    }
49
+	/**
50
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
51
+	 *
52
+	 * @param WP_REST_Request $request
53
+	 * @param string          $version
54
+	 * @param string          $model_name
55
+	 * @return WP_REST_Response|\WP_Error
56
+	 */
57
+	public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name)
58
+	{
59
+		$controller = new Write();
60
+		try {
61
+			$controller->setRequestedVersion($version);
62
+			return $controller->sendResponse(
63
+				$controller->insert(
64
+					$controller->getModelVersionInfo()->loadModel($model_name),
65
+					$request
66
+				)
67
+			);
68
+		} catch (Exception $e) {
69
+			return $controller->sendResponse($e);
70
+		}
71
+	}
72 72
 
73 73
 
74
-    /**
75
-     * Handles a request from \WP_REST_Server to update an EE model
76
-     *
77
-     * @param WP_REST_Request $request
78
-     * @param string          $version
79
-     * @param string          $model_name
80
-     * @return WP_REST_Response|\WP_Error
81
-     */
82
-    public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name)
83
-    {
84
-        $controller = new Write();
85
-        try {
86
-            $controller->setRequestedVersion($version);
87
-            return $controller->sendResponse(
88
-                $controller->update(
89
-                    $controller->getModelVersionInfo()->loadModel($model_name),
90
-                    $request
91
-                )
92
-            );
93
-        } catch (Exception $e) {
94
-            return $controller->sendResponse($e);
95
-        }
96
-    }
74
+	/**
75
+	 * Handles a request from \WP_REST_Server to update an EE model
76
+	 *
77
+	 * @param WP_REST_Request $request
78
+	 * @param string          $version
79
+	 * @param string          $model_name
80
+	 * @return WP_REST_Response|\WP_Error
81
+	 */
82
+	public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name)
83
+	{
84
+		$controller = new Write();
85
+		try {
86
+			$controller->setRequestedVersion($version);
87
+			return $controller->sendResponse(
88
+				$controller->update(
89
+					$controller->getModelVersionInfo()->loadModel($model_name),
90
+					$request
91
+				)
92
+			);
93
+		} catch (Exception $e) {
94
+			return $controller->sendResponse($e);
95
+		}
96
+	}
97 97
 
98 98
 
99
-    /**
100
-     * Deletes a single model object and returns it. Unless
101
-     *
102
-     * @param WP_REST_Request $request
103
-     * @param string          $version
104
-     * @param string          $model_name
105
-     * @return WP_REST_Response|\WP_Error
106
-     */
107
-    public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name)
108
-    {
109
-        $controller = new Write();
110
-        try {
111
-            $controller->setRequestedVersion($version);
112
-            return $controller->sendResponse(
113
-                $controller->delete(
114
-                    $controller->getModelVersionInfo()->loadModel($model_name),
115
-                    $request
116
-                )
117
-            );
118
-        } catch (Exception $e) {
119
-            return $controller->sendResponse($e);
120
-        }
121
-    }
99
+	/**
100
+	 * Deletes a single model object and returns it. Unless
101
+	 *
102
+	 * @param WP_REST_Request $request
103
+	 * @param string          $version
104
+	 * @param string          $model_name
105
+	 * @return WP_REST_Response|\WP_Error
106
+	 */
107
+	public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name)
108
+	{
109
+		$controller = new Write();
110
+		try {
111
+			$controller->setRequestedVersion($version);
112
+			return $controller->sendResponse(
113
+				$controller->delete(
114
+					$controller->getModelVersionInfo()->loadModel($model_name),
115
+					$request
116
+				)
117
+			);
118
+		} catch (Exception $e) {
119
+			return $controller->sendResponse($e);
120
+		}
121
+	}
122 122
 
123 123
 
124
-    /**
125
-     * Inserts a new model object according to the $request
126
-     *
127
-     * @param EEM_Base        $model
128
-     * @param WP_REST_Request $request
129
-     * @return array
130
-     * @throws EE_Error
131
-     * @throws RestException
132
-     */
133
-    public function insert(EEM_Base $model, WP_REST_Request $request)
134
-    {
135
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
136
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
137
-        if (! current_user_can($default_cap_to_check_for)) {
138
-            throw new RestException(
139
-                'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
140
-                sprintf(
141
-                    esc_html__(
142
-                    // @codingStandardsIgnoreStart
143
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.',
144
-                        // @codingStandardsIgnoreEnd
145
-                        'event_espresso'
146
-                    ),
147
-                    $default_cap_to_check_for
148
-                ),
149
-                array('status' => 403)
150
-            );
151
-        }
152
-        $submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params());
153
-        $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
154
-            $submitted_json_data,
155
-            $model,
156
-            $this->getModelVersionInfo()->requestedVersion(),
157
-            true
158
-        );
159
-        $model_obj = EE_Registry::instance()->load_class(
160
-            $model->get_this_model_name(),
161
-            array($model_data, $model->get_timezone()),
162
-            false,
163
-            false
164
-        );
165
-        $model_obj->save();
166
-        $new_id = $model_obj->ID();
167
-        if (! $new_id) {
168
-            throw new RestException(
169
-                'rest_insertion_failed',
170
-                sprintf(__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name())
171
-            );
172
-        }
173
-        return $this->returnModelObjAsJsonResponse($model_obj, $request);
174
-    }
124
+	/**
125
+	 * Inserts a new model object according to the $request
126
+	 *
127
+	 * @param EEM_Base        $model
128
+	 * @param WP_REST_Request $request
129
+	 * @return array
130
+	 * @throws EE_Error
131
+	 * @throws RestException
132
+	 */
133
+	public function insert(EEM_Base $model, WP_REST_Request $request)
134
+	{
135
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
136
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
137
+		if (! current_user_can($default_cap_to_check_for)) {
138
+			throw new RestException(
139
+				'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
140
+				sprintf(
141
+					esc_html__(
142
+					// @codingStandardsIgnoreStart
143
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.',
144
+						// @codingStandardsIgnoreEnd
145
+						'event_espresso'
146
+					),
147
+					$default_cap_to_check_for
148
+				),
149
+				array('status' => 403)
150
+			);
151
+		}
152
+		$submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params());
153
+		$model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
154
+			$submitted_json_data,
155
+			$model,
156
+			$this->getModelVersionInfo()->requestedVersion(),
157
+			true
158
+		);
159
+		$model_obj = EE_Registry::instance()->load_class(
160
+			$model->get_this_model_name(),
161
+			array($model_data, $model->get_timezone()),
162
+			false,
163
+			false
164
+		);
165
+		$model_obj->save();
166
+		$new_id = $model_obj->ID();
167
+		if (! $new_id) {
168
+			throw new RestException(
169
+				'rest_insertion_failed',
170
+				sprintf(__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name())
171
+			);
172
+		}
173
+		return $this->returnModelObjAsJsonResponse($model_obj, $request);
174
+	}
175 175
 
176 176
 
177
-    /**
178
-     * Updates an existing model object according to the $request
179
-     *
180
-     * @param EEM_Base        $model
181
-     * @param WP_REST_Request $request
182
-     * @return array
183
-     * @throws EE_Error
184
-     */
185
-    public function update(EEM_Base $model, WP_REST_Request $request)
186
-    {
187
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
188
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
189
-        if (! current_user_can($default_cap_to_check_for)) {
190
-            throw new RestException(
191
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
192
-                sprintf(
193
-                    esc_html__(
194
-                    // @codingStandardsIgnoreStart
195
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.',
196
-                        // @codingStandardsIgnoreEnd
197
-                        'event_espresso'
198
-                    ),
199
-                    $default_cap_to_check_for
200
-                ),
201
-                array('status' => 403)
202
-            );
203
-        }
204
-        $obj_id = $request->get_param('id');
205
-        if (! $obj_id) {
206
-            throw new RestException(
207
-                'rest_edit_failed',
208
-                sprintf(__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name())
209
-            );
210
-        }
211
-        $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
212
-            $this->getBodyParams($request),
213
-            $model,
214
-            $this->getModelVersionInfo()->requestedVersion(),
215
-            true
216
-        );
217
-        $model_obj = $model->get_one_by_ID($obj_id);
218
-        if (! $model_obj instanceof EE_Base_Class) {
219
-            $lowercase_model_name = strtolower($model->get_this_model_name());
220
-            throw new RestException(
221
-                sprintf('rest_%s_invalid_id', $lowercase_model_name),
222
-                sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
223
-                array('status' => 404)
224
-            );
225
-        }
226
-        $model_obj->save($model_data);
227
-        return $this->returnModelObjAsJsonResponse($model_obj, $request);
228
-    }
177
+	/**
178
+	 * Updates an existing model object according to the $request
179
+	 *
180
+	 * @param EEM_Base        $model
181
+	 * @param WP_REST_Request $request
182
+	 * @return array
183
+	 * @throws EE_Error
184
+	 */
185
+	public function update(EEM_Base $model, WP_REST_Request $request)
186
+	{
187
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
188
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
189
+		if (! current_user_can($default_cap_to_check_for)) {
190
+			throw new RestException(
191
+				'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
192
+				sprintf(
193
+					esc_html__(
194
+					// @codingStandardsIgnoreStart
195
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.',
196
+						// @codingStandardsIgnoreEnd
197
+						'event_espresso'
198
+					),
199
+					$default_cap_to_check_for
200
+				),
201
+				array('status' => 403)
202
+			);
203
+		}
204
+		$obj_id = $request->get_param('id');
205
+		if (! $obj_id) {
206
+			throw new RestException(
207
+				'rest_edit_failed',
208
+				sprintf(__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name())
209
+			);
210
+		}
211
+		$model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
212
+			$this->getBodyParams($request),
213
+			$model,
214
+			$this->getModelVersionInfo()->requestedVersion(),
215
+			true
216
+		);
217
+		$model_obj = $model->get_one_by_ID($obj_id);
218
+		if (! $model_obj instanceof EE_Base_Class) {
219
+			$lowercase_model_name = strtolower($model->get_this_model_name());
220
+			throw new RestException(
221
+				sprintf('rest_%s_invalid_id', $lowercase_model_name),
222
+				sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
223
+				array('status' => 404)
224
+			);
225
+		}
226
+		$model_obj->save($model_data);
227
+		return $this->returnModelObjAsJsonResponse($model_obj, $request);
228
+	}
229 229
 
230 230
 
231
-    /**
232
-     * Updates an existing model object according to the $request
233
-     *
234
-     * @param EEM_Base        $model
235
-     * @param WP_REST_Request $request
236
-     * @return array of either the soft-deleted item, or
237
-     * @throws EE_Error
238
-     */
239
-    public function delete(EEM_Base $model, WP_REST_Request $request)
240
-    {
241
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete');
242
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
243
-        if (! current_user_can($default_cap_to_check_for)) {
244
-            throw new RestException(
245
-                'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
246
-                sprintf(
247
-                    esc_html__(
248
-                    // @codingStandardsIgnoreStart
249
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.',
250
-                        // @codingStandardsIgnoreEnd
251
-                        'event_espresso'
252
-                    ),
253
-                    $default_cap_to_check_for
254
-                ),
255
-                array('status' => 403)
256
-            );
257
-        }
258
-        $obj_id = $request->get_param('id');
259
-        // this is where we would apply more fine-grained caps
260
-        $model_obj = $model->get_one_by_ID($obj_id);
261
-        if (! $model_obj instanceof EE_Base_Class) {
262
-            $lowercase_model_name = strtolower($model->get_this_model_name());
263
-            throw new RestException(
264
-                sprintf('rest_%s_invalid_id', $lowercase_model_name),
265
-                sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
266
-                array('status' => 404)
267
-            );
268
-        }
269
-        $requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN);
270
-        $requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN);
271
-        if ($requested_permanent_delete) {
272
-            $previous = $this->returnModelObjAsJsonResponse($model_obj, $request);
273
-            $deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking);
274
-            return array(
275
-                'deleted'  => $deleted,
276
-                'previous' => $previous,
277
-            );
278
-        } else {
279
-            if ($model instanceof EEM_Soft_Delete_Base) {
280
-                $model->delete_by_ID($obj_id, $requested_allow_blocking);
281
-                return $this->returnModelObjAsJsonResponse($model_obj, $request);
282
-            } else {
283
-                throw new RestException(
284
-                    'rest_trash_not_supported',
285
-                    501,
286
-                    sprintf(
287
-                        esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'),
288
-                        EEH_Inflector::pluralize($model->get_this_model_name())
289
-                    )
290
-                );
291
-            }
292
-        }
293
-    }
231
+	/**
232
+	 * Updates an existing model object according to the $request
233
+	 *
234
+	 * @param EEM_Base        $model
235
+	 * @param WP_REST_Request $request
236
+	 * @return array of either the soft-deleted item, or
237
+	 * @throws EE_Error
238
+	 */
239
+	public function delete(EEM_Base $model, WP_REST_Request $request)
240
+	{
241
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete');
242
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
243
+		if (! current_user_can($default_cap_to_check_for)) {
244
+			throw new RestException(
245
+				'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
246
+				sprintf(
247
+					esc_html__(
248
+					// @codingStandardsIgnoreStart
249
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.',
250
+						// @codingStandardsIgnoreEnd
251
+						'event_espresso'
252
+					),
253
+					$default_cap_to_check_for
254
+				),
255
+				array('status' => 403)
256
+			);
257
+		}
258
+		$obj_id = $request->get_param('id');
259
+		// this is where we would apply more fine-grained caps
260
+		$model_obj = $model->get_one_by_ID($obj_id);
261
+		if (! $model_obj instanceof EE_Base_Class) {
262
+			$lowercase_model_name = strtolower($model->get_this_model_name());
263
+			throw new RestException(
264
+				sprintf('rest_%s_invalid_id', $lowercase_model_name),
265
+				sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
266
+				array('status' => 404)
267
+			);
268
+		}
269
+		$requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN);
270
+		$requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN);
271
+		if ($requested_permanent_delete) {
272
+			$previous = $this->returnModelObjAsJsonResponse($model_obj, $request);
273
+			$deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking);
274
+			return array(
275
+				'deleted'  => $deleted,
276
+				'previous' => $previous,
277
+			);
278
+		} else {
279
+			if ($model instanceof EEM_Soft_Delete_Base) {
280
+				$model->delete_by_ID($obj_id, $requested_allow_blocking);
281
+				return $this->returnModelObjAsJsonResponse($model_obj, $request);
282
+			} else {
283
+				throw new RestException(
284
+					'rest_trash_not_supported',
285
+					501,
286
+					sprintf(
287
+						esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'),
288
+						EEH_Inflector::pluralize($model->get_this_model_name())
289
+					)
290
+				);
291
+			}
292
+		}
293
+	}
294 294
 
295 295
 
296
-    /**
297
-     * Returns an array ready to be converted into a JSON response, based solely on the model object
298
-     *
299
-     * @param EE_Base_Class   $model_obj
300
-     * @param WP_REST_Request $request
301
-     * @return array ready for a response
302
-     */
303
-    protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request)
304
-    {
305
-        $model = $model_obj->get_model();
306
-        // create an array exactly like the wpdb results row,
307
-        // so we can pass it to controllers/model/Read::create_entity_from_wpdb_result()
308
-        $simulated_db_row = array();
309
-        foreach ($model->field_settings(true) as $field_name => $field_obj) {
310
-            // we need to reconstruct the normal wpdb results, including the db-only fields
311
-            // like a secondary table's primary key. The models expect those (but don't care what value they have)
312
-            if ($field_obj instanceof EE_DB_Only_Field_Base) {
313
-                $raw_value = true;
314
-            } elseif ($field_obj instanceof EE_Datetime_Field) {
315
-                $raw_value = $model_obj->get_DateTime_object($field_name);
316
-            } else {
317
-                $raw_value = $model_obj->get_raw($field_name);
318
-            }
319
-            $simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value);
320
-        }
321
-        $read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
322
-        $read_controller->setRequestedVersion($this->getRequestedVersion());
323
-        // the simulates request really doesn't need any info downstream
324
-        $simulated_request = new WP_REST_Request('GET');
325
-        // set the caps context on the simulated according to the original request.
326
-        switch ($request->get_method()) {
327
-            case 'POST':
328
-            case 'PUT':
329
-                $caps_context = EEM_Base::caps_edit;
330
-                break;
331
-            case 'DELETE':
332
-                $caps_context = EEM_Base::caps_delete;
333
-                break;
334
-            default:
335
-                $caps_context = EEM_Base::caps_read_admin;
336
-        }
337
-        $simulated_request->set_param('caps', $caps_context);
338
-        return $read_controller->createEntityFromWpdbResult(
339
-            $model_obj->get_model(),
340
-            $simulated_db_row,
341
-            $simulated_request
342
-        );
343
-    }
296
+	/**
297
+	 * Returns an array ready to be converted into a JSON response, based solely on the model object
298
+	 *
299
+	 * @param EE_Base_Class   $model_obj
300
+	 * @param WP_REST_Request $request
301
+	 * @return array ready for a response
302
+	 */
303
+	protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request)
304
+	{
305
+		$model = $model_obj->get_model();
306
+		// create an array exactly like the wpdb results row,
307
+		// so we can pass it to controllers/model/Read::create_entity_from_wpdb_result()
308
+		$simulated_db_row = array();
309
+		foreach ($model->field_settings(true) as $field_name => $field_obj) {
310
+			// we need to reconstruct the normal wpdb results, including the db-only fields
311
+			// like a secondary table's primary key. The models expect those (but don't care what value they have)
312
+			if ($field_obj instanceof EE_DB_Only_Field_Base) {
313
+				$raw_value = true;
314
+			} elseif ($field_obj instanceof EE_Datetime_Field) {
315
+				$raw_value = $model_obj->get_DateTime_object($field_name);
316
+			} else {
317
+				$raw_value = $model_obj->get_raw($field_name);
318
+			}
319
+			$simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value);
320
+		}
321
+		$read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
322
+		$read_controller->setRequestedVersion($this->getRequestedVersion());
323
+		// the simulates request really doesn't need any info downstream
324
+		$simulated_request = new WP_REST_Request('GET');
325
+		// set the caps context on the simulated according to the original request.
326
+		switch ($request->get_method()) {
327
+			case 'POST':
328
+			case 'PUT':
329
+				$caps_context = EEM_Base::caps_edit;
330
+				break;
331
+			case 'DELETE':
332
+				$caps_context = EEM_Base::caps_delete;
333
+				break;
334
+			default:
335
+				$caps_context = EEM_Base::caps_read_admin;
336
+		}
337
+		$simulated_request->set_param('caps', $caps_context);
338
+		return $read_controller->createEntityFromWpdbResult(
339
+			$model_obj->get_model(),
340
+			$simulated_db_row,
341
+			$simulated_request
342
+		);
343
+	}
344 344
 
345 345
 
346
-    /**
347
-     * Gets the item affected by this request
348
-     *
349
-     * @param EEM_Base        $model
350
-     * @param WP_REST_Request $request
351
-     * @param  int|string     $obj_id
352
-     * @return \WP_Error|array
353
-     */
354
-    protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id)
355
-    {
356
-        $requested_version = $this->getRequestedVersion($request->get_route());
357
-        $get_request = new WP_REST_Request(
358
-            'GET',
359
-            EED_Core_Rest_Api::ee_api_namespace
360
-            . $requested_version
361
-            . '/'
362
-            . EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
363
-            . '/'
364
-            . $obj_id
365
-        );
366
-        $get_request->set_url_params(
367
-            array(
368
-                'id'      => $obj_id,
369
-                'include' => $request->get_param('include'),
370
-            )
371
-        );
372
-        $read_controller = new Read();
373
-        $read_controller->setRequestedVersion($this->getRequestedVersion());
374
-        return $read_controller->getEntityFromModel($model, $get_request);
375
-    }
346
+	/**
347
+	 * Gets the item affected by this request
348
+	 *
349
+	 * @param EEM_Base        $model
350
+	 * @param WP_REST_Request $request
351
+	 * @param  int|string     $obj_id
352
+	 * @return \WP_Error|array
353
+	 */
354
+	protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id)
355
+	{
356
+		$requested_version = $this->getRequestedVersion($request->get_route());
357
+		$get_request = new WP_REST_Request(
358
+			'GET',
359
+			EED_Core_Rest_Api::ee_api_namespace
360
+			. $requested_version
361
+			. '/'
362
+			. EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
363
+			. '/'
364
+			. $obj_id
365
+		);
366
+		$get_request->set_url_params(
367
+			array(
368
+				'id'      => $obj_id,
369
+				'include' => $request->get_param('include'),
370
+			)
371
+		);
372
+		$read_controller = new Read();
373
+		$read_controller->setRequestedVersion($this->getRequestedVersion());
374
+		return $read_controller->getEntityFromModel($model, $get_request);
375
+	}
376 376
 
377
-    /**
378
-     * Adds a relation between the specified models (if it doesn't already exist.)
379
-     * @since 4.9.76.p
380
-     * @param WP_REST_Request $request
381
-     * @return WP_REST_Response
382
-     */
383
-    public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
384
-    {
385
-        $controller = new Write();
386
-        try {
387
-            $controller->setRequestedVersion($version);
388
-            $main_model = $controller->validateModel($model_name);
389
-            $controller->validateModel($related_model_name);
390
-            return $controller->sendResponse(
391
-                $controller->addRelation(
392
-                    $main_model,
393
-                    $main_model->related_settings_for($related_model_name),
394
-                    $request
395
-                )
396
-            );
397
-        } catch (Exception $e) {
398
-            return $controller->sendResponse($e);
399
-        }
400
-    }
377
+	/**
378
+	 * Adds a relation between the specified models (if it doesn't already exist.)
379
+	 * @since 4.9.76.p
380
+	 * @param WP_REST_Request $request
381
+	 * @return WP_REST_Response
382
+	 */
383
+	public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
384
+	{
385
+		$controller = new Write();
386
+		try {
387
+			$controller->setRequestedVersion($version);
388
+			$main_model = $controller->validateModel($model_name);
389
+			$controller->validateModel($related_model_name);
390
+			return $controller->sendResponse(
391
+				$controller->addRelation(
392
+					$main_model,
393
+					$main_model->related_settings_for($related_model_name),
394
+					$request
395
+				)
396
+			);
397
+		} catch (Exception $e) {
398
+			return $controller->sendResponse($e);
399
+		}
400
+	}
401 401
 
402
-    /**
403
-     * Adds a relation between the two model specified model objects.
404
-     * @since 4.9.76.p
405
-     * @param EEM_Base $model
406
-     * @param EE_Model_Relation_Base $relation
407
-     * @param WP_REST_Request $request
408
-     * @return array
409
-     * @throws EE_Error
410
-     * @throws InvalidArgumentException
411
-     * @throws InvalidDataTypeException
412
-     * @throws InvalidInterfaceException
413
-     * @throws RestException
414
-     * @throws DomainException
415
-     */
416
-    public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
417
-    {
418
-        list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
419
-        $extra_params = array();
420
-        if ($relation instanceof EE_HABTM_Relation) {
421
-            $extra_params = array_intersect_key(
422
-                ModelDataTranslator::prepareConditionsQueryParamsForModels(
423
-                    $request->get_body_params(),
424
-                    $relation->get_join_model(),
425
-                    $this->getModelVersionInfo()->requestedVersion(),
426
-                    true
427
-                ),
428
-                $relation->getNonKeyFields()
429
-            );
430
-        }
431
-        // Add a relation.
432
-        $related_obj = $model_obj->_add_relation_to(
433
-            $other_obj,
434
-            $relation->get_other_model()->get_this_model_name(),
435
-            $extra_params
436
-        );
437
-        $response = array(
438
-            strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
439
-            strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
440
-        );
441
-        if ($relation instanceof EE_HABTM_Relation) {
442
-            $join_model_obj = $relation->get_join_model()->get_one(
443
-                array(
444
-                    array(
445
-                        $model->primary_key_name() => $model_obj->ID(),
446
-                        $relation->get_other_model()->primary_key_name() => $related_obj->ID()
447
-                    )
448
-                )
449
-            );
450
-            $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
451
-        }
452
-        return $response;
453
-    }
402
+	/**
403
+	 * Adds a relation between the two model specified model objects.
404
+	 * @since 4.9.76.p
405
+	 * @param EEM_Base $model
406
+	 * @param EE_Model_Relation_Base $relation
407
+	 * @param WP_REST_Request $request
408
+	 * @return array
409
+	 * @throws EE_Error
410
+	 * @throws InvalidArgumentException
411
+	 * @throws InvalidDataTypeException
412
+	 * @throws InvalidInterfaceException
413
+	 * @throws RestException
414
+	 * @throws DomainException
415
+	 */
416
+	public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
417
+	{
418
+		list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
419
+		$extra_params = array();
420
+		if ($relation instanceof EE_HABTM_Relation) {
421
+			$extra_params = array_intersect_key(
422
+				ModelDataTranslator::prepareConditionsQueryParamsForModels(
423
+					$request->get_body_params(),
424
+					$relation->get_join_model(),
425
+					$this->getModelVersionInfo()->requestedVersion(),
426
+					true
427
+				),
428
+				$relation->getNonKeyFields()
429
+			);
430
+		}
431
+		// Add a relation.
432
+		$related_obj = $model_obj->_add_relation_to(
433
+			$other_obj,
434
+			$relation->get_other_model()->get_this_model_name(),
435
+			$extra_params
436
+		);
437
+		$response = array(
438
+			strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
439
+			strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
440
+		);
441
+		if ($relation instanceof EE_HABTM_Relation) {
442
+			$join_model_obj = $relation->get_join_model()->get_one(
443
+				array(
444
+					array(
445
+						$model->primary_key_name() => $model_obj->ID(),
446
+						$relation->get_other_model()->primary_key_name() => $related_obj->ID()
447
+					)
448
+				)
449
+			);
450
+			$response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = $this->returnModelObjAsJsonResponse($join_model_obj, $request);
451
+		}
452
+		return $response;
453
+	}
454 454
 
455 455
 
456
-    /**
457
-     * Removes the relation between the specified models (if it exists).
458
-     * @since 4.9.76.p
459
-     * @param WP_REST_Request $request
460
-     * @return WP_REST_Response
461
-     */
462
-    public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
463
-    {
464
-        $controller = new Write();
465
-        try {
466
-            $controller->setRequestedVersion($version);
467
-            $main_model = $controller->getModelVersionInfo()->loadModel($model_name);
468
-            return $controller->sendResponse(
469
-                $controller->removeRelation(
470
-                    $main_model,
471
-                    $main_model->related_settings_for($related_model_name),
472
-                    $request
473
-                )
474
-            );
475
-        } catch (Exception $e) {
476
-            return $controller->sendResponse($e);
477
-        }
478
-    }
456
+	/**
457
+	 * Removes the relation between the specified models (if it exists).
458
+	 * @since 4.9.76.p
459
+	 * @param WP_REST_Request $request
460
+	 * @return WP_REST_Response
461
+	 */
462
+	public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
463
+	{
464
+		$controller = new Write();
465
+		try {
466
+			$controller->setRequestedVersion($version);
467
+			$main_model = $controller->getModelVersionInfo()->loadModel($model_name);
468
+			return $controller->sendResponse(
469
+				$controller->removeRelation(
470
+					$main_model,
471
+					$main_model->related_settings_for($related_model_name),
472
+					$request
473
+				)
474
+			);
475
+		} catch (Exception $e) {
476
+			return $controller->sendResponse($e);
477
+		}
478
+	}
479 479
 
480
-    /**
481
-     * Adds a relation between the two model specified model objects.
482
-     * @since 4.9.76.p
483
-     * @param EEM_Base $model
484
-     * @param EE_Model_Relation_Base $relation
485
-     * @param WP_REST_Request $request
486
-     * @return array
487
-     * @throws DomainException
488
-     * @throws EE_Error
489
-     * @throws InvalidArgumentException
490
-     * @throws InvalidDataTypeException
491
-     * @throws InvalidInterfaceException
492
-     * @throws RestException
493
-     */
494
-    public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
495
-    {
496
-        // This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know
497
-        // up-front that it doesn't.)
498
-        if (!empty($request->get_body_params())) {
499
-            $body_params = $request->get_body_params();
500
-            throw new RestException(
501
-                'invalid_field',
502
-                sprintf(
503
-                    esc_html__('This endpoint doesn\'t accept post body arguments, you sent in %1$s', 'event_espresso'),
504
-                    implode(array_keys($body_params))
505
-                )
506
-            );
507
-        }
508
-        list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
509
-        // Remember the old relation, if it used a join entry.
510
-        $join_model_obj = null;
511
-        if ($relation instanceof EE_HABTM_Relation) {
512
-            $join_model_obj = $relation->get_join_model()->get_one(
513
-                array(
514
-                    array(
515
-                        $model->primary_key_name() => $model_obj->ID(),
516
-                        $relation->get_other_model()->primary_key_name() => $other_obj->ID()
517
-                    )
518
-                )
519
-            );
520
-        }
521
-        // Remove the relation.
522
-        $related_obj = $model_obj->_remove_relation_to(
523
-            $other_obj,
524
-            $relation->get_other_model()->get_this_model_name()
525
-        );
526
-        $response = array(
527
-            strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
528
-            strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
529
-        );
530
-        if ($relation instanceof EE_HABTM_Relation) {
531
-            $join_model_obj_after_removal = $relation->get_join_model()->get_one(
532
-                array(
533
-                    array(
534
-                        $model->primary_key_name() => $model_obj->ID(),
535
-                        $relation->get_other_model()->primary_key_name() => $other_obj->ID()
536
-                    )
537
-                )
538
-            );
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);
541
-            } else {
542
-                $response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null;
543
-            }
544
-        }
545
-        return $response;
546
-    }
480
+	/**
481
+	 * Adds a relation between the two model specified model objects.
482
+	 * @since 4.9.76.p
483
+	 * @param EEM_Base $model
484
+	 * @param EE_Model_Relation_Base $relation
485
+	 * @param WP_REST_Request $request
486
+	 * @return array
487
+	 * @throws DomainException
488
+	 * @throws EE_Error
489
+	 * @throws InvalidArgumentException
490
+	 * @throws InvalidDataTypeException
491
+	 * @throws InvalidInterfaceException
492
+	 * @throws RestException
493
+	 */
494
+	public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
495
+	{
496
+		// This endpoint doesn't accept body parameters (it's understandable to think it might, so let developers know
497
+		// up-front that it doesn't.)
498
+		if (!empty($request->get_body_params())) {
499
+			$body_params = $request->get_body_params();
500
+			throw new RestException(
501
+				'invalid_field',
502
+				sprintf(
503
+					esc_html__('This endpoint doesn\'t accept post body arguments, you sent in %1$s', 'event_espresso'),
504
+					implode(array_keys($body_params))
505
+				)
506
+			);
507
+		}
508
+		list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
509
+		// Remember the old relation, if it used a join entry.
510
+		$join_model_obj = null;
511
+		if ($relation instanceof EE_HABTM_Relation) {
512
+			$join_model_obj = $relation->get_join_model()->get_one(
513
+				array(
514
+					array(
515
+						$model->primary_key_name() => $model_obj->ID(),
516
+						$relation->get_other_model()->primary_key_name() => $other_obj->ID()
517
+					)
518
+				)
519
+			);
520
+		}
521
+		// Remove the relation.
522
+		$related_obj = $model_obj->_remove_relation_to(
523
+			$other_obj,
524
+			$relation->get_other_model()->get_this_model_name()
525
+		);
526
+		$response = array(
527
+			strtolower($model->get_this_model_name()) => $this->returnModelObjAsJsonResponse($model_obj, $request),
528
+			strtolower($relation->get_other_model()->get_this_model_name()) => $this->returnModelObjAsJsonResponse($related_obj, $request),
529
+		);
530
+		if ($relation instanceof EE_HABTM_Relation) {
531
+			$join_model_obj_after_removal = $relation->get_join_model()->get_one(
532
+				array(
533
+					array(
534
+						$model->primary_key_name() => $model_obj->ID(),
535
+						$relation->get_other_model()->primary_key_name() => $other_obj->ID()
536
+					)
537
+				)
538
+			);
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);
541
+			} else {
542
+				$response['join'][ strtolower($relation->get_join_model()->get_this_model_name()) ] = null;
543
+			}
544
+		}
545
+		return $response;
546
+	}
547 547
 
548
-    /**
549
-     * Gets the model objects indicated by the model, relation object, and request.
550
-     * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist.
551
-     * However, this behaviour may change, as we may add support for simultaneously creating and relating data.
552
-     * @since 4.9.76.p
553
-     * @param EEM_Base $model
554
-     * @param EE_Model_Relation_Base $relation
555
-     * @param WP_REST_Request $request
556
-     * @return array {
557
-     * @type EE_Base_Class $model_obj
558
-     * @type EE_Base_Class|null $other_model_obj
559
-     * }
560
-     * @throws RestException
561
-     */
562
-    protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
563
-    {
564
-        // Check generic caps. For now, we're only allowing access to this endpoint to full admins.
565
-        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
566
-        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
567
-        if (! current_user_can($default_cap_to_check_for)) {
568
-            throw new RestException(
569
-                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
570
-                sprintf(
571
-                    esc_html__(
572
-                        // @codingStandardsIgnoreStart
573
-                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.',
574
-                        // @codingStandardsIgnoreEnd
575
-                        'event_espresso'
576
-                    ),
577
-                    $default_cap_to_check_for
578
-                ),
579
-                array('status' => 403)
580
-            );
581
-        }
582
-        // Get the main model object.
583
-        $model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
584
-        // For now, we require the other model object to exist too. This might be relaxed later.
585
-        $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id'));
586
-        return array($model_obj,$other_obj);
587
-    }
548
+	/**
549
+	 * Gets the model objects indicated by the model, relation object, and request.
550
+	 * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist.
551
+	 * However, this behaviour may change, as we may add support for simultaneously creating and relating data.
552
+	 * @since 4.9.76.p
553
+	 * @param EEM_Base $model
554
+	 * @param EE_Model_Relation_Base $relation
555
+	 * @param WP_REST_Request $request
556
+	 * @return array {
557
+	 * @type EE_Base_Class $model_obj
558
+	 * @type EE_Base_Class|null $other_model_obj
559
+	 * }
560
+	 * @throws RestException
561
+	 */
562
+	protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
563
+	{
564
+		// Check generic caps. For now, we're only allowing access to this endpoint to full admins.
565
+		Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
566
+		$default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
567
+		if (! current_user_can($default_cap_to_check_for)) {
568
+			throw new RestException(
569
+				'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
570
+				sprintf(
571
+					esc_html__(
572
+						// @codingStandardsIgnoreStart
573
+						'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.',
574
+						// @codingStandardsIgnoreEnd
575
+						'event_espresso'
576
+					),
577
+					$default_cap_to_check_for
578
+				),
579
+				array('status' => 403)
580
+			);
581
+		}
582
+		// Get the main model object.
583
+		$model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
584
+		// For now, we require the other model object to exist too. This might be relaxed later.
585
+		$other_obj = $this->getOneOrThrowException($relation->get_other_model(), $request->get_param('related_id'));
586
+		return array($model_obj,$other_obj);
587
+	}
588 588
 
589
-    /**
590
-     * Gets the model with that ID or throws a REST exception.
591
-     * @since 4.9.76.p
592
-     * @param EEM_Base $model
593
-     * @param $id
594
-     * @return EE_Base_Class
595
-     * @throws RestException
596
-     */
597
-    protected function getOneOrThrowException(EEM_Base $model, $id)
598
-    {
599
-        $model_obj = $model->get_one_by_ID($id);
600
-        // @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint.
601
-        if ($model_obj instanceof EE_Base_Class) {
602
-            return $model_obj;
603
-        }
604
-        $lowercase_model_name = strtolower($model->get_this_model_name());
605
-        throw new RestException(
606
-            sprintf('rest_%s_invalid_id', $lowercase_model_name),
607
-            sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
608
-            array('status' => 404)
609
-        );
610
-    }
589
+	/**
590
+	 * Gets the model with that ID or throws a REST exception.
591
+	 * @since 4.9.76.p
592
+	 * @param EEM_Base $model
593
+	 * @param $id
594
+	 * @return EE_Base_Class
595
+	 * @throws RestException
596
+	 */
597
+	protected function getOneOrThrowException(EEM_Base $model, $id)
598
+	{
599
+		$model_obj = $model->get_one_by_ID($id);
600
+		// @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint.
601
+		if ($model_obj instanceof EE_Base_Class) {
602
+			return $model_obj;
603
+		}
604
+		$lowercase_model_name = strtolower($model->get_this_model_name());
605
+		throw new RestException(
606
+			sprintf('rest_%s_invalid_id', $lowercase_model_name),
607
+			sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
608
+			array('status' => 404)
609
+		);
610
+	}
611 611
 }
Please login to merge, or discard this patch.
modules/core_rest_api/EED_Core_Rest_Api.module.php 3 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -765,6 +765,9 @@
 block discarded – undo
765 765
         );
766 766
     }
767 767
 
768
+    /**
769
+     * @param string $version
770
+     */
768 771
     protected function _get_add_relation_query_params(\EEM_Base $source_model, \EEM_Base $related_model, $version)
769 772
     {
770 773
         // if they're related through a HABTM relation, check for any non-FKs
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
      */
124 124
     protected static function _set_hooks_for_changes()
125 125
     {
126
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
126
+        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES.'rest_api'.DS.'changes'), false);
127 127
         foreach ($folder_contents as $classname_in_namespace => $filepath) {
128 128
             // ignore the base parent class
129 129
             // and legacy named classes
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
             ) {
133 133
                 continue;
134 134
             }
135
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
135
+            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\'.$classname_in_namespace;
136 136
             if (class_exists($full_classname)) {
137 137
                 $instance_of_class = new $full_classname;
138 138
                 if ($instance_of_class instanceof ChangesInBase) {
@@ -177,10 +177,10 @@  discard block
 block discarded – undo
177 177
                      * }
178 178
                      */
179 179
                     // skip route options
180
-                    if (! is_numeric($endpoint_key)) {
180
+                    if ( ! is_numeric($endpoint_key)) {
181 181
                         continue;
182 182
                     }
183
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
183
+                    if ( ! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
184 184
                         throw new EE_Error(
185 185
                             esc_html__(
186 186
                             // @codingStandardsIgnoreStart
@@ -201,7 +201,7 @@  discard block
 block discarded – undo
201 201
                     }
202 202
                     if (isset($data_for_single_endpoint['callback_args'])) {
203 203
                         $callback_args = $data_for_single_endpoint['callback_args'];
204
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
204
+                        $single_endpoint_args['callback'] = function(\WP_REST_Request $request) use (
205 205
                             $callback,
206 206
                             $callback_args
207 207
                         ) {
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
                     $schema_route_data = $data_for_multiple_endpoints['schema'];
221 221
                     $schema_callback = $schema_route_data['schema_callback'];
222 222
                     $callback_args = $schema_route_data['callback_args'];
223
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
223
+                    $multiple_endpoint_args['schema'] = function() use ($schema_callback, $callback_args) {
224 224
                         return call_user_func_array(
225 225
                             $schema_callback,
226 226
                             $callback_args
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
     {
263 263
         // delete the saved EE REST API routes
264 264
         foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
265
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
265
+            delete_option(EED_Core_Rest_Api::saved_routes_option_names.$version);
266 266
         }
267 267
     }
268 268
 
@@ -281,7 +281,7 @@  discard block
 block discarded – undo
281 281
     {
282 282
         $ee_routes = array();
283 283
         foreach (self::versions_served() as $version => $hidden_endpoints) {
284
-            $ee_routes[ self::ee_api_namespace . $version ] = self::_get_ee_route_data_for_version(
284
+            $ee_routes[self::ee_api_namespace.$version] = self::_get_ee_route_data_for_version(
285 285
                 $version,
286 286
                 $hidden_endpoints
287 287
             );
@@ -301,8 +301,8 @@  discard block
 block discarded – undo
301 301
      */
302 302
     protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
303 303
     {
304
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
305
-        if (! $ee_routes || EED_Core_Rest_Api::debugMode()) {
304
+        $ee_routes = get_option(self::saved_routes_option_names.$version, null);
305
+        if ( ! $ee_routes || EED_Core_Rest_Api::debugMode()) {
306 306
             $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
307 307
         }
308 308
         return $ee_routes;
@@ -329,7 +329,7 @@  discard block
 block discarded – undo
329 329
                 $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
330 330
             )
331 331
         );
332
-        $option_name = self::saved_routes_option_names . $version;
332
+        $option_name = self::saved_routes_option_names.$version;
333 333
         if (get_option($option_name)) {
334 334
             update_option($option_name, $routes, true);
335 335
         } else {
@@ -374,8 +374,8 @@  discard block
 block discarded – undo
374 374
     {
375 375
         $model_routes = array();
376 376
         foreach (self::versions_served() as $version => $hidden_endpoint) {
377
-            $model_routes[ EED_Core_Rest_Api::ee_api_namespace
378
-                           . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
377
+            $model_routes[EED_Core_Rest_Api::ee_api_namespace
378
+                           . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
379 379
         }
380 380
         return $model_routes;
381 381
     }
@@ -444,13 +444,13 @@  discard block
 block discarded – undo
444 444
         foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
445 445
             $model = \EE_Registry::instance()->load_model($model_name);
446 446
             // if this isn't a valid model then let's skip iterate to the next item in the loop.
447
-            if (! $model instanceof EEM_Base) {
447
+            if ( ! $model instanceof EEM_Base) {
448 448
                 continue;
449 449
             }
450 450
             // yes we could just register one route for ALL models, but then they wouldn't show up in the index
451 451
             $plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
452 452
             $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
453
-            $model_routes[ $plural_model_route ] = array(
453
+            $model_routes[$plural_model_route] = array(
454 454
                 array(
455 455
                     'callback'        => array(
456 456
                         'EventEspresso\core\libraries\rest_api\controllers\model\Read',
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
                     'hidden_endpoint' => $hidden_endpoint,
462 462
                     'args'            => $this->_get_read_query_params($model, $version),
463 463
                     '_links'          => array(
464
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
464
+                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace.$version.$singular_model_route),
465 465
                     ),
466 466
                 ),
467 467
                 'schema' => array(
@@ -472,7 +472,7 @@  discard block
 block discarded – undo
472 472
                     'callback_args'   => array($version, $model_name),
473 473
                 ),
474 474
             );
475
-            $model_routes[ $singular_model_route ] = array(
475
+            $model_routes[$singular_model_route] = array(
476 476
                 array(
477 477
                     'callback'        => array(
478 478
                         'EventEspresso\core\libraries\rest_api\controllers\model\Read',
@@ -489,7 +489,7 @@  discard block
 block discarded – undo
489 489
                 EED_Core_Rest_Api::should_have_write_endpoints($model),
490 490
                 $model
491 491
             )) {
492
-                $model_routes[ $plural_model_route ][] = array(
492
+                $model_routes[$plural_model_route][] = array(
493 493
                     'callback'        => array(
494 494
                         'EventEspresso\core\libraries\rest_api\controllers\model\Write',
495 495
                         'handleRequestInsert',
@@ -499,8 +499,8 @@  discard block
 block discarded – undo
499 499
                     'hidden_endpoint' => $hidden_endpoint,
500 500
                     'args'            => $this->_get_write_params($model_name, $model_version_info, true),
501 501
                 );
502
-                $model_routes[ $singular_model_route ] = array_merge(
503
-                    $model_routes[ $singular_model_route ],
502
+                $model_routes[$singular_model_route] = array_merge(
503
+                    $model_routes[$singular_model_route],
504 504
                     array(
505 505
                         array(
506 506
                             'callback'        => array(
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
                     '(?P<id>[^\/]+)',
532 532
                     $relation_obj
533 533
                 );
534
-                $model_routes[ $related_route ] = array(
534
+                $model_routes[$related_route] = array(
535 535
                     array(
536 536
                         'callback'        => array(
537 537
                             'EventEspresso\core\libraries\rest_api\controllers\model\Read',
@@ -544,8 +544,8 @@  discard block
 block discarded – undo
544 544
                     ),
545 545
                 );
546 546
 
547
-                $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)';
548
-                $model_routes[ $related_write_route ] = array(
547
+                $related_write_route = $related_route.'/'.'(?P<related_id>[^\/]+)';
548
+                $model_routes[$related_write_route] = array(
549 549
                     array(
550 550
                         'callback'        => array(
551 551
                             'EventEspresso\core\libraries\rest_api\controllers\model\Write',
@@ -598,7 +598,7 @@  discard block
 block discarded – undo
598 598
      */
599 599
     public static function get_entity_route($model, $id)
600 600
     {
601
-        return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id;
601
+        return EED_Core_Rest_Api::get_collection_route($model).'/'.$id;
602 602
     }
603 603
 
604 604
 
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
             $relation_obj->get_other_model()->get_this_model_name(),
619 619
             $relation_obj
620 620
         );
621
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
621
+        return EED_Core_Rest_Api::get_entity_route($model, $id).'/'.$related_model_name_endpoint_part;
622 622
     }
623 623
 
624 624
 
@@ -632,7 +632,7 @@  discard block
 block discarded – undo
632 632
      */
633 633
     public static function get_versioned_route_to($relative_route, $version = '4.8.36')
634 634
     {
635
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
635
+        return '/'.EED_Core_Rest_Api::ee_api_namespace.$version.'/'.$relative_route;
636 636
     }
637 637
 
638 638
 
@@ -646,7 +646,7 @@  discard block
 block discarded – undo
646 646
     {
647 647
         $routes = array();
648 648
         foreach (self::versions_served() as $version => $hidden_endpoint) {
649
-            $routes[ self::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version(
649
+            $routes[self::ee_api_namespace.$version] = $this->_get_rpc_route_data_for_version(
650 650
                 $version,
651 651
                 $hidden_endpoint
652 652
             );
@@ -769,12 +769,12 @@  discard block
 block discarded – undo
769 769
     {
770 770
         // if they're related through a HABTM relation, check for any non-FKs
771 771
         $all_relation_settings = $source_model->relation_settings();
772
-        $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ];
772
+        $relation_settings = $all_relation_settings[$related_model->get_this_model_name()];
773 773
         $params = array();
774 774
         if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) {
775 775
             foreach ($relation_settings->getNonKeyFields() as $field) {
776 776
                 /* @var $field EE_Model_Field_Base */
777
-                $params[ $field->get_name() ] = array(
777
+                $params[$field->get_name()] = array(
778 778
                     'required' => ! $field->is_nullable(),
779 779
                     'default' => ModelDataTranslator::prepareFieldValueForJson($field, $field->get_default_value(), $version),
780 780
                     'type' => $field->getSchemaType(),
@@ -799,7 +799,7 @@  discard block
 block discarded – undo
799 799
     {
800 800
         $default_orderby = array();
801 801
         foreach ($model->get_combined_primary_key_fields() as $key_field) {
802
-            $default_orderby[ $key_field->get_name() ] = 'ASC';
802
+            $default_orderby[$key_field->get_name()] = 'ASC';
803 803
         }
804 804
         return array_merge(
805 805
             $this->_get_response_selection_query_params($model, $version),
@@ -833,7 +833,7 @@  discard block
 block discarded – undo
833 833
                     'type'              => array(
834 834
                         'object',
835 835
                         'string',
836
-                    ),// because we accept a variety of types, WP core validation and sanitization
836
+                    ), // because we accept a variety of types, WP core validation and sanitization
837 837
                     // freaks out. We'll just validate this argument while handling the request
838 838
                     'validate_callback' => null,
839 839
                     'sanitize_callback' => null,
@@ -931,7 +931,7 @@  discard block
 block discarded – undo
931 931
                 $sanitize_callback = null;
932 932
             }
933 933
             $arg_info['sanitize_callback'] = $sanitize_callback;
934
-            $args_info[ $field_name ] = $arg_info;
934
+            $args_info[$field_name] = $arg_info;
935 935
             if ($field_obj instanceof EE_Datetime_Field) {
936 936
                 $gmt_arg_info = $arg_info;
937 937
                 $gmt_arg_info['description'] = sprintf(
@@ -942,7 +942,7 @@  discard block
 block discarded – undo
942 942
                     $field_obj->get_nicename(),
943 943
                     $field_name
944 944
                 );
945
-                $args_info[ $field_name . '_gmt' ] = $gmt_arg_info;
945
+                $args_info[$field_name.'_gmt'] = $gmt_arg_info;
946 946
             }
947 947
         }
948 948
         return $args_info;
@@ -965,16 +965,16 @@  discard block
 block discarded – undo
965 965
     public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
966 966
     {
967 967
         $attributes = $request->get_attributes();
968
-        if (! isset($attributes['args'][ $param ])
969
-            || ! is_array($attributes['args'][ $param ])) {
968
+        if ( ! isset($attributes['args'][$param])
969
+            || ! is_array($attributes['args'][$param])) {
970 970
             $validation_result = true;
971 971
         } else {
972
-            $args = $attributes['args'][ $param ];
972
+            $args = $attributes['args'][$param];
973 973
             if ((
974 974
                     $value === ''
975 975
                     || $value === null
976 976
                 )
977
-                && (! isset($args['required'])
977
+                && ( ! isset($args['required'])
978 978
                     || $args['required'] === false
979 979
                 )
980 980
             ) {
@@ -984,7 +984,7 @@  discard block
 block discarded – undo
984 984
                       && $args['format'] === 'email'
985 985
             ) {
986 986
                 $validation_result = true;
987
-                if (! self::_validate_email($value)) {
987
+                if ( ! self::_validate_email($value)) {
988 988
                     $validation_result = new WP_Error(
989 989
                         'rest_invalid_param',
990 990
                         esc_html__(
@@ -1034,7 +1034,7 @@  discard block
 block discarded – undo
1034 1034
     {
1035 1035
         $config_routes = array();
1036 1036
         foreach (self::versions_served() as $version => $hidden_endpoint) {
1037
-            $config_routes[ self::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version(
1037
+            $config_routes[self::ee_api_namespace.$version] = $this->_get_config_route_data_for_version(
1038 1038
                 $version,
1039 1039
                 $hidden_endpoint
1040 1040
             );
@@ -1089,7 +1089,7 @@  discard block
 block discarded – undo
1089 1089
     {
1090 1090
         $meta_routes = array();
1091 1091
         foreach (self::versions_served() as $version => $hidden_endpoint) {
1092
-            $meta_routes[ self::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version(
1092
+            $meta_routes[self::ee_api_namespace.$version] = $this->_get_meta_route_data_for_version(
1093 1093
                 $version,
1094 1094
                 $hidden_endpoint
1095 1095
             );
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
             foreach ($relative_urls as $resource_name => $endpoints) {
1142 1142
                 foreach ($endpoints as $key => $endpoint) {
1143 1143
                     // skip schema and other route options
1144
-                    if (! is_numeric($key)) {
1144
+                    if ( ! is_numeric($key)) {
1145 1145
                         continue;
1146 1146
                     }
1147 1147
                     // by default, hide "hidden_endpoint"s, unless the request indicates
@@ -1150,9 +1150,9 @@  discard block
 block discarded – undo
1150 1150
                     if (($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1151 1151
                         || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1152 1152
                     ) {
1153
-                        $full_route = '/' . ltrim($namespace, '/');
1154
-                        $full_route .= '/' . ltrim($resource_name, '/');
1155
-                        unset($route_data[ $full_route ]);
1153
+                        $full_route = '/'.ltrim($namespace, '/');
1154
+                        $full_route .= '/'.ltrim($resource_name, '/');
1155
+                        unset($route_data[$full_route]);
1156 1156
                     }
1157 1157
                 }
1158 1158
             }
@@ -1225,19 +1225,19 @@  discard block
 block discarded – undo
1225 1225
             // if it's not above the current core version, and it's compatible with the current version of core
1226 1226
             if ($key_versioned_endpoint === $latest_version) {
1227 1227
                 // don't hide the latest version in the index
1228
-                $versions_served[ $key_versioned_endpoint ] = false;
1228
+                $versions_served[$key_versioned_endpoint] = false;
1229 1229
             } elseif ($key_versioned_endpoint >= $lowest_compatible_version
1230 1230
                 && $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1231 1231
             ) {
1232 1232
                 // include, but hide, previous versions which are still supported
1233
-                $versions_served[ $key_versioned_endpoint ] = true;
1233
+                $versions_served[$key_versioned_endpoint] = true;
1234 1234
             } elseif (apply_filters(
1235 1235
                 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1236 1236
                 false,
1237 1237
                 $possibly_served_versions
1238 1238
             )) {
1239 1239
                 // if a version is no longer supported, don't include it in index or list of versions served
1240
-                $versions_served[ $key_versioned_endpoint ] = true;
1240
+                $versions_served[$key_versioned_endpoint] = true;
1241 1241
             }
1242 1242
         }
1243 1243
         return $versions_served;
@@ -1295,7 +1295,7 @@  discard block
 block discarded – undo
1295 1295
         $model_names = self::model_names_with_plural_routes($version);
1296 1296
         $collection_routes = array();
1297 1297
         foreach ($model_names as $model_name => $model_class_name) {
1298
-            $collection_routes[ strtolower($model_name) ] = '/' . self::ee_api_namespace . $version . '/'
1298
+            $collection_routes[strtolower($model_name)] = '/'.self::ee_api_namespace.$version.'/'
1299 1299
                                                             . EEH_Inflector::pluralize_and_lower($model_name);
1300 1300
         }
1301 1301
         return $collection_routes;
@@ -1316,9 +1316,9 @@  discard block
 block discarded – undo
1316 1316
             $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields();
1317 1317
             foreach ($primary_keys as $primary_key_name => $primary_key_field) {
1318 1318
                 if (count($primary_keys) > 1) {
1319
-                    $primary_key_items[ strtolower($model_name) ][] = $primary_key_name;
1319
+                    $primary_key_items[strtolower($model_name)][] = $primary_key_name;
1320 1320
                 } else {
1321
-                    $primary_key_items[ strtolower($model_name) ] = $primary_key_name;
1321
+                    $primary_key_items[strtolower($model_name)] = $primary_key_name;
1322 1322
                 }
1323 1323
             }
1324 1324
         }
Please login to merge, or discard this patch.
Indentation   +1328 added lines, -1328 removed lines patch added patch discarded remove patch
@@ -23,1332 +23,1332 @@
 block discarded – undo
23 23
 class EED_Core_Rest_Api extends \EED_Module
24 24
 {
25 25
 
26
-    const ee_api_namespace = Domain::API_NAMESPACE;
27
-
28
-    const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
29
-
30
-    const saved_routes_option_names = 'ee_core_routes';
31
-
32
-    /**
33
-     * string used in _links response bodies to make them globally unique.
34
-     *
35
-     * @see http://v2.wp-api.org/extending/linking/
36
-     */
37
-    const ee_api_link_namespace = 'https://api.eventespresso.com/';
38
-
39
-    /**
40
-     * @var CalculatedModelFields
41
-     */
42
-    protected static $_field_calculator;
43
-
44
-
45
-    /**
46
-     * @return EED_Core_Rest_Api|EED_Module
47
-     */
48
-    public static function instance()
49
-    {
50
-        self::$_field_calculator = LoaderFactory::getLoader()->load('EventEspresso\core\libraries\rest_api\CalculatedModelFields');
51
-        return parent::get_instance(__CLASS__);
52
-    }
53
-
54
-
55
-    /**
56
-     *    set_hooks - for hooking into EE Core, other modules, etc
57
-     *
58
-     * @access    public
59
-     * @return    void
60
-     */
61
-    public static function set_hooks()
62
-    {
63
-        self::set_hooks_both();
64
-    }
65
-
66
-
67
-    /**
68
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
69
-     *
70
-     * @access    public
71
-     * @return    void
72
-     */
73
-    public static function set_hooks_admin()
74
-    {
75
-        self::set_hooks_both();
76
-    }
77
-
78
-
79
-    public static function set_hooks_both()
80
-    {
81
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
82
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
83
-        add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
84
-        add_filter(
85
-            'rest_index',
86
-            array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex')
87
-        );
88
-        EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
89
-    }
90
-
91
-
92
-    /**
93
-     * sets up hooks which only need to be included as part of REST API requests;
94
-     * other requests like to the frontend or admin etc don't need them
95
-     *
96
-     * @throws \EE_Error
97
-     */
98
-    public static function set_hooks_rest_api()
99
-    {
100
-        // set hooks which account for changes made to the API
101
-        EED_Core_Rest_Api::_set_hooks_for_changes();
102
-    }
103
-
104
-
105
-    /**
106
-     * public wrapper of _set_hooks_for_changes.
107
-     * Loads all the hooks which make requests to old versions of the API
108
-     * appear the same as they always did
109
-     *
110
-     * @throws EE_Error
111
-     */
112
-    public static function set_hooks_for_changes()
113
-    {
114
-        self::_set_hooks_for_changes();
115
-    }
116
-
117
-
118
-    /**
119
-     * Loads all the hooks which make requests to old versions of the API
120
-     * appear the same as they always did
121
-     *
122
-     * @throws EE_Error
123
-     */
124
-    protected static function _set_hooks_for_changes()
125
-    {
126
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
127
-        foreach ($folder_contents as $classname_in_namespace => $filepath) {
128
-            // ignore the base parent class
129
-            // and legacy named classes
130
-            if ($classname_in_namespace === 'ChangesInBase'
131
-                || strpos($classname_in_namespace, 'Changes_In_') === 0
132
-            ) {
133
-                continue;
134
-            }
135
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
136
-            if (class_exists($full_classname)) {
137
-                $instance_of_class = new $full_classname;
138
-                if ($instance_of_class instanceof ChangesInBase) {
139
-                    $instance_of_class->setHooks();
140
-                }
141
-            }
142
-        }
143
-    }
144
-
145
-
146
-    /**
147
-     * Filters the WP routes to add our EE-related ones. This takes a bit of time
148
-     * so we actually prefer to only do it when an EE plugin is activated or upgraded
149
-     *
150
-     * @throws \EE_Error
151
-     */
152
-    public static function register_routes()
153
-    {
154
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
155
-            foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
156
-                /**
157
-                 * @var array     $data_for_multiple_endpoints numerically indexed array
158
-                 *                                         but can also contain route options like {
159
-                 * @type array    $schema                      {
160
-                 * @type callable $schema_callback
161
-                 * @type array    $callback_args               arguments that will be passed to the callback, after the
162
-                 * WP_REST_Request of course
163
-                 * }
164
-                 * }
165
-                 */
166
-                // when registering routes, register all the endpoints' data at the same time
167
-                $multiple_endpoint_args = array();
168
-                foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
169
-                    /**
170
-                     * @var array     $data_for_single_endpoint {
171
-                     * @type callable $callback
172
-                     * @type string methods
173
-                     * @type array args
174
-                     * @type array _links
175
-                     * @type array    $callback_args            arguments that will be passed to the callback, after the
176
-                     * WP_REST_Request of course
177
-                     * }
178
-                     */
179
-                    // skip route options
180
-                    if (! is_numeric($endpoint_key)) {
181
-                        continue;
182
-                    }
183
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
184
-                        throw new EE_Error(
185
-                            esc_html__(
186
-                            // @codingStandardsIgnoreStart
187
-                                'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
188
-                                // @codingStandardsIgnoreEnd
189
-                                'event_espresso'
190
-                            )
191
-                        );
192
-                    }
193
-                    $callback = $data_for_single_endpoint['callback'];
194
-                    $single_endpoint_args = array(
195
-                        'methods' => $data_for_single_endpoint['methods'],
196
-                        'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
197
-                            : array(),
198
-                    );
199
-                    if (isset($data_for_single_endpoint['_links'])) {
200
-                        $single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
201
-                    }
202
-                    if (isset($data_for_single_endpoint['callback_args'])) {
203
-                        $callback_args = $data_for_single_endpoint['callback_args'];
204
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
205
-                            $callback,
206
-                            $callback_args
207
-                        ) {
208
-                            array_unshift($callback_args, $request);
209
-                            return call_user_func_array(
210
-                                $callback,
211
-                                $callback_args
212
-                            );
213
-                        };
214
-                    } else {
215
-                        $single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
216
-                    }
217
-                    $multiple_endpoint_args[] = $single_endpoint_args;
218
-                }
219
-                if (isset($data_for_multiple_endpoints['schema'])) {
220
-                    $schema_route_data = $data_for_multiple_endpoints['schema'];
221
-                    $schema_callback = $schema_route_data['schema_callback'];
222
-                    $callback_args = $schema_route_data['callback_args'];
223
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
224
-                        return call_user_func_array(
225
-                            $schema_callback,
226
-                            $callback_args
227
-                        );
228
-                    };
229
-                }
230
-                register_rest_route(
231
-                    $namespace,
232
-                    $relative_route,
233
-                    $multiple_endpoint_args
234
-                );
235
-            }
236
-        }
237
-    }
238
-
239
-
240
-    /**
241
-     * Checks if there was a version change or something that merits invalidating the cached
242
-     * route data. If so, invalidates the cached route data so that it gets refreshed
243
-     * next time the WP API is used
244
-     */
245
-    public static function invalidate_cached_route_data_on_version_change()
246
-    {
247
-        if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
248
-            EED_Core_Rest_Api::invalidate_cached_route_data();
249
-        }
250
-        foreach (EE_Registry::instance()->addons as $addon) {
251
-            if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
252
-                EED_Core_Rest_Api::invalidate_cached_route_data();
253
-            }
254
-        }
255
-    }
256
-
257
-
258
-    /**
259
-     * Removes the cached route data so it will get refreshed next time the WP API is used
260
-     */
261
-    public static function invalidate_cached_route_data()
262
-    {
263
-        // delete the saved EE REST API routes
264
-        foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
265
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
266
-        }
267
-    }
268
-
269
-
270
-    /**
271
-     * Gets the EE route data
272
-     *
273
-     * @return array top-level key is the namespace, next-level key is the route and its value is array{
274
-     * @throws \EE_Error
275
-     * @type string|array $callback
276
-     * @type string       $methods
277
-     * @type boolean      $hidden_endpoint
278
-     * }
279
-     */
280
-    public static function get_ee_route_data()
281
-    {
282
-        $ee_routes = array();
283
-        foreach (self::versions_served() as $version => $hidden_endpoints) {
284
-            $ee_routes[ self::ee_api_namespace . $version ] = self::_get_ee_route_data_for_version(
285
-                $version,
286
-                $hidden_endpoints
287
-            );
288
-        }
289
-        return $ee_routes;
290
-    }
291
-
292
-
293
-    /**
294
-     * Gets the EE route data from the wp options if it exists already,
295
-     * otherwise re-generates it and saves it to the option
296
-     *
297
-     * @param string  $version
298
-     * @param boolean $hidden_endpoints
299
-     * @return array
300
-     * @throws \EE_Error
301
-     */
302
-    protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
303
-    {
304
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
305
-        if (! $ee_routes || EED_Core_Rest_Api::debugMode()) {
306
-            $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
307
-        }
308
-        return $ee_routes;
309
-    }
310
-
311
-
312
-    /**
313
-     * Saves the EE REST API route data to a wp option and returns it
314
-     *
315
-     * @param string  $version
316
-     * @param boolean $hidden_endpoints
317
-     * @return mixed|null
318
-     * @throws \EE_Error
319
-     */
320
-    protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
321
-    {
322
-        $instance = self::instance();
323
-        $routes = apply_filters(
324
-            'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
325
-            array_replace_recursive(
326
-                $instance->_get_config_route_data_for_version($version, $hidden_endpoints),
327
-                $instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
328
-                $instance->_get_model_route_data_for_version($version, $hidden_endpoints),
329
-                $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
330
-            )
331
-        );
332
-        $option_name = self::saved_routes_option_names . $version;
333
-        if (get_option($option_name)) {
334
-            update_option($option_name, $routes, true);
335
-        } else {
336
-            add_option($option_name, $routes, null, 'no');
337
-        }
338
-        return $routes;
339
-    }
340
-
341
-
342
-    /**
343
-     * Calculates all the EE routes and saves it to a WordPress option so we don't
344
-     * need to calculate it on every request
345
-     *
346
-     * @deprecated since version 4.9.1
347
-     * @return void
348
-     */
349
-    public static function save_ee_routes()
350
-    {
351
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
352
-            $instance = self::instance();
353
-            $routes = apply_filters(
354
-                'EED_Core_Rest_Api__save_ee_routes__routes',
355
-                array_replace_recursive(
356
-                    $instance->_register_config_routes(),
357
-                    $instance->_register_meta_routes(),
358
-                    $instance->_register_model_routes(),
359
-                    $instance->_register_rpc_routes()
360
-                )
361
-            );
362
-            update_option(self::saved_routes_option_names, $routes, true);
363
-        }
364
-    }
365
-
366
-
367
-    /**
368
-     * Gets all the route information relating to EE models
369
-     *
370
-     * @return array @see get_ee_route_data
371
-     * @deprecated since version 4.9.1
372
-     */
373
-    protected function _register_model_routes()
374
-    {
375
-        $model_routes = array();
376
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
377
-            $model_routes[ EED_Core_Rest_Api::ee_api_namespace
378
-                           . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
379
-        }
380
-        return $model_routes;
381
-    }
382
-
383
-
384
-    /**
385
-     * Decides whether or not to add write endpoints for this model.
386
-     *
387
-     * Currently, this defaults to exclude all global tables and models
388
-     * which would allow inserting WP core data (we don't want to duplicate
389
-     * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
390
-     *
391
-     * @param EEM_Base $model
392
-     * @return bool
393
-     */
394
-    public static function should_have_write_endpoints(EEM_Base $model)
395
-    {
396
-        if ($model->is_wp_core_model()) {
397
-            return false;
398
-        }
399
-        foreach ($model->get_tables() as $table) {
400
-            if ($table->is_global()) {
401
-                return false;
402
-            }
403
-        }
404
-        return true;
405
-    }
406
-
407
-
408
-    /**
409
-     * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
410
-     * in this versioned namespace of EE4
411
-     *
412
-     * @param $version
413
-     * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
414
-     */
415
-    public static function model_names_with_plural_routes($version)
416
-    {
417
-        $model_version_info = new ModelVersionInfo($version);
418
-        $models_to_register = $model_version_info->modelsForRequestedVersion();
419
-        // let's not bother having endpoints for extra metas
420
-        unset(
421
-            $models_to_register['Extra_Meta'],
422
-            $models_to_register['Extra_Join'],
423
-            $models_to_register['Post_Meta']
424
-        );
425
-        return apply_filters(
426
-            'FHEE__EED_Core_REST_API___register_model_routes',
427
-            $models_to_register
428
-        );
429
-    }
430
-
431
-
432
-    /**
433
-     * Gets the route data for EE models in the specified version
434
-     *
435
-     * @param string  $version
436
-     * @param boolean $hidden_endpoint
437
-     * @return array
438
-     * @throws EE_Error
439
-     */
440
-    protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
441
-    {
442
-        $model_routes = array();
443
-        $model_version_info = new ModelVersionInfo($version);
444
-        foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
445
-            $model = \EE_Registry::instance()->load_model($model_name);
446
-            // if this isn't a valid model then let's skip iterate to the next item in the loop.
447
-            if (! $model instanceof EEM_Base) {
448
-                continue;
449
-            }
450
-            // yes we could just register one route for ALL models, but then they wouldn't show up in the index
451
-            $plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
452
-            $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
453
-            $model_routes[ $plural_model_route ] = array(
454
-                array(
455
-                    'callback'        => array(
456
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
457
-                        'handleRequestGetAll',
458
-                    ),
459
-                    'callback_args'   => array($version, $model_name),
460
-                    'methods'         => WP_REST_Server::READABLE,
461
-                    'hidden_endpoint' => $hidden_endpoint,
462
-                    'args'            => $this->_get_read_query_params($model, $version),
463
-                    '_links'          => array(
464
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
465
-                    ),
466
-                ),
467
-                'schema' => array(
468
-                    'schema_callback' => array(
469
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
470
-                        'handleSchemaRequest',
471
-                    ),
472
-                    'callback_args'   => array($version, $model_name),
473
-                ),
474
-            );
475
-            $model_routes[ $singular_model_route ] = array(
476
-                array(
477
-                    'callback'        => array(
478
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
479
-                        'handleRequestGetOne',
480
-                    ),
481
-                    'callback_args'   => array($version, $model_name),
482
-                    'methods'         => WP_REST_Server::READABLE,
483
-                    'hidden_endpoint' => $hidden_endpoint,
484
-                    'args'            => $this->_get_response_selection_query_params($model, $version, true),
485
-                ),
486
-            );
487
-            if (apply_filters(
488
-                'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
489
-                EED_Core_Rest_Api::should_have_write_endpoints($model),
490
-                $model
491
-            )) {
492
-                $model_routes[ $plural_model_route ][] = array(
493
-                    'callback'        => array(
494
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Write',
495
-                        'handleRequestInsert',
496
-                    ),
497
-                    'callback_args'   => array($version, $model_name),
498
-                    'methods'         => WP_REST_Server::CREATABLE,
499
-                    'hidden_endpoint' => $hidden_endpoint,
500
-                    'args'            => $this->_get_write_params($model_name, $model_version_info, true),
501
-                );
502
-                $model_routes[ $singular_model_route ] = array_merge(
503
-                    $model_routes[ $singular_model_route ],
504
-                    array(
505
-                        array(
506
-                            'callback'        => array(
507
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
508
-                                'handleRequestUpdate',
509
-                            ),
510
-                            'callback_args'   => array($version, $model_name),
511
-                            'methods'         => WP_REST_Server::EDITABLE,
512
-                            'hidden_endpoint' => $hidden_endpoint,
513
-                            'args'            => $this->_get_write_params($model_name, $model_version_info),
514
-                        ),
515
-                        array(
516
-                            'callback'        => array(
517
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
518
-                                'handleRequestDelete',
519
-                            ),
520
-                            'callback_args'   => array($version, $model_name),
521
-                            'methods'         => WP_REST_Server::DELETABLE,
522
-                            'hidden_endpoint' => $hidden_endpoint,
523
-                            'args'            => $this->_get_delete_query_params($model, $version),
524
-                        ),
525
-                    )
526
-                );
527
-            }
528
-            foreach ($model->relation_settings() as $relation_name => $relation_obj) {
529
-                $related_route = EED_Core_Rest_Api::get_relation_route_via(
530
-                    $model,
531
-                    '(?P<id>[^\/]+)',
532
-                    $relation_obj
533
-                );
534
-                $model_routes[ $related_route ] = array(
535
-                    array(
536
-                        'callback'        => array(
537
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Read',
538
-                            'handleRequestGetRelated',
539
-                        ),
540
-                        'callback_args'   => array($version, $model_name, $relation_name),
541
-                        'methods'         => WP_REST_Server::READABLE,
542
-                        'hidden_endpoint' => $hidden_endpoint,
543
-                        'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
544
-                    ),
545
-                );
546
-
547
-                $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)';
548
-                $model_routes[ $related_write_route ] = array(
549
-                    array(
550
-                        'callback'        => array(
551
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Write',
552
-                            'handleRequestAddRelation',
553
-                        ),
554
-                        'callback_args'   => array($version, $model_name, $relation_name),
555
-                        'methods'         => WP_REST_Server::EDITABLE,
556
-                        'hidden_endpoint' => $hidden_endpoint,
557
-                        'args'            => $this->_get_add_relation_query_params($model, $relation_obj->get_other_model(), $version)
558
-                    ),
559
-                    array(
560
-                        'callback'        => array(
561
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Write',
562
-                            'handleRequestRemoveRelation',
563
-                        ),
564
-                        'callback_args'   => array($version, $model_name, $relation_name),
565
-                        'methods'         => WP_REST_Server::DELETABLE,
566
-                        'hidden_endpoint' => $hidden_endpoint,
567
-                        'args'            => array()
568
-                    ),
569
-                );
570
-            }
571
-        }
572
-        return $model_routes;
573
-    }
574
-
575
-
576
-    /**
577
-     * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
578
-     * excluding the preceding slash.
579
-     * Eg you pass get_plural_route_to('Event') = 'events'
580
-     *
581
-     * @param EEM_Base $model
582
-     * @return string
583
-     */
584
-    public static function get_collection_route(EEM_Base $model)
585
-    {
586
-        return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
587
-    }
588
-
589
-
590
-    /**
591
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
592
-     * excluding the preceding slash.
593
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
594
-     *
595
-     * @param EEM_Base $model eg Event or Venue
596
-     * @param string   $id
597
-     * @return string
598
-     */
599
-    public static function get_entity_route($model, $id)
600
-    {
601
-        return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id;
602
-    }
603
-
604
-
605
-    /**
606
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
607
-     * excluding the preceding slash.
608
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
609
-     *
610
-     * @param EEM_Base               $model eg Event or Venue
611
-     * @param string                 $id
612
-     * @param EE_Model_Relation_Base $relation_obj
613
-     * @return string
614
-     */
615
-    public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
616
-    {
617
-        $related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
618
-            $relation_obj->get_other_model()->get_this_model_name(),
619
-            $relation_obj
620
-        );
621
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
622
-    }
623
-
624
-
625
-    /**
626
-     * Adds onto the $relative_route the EE4 REST API versioned namespace.
627
-     * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
628
-     *
629
-     * @param string $relative_route
630
-     * @param string $version
631
-     * @return string
632
-     */
633
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36')
634
-    {
635
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
636
-    }
637
-
638
-
639
-    /**
640
-     * Adds all the RPC-style routes (remote procedure call-like routes, ie
641
-     * routes that don't conform to the traditional REST CRUD-style).
642
-     *
643
-     * @deprecated since 4.9.1
644
-     */
645
-    protected function _register_rpc_routes()
646
-    {
647
-        $routes = array();
648
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
649
-            $routes[ self::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version(
650
-                $version,
651
-                $hidden_endpoint
652
-            );
653
-        }
654
-        return $routes;
655
-    }
656
-
657
-
658
-    /**
659
-     * @param string  $version
660
-     * @param boolean $hidden_endpoint
661
-     * @return array
662
-     */
663
-    protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
664
-    {
665
-        $this_versions_routes = array();
666
-        // checkin endpoint
667
-        $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
668
-            array(
669
-                'callback'        => array(
670
-                    'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
671
-                    'handleRequestToggleCheckin',
672
-                ),
673
-                'methods'         => WP_REST_Server::CREATABLE,
674
-                'hidden_endpoint' => $hidden_endpoint,
675
-                'args'            => array(
676
-                    'force' => array(
677
-                        'required'    => false,
678
-                        'default'     => false,
679
-                        'description' => __(
680
-                        // @codingStandardsIgnoreStart
681
-                            'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
682
-                            // @codingStandardsIgnoreEnd
683
-                            'event_espresso'
684
-                        ),
685
-                    ),
686
-                ),
687
-                'callback_args'   => array($version),
688
-            ),
689
-        );
690
-        return apply_filters(
691
-            'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
692
-            $this_versions_routes,
693
-            $version,
694
-            $hidden_endpoint
695
-        );
696
-    }
697
-
698
-
699
-    /**
700
-     * Gets the query params that can be used when request one or many
701
-     *
702
-     * @param EEM_Base $model
703
-     * @param string   $version
704
-     * @return array
705
-     */
706
-    protected function _get_response_selection_query_params(\EEM_Base $model, $version, $single_only = false)
707
-    {
708
-        $query_params = array(
709
-            'include'   => array(
710
-                'required' => false,
711
-                'default'  => '*',
712
-                'type'     => 'string',
713
-            ),
714
-            'calculate' => array(
715
-                'required'          => false,
716
-                'default'           => '',
717
-                'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
718
-                'type'              => 'string',
719
-                // because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
720
-                // freaks out. We'll just validate this argument while handling the request
721
-                'validate_callback' => null,
722
-                'sanitize_callback' => null,
723
-            ),
724
-            'password' => array(
725
-                'required' => false,
726
-                'default' => '',
727
-                'type' => 'string'
728
-            )
729
-        );
730
-        return apply_filters(
731
-            'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
732
-            $query_params,
733
-            $model,
734
-            $version
735
-        );
736
-    }
737
-
738
-
739
-    /**
740
-     * Gets the parameters acceptable for delete requests
741
-     *
742
-     * @param \EEM_Base $model
743
-     * @param string    $version
744
-     * @return array
745
-     */
746
-    protected function _get_delete_query_params(\EEM_Base $model, $version)
747
-    {
748
-        $params_for_delete = array(
749
-            'allow_blocking' => array(
750
-                'required' => false,
751
-                'default'  => true,
752
-                'type'     => 'boolean',
753
-            ),
754
-        );
755
-        $params_for_delete['force'] = array(
756
-            'required' => false,
757
-            'default'  => false,
758
-            'type'     => 'boolean',
759
-        );
760
-        return apply_filters(
761
-            'FHEE__EED_Core_Rest_Api___get_delete_query_params',
762
-            $params_for_delete,
763
-            $model,
764
-            $version
765
-        );
766
-    }
767
-
768
-    protected function _get_add_relation_query_params(\EEM_Base $source_model, \EEM_Base $related_model, $version)
769
-    {
770
-        // if they're related through a HABTM relation, check for any non-FKs
771
-        $all_relation_settings = $source_model->relation_settings();
772
-        $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ];
773
-        $params = array();
774
-        if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) {
775
-            foreach ($relation_settings->getNonKeyFields() as $field) {
776
-                /* @var $field EE_Model_Field_Base */
777
-                $params[ $field->get_name() ] = array(
778
-                    'required' => ! $field->is_nullable(),
779
-                    'default' => ModelDataTranslator::prepareFieldValueForJson($field, $field->get_default_value(), $version),
780
-                    'type' => $field->getSchemaType(),
781
-                    'validate_callbaack' => null,
782
-                    'sanitize_callback' => null
783
-                );
784
-            }
785
-        }
786
-        return $params;
787
-    }
788
-
789
-
790
-    /**
791
-     * Gets info about reading query params that are acceptable
792
-     *
793
-     * @param \EEM_Base $model eg 'Event' or 'Venue'
794
-     * @param  string   $version
795
-     * @return array    describing the args acceptable when querying this model
796
-     * @throws EE_Error
797
-     */
798
-    protected function _get_read_query_params(\EEM_Base $model, $version)
799
-    {
800
-        $default_orderby = array();
801
-        foreach ($model->get_combined_primary_key_fields() as $key_field) {
802
-            $default_orderby[ $key_field->get_name() ] = 'ASC';
803
-        }
804
-        return array_merge(
805
-            $this->_get_response_selection_query_params($model, $version),
806
-            array(
807
-                'where'    => array(
808
-                    'required'          => false,
809
-                    'default'           => array(),
810
-                    'type'              => 'object',
811
-                    // because we accept an almost infinite list of possible where conditions, WP
812
-                    // core validation and sanitization freaks out. We'll just validate this argument
813
-                    // while handling the request
814
-                    'validate_callback' => null,
815
-                    'sanitize_callback' => null,
816
-                ),
817
-                'limit'    => array(
818
-                    'required'          => false,
819
-                    'default'           => EED_Core_Rest_Api::get_default_query_limit(),
820
-                    'type'              => array(
821
-                        'array',
822
-                        'string',
823
-                        'integer',
824
-                    ),
825
-                    // because we accept a variety of types, WP core validation and sanitization
826
-                    // freaks out. We'll just validate this argument while handling the request
827
-                    'validate_callback' => null,
828
-                    'sanitize_callback' => null,
829
-                ),
830
-                'order_by' => array(
831
-                    'required'          => false,
832
-                    'default'           => $default_orderby,
833
-                    'type'              => array(
834
-                        'object',
835
-                        'string',
836
-                    ),// because we accept a variety of types, WP core validation and sanitization
837
-                    // freaks out. We'll just validate this argument while handling the request
838
-                    'validate_callback' => null,
839
-                    'sanitize_callback' => null,
840
-                ),
841
-                'group_by' => array(
842
-                    'required'          => false,
843
-                    'default'           => null,
844
-                    'type'              => array(
845
-                        'object',
846
-                        'string',
847
-                    ),
848
-                    // because we accept  an almost infinite list of possible groupings,
849
-                    // WP core validation and sanitization
850
-                    // freaks out. We'll just validate this argument while handling the request
851
-                    'validate_callback' => null,
852
-                    'sanitize_callback' => null,
853
-                ),
854
-                'having'   => array(
855
-                    'required'          => false,
856
-                    'default'           => null,
857
-                    'type'              => 'object',
858
-                    // because we accept an almost infinite list of possible where conditions, WP
859
-                    // core validation and sanitization freaks out. We'll just validate this argument
860
-                    // while handling the request
861
-                    'validate_callback' => null,
862
-                    'sanitize_callback' => null,
863
-                ),
864
-                'caps'     => array(
865
-                    'required' => false,
866
-                    'default'  => EEM_Base::caps_read,
867
-                    'type'     => 'string',
868
-                    'enum'     => array(
869
-                        EEM_Base::caps_read,
870
-                        EEM_Base::caps_read_admin,
871
-                        EEM_Base::caps_edit,
872
-                        EEM_Base::caps_delete,
873
-                    ),
874
-                ),
875
-            )
876
-        );
877
-    }
878
-
879
-
880
-    /**
881
-     * Gets parameter information for a model regarding writing data
882
-     *
883
-     * @param string           $model_name
884
-     * @param ModelVersionInfo $model_version_info
885
-     * @param boolean          $create                                       whether this is for request to create (in
886
-     *                                                                       which case we need all required params) or
887
-     *                                                                       just to update (in which case we don't
888
-     *                                                                       need those on every request)
889
-     * @return array
890
-     */
891
-    protected function _get_write_params(
892
-        $model_name,
893
-        ModelVersionInfo $model_version_info,
894
-        $create = false
895
-    ) {
896
-        $model = EE_Registry::instance()->load_model($model_name);
897
-        $fields = $model_version_info->fieldsOnModelInThisVersion($model);
898
-        $args_info = array();
899
-        foreach ($fields as $field_name => $field_obj) {
900
-            if ($field_obj->is_auto_increment()) {
901
-                // totally ignore auto increment IDs
902
-                continue;
903
-            }
904
-            $arg_info = $field_obj->getSchema();
905
-            $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
906
-            $arg_info['required'] = $required;
907
-            // remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
908
-            unset($arg_info['readonly']);
909
-            $schema_properties = $field_obj->getSchemaProperties();
910
-            if (isset($schema_properties['raw'])
911
-                && $field_obj->getSchemaType() === 'object'
912
-            ) {
913
-                // if there's a "raw" form of this argument, use those properties instead
914
-                $arg_info = array_replace(
915
-                    $arg_info,
916
-                    $schema_properties['raw']
917
-                );
918
-            }
919
-            $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
920
-                $field_obj,
921
-                $field_obj->get_default_value(),
922
-                $model_version_info->requestedVersion()
923
-            );
924
-            // we do our own validation and sanitization within the controller
925
-            if (function_exists('rest_validate_value_from_schema')) {
926
-                $sanitize_callback = array(
927
-                    'EED_Core_Rest_Api',
928
-                    'default_sanitize_callback',
929
-                );
930
-            } else {
931
-                $sanitize_callback = null;
932
-            }
933
-            $arg_info['sanitize_callback'] = $sanitize_callback;
934
-            $args_info[ $field_name ] = $arg_info;
935
-            if ($field_obj instanceof EE_Datetime_Field) {
936
-                $gmt_arg_info = $arg_info;
937
-                $gmt_arg_info['description'] = sprintf(
938
-                    esc_html__(
939
-                        '%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
940
-                        'event_espresso'
941
-                    ),
942
-                    $field_obj->get_nicename(),
943
-                    $field_name
944
-                );
945
-                $args_info[ $field_name . '_gmt' ] = $gmt_arg_info;
946
-            }
947
-        }
948
-        return $args_info;
949
-    }
950
-
951
-
952
-    /**
953
-     * Replacement for WP API's 'rest_parse_request_arg'.
954
-     * If the value is blank but not required, don't bother validating it.
955
-     * Also, it uses our email validation instead of WP API's default.
956
-     *
957
-     * @param                 $value
958
-     * @param WP_REST_Request $request
959
-     * @param                 $param
960
-     * @return bool|true|WP_Error
961
-     * @throws InvalidArgumentException
962
-     * @throws InvalidInterfaceException
963
-     * @throws InvalidDataTypeException
964
-     */
965
-    public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
966
-    {
967
-        $attributes = $request->get_attributes();
968
-        if (! isset($attributes['args'][ $param ])
969
-            || ! is_array($attributes['args'][ $param ])) {
970
-            $validation_result = true;
971
-        } else {
972
-            $args = $attributes['args'][ $param ];
973
-            if ((
974
-                    $value === ''
975
-                    || $value === null
976
-                )
977
-                && (! isset($args['required'])
978
-                    || $args['required'] === false
979
-                )
980
-            ) {
981
-                // not required and not provided? that's cool
982
-                $validation_result = true;
983
-            } elseif (isset($args['format'])
984
-                      && $args['format'] === 'email'
985
-            ) {
986
-                $validation_result = true;
987
-                if (! self::_validate_email($value)) {
988
-                    $validation_result = new WP_Error(
989
-                        'rest_invalid_param',
990
-                        esc_html__(
991
-                            'The email address is not valid or does not exist.',
992
-                            'event_espresso'
993
-                        )
994
-                    );
995
-                }
996
-            } else {
997
-                $validation_result = rest_validate_value_from_schema($value, $args, $param);
998
-            }
999
-        }
1000
-        if (is_wp_error($validation_result)) {
1001
-            return $validation_result;
1002
-        }
1003
-        return rest_sanitize_request_arg($value, $request, $param);
1004
-    }
1005
-
1006
-
1007
-    /**
1008
-     * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
1009
-     *
1010
-     * @param $email
1011
-     * @return bool
1012
-     * @throws InvalidArgumentException
1013
-     * @throws InvalidInterfaceException
1014
-     * @throws InvalidDataTypeException
1015
-     */
1016
-    protected static function _validate_email($email)
1017
-    {
1018
-        try {
1019
-            EmailAddressFactory::create($email);
1020
-            return true;
1021
-        } catch (EmailValidationException $e) {
1022
-            return false;
1023
-        }
1024
-    }
1025
-
1026
-
1027
-    /**
1028
-     * Gets routes for the config
1029
-     *
1030
-     * @return array @see _register_model_routes
1031
-     * @deprecated since version 4.9.1
1032
-     */
1033
-    protected function _register_config_routes()
1034
-    {
1035
-        $config_routes = array();
1036
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1037
-            $config_routes[ self::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version(
1038
-                $version,
1039
-                $hidden_endpoint
1040
-            );
1041
-        }
1042
-        return $config_routes;
1043
-    }
1044
-
1045
-
1046
-    /**
1047
-     * Gets routes for the config for the specified version
1048
-     *
1049
-     * @param string  $version
1050
-     * @param boolean $hidden_endpoint
1051
-     * @return array
1052
-     */
1053
-    protected function _get_config_route_data_for_version($version, $hidden_endpoint)
1054
-    {
1055
-        return array(
1056
-            'config'    => array(
1057
-                array(
1058
-                    'callback'        => array(
1059
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1060
-                        'handleRequest',
1061
-                    ),
1062
-                    'methods'         => WP_REST_Server::READABLE,
1063
-                    'hidden_endpoint' => $hidden_endpoint,
1064
-                    'callback_args'   => array($version),
1065
-                ),
1066
-            ),
1067
-            'site_info' => array(
1068
-                array(
1069
-                    'callback'        => array(
1070
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1071
-                        'handleRequestSiteInfo',
1072
-                    ),
1073
-                    'methods'         => WP_REST_Server::READABLE,
1074
-                    'hidden_endpoint' => $hidden_endpoint,
1075
-                    'callback_args'   => array($version),
1076
-                ),
1077
-            ),
1078
-        );
1079
-    }
1080
-
1081
-
1082
-    /**
1083
-     * Gets the meta info routes
1084
-     *
1085
-     * @return array @see _register_model_routes
1086
-     * @deprecated since version 4.9.1
1087
-     */
1088
-    protected function _register_meta_routes()
1089
-    {
1090
-        $meta_routes = array();
1091
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1092
-            $meta_routes[ self::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version(
1093
-                $version,
1094
-                $hidden_endpoint
1095
-            );
1096
-        }
1097
-        return $meta_routes;
1098
-    }
1099
-
1100
-
1101
-    /**
1102
-     * @param string  $version
1103
-     * @param boolean $hidden_endpoint
1104
-     * @return array
1105
-     */
1106
-    protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1107
-    {
1108
-        return array(
1109
-            'resources' => array(
1110
-                array(
1111
-                    'callback'        => array(
1112
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1113
-                        'handleRequestModelsMeta',
1114
-                    ),
1115
-                    'methods'         => WP_REST_Server::READABLE,
1116
-                    'hidden_endpoint' => $hidden_endpoint,
1117
-                    'callback_args'   => array($version),
1118
-                ),
1119
-            ),
1120
-        );
1121
-    }
1122
-
1123
-
1124
-    /**
1125
-     * Tries to hide old 4.6 endpoints from the
1126
-     *
1127
-     * @param array $route_data
1128
-     * @return array
1129
-     * @throws \EE_Error
1130
-     */
1131
-    public static function hide_old_endpoints($route_data)
1132
-    {
1133
-        // allow API clients to override which endpoints get hidden, in case
1134
-        // they want to discover particular endpoints
1135
-        // also, we don't have access to the request so we have to just grab it from the superglobal
1136
-        $force_show_ee_namespace = ltrim(
1137
-            EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1138
-            '/'
1139
-        );
1140
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1141
-            foreach ($relative_urls as $resource_name => $endpoints) {
1142
-                foreach ($endpoints as $key => $endpoint) {
1143
-                    // skip schema and other route options
1144
-                    if (! is_numeric($key)) {
1145
-                        continue;
1146
-                    }
1147
-                    // by default, hide "hidden_endpoint"s, unless the request indicates
1148
-                    // to $force_show_ee_namespace, in which case only show that one
1149
-                    // namespace's endpoints (and hide all others)
1150
-                    if (($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1151
-                        || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1152
-                    ) {
1153
-                        $full_route = '/' . ltrim($namespace, '/');
1154
-                        $full_route .= '/' . ltrim($resource_name, '/');
1155
-                        unset($route_data[ $full_route ]);
1156
-                    }
1157
-                }
1158
-            }
1159
-        }
1160
-        return $route_data;
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * Returns an array describing which versions of core support serving requests for.
1166
-     * Keys are core versions' major and minor version, and values are the
1167
-     * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1168
-     * data by just removing a few models and fields from the responses. However, 4.15 might remove
1169
-     * the answers table entirely, in which case it would be very difficult for
1170
-     * it to serve 4.6-style responses.
1171
-     * Versions of core that are missing from this array are unknowns.
1172
-     * previous ver
1173
-     *
1174
-     * @return array
1175
-     */
1176
-    public static function version_compatibilities()
1177
-    {
1178
-        return apply_filters(
1179
-            'FHEE__EED_Core_REST_API__version_compatibilities',
1180
-            array(
1181
-                '4.8.29' => '4.8.29',
1182
-                '4.8.33' => '4.8.29',
1183
-                '4.8.34' => '4.8.29',
1184
-                '4.8.36' => '4.8.29',
1185
-            )
1186
-        );
1187
-    }
1188
-
1189
-
1190
-    /**
1191
-     * Gets the latest API version served. Eg if there
1192
-     * are two versions served of the API, 4.8.29 and 4.8.32, and
1193
-     * we are on core version 4.8.34, it will return the string "4.8.32"
1194
-     *
1195
-     * @return string
1196
-     */
1197
-    public static function latest_rest_api_version()
1198
-    {
1199
-        $versions_served = \EED_Core_Rest_Api::versions_served();
1200
-        $versions_served_keys = array_keys($versions_served);
1201
-        return end($versions_served_keys);
1202
-    }
1203
-
1204
-
1205
-    /**
1206
-     * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1207
-     * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1208
-     * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1209
-     * We also indicate whether or not this version should be put in the index or not
1210
-     *
1211
-     * @return array keys are API version numbers (just major and minor numbers), and values
1212
-     * are whether or not they should be hidden
1213
-     */
1214
-    public static function versions_served()
1215
-    {
1216
-        $versions_served = array();
1217
-        $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1218
-        $lowest_compatible_version = end($possibly_served_versions);
1219
-        reset($possibly_served_versions);
1220
-        $versions_served_historically = array_keys($possibly_served_versions);
1221
-        $latest_version = end($versions_served_historically);
1222
-        reset($versions_served_historically);
1223
-        // for each version of core we have ever served:
1224
-        foreach ($versions_served_historically as $key_versioned_endpoint) {
1225
-            // if it's not above the current core version, and it's compatible with the current version of core
1226
-            if ($key_versioned_endpoint === $latest_version) {
1227
-                // don't hide the latest version in the index
1228
-                $versions_served[ $key_versioned_endpoint ] = false;
1229
-            } elseif ($key_versioned_endpoint >= $lowest_compatible_version
1230
-                && $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1231
-            ) {
1232
-                // include, but hide, previous versions which are still supported
1233
-                $versions_served[ $key_versioned_endpoint ] = true;
1234
-            } elseif (apply_filters(
1235
-                'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1236
-                false,
1237
-                $possibly_served_versions
1238
-            )) {
1239
-                // if a version is no longer supported, don't include it in index or list of versions served
1240
-                $versions_served[ $key_versioned_endpoint ] = true;
1241
-            }
1242
-        }
1243
-        return $versions_served;
1244
-    }
1245
-
1246
-
1247
-    /**
1248
-     * Gets the major and minor version of EE core's version string
1249
-     *
1250
-     * @return string
1251
-     */
1252
-    public static function core_version()
1253
-    {
1254
-        return apply_filters(
1255
-            'FHEE__EED_Core_REST_API__core_version',
1256
-            implode(
1257
-                '.',
1258
-                array_slice(
1259
-                    explode(
1260
-                        '.',
1261
-                        espresso_version()
1262
-                    ),
1263
-                    0,
1264
-                    3
1265
-                )
1266
-            )
1267
-        );
1268
-    }
1269
-
1270
-
1271
-    /**
1272
-     * Gets the default limit that should be used when querying for resources
1273
-     *
1274
-     * @return int
1275
-     */
1276
-    public static function get_default_query_limit()
1277
-    {
1278
-        // we actually don't use a const because we want folks to always use
1279
-        // this method, not the const directly
1280
-        return apply_filters(
1281
-            'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1282
-            50
1283
-        );
1284
-    }
1285
-
1286
-
1287
-    /**
1288
-     *
1289
-     * @param string $version api version string (i.e. '4.8.36')
1290
-     * @return array
1291
-     */
1292
-    public static function getCollectionRoutesIndexedByModelName($version = '')
1293
-    {
1294
-        $version = empty($version) ? self::latest_rest_api_version() : $version;
1295
-        $model_names = self::model_names_with_plural_routes($version);
1296
-        $collection_routes = array();
1297
-        foreach ($model_names as $model_name => $model_class_name) {
1298
-            $collection_routes[ strtolower($model_name) ] = '/' . self::ee_api_namespace . $version . '/'
1299
-                                                            . EEH_Inflector::pluralize_and_lower($model_name);
1300
-        }
1301
-        return $collection_routes;
1302
-    }
1303
-
1304
-
1305
-    /**
1306
-     * Returns an array of primary key names indexed by model names.
1307
-     * @param string $version
1308
-     * @return array
1309
-     */
1310
-    public static function getPrimaryKeyNamesIndexedByModelName($version = '')
1311
-    {
1312
-        $version = empty($version) ? self::latest_rest_api_version() : $version;
1313
-        $model_names = self::model_names_with_plural_routes($version);
1314
-        $primary_key_items = array();
1315
-        foreach ($model_names as $model_name => $model_class_name) {
1316
-            $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields();
1317
-            foreach ($primary_keys as $primary_key_name => $primary_key_field) {
1318
-                if (count($primary_keys) > 1) {
1319
-                    $primary_key_items[ strtolower($model_name) ][] = $primary_key_name;
1320
-                } else {
1321
-                    $primary_key_items[ strtolower($model_name) ] = $primary_key_name;
1322
-                }
1323
-            }
1324
-        }
1325
-        return $primary_key_items;
1326
-    }
1327
-
1328
-    /**
1329
-     * Determines the EE REST API debug mode is activated, or not.
1330
-     * @since 4.9.76.p
1331
-     * @return bool
1332
-     */
1333
-    public static function debugMode()
1334
-    {
1335
-        static $debug_mode = null; // could be class prop
1336
-        if ($debug_mode === null) {
1337
-            $debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE;
1338
-        }
1339
-        return $debug_mode;
1340
-    }
1341
-
1342
-
1343
-
1344
-    /**
1345
-     *    run - initial module setup
1346
-     *
1347
-     * @access    public
1348
-     * @param  WP $WP
1349
-     * @return    void
1350
-     */
1351
-    public function run($WP)
1352
-    {
1353
-    }
26
+	const ee_api_namespace = Domain::API_NAMESPACE;
27
+
28
+	const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
29
+
30
+	const saved_routes_option_names = 'ee_core_routes';
31
+
32
+	/**
33
+	 * string used in _links response bodies to make them globally unique.
34
+	 *
35
+	 * @see http://v2.wp-api.org/extending/linking/
36
+	 */
37
+	const ee_api_link_namespace = 'https://api.eventespresso.com/';
38
+
39
+	/**
40
+	 * @var CalculatedModelFields
41
+	 */
42
+	protected static $_field_calculator;
43
+
44
+
45
+	/**
46
+	 * @return EED_Core_Rest_Api|EED_Module
47
+	 */
48
+	public static function instance()
49
+	{
50
+		self::$_field_calculator = LoaderFactory::getLoader()->load('EventEspresso\core\libraries\rest_api\CalculatedModelFields');
51
+		return parent::get_instance(__CLASS__);
52
+	}
53
+
54
+
55
+	/**
56
+	 *    set_hooks - for hooking into EE Core, other modules, etc
57
+	 *
58
+	 * @access    public
59
+	 * @return    void
60
+	 */
61
+	public static function set_hooks()
62
+	{
63
+		self::set_hooks_both();
64
+	}
65
+
66
+
67
+	/**
68
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
69
+	 *
70
+	 * @access    public
71
+	 * @return    void
72
+	 */
73
+	public static function set_hooks_admin()
74
+	{
75
+		self::set_hooks_both();
76
+	}
77
+
78
+
79
+	public static function set_hooks_both()
80
+	{
81
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
82
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
83
+		add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
84
+		add_filter(
85
+			'rest_index',
86
+			array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex')
87
+		);
88
+		EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
89
+	}
90
+
91
+
92
+	/**
93
+	 * sets up hooks which only need to be included as part of REST API requests;
94
+	 * other requests like to the frontend or admin etc don't need them
95
+	 *
96
+	 * @throws \EE_Error
97
+	 */
98
+	public static function set_hooks_rest_api()
99
+	{
100
+		// set hooks which account for changes made to the API
101
+		EED_Core_Rest_Api::_set_hooks_for_changes();
102
+	}
103
+
104
+
105
+	/**
106
+	 * public wrapper of _set_hooks_for_changes.
107
+	 * Loads all the hooks which make requests to old versions of the API
108
+	 * appear the same as they always did
109
+	 *
110
+	 * @throws EE_Error
111
+	 */
112
+	public static function set_hooks_for_changes()
113
+	{
114
+		self::_set_hooks_for_changes();
115
+	}
116
+
117
+
118
+	/**
119
+	 * Loads all the hooks which make requests to old versions of the API
120
+	 * appear the same as they always did
121
+	 *
122
+	 * @throws EE_Error
123
+	 */
124
+	protected static function _set_hooks_for_changes()
125
+	{
126
+		$folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
127
+		foreach ($folder_contents as $classname_in_namespace => $filepath) {
128
+			// ignore the base parent class
129
+			// and legacy named classes
130
+			if ($classname_in_namespace === 'ChangesInBase'
131
+				|| strpos($classname_in_namespace, 'Changes_In_') === 0
132
+			) {
133
+				continue;
134
+			}
135
+			$full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
136
+			if (class_exists($full_classname)) {
137
+				$instance_of_class = new $full_classname;
138
+				if ($instance_of_class instanceof ChangesInBase) {
139
+					$instance_of_class->setHooks();
140
+				}
141
+			}
142
+		}
143
+	}
144
+
145
+
146
+	/**
147
+	 * Filters the WP routes to add our EE-related ones. This takes a bit of time
148
+	 * so we actually prefer to only do it when an EE plugin is activated or upgraded
149
+	 *
150
+	 * @throws \EE_Error
151
+	 */
152
+	public static function register_routes()
153
+	{
154
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
155
+			foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
156
+				/**
157
+				 * @var array     $data_for_multiple_endpoints numerically indexed array
158
+				 *                                         but can also contain route options like {
159
+				 * @type array    $schema                      {
160
+				 * @type callable $schema_callback
161
+				 * @type array    $callback_args               arguments that will be passed to the callback, after the
162
+				 * WP_REST_Request of course
163
+				 * }
164
+				 * }
165
+				 */
166
+				// when registering routes, register all the endpoints' data at the same time
167
+				$multiple_endpoint_args = array();
168
+				foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
169
+					/**
170
+					 * @var array     $data_for_single_endpoint {
171
+					 * @type callable $callback
172
+					 * @type string methods
173
+					 * @type array args
174
+					 * @type array _links
175
+					 * @type array    $callback_args            arguments that will be passed to the callback, after the
176
+					 * WP_REST_Request of course
177
+					 * }
178
+					 */
179
+					// skip route options
180
+					if (! is_numeric($endpoint_key)) {
181
+						continue;
182
+					}
183
+					if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
184
+						throw new EE_Error(
185
+							esc_html__(
186
+							// @codingStandardsIgnoreStart
187
+								'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
188
+								// @codingStandardsIgnoreEnd
189
+								'event_espresso'
190
+							)
191
+						);
192
+					}
193
+					$callback = $data_for_single_endpoint['callback'];
194
+					$single_endpoint_args = array(
195
+						'methods' => $data_for_single_endpoint['methods'],
196
+						'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
197
+							: array(),
198
+					);
199
+					if (isset($data_for_single_endpoint['_links'])) {
200
+						$single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
201
+					}
202
+					if (isset($data_for_single_endpoint['callback_args'])) {
203
+						$callback_args = $data_for_single_endpoint['callback_args'];
204
+						$single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
205
+							$callback,
206
+							$callback_args
207
+						) {
208
+							array_unshift($callback_args, $request);
209
+							return call_user_func_array(
210
+								$callback,
211
+								$callback_args
212
+							);
213
+						};
214
+					} else {
215
+						$single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
216
+					}
217
+					$multiple_endpoint_args[] = $single_endpoint_args;
218
+				}
219
+				if (isset($data_for_multiple_endpoints['schema'])) {
220
+					$schema_route_data = $data_for_multiple_endpoints['schema'];
221
+					$schema_callback = $schema_route_data['schema_callback'];
222
+					$callback_args = $schema_route_data['callback_args'];
223
+					$multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
224
+						return call_user_func_array(
225
+							$schema_callback,
226
+							$callback_args
227
+						);
228
+					};
229
+				}
230
+				register_rest_route(
231
+					$namespace,
232
+					$relative_route,
233
+					$multiple_endpoint_args
234
+				);
235
+			}
236
+		}
237
+	}
238
+
239
+
240
+	/**
241
+	 * Checks if there was a version change or something that merits invalidating the cached
242
+	 * route data. If so, invalidates the cached route data so that it gets refreshed
243
+	 * next time the WP API is used
244
+	 */
245
+	public static function invalidate_cached_route_data_on_version_change()
246
+	{
247
+		if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
248
+			EED_Core_Rest_Api::invalidate_cached_route_data();
249
+		}
250
+		foreach (EE_Registry::instance()->addons as $addon) {
251
+			if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
252
+				EED_Core_Rest_Api::invalidate_cached_route_data();
253
+			}
254
+		}
255
+	}
256
+
257
+
258
+	/**
259
+	 * Removes the cached route data so it will get refreshed next time the WP API is used
260
+	 */
261
+	public static function invalidate_cached_route_data()
262
+	{
263
+		// delete the saved EE REST API routes
264
+		foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
265
+			delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
266
+		}
267
+	}
268
+
269
+
270
+	/**
271
+	 * Gets the EE route data
272
+	 *
273
+	 * @return array top-level key is the namespace, next-level key is the route and its value is array{
274
+	 * @throws \EE_Error
275
+	 * @type string|array $callback
276
+	 * @type string       $methods
277
+	 * @type boolean      $hidden_endpoint
278
+	 * }
279
+	 */
280
+	public static function get_ee_route_data()
281
+	{
282
+		$ee_routes = array();
283
+		foreach (self::versions_served() as $version => $hidden_endpoints) {
284
+			$ee_routes[ self::ee_api_namespace . $version ] = self::_get_ee_route_data_for_version(
285
+				$version,
286
+				$hidden_endpoints
287
+			);
288
+		}
289
+		return $ee_routes;
290
+	}
291
+
292
+
293
+	/**
294
+	 * Gets the EE route data from the wp options if it exists already,
295
+	 * otherwise re-generates it and saves it to the option
296
+	 *
297
+	 * @param string  $version
298
+	 * @param boolean $hidden_endpoints
299
+	 * @return array
300
+	 * @throws \EE_Error
301
+	 */
302
+	protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
303
+	{
304
+		$ee_routes = get_option(self::saved_routes_option_names . $version, null);
305
+		if (! $ee_routes || EED_Core_Rest_Api::debugMode()) {
306
+			$ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
307
+		}
308
+		return $ee_routes;
309
+	}
310
+
311
+
312
+	/**
313
+	 * Saves the EE REST API route data to a wp option and returns it
314
+	 *
315
+	 * @param string  $version
316
+	 * @param boolean $hidden_endpoints
317
+	 * @return mixed|null
318
+	 * @throws \EE_Error
319
+	 */
320
+	protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
321
+	{
322
+		$instance = self::instance();
323
+		$routes = apply_filters(
324
+			'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
325
+			array_replace_recursive(
326
+				$instance->_get_config_route_data_for_version($version, $hidden_endpoints),
327
+				$instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
328
+				$instance->_get_model_route_data_for_version($version, $hidden_endpoints),
329
+				$instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
330
+			)
331
+		);
332
+		$option_name = self::saved_routes_option_names . $version;
333
+		if (get_option($option_name)) {
334
+			update_option($option_name, $routes, true);
335
+		} else {
336
+			add_option($option_name, $routes, null, 'no');
337
+		}
338
+		return $routes;
339
+	}
340
+
341
+
342
+	/**
343
+	 * Calculates all the EE routes and saves it to a WordPress option so we don't
344
+	 * need to calculate it on every request
345
+	 *
346
+	 * @deprecated since version 4.9.1
347
+	 * @return void
348
+	 */
349
+	public static function save_ee_routes()
350
+	{
351
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
352
+			$instance = self::instance();
353
+			$routes = apply_filters(
354
+				'EED_Core_Rest_Api__save_ee_routes__routes',
355
+				array_replace_recursive(
356
+					$instance->_register_config_routes(),
357
+					$instance->_register_meta_routes(),
358
+					$instance->_register_model_routes(),
359
+					$instance->_register_rpc_routes()
360
+				)
361
+			);
362
+			update_option(self::saved_routes_option_names, $routes, true);
363
+		}
364
+	}
365
+
366
+
367
+	/**
368
+	 * Gets all the route information relating to EE models
369
+	 *
370
+	 * @return array @see get_ee_route_data
371
+	 * @deprecated since version 4.9.1
372
+	 */
373
+	protected function _register_model_routes()
374
+	{
375
+		$model_routes = array();
376
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
377
+			$model_routes[ EED_Core_Rest_Api::ee_api_namespace
378
+						   . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
379
+		}
380
+		return $model_routes;
381
+	}
382
+
383
+
384
+	/**
385
+	 * Decides whether or not to add write endpoints for this model.
386
+	 *
387
+	 * Currently, this defaults to exclude all global tables and models
388
+	 * which would allow inserting WP core data (we don't want to duplicate
389
+	 * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
390
+	 *
391
+	 * @param EEM_Base $model
392
+	 * @return bool
393
+	 */
394
+	public static function should_have_write_endpoints(EEM_Base $model)
395
+	{
396
+		if ($model->is_wp_core_model()) {
397
+			return false;
398
+		}
399
+		foreach ($model->get_tables() as $table) {
400
+			if ($table->is_global()) {
401
+				return false;
402
+			}
403
+		}
404
+		return true;
405
+	}
406
+
407
+
408
+	/**
409
+	 * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
410
+	 * in this versioned namespace of EE4
411
+	 *
412
+	 * @param $version
413
+	 * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
414
+	 */
415
+	public static function model_names_with_plural_routes($version)
416
+	{
417
+		$model_version_info = new ModelVersionInfo($version);
418
+		$models_to_register = $model_version_info->modelsForRequestedVersion();
419
+		// let's not bother having endpoints for extra metas
420
+		unset(
421
+			$models_to_register['Extra_Meta'],
422
+			$models_to_register['Extra_Join'],
423
+			$models_to_register['Post_Meta']
424
+		);
425
+		return apply_filters(
426
+			'FHEE__EED_Core_REST_API___register_model_routes',
427
+			$models_to_register
428
+		);
429
+	}
430
+
431
+
432
+	/**
433
+	 * Gets the route data for EE models in the specified version
434
+	 *
435
+	 * @param string  $version
436
+	 * @param boolean $hidden_endpoint
437
+	 * @return array
438
+	 * @throws EE_Error
439
+	 */
440
+	protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
441
+	{
442
+		$model_routes = array();
443
+		$model_version_info = new ModelVersionInfo($version);
444
+		foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
445
+			$model = \EE_Registry::instance()->load_model($model_name);
446
+			// if this isn't a valid model then let's skip iterate to the next item in the loop.
447
+			if (! $model instanceof EEM_Base) {
448
+				continue;
449
+			}
450
+			// yes we could just register one route for ALL models, but then they wouldn't show up in the index
451
+			$plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
452
+			$singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
453
+			$model_routes[ $plural_model_route ] = array(
454
+				array(
455
+					'callback'        => array(
456
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
457
+						'handleRequestGetAll',
458
+					),
459
+					'callback_args'   => array($version, $model_name),
460
+					'methods'         => WP_REST_Server::READABLE,
461
+					'hidden_endpoint' => $hidden_endpoint,
462
+					'args'            => $this->_get_read_query_params($model, $version),
463
+					'_links'          => array(
464
+						'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
465
+					),
466
+				),
467
+				'schema' => array(
468
+					'schema_callback' => array(
469
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
470
+						'handleSchemaRequest',
471
+					),
472
+					'callback_args'   => array($version, $model_name),
473
+				),
474
+			);
475
+			$model_routes[ $singular_model_route ] = array(
476
+				array(
477
+					'callback'        => array(
478
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
479
+						'handleRequestGetOne',
480
+					),
481
+					'callback_args'   => array($version, $model_name),
482
+					'methods'         => WP_REST_Server::READABLE,
483
+					'hidden_endpoint' => $hidden_endpoint,
484
+					'args'            => $this->_get_response_selection_query_params($model, $version, true),
485
+				),
486
+			);
487
+			if (apply_filters(
488
+				'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
489
+				EED_Core_Rest_Api::should_have_write_endpoints($model),
490
+				$model
491
+			)) {
492
+				$model_routes[ $plural_model_route ][] = array(
493
+					'callback'        => array(
494
+						'EventEspresso\core\libraries\rest_api\controllers\model\Write',
495
+						'handleRequestInsert',
496
+					),
497
+					'callback_args'   => array($version, $model_name),
498
+					'methods'         => WP_REST_Server::CREATABLE,
499
+					'hidden_endpoint' => $hidden_endpoint,
500
+					'args'            => $this->_get_write_params($model_name, $model_version_info, true),
501
+				);
502
+				$model_routes[ $singular_model_route ] = array_merge(
503
+					$model_routes[ $singular_model_route ],
504
+					array(
505
+						array(
506
+							'callback'        => array(
507
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
508
+								'handleRequestUpdate',
509
+							),
510
+							'callback_args'   => array($version, $model_name),
511
+							'methods'         => WP_REST_Server::EDITABLE,
512
+							'hidden_endpoint' => $hidden_endpoint,
513
+							'args'            => $this->_get_write_params($model_name, $model_version_info),
514
+						),
515
+						array(
516
+							'callback'        => array(
517
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
518
+								'handleRequestDelete',
519
+							),
520
+							'callback_args'   => array($version, $model_name),
521
+							'methods'         => WP_REST_Server::DELETABLE,
522
+							'hidden_endpoint' => $hidden_endpoint,
523
+							'args'            => $this->_get_delete_query_params($model, $version),
524
+						),
525
+					)
526
+				);
527
+			}
528
+			foreach ($model->relation_settings() as $relation_name => $relation_obj) {
529
+				$related_route = EED_Core_Rest_Api::get_relation_route_via(
530
+					$model,
531
+					'(?P<id>[^\/]+)',
532
+					$relation_obj
533
+				);
534
+				$model_routes[ $related_route ] = array(
535
+					array(
536
+						'callback'        => array(
537
+							'EventEspresso\core\libraries\rest_api\controllers\model\Read',
538
+							'handleRequestGetRelated',
539
+						),
540
+						'callback_args'   => array($version, $model_name, $relation_name),
541
+						'methods'         => WP_REST_Server::READABLE,
542
+						'hidden_endpoint' => $hidden_endpoint,
543
+						'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
544
+					),
545
+				);
546
+
547
+				$related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)';
548
+				$model_routes[ $related_write_route ] = array(
549
+					array(
550
+						'callback'        => array(
551
+							'EventEspresso\core\libraries\rest_api\controllers\model\Write',
552
+							'handleRequestAddRelation',
553
+						),
554
+						'callback_args'   => array($version, $model_name, $relation_name),
555
+						'methods'         => WP_REST_Server::EDITABLE,
556
+						'hidden_endpoint' => $hidden_endpoint,
557
+						'args'            => $this->_get_add_relation_query_params($model, $relation_obj->get_other_model(), $version)
558
+					),
559
+					array(
560
+						'callback'        => array(
561
+							'EventEspresso\core\libraries\rest_api\controllers\model\Write',
562
+							'handleRequestRemoveRelation',
563
+						),
564
+						'callback_args'   => array($version, $model_name, $relation_name),
565
+						'methods'         => WP_REST_Server::DELETABLE,
566
+						'hidden_endpoint' => $hidden_endpoint,
567
+						'args'            => array()
568
+					),
569
+				);
570
+			}
571
+		}
572
+		return $model_routes;
573
+	}
574
+
575
+
576
+	/**
577
+	 * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
578
+	 * excluding the preceding slash.
579
+	 * Eg you pass get_plural_route_to('Event') = 'events'
580
+	 *
581
+	 * @param EEM_Base $model
582
+	 * @return string
583
+	 */
584
+	public static function get_collection_route(EEM_Base $model)
585
+	{
586
+		return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
587
+	}
588
+
589
+
590
+	/**
591
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
592
+	 * excluding the preceding slash.
593
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
594
+	 *
595
+	 * @param EEM_Base $model eg Event or Venue
596
+	 * @param string   $id
597
+	 * @return string
598
+	 */
599
+	public static function get_entity_route($model, $id)
600
+	{
601
+		return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id;
602
+	}
603
+
604
+
605
+	/**
606
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
607
+	 * excluding the preceding slash.
608
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
609
+	 *
610
+	 * @param EEM_Base               $model eg Event or Venue
611
+	 * @param string                 $id
612
+	 * @param EE_Model_Relation_Base $relation_obj
613
+	 * @return string
614
+	 */
615
+	public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
616
+	{
617
+		$related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
618
+			$relation_obj->get_other_model()->get_this_model_name(),
619
+			$relation_obj
620
+		);
621
+		return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
622
+	}
623
+
624
+
625
+	/**
626
+	 * Adds onto the $relative_route the EE4 REST API versioned namespace.
627
+	 * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
628
+	 *
629
+	 * @param string $relative_route
630
+	 * @param string $version
631
+	 * @return string
632
+	 */
633
+	public static function get_versioned_route_to($relative_route, $version = '4.8.36')
634
+	{
635
+		return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
636
+	}
637
+
638
+
639
+	/**
640
+	 * Adds all the RPC-style routes (remote procedure call-like routes, ie
641
+	 * routes that don't conform to the traditional REST CRUD-style).
642
+	 *
643
+	 * @deprecated since 4.9.1
644
+	 */
645
+	protected function _register_rpc_routes()
646
+	{
647
+		$routes = array();
648
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
649
+			$routes[ self::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version(
650
+				$version,
651
+				$hidden_endpoint
652
+			);
653
+		}
654
+		return $routes;
655
+	}
656
+
657
+
658
+	/**
659
+	 * @param string  $version
660
+	 * @param boolean $hidden_endpoint
661
+	 * @return array
662
+	 */
663
+	protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
664
+	{
665
+		$this_versions_routes = array();
666
+		// checkin endpoint
667
+		$this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
668
+			array(
669
+				'callback'        => array(
670
+					'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
671
+					'handleRequestToggleCheckin',
672
+				),
673
+				'methods'         => WP_REST_Server::CREATABLE,
674
+				'hidden_endpoint' => $hidden_endpoint,
675
+				'args'            => array(
676
+					'force' => array(
677
+						'required'    => false,
678
+						'default'     => false,
679
+						'description' => __(
680
+						// @codingStandardsIgnoreStart
681
+							'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
682
+							// @codingStandardsIgnoreEnd
683
+							'event_espresso'
684
+						),
685
+					),
686
+				),
687
+				'callback_args'   => array($version),
688
+			),
689
+		);
690
+		return apply_filters(
691
+			'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
692
+			$this_versions_routes,
693
+			$version,
694
+			$hidden_endpoint
695
+		);
696
+	}
697
+
698
+
699
+	/**
700
+	 * Gets the query params that can be used when request one or many
701
+	 *
702
+	 * @param EEM_Base $model
703
+	 * @param string   $version
704
+	 * @return array
705
+	 */
706
+	protected function _get_response_selection_query_params(\EEM_Base $model, $version, $single_only = false)
707
+	{
708
+		$query_params = array(
709
+			'include'   => array(
710
+				'required' => false,
711
+				'default'  => '*',
712
+				'type'     => 'string',
713
+			),
714
+			'calculate' => array(
715
+				'required'          => false,
716
+				'default'           => '',
717
+				'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
718
+				'type'              => 'string',
719
+				// because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
720
+				// freaks out. We'll just validate this argument while handling the request
721
+				'validate_callback' => null,
722
+				'sanitize_callback' => null,
723
+			),
724
+			'password' => array(
725
+				'required' => false,
726
+				'default' => '',
727
+				'type' => 'string'
728
+			)
729
+		);
730
+		return apply_filters(
731
+			'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
732
+			$query_params,
733
+			$model,
734
+			$version
735
+		);
736
+	}
737
+
738
+
739
+	/**
740
+	 * Gets the parameters acceptable for delete requests
741
+	 *
742
+	 * @param \EEM_Base $model
743
+	 * @param string    $version
744
+	 * @return array
745
+	 */
746
+	protected function _get_delete_query_params(\EEM_Base $model, $version)
747
+	{
748
+		$params_for_delete = array(
749
+			'allow_blocking' => array(
750
+				'required' => false,
751
+				'default'  => true,
752
+				'type'     => 'boolean',
753
+			),
754
+		);
755
+		$params_for_delete['force'] = array(
756
+			'required' => false,
757
+			'default'  => false,
758
+			'type'     => 'boolean',
759
+		);
760
+		return apply_filters(
761
+			'FHEE__EED_Core_Rest_Api___get_delete_query_params',
762
+			$params_for_delete,
763
+			$model,
764
+			$version
765
+		);
766
+	}
767
+
768
+	protected function _get_add_relation_query_params(\EEM_Base $source_model, \EEM_Base $related_model, $version)
769
+	{
770
+		// if they're related through a HABTM relation, check for any non-FKs
771
+		$all_relation_settings = $source_model->relation_settings();
772
+		$relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ];
773
+		$params = array();
774
+		if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) {
775
+			foreach ($relation_settings->getNonKeyFields() as $field) {
776
+				/* @var $field EE_Model_Field_Base */
777
+				$params[ $field->get_name() ] = array(
778
+					'required' => ! $field->is_nullable(),
779
+					'default' => ModelDataTranslator::prepareFieldValueForJson($field, $field->get_default_value(), $version),
780
+					'type' => $field->getSchemaType(),
781
+					'validate_callbaack' => null,
782
+					'sanitize_callback' => null
783
+				);
784
+			}
785
+		}
786
+		return $params;
787
+	}
788
+
789
+
790
+	/**
791
+	 * Gets info about reading query params that are acceptable
792
+	 *
793
+	 * @param \EEM_Base $model eg 'Event' or 'Venue'
794
+	 * @param  string   $version
795
+	 * @return array    describing the args acceptable when querying this model
796
+	 * @throws EE_Error
797
+	 */
798
+	protected function _get_read_query_params(\EEM_Base $model, $version)
799
+	{
800
+		$default_orderby = array();
801
+		foreach ($model->get_combined_primary_key_fields() as $key_field) {
802
+			$default_orderby[ $key_field->get_name() ] = 'ASC';
803
+		}
804
+		return array_merge(
805
+			$this->_get_response_selection_query_params($model, $version),
806
+			array(
807
+				'where'    => array(
808
+					'required'          => false,
809
+					'default'           => array(),
810
+					'type'              => 'object',
811
+					// because we accept an almost infinite list of possible where conditions, WP
812
+					// core validation and sanitization freaks out. We'll just validate this argument
813
+					// while handling the request
814
+					'validate_callback' => null,
815
+					'sanitize_callback' => null,
816
+				),
817
+				'limit'    => array(
818
+					'required'          => false,
819
+					'default'           => EED_Core_Rest_Api::get_default_query_limit(),
820
+					'type'              => array(
821
+						'array',
822
+						'string',
823
+						'integer',
824
+					),
825
+					// because we accept a variety of types, WP core validation and sanitization
826
+					// freaks out. We'll just validate this argument while handling the request
827
+					'validate_callback' => null,
828
+					'sanitize_callback' => null,
829
+				),
830
+				'order_by' => array(
831
+					'required'          => false,
832
+					'default'           => $default_orderby,
833
+					'type'              => array(
834
+						'object',
835
+						'string',
836
+					),// because we accept a variety of types, WP core validation and sanitization
837
+					// freaks out. We'll just validate this argument while handling the request
838
+					'validate_callback' => null,
839
+					'sanitize_callback' => null,
840
+				),
841
+				'group_by' => array(
842
+					'required'          => false,
843
+					'default'           => null,
844
+					'type'              => array(
845
+						'object',
846
+						'string',
847
+					),
848
+					// because we accept  an almost infinite list of possible groupings,
849
+					// WP core validation and sanitization
850
+					// freaks out. We'll just validate this argument while handling the request
851
+					'validate_callback' => null,
852
+					'sanitize_callback' => null,
853
+				),
854
+				'having'   => array(
855
+					'required'          => false,
856
+					'default'           => null,
857
+					'type'              => 'object',
858
+					// because we accept an almost infinite list of possible where conditions, WP
859
+					// core validation and sanitization freaks out. We'll just validate this argument
860
+					// while handling the request
861
+					'validate_callback' => null,
862
+					'sanitize_callback' => null,
863
+				),
864
+				'caps'     => array(
865
+					'required' => false,
866
+					'default'  => EEM_Base::caps_read,
867
+					'type'     => 'string',
868
+					'enum'     => array(
869
+						EEM_Base::caps_read,
870
+						EEM_Base::caps_read_admin,
871
+						EEM_Base::caps_edit,
872
+						EEM_Base::caps_delete,
873
+					),
874
+				),
875
+			)
876
+		);
877
+	}
878
+
879
+
880
+	/**
881
+	 * Gets parameter information for a model regarding writing data
882
+	 *
883
+	 * @param string           $model_name
884
+	 * @param ModelVersionInfo $model_version_info
885
+	 * @param boolean          $create                                       whether this is for request to create (in
886
+	 *                                                                       which case we need all required params) or
887
+	 *                                                                       just to update (in which case we don't
888
+	 *                                                                       need those on every request)
889
+	 * @return array
890
+	 */
891
+	protected function _get_write_params(
892
+		$model_name,
893
+		ModelVersionInfo $model_version_info,
894
+		$create = false
895
+	) {
896
+		$model = EE_Registry::instance()->load_model($model_name);
897
+		$fields = $model_version_info->fieldsOnModelInThisVersion($model);
898
+		$args_info = array();
899
+		foreach ($fields as $field_name => $field_obj) {
900
+			if ($field_obj->is_auto_increment()) {
901
+				// totally ignore auto increment IDs
902
+				continue;
903
+			}
904
+			$arg_info = $field_obj->getSchema();
905
+			$required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
906
+			$arg_info['required'] = $required;
907
+			// remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
908
+			unset($arg_info['readonly']);
909
+			$schema_properties = $field_obj->getSchemaProperties();
910
+			if (isset($schema_properties['raw'])
911
+				&& $field_obj->getSchemaType() === 'object'
912
+			) {
913
+				// if there's a "raw" form of this argument, use those properties instead
914
+				$arg_info = array_replace(
915
+					$arg_info,
916
+					$schema_properties['raw']
917
+				);
918
+			}
919
+			$arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
920
+				$field_obj,
921
+				$field_obj->get_default_value(),
922
+				$model_version_info->requestedVersion()
923
+			);
924
+			// we do our own validation and sanitization within the controller
925
+			if (function_exists('rest_validate_value_from_schema')) {
926
+				$sanitize_callback = array(
927
+					'EED_Core_Rest_Api',
928
+					'default_sanitize_callback',
929
+				);
930
+			} else {
931
+				$sanitize_callback = null;
932
+			}
933
+			$arg_info['sanitize_callback'] = $sanitize_callback;
934
+			$args_info[ $field_name ] = $arg_info;
935
+			if ($field_obj instanceof EE_Datetime_Field) {
936
+				$gmt_arg_info = $arg_info;
937
+				$gmt_arg_info['description'] = sprintf(
938
+					esc_html__(
939
+						'%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
940
+						'event_espresso'
941
+					),
942
+					$field_obj->get_nicename(),
943
+					$field_name
944
+				);
945
+				$args_info[ $field_name . '_gmt' ] = $gmt_arg_info;
946
+			}
947
+		}
948
+		return $args_info;
949
+	}
950
+
951
+
952
+	/**
953
+	 * Replacement for WP API's 'rest_parse_request_arg'.
954
+	 * If the value is blank but not required, don't bother validating it.
955
+	 * Also, it uses our email validation instead of WP API's default.
956
+	 *
957
+	 * @param                 $value
958
+	 * @param WP_REST_Request $request
959
+	 * @param                 $param
960
+	 * @return bool|true|WP_Error
961
+	 * @throws InvalidArgumentException
962
+	 * @throws InvalidInterfaceException
963
+	 * @throws InvalidDataTypeException
964
+	 */
965
+	public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
966
+	{
967
+		$attributes = $request->get_attributes();
968
+		if (! isset($attributes['args'][ $param ])
969
+			|| ! is_array($attributes['args'][ $param ])) {
970
+			$validation_result = true;
971
+		} else {
972
+			$args = $attributes['args'][ $param ];
973
+			if ((
974
+					$value === ''
975
+					|| $value === null
976
+				)
977
+				&& (! isset($args['required'])
978
+					|| $args['required'] === false
979
+				)
980
+			) {
981
+				// not required and not provided? that's cool
982
+				$validation_result = true;
983
+			} elseif (isset($args['format'])
984
+					  && $args['format'] === 'email'
985
+			) {
986
+				$validation_result = true;
987
+				if (! self::_validate_email($value)) {
988
+					$validation_result = new WP_Error(
989
+						'rest_invalid_param',
990
+						esc_html__(
991
+							'The email address is not valid or does not exist.',
992
+							'event_espresso'
993
+						)
994
+					);
995
+				}
996
+			} else {
997
+				$validation_result = rest_validate_value_from_schema($value, $args, $param);
998
+			}
999
+		}
1000
+		if (is_wp_error($validation_result)) {
1001
+			return $validation_result;
1002
+		}
1003
+		return rest_sanitize_request_arg($value, $request, $param);
1004
+	}
1005
+
1006
+
1007
+	/**
1008
+	 * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
1009
+	 *
1010
+	 * @param $email
1011
+	 * @return bool
1012
+	 * @throws InvalidArgumentException
1013
+	 * @throws InvalidInterfaceException
1014
+	 * @throws InvalidDataTypeException
1015
+	 */
1016
+	protected static function _validate_email($email)
1017
+	{
1018
+		try {
1019
+			EmailAddressFactory::create($email);
1020
+			return true;
1021
+		} catch (EmailValidationException $e) {
1022
+			return false;
1023
+		}
1024
+	}
1025
+
1026
+
1027
+	/**
1028
+	 * Gets routes for the config
1029
+	 *
1030
+	 * @return array @see _register_model_routes
1031
+	 * @deprecated since version 4.9.1
1032
+	 */
1033
+	protected function _register_config_routes()
1034
+	{
1035
+		$config_routes = array();
1036
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1037
+			$config_routes[ self::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version(
1038
+				$version,
1039
+				$hidden_endpoint
1040
+			);
1041
+		}
1042
+		return $config_routes;
1043
+	}
1044
+
1045
+
1046
+	/**
1047
+	 * Gets routes for the config for the specified version
1048
+	 *
1049
+	 * @param string  $version
1050
+	 * @param boolean $hidden_endpoint
1051
+	 * @return array
1052
+	 */
1053
+	protected function _get_config_route_data_for_version($version, $hidden_endpoint)
1054
+	{
1055
+		return array(
1056
+			'config'    => array(
1057
+				array(
1058
+					'callback'        => array(
1059
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1060
+						'handleRequest',
1061
+					),
1062
+					'methods'         => WP_REST_Server::READABLE,
1063
+					'hidden_endpoint' => $hidden_endpoint,
1064
+					'callback_args'   => array($version),
1065
+				),
1066
+			),
1067
+			'site_info' => array(
1068
+				array(
1069
+					'callback'        => array(
1070
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1071
+						'handleRequestSiteInfo',
1072
+					),
1073
+					'methods'         => WP_REST_Server::READABLE,
1074
+					'hidden_endpoint' => $hidden_endpoint,
1075
+					'callback_args'   => array($version),
1076
+				),
1077
+			),
1078
+		);
1079
+	}
1080
+
1081
+
1082
+	/**
1083
+	 * Gets the meta info routes
1084
+	 *
1085
+	 * @return array @see _register_model_routes
1086
+	 * @deprecated since version 4.9.1
1087
+	 */
1088
+	protected function _register_meta_routes()
1089
+	{
1090
+		$meta_routes = array();
1091
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1092
+			$meta_routes[ self::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version(
1093
+				$version,
1094
+				$hidden_endpoint
1095
+			);
1096
+		}
1097
+		return $meta_routes;
1098
+	}
1099
+
1100
+
1101
+	/**
1102
+	 * @param string  $version
1103
+	 * @param boolean $hidden_endpoint
1104
+	 * @return array
1105
+	 */
1106
+	protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1107
+	{
1108
+		return array(
1109
+			'resources' => array(
1110
+				array(
1111
+					'callback'        => array(
1112
+						'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1113
+						'handleRequestModelsMeta',
1114
+					),
1115
+					'methods'         => WP_REST_Server::READABLE,
1116
+					'hidden_endpoint' => $hidden_endpoint,
1117
+					'callback_args'   => array($version),
1118
+				),
1119
+			),
1120
+		);
1121
+	}
1122
+
1123
+
1124
+	/**
1125
+	 * Tries to hide old 4.6 endpoints from the
1126
+	 *
1127
+	 * @param array $route_data
1128
+	 * @return array
1129
+	 * @throws \EE_Error
1130
+	 */
1131
+	public static function hide_old_endpoints($route_data)
1132
+	{
1133
+		// allow API clients to override which endpoints get hidden, in case
1134
+		// they want to discover particular endpoints
1135
+		// also, we don't have access to the request so we have to just grab it from the superglobal
1136
+		$force_show_ee_namespace = ltrim(
1137
+			EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1138
+			'/'
1139
+		);
1140
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1141
+			foreach ($relative_urls as $resource_name => $endpoints) {
1142
+				foreach ($endpoints as $key => $endpoint) {
1143
+					// skip schema and other route options
1144
+					if (! is_numeric($key)) {
1145
+						continue;
1146
+					}
1147
+					// by default, hide "hidden_endpoint"s, unless the request indicates
1148
+					// to $force_show_ee_namespace, in which case only show that one
1149
+					// namespace's endpoints (and hide all others)
1150
+					if (($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1151
+						|| ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1152
+					) {
1153
+						$full_route = '/' . ltrim($namespace, '/');
1154
+						$full_route .= '/' . ltrim($resource_name, '/');
1155
+						unset($route_data[ $full_route ]);
1156
+					}
1157
+				}
1158
+			}
1159
+		}
1160
+		return $route_data;
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * Returns an array describing which versions of core support serving requests for.
1166
+	 * Keys are core versions' major and minor version, and values are the
1167
+	 * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1168
+	 * data by just removing a few models and fields from the responses. However, 4.15 might remove
1169
+	 * the answers table entirely, in which case it would be very difficult for
1170
+	 * it to serve 4.6-style responses.
1171
+	 * Versions of core that are missing from this array are unknowns.
1172
+	 * previous ver
1173
+	 *
1174
+	 * @return array
1175
+	 */
1176
+	public static function version_compatibilities()
1177
+	{
1178
+		return apply_filters(
1179
+			'FHEE__EED_Core_REST_API__version_compatibilities',
1180
+			array(
1181
+				'4.8.29' => '4.8.29',
1182
+				'4.8.33' => '4.8.29',
1183
+				'4.8.34' => '4.8.29',
1184
+				'4.8.36' => '4.8.29',
1185
+			)
1186
+		);
1187
+	}
1188
+
1189
+
1190
+	/**
1191
+	 * Gets the latest API version served. Eg if there
1192
+	 * are two versions served of the API, 4.8.29 and 4.8.32, and
1193
+	 * we are on core version 4.8.34, it will return the string "4.8.32"
1194
+	 *
1195
+	 * @return string
1196
+	 */
1197
+	public static function latest_rest_api_version()
1198
+	{
1199
+		$versions_served = \EED_Core_Rest_Api::versions_served();
1200
+		$versions_served_keys = array_keys($versions_served);
1201
+		return end($versions_served_keys);
1202
+	}
1203
+
1204
+
1205
+	/**
1206
+	 * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1207
+	 * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1208
+	 * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1209
+	 * We also indicate whether or not this version should be put in the index or not
1210
+	 *
1211
+	 * @return array keys are API version numbers (just major and minor numbers), and values
1212
+	 * are whether or not they should be hidden
1213
+	 */
1214
+	public static function versions_served()
1215
+	{
1216
+		$versions_served = array();
1217
+		$possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1218
+		$lowest_compatible_version = end($possibly_served_versions);
1219
+		reset($possibly_served_versions);
1220
+		$versions_served_historically = array_keys($possibly_served_versions);
1221
+		$latest_version = end($versions_served_historically);
1222
+		reset($versions_served_historically);
1223
+		// for each version of core we have ever served:
1224
+		foreach ($versions_served_historically as $key_versioned_endpoint) {
1225
+			// if it's not above the current core version, and it's compatible with the current version of core
1226
+			if ($key_versioned_endpoint === $latest_version) {
1227
+				// don't hide the latest version in the index
1228
+				$versions_served[ $key_versioned_endpoint ] = false;
1229
+			} elseif ($key_versioned_endpoint >= $lowest_compatible_version
1230
+				&& $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1231
+			) {
1232
+				// include, but hide, previous versions which are still supported
1233
+				$versions_served[ $key_versioned_endpoint ] = true;
1234
+			} elseif (apply_filters(
1235
+				'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1236
+				false,
1237
+				$possibly_served_versions
1238
+			)) {
1239
+				// if a version is no longer supported, don't include it in index or list of versions served
1240
+				$versions_served[ $key_versioned_endpoint ] = true;
1241
+			}
1242
+		}
1243
+		return $versions_served;
1244
+	}
1245
+
1246
+
1247
+	/**
1248
+	 * Gets the major and minor version of EE core's version string
1249
+	 *
1250
+	 * @return string
1251
+	 */
1252
+	public static function core_version()
1253
+	{
1254
+		return apply_filters(
1255
+			'FHEE__EED_Core_REST_API__core_version',
1256
+			implode(
1257
+				'.',
1258
+				array_slice(
1259
+					explode(
1260
+						'.',
1261
+						espresso_version()
1262
+					),
1263
+					0,
1264
+					3
1265
+				)
1266
+			)
1267
+		);
1268
+	}
1269
+
1270
+
1271
+	/**
1272
+	 * Gets the default limit that should be used when querying for resources
1273
+	 *
1274
+	 * @return int
1275
+	 */
1276
+	public static function get_default_query_limit()
1277
+	{
1278
+		// we actually don't use a const because we want folks to always use
1279
+		// this method, not the const directly
1280
+		return apply_filters(
1281
+			'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1282
+			50
1283
+		);
1284
+	}
1285
+
1286
+
1287
+	/**
1288
+	 *
1289
+	 * @param string $version api version string (i.e. '4.8.36')
1290
+	 * @return array
1291
+	 */
1292
+	public static function getCollectionRoutesIndexedByModelName($version = '')
1293
+	{
1294
+		$version = empty($version) ? self::latest_rest_api_version() : $version;
1295
+		$model_names = self::model_names_with_plural_routes($version);
1296
+		$collection_routes = array();
1297
+		foreach ($model_names as $model_name => $model_class_name) {
1298
+			$collection_routes[ strtolower($model_name) ] = '/' . self::ee_api_namespace . $version . '/'
1299
+															. EEH_Inflector::pluralize_and_lower($model_name);
1300
+		}
1301
+		return $collection_routes;
1302
+	}
1303
+
1304
+
1305
+	/**
1306
+	 * Returns an array of primary key names indexed by model names.
1307
+	 * @param string $version
1308
+	 * @return array
1309
+	 */
1310
+	public static function getPrimaryKeyNamesIndexedByModelName($version = '')
1311
+	{
1312
+		$version = empty($version) ? self::latest_rest_api_version() : $version;
1313
+		$model_names = self::model_names_with_plural_routes($version);
1314
+		$primary_key_items = array();
1315
+		foreach ($model_names as $model_name => $model_class_name) {
1316
+			$primary_keys = $model_class_name::instance()->get_combined_primary_key_fields();
1317
+			foreach ($primary_keys as $primary_key_name => $primary_key_field) {
1318
+				if (count($primary_keys) > 1) {
1319
+					$primary_key_items[ strtolower($model_name) ][] = $primary_key_name;
1320
+				} else {
1321
+					$primary_key_items[ strtolower($model_name) ] = $primary_key_name;
1322
+				}
1323
+			}
1324
+		}
1325
+		return $primary_key_items;
1326
+	}
1327
+
1328
+	/**
1329
+	 * Determines the EE REST API debug mode is activated, or not.
1330
+	 * @since 4.9.76.p
1331
+	 * @return bool
1332
+	 */
1333
+	public static function debugMode()
1334
+	{
1335
+		static $debug_mode = null; // could be class prop
1336
+		if ($debug_mode === null) {
1337
+			$debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE;
1338
+		}
1339
+		return $debug_mode;
1340
+	}
1341
+
1342
+
1343
+
1344
+	/**
1345
+	 *    run - initial module setup
1346
+	 *
1347
+	 * @access    public
1348
+	 * @param  WP $WP
1349
+	 * @return    void
1350
+	 */
1351
+	public function run($WP)
1352
+	{
1353
+	}
1354 1354
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/model/Base.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
      */
50 50
     public function getModelVersionInfo()
51 51
     {
52
-        if (! $this->model_version_info) {
52
+        if ( ! $this->model_version_info) {
53 53
             throw new EE_Error(
54 54
                 sprintf(
55 55
                     __(
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
      */
95 95
     protected function validateModel($model_name)
96 96
     {
97
-        if (! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
97
+        if ( ! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
98 98
             throw new RestException(
99 99
                 'endpoint_parsing_error',
100 100
                 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
 class Base extends Controller_Base
19 19
 {
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
-                    __(
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
+					__(
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
-                    __(
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
+					__(
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.
ui/blocks/event-attendees.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -11,29 +11,29 @@
 block discarded – undo
11 11
 <div id="ee-block-event-attendees" class="ee-core-blocks event-espresso-blocks event-attendees">
12 12
     <ul>
13 13
         <?php
14
-        foreach ($attendees as $attendee) {
15
-            $gravatar = $attributes['showGravatar']
16
-                ? get_avatar_url(
17
-                    $attendee->email(),
18
-                    array(
19
-                        'width'   => $attributes['avatarSize'],
20
-                        'height'  => $attributes['avatarSize']
21
-                    )
22
-                )
23
-                : '';
24
-            $gravatar_class = $attributes['avatarClass']
25
-                ? $attributes['avatarClass'] . ' contact-avatar-img avatar'
26
-                : 'contact-avatar-img avatar';
27
-            $gravatar = $gravatar !== ''
28
-                ? '<div class="contact-image-wrap-div">'
29
-                    . '<img class="' . $gravatar_class . '"'
30
-                    . ' width="' . $attributes['avatarSize'] . '"'
31
-                    . ' height="' . $attributes['avatarSize'] . '"'
32
-                    . ' src="' . $gravatar . '" alt="contact avatar">'
33
-                    . '</div>'
34
-                : '';
35
-            echo "<li>{$gravatar}<span>{$attendee->full_name()}</span>";
36
-        }
37
-        ?>
14
+		foreach ($attendees as $attendee) {
15
+			$gravatar = $attributes['showGravatar']
16
+				? get_avatar_url(
17
+					$attendee->email(),
18
+					array(
19
+						'width'   => $attributes['avatarSize'],
20
+						'height'  => $attributes['avatarSize']
21
+					)
22
+				)
23
+				: '';
24
+			$gravatar_class = $attributes['avatarClass']
25
+				? $attributes['avatarClass'] . ' contact-avatar-img avatar'
26
+				: 'contact-avatar-img avatar';
27
+			$gravatar = $gravatar !== ''
28
+				? '<div class="contact-image-wrap-div">'
29
+					. '<img class="' . $gravatar_class . '"'
30
+					. ' width="' . $attributes['avatarSize'] . '"'
31
+					. ' height="' . $attributes['avatarSize'] . '"'
32
+					. ' src="' . $gravatar . '" alt="contact avatar">'
33
+					. '</div>'
34
+				: '';
35
+			echo "<li>{$gravatar}<span>{$attendee->full_name()}</span>";
36
+		}
37
+		?>
38 38
     </ul>
39 39
 </div>
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Attendee.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -17,43 +17,43 @@
 block discarded – undo
17 17
 class Attendee extends AttendeeCalculationsBase
18 18
 {
19 19
 
20
-    /**
21
-     * @param array                  $wpdb_row
22
-     * @param WP_REST_Request        $request
23
-     * @param AttendeeControllerBase $controller
24
-     * @since 4.9.66.p
25
-     * @return string
26
-     */
27
-    public function userAvatar(array $wpdb_row, WP_REST_Request $request, AttendeeControllerBase $controller)
28
-    {
29
-        if (is_array($wpdb_row) && isset($wpdb_row['Attendee_Meta.ATT_email'])) {
30
-            $email_address = $wpdb_row['Attendee_Meta.ATT_email'];
31
-        }
32
-        if (empty($email_address)) {
33
-            return get_avatar_url('', array('force_default' => true));
34
-        }
35
-        $avatar = get_avatar_url($email_address);
36
-        return $avatar ? $avatar : '';
37
-    }
20
+	/**
21
+	 * @param array                  $wpdb_row
22
+	 * @param WP_REST_Request        $request
23
+	 * @param AttendeeControllerBase $controller
24
+	 * @since 4.9.66.p
25
+	 * @return string
26
+	 */
27
+	public function userAvatar(array $wpdb_row, WP_REST_Request $request, AttendeeControllerBase $controller)
28
+	{
29
+		if (is_array($wpdb_row) && isset($wpdb_row['Attendee_Meta.ATT_email'])) {
30
+			$email_address = $wpdb_row['Attendee_Meta.ATT_email'];
31
+		}
32
+		if (empty($email_address)) {
33
+			return get_avatar_url('', array('force_default' => true));
34
+		}
35
+		$avatar = get_avatar_url($email_address);
36
+		return $avatar ? $avatar : '';
37
+	}
38 38
 
39 39
 
40
-    /**
41
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
42
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
43
-     *
44
-     * @since 4.9.68.p
45
-     * @return array
46
-     */
47
-    public function schemaForCalculations()
48
-    {
49
-        return array(
50
-            'user_avatar' => array(
51
-                'description' => esc_html__(
52
-                    'The avatar url for the attendee (if available).',
53
-                    'event_espresso'
54
-                ),
55
-                'type'        => 'string',
56
-            ),
57
-        );
58
-    }
40
+	/**
41
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
42
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
43
+	 *
44
+	 * @since 4.9.68.p
45
+	 * @return array
46
+	 */
47
+	public function schemaForCalculations()
48
+	{
49
+		return array(
50
+			'user_avatar' => array(
51
+				'description' => esc_html__(
52
+					'The avatar url for the attendee (if available).',
53
+					'event_espresso'
54
+				),
55
+				'type'        => 'string',
56
+			),
57
+		);
58
+	}
59 59
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Export.class.php 2 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
     /**
70 70
      * @Export Event Espresso data - routes export requests
71 71
      * @access public
72
-     * @return void | bool
72
+     * @return false|null | bool
73 73
      */
74 74
     public function export()
75 75
     {
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
      * @access    private
751 751
      * @param array $models_to_export keys are model names (eg 'Event', 'Attendee', etc.) and values are arrays of
752 752
      *                                query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
753
-     * @return array on success, FALSE on fail
753
+     * @return boolean on success, FALSE on fail
754 754
      */
755 755
     private function _get_export_data_for_models($models_to_export = array())
756 756
     {
Please login to merge, or discard this patch.
Indentation   +773 added lines, -773 removed lines patch added patch discarded remove patch
@@ -16,777 +16,777 @@
 block discarded – undo
16 16
 class EE_Export
17 17
 {
18 18
 
19
-    const option_prefix = 'ee_report_job_';
20
-
21
-
22
-    // instance of the EE_Export object
23
-    private static $_instance = null;
24
-
25
-    // instance of the EE_CSV object
26
-    /**
27
-     *
28
-     * @var EE_CSV
29
-     */
30
-    public $EE_CSV = null;
31
-
32
-
33
-    private $_req_data = array();
34
-
35
-
36
-    /**
37
-     *        private constructor to prevent direct creation
38
-     *
39
-     * @Constructor
40
-     * @access private
41
-     * @param array $request_data
42
-     */
43
-    private function __construct($request_data = array())
44
-    {
45
-        $this->_req_data = $request_data;
46
-        $this->today = date("Y-m-d", time());
47
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
48
-        $this->EE_CSV = EE_CSV::instance();
49
-    }
50
-
51
-
52
-    /**
53
-     *        @ singleton method used to instantiate class object
54
-     *        @ access public
55
-     *
56
-     * @param array $request_data
57
-     * @return \EE_Export
58
-     */
59
-    public static function instance($request_data = array())
60
-    {
61
-        // check if class object is instantiated
62
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Export)) {
63
-            self::$_instance = new self($request_data);
64
-        }
65
-        return self::$_instance;
66
-    }
67
-
68
-
69
-    /**
70
-     * @Export Event Espresso data - routes export requests
71
-     * @access public
72
-     * @return void | bool
73
-     */
74
-    public function export()
75
-    {
76
-        // in case of bulk exports, the "actual" action will be in action2, but first check regular action for "export" keyword
77
-        if (isset($this->_req_data['action']) && strpos($this->_req_data['action'], 'export') === false) {
78
-            // check if action2 has export action
79
-            if (isset($this->_req_data['action2']) && strpos($this->_req_data['action2'], 'export') !== false) {
80
-                // whoop! there it is!
81
-                $this->_req_data['action'] = $this->_req_data['action2'];
82
-            }
83
-        }
84
-
85
-        $this->_req_data['export'] = isset($this->_req_data['export']) ? $this->_req_data['export'] : '';
86
-
87
-        switch ($this->_req_data['export']) {
88
-            case 'report':
89
-                switch ($this->_req_data['action']) {
90
-                    case "event":
91
-                    case "export_events":
92
-                    case 'all_event_data':
93
-                        $this->export_all_event_data();
94
-                        break;
95
-
96
-                    case 'registrations_report_for_event':
97
-                        $this->report_registrations_for_event($this->_req_data['EVT_ID']);
98
-                        break;
99
-
100
-                    case 'attendees':
101
-                        $this->export_attendees();
102
-                        break;
103
-
104
-                    case 'categories':
105
-                        $this->export_categories();
106
-                        break;
107
-
108
-                    default:
109
-                        EE_Error::add_error(
110
-                            __('An error occurred! The requested export report could not be found.', 'event_espresso'),
111
-                            __FILE__,
112
-                            __FUNCTION__,
113
-                            __LINE__
114
-                        );
115
-                        return false;
116
-                        break;
117
-                }
118
-                break; // end of switch export : report
119
-            default:
120
-                break;
121
-        } // end of switch export
122
-
123
-        exit;
124
-    }
125
-
126
-    /**
127
-     * Downloads a CSV file with all the columns, but no data. This should be used for importing
128
-     *
129
-     * @return null kills execution
130
-     */
131
-    public function export_sample()
132
-    {
133
-        $event = EEM_Event::instance()->get_one();
134
-        $this->_req_data['EVT_ID'] = $event->ID();
135
-        $this->export_all_event_data();
136
-    }
137
-
138
-
139
-    /**
140
-     * @Export data for ALL events
141
-     * @access public
142
-     * @return void
143
-     */
144
-    public function export_all_event_data()
145
-    {
146
-        // are any Event IDs set?
147
-        $event_query_params = array();
148
-        $related_models_query_params = array();
149
-        $related_through_reg_query_params = array();
150
-        $datetime_ticket_query_params = array();
151
-        $price_query_params = array();
152
-        $price_type_query_params = array();
153
-        $term_query_params = array();
154
-        $state_country_query_params = array();
155
-        $question_group_query_params = array();
156
-        $question_query_params = array();
157
-        if (isset($this->_req_data['EVT_ID'])) {
158
-            // do we have an array of IDs ?
159
-
160
-            if (is_array($this->_req_data['EVT_ID'])) {
161
-                $EVT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_ID']);
162
-                $value_to_equal = array('IN', $EVT_IDs);
163
-                $filename = 'events';
164
-            } else {
165
-                // generate regular where = clause
166
-                $EVT_ID = absint($this->_req_data['EVT_ID']);
167
-                $value_to_equal = $EVT_ID;
168
-                $event = EE_Registry::instance()->load_model('Event')->get_one_by_ID($EVT_ID);
169
-
170
-                $filename = 'event-' . ($event instanceof EE_Event ? $event->slug() : __('unknown', 'event_espresso'));
171
-            }
172
-            $event_query_params[0]['EVT_ID'] = $value_to_equal;
173
-            $related_models_query_params[0]['Event.EVT_ID'] = $value_to_equal;
174
-            $related_through_reg_query_params[0]['Registration.EVT_ID'] = $value_to_equal;
175
-            $datetime_ticket_query_params[0]['Datetime.EVT_ID'] = $value_to_equal;
176
-            $price_query_params[0]['Ticket.Datetime.EVT_ID'] = $value_to_equal;
177
-            $price_type_query_params[0]['Price.Ticket.Datetime.EVT_ID'] = $value_to_equal;
178
-            $term_query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $value_to_equal;
179
-            $state_country_query_params[0]['Venue.Event.EVT_ID'] = $value_to_equal;
180
-            $question_group_query_params[0]['Event.EVT_ID'] = $value_to_equal;
181
-            $question_query_params[0]['Question_Group.Event.EVT_ID'] = $value_to_equal;
182
-        } else {
183
-            $filename = 'all-events';
184
-        }
185
-
186
-
187
-        // array in the format:  table name =>  query where clause
188
-        $models_to_export = array(
189
-            'Event'                   => $event_query_params,
190
-            'Datetime'                => $related_models_query_params,
191
-            'Ticket_Template'         => $price_query_params,
192
-            'Ticket'                  => $datetime_ticket_query_params,
193
-            'Datetime_Ticket'         => $datetime_ticket_query_params,
194
-            'Price_Type'              => $price_type_query_params,
195
-            'Price'                   => $price_query_params,
196
-            'Ticket_Price'            => $price_query_params,
197
-            'Term'                    => $term_query_params,
198
-            'Term_Taxonomy'           => $related_models_query_params,
199
-            'Term_Relationship'       => $related_models_query_params, // model has NO primary key...
200
-            'Country'                 => $state_country_query_params,
201
-            'State'                   => $state_country_query_params,
202
-            'Venue'                   => $related_models_query_params,
203
-            'Event_Venue'             => $related_models_query_params,
204
-            'Question_Group'          => $question_group_query_params,
205
-            'Event_Question_Group'    => $question_group_query_params,
206
-            'Question'                => $question_query_params,
207
-            'Question_Group_Question' => $question_query_params,
208
-            // 'Transaction'=>$related_through_reg_query_params,
209
-            // 'Registration'=>$related_models_query_params,
210
-            // 'Attendee'=>$related_through_reg_query_params,
211
-            // 'Line_Item'=>
212
-
213
-        );
214
-
215
-        $model_data = $this->_get_export_data_for_models($models_to_export);
216
-
217
-        $filename = $this->generate_filename($filename);
218
-
219
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
220
-            EE_Error::add_error(
221
-                __(
222
-                    "'An error occurred and the Event details could not be exported from the database.'",
223
-                    "event_espresso"
224
-                ),
225
-                __FILE__,
226
-                __FUNCTION__,
227
-                __LINE__
228
-            );
229
-        }
230
-    }
231
-
232
-    public function report_attendees()
233
-    {
234
-        $attendee_rows = EEM_Attendee::instance()->get_all_wpdb_results(
235
-            array(
236
-                'force_join' => array('State', 'Country'),
237
-                'caps'       => EEM_Base::caps_read_admin,
238
-            )
239
-        );
240
-        $csv_data = array();
241
-        foreach ($attendee_rows as $attendee_row) {
242
-            $csv_row = array();
243
-            foreach (EEM_Attendee::instance()->field_settings() as $field_name => $field_obj) {
244
-                if ($field_name == 'STA_ID') {
245
-                    $state_name_field = EEM_State::instance()->field_settings_for('STA_name');
246
-                    $csv_row[ __('State', 'event_espresso') ] = $attendee_row[ $state_name_field->get_qualified_column(
247
-                    ) ];
248
-                } elseif ($field_name == 'CNT_ISO') {
249
-                    $country_name_field = EEM_Country::instance()->field_settings_for('CNT_name');
250
-                    $csv_row[ __(
251
-                        'Country',
252
-                        'event_espresso'
253
-                    ) ] = $attendee_row[ $country_name_field->get_qualified_column() ];
254
-                } else {
255
-                    $csv_row[ $field_obj->get_nicename() ] = $attendee_row[ $field_obj->get_qualified_column() ];
256
-                }
257
-            }
258
-            $csv_data[] = $csv_row;
259
-        }
260
-
261
-        $filename = $this->generate_filename('contact-list-report');
262
-
263
-        $handle = $this->EE_CSV->begin_sending_csv($filename);
264
-        $this->EE_CSV->write_data_array_to_csv($handle, $csv_data);
265
-        $this->EE_CSV->end_sending_csv($handle);
266
-    }
267
-
268
-
269
-    /**
270
-     * @Export data for ALL attendees
271
-     * @access public
272
-     * @return void
273
-     */
274
-    public function export_attendees()
275
-    {
276
-
277
-        $states_that_have_an_attendee = EEM_State::instance()->get_all(
278
-            array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
279
-        );
280
-        $countries_that_have_an_attendee = EEM_Country::instance()->get_all(
281
-            array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
282
-        );
283
-        // $states_to_export_query_params
284
-        $models_to_export = array(
285
-            'Country'  => array(array('CNT_ISO' => array('IN', array_keys($countries_that_have_an_attendee)))),
286
-            'State'    => array(array('STA_ID' => array('IN', array_keys($states_that_have_an_attendee)))),
287
-            'Attendee' => array(),
288
-        );
289
-
290
-
291
-        $model_data = $this->_get_export_data_for_models($models_to_export);
292
-        $filename = $this->generate_filename('all-attendees');
293
-
294
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
295
-            EE_Error::add_error(
296
-                __(
297
-                    'An error occurred and the Attendee data could not be exported from the database.',
298
-                    'event_espresso'
299
-                ),
300
-                __FILE__,
301
-                __FUNCTION__,
302
-                __LINE__
303
-            );
304
-        }
305
-    }
306
-
307
-    /**
308
-     * Shortcut for preparing a database result for display
309
-     *
310
-     * @param EEM_Base       $model
311
-     * @param string         $field_name
312
-     * @param string         $raw_db_value
313
-     * @param boolean|string $pretty_schema true to display pretty, a string to use a specific "Schema", or false to
314
-     *                                      NOT display pretty
315
-     * @return string
316
-     */
317
-    protected function _prepare_value_from_db_for_display($model, $field_name, $raw_db_value, $pretty_schema = true)
318
-    {
319
-        $field_obj = $model->field_settings_for($field_name);
320
-        $value_on_model_obj = $field_obj->prepare_for_set_from_db($raw_db_value);
321
-        if ($field_obj instanceof EE_Datetime_Field) {
322
-            $field_obj->set_date_format(
323
-                EE_CSV::instance()->get_date_format_for_csv($field_obj->get_date_format($pretty_schema)),
324
-                $pretty_schema
325
-            );
326
-            $field_obj->set_time_format(
327
-                EE_CSV::instance()->get_time_format_for_csv($field_obj->get_time_format($pretty_schema)),
328
-                $pretty_schema
329
-            );
330
-        }
331
-        if ($pretty_schema === true) {
332
-            return $field_obj->prepare_for_pretty_echoing($value_on_model_obj);
333
-        } elseif (is_string($pretty_schema)) {
334
-            return $field_obj->prepare_for_pretty_echoing($value_on_model_obj, $pretty_schema);
335
-        } else {
336
-            return $field_obj->prepare_for_get($value_on_model_obj);
337
-        }
338
-    }
339
-
340
-    /**
341
-     * Export a custom CSV of registration info including: A bunch of the reg fields, the time of the event, the price
342
-     * name, and the questions associated with the registrations
343
-     *
344
-     * @param int $event_id
345
-     */
346
-    public function report_registrations_for_event($event_id = null)
347
-    {
348
-        $reg_fields_to_include = array(
349
-            'TXN_ID',
350
-            'ATT_ID',
351
-            'REG_ID',
352
-            'REG_date',
353
-            'REG_code',
354
-            'REG_count',
355
-            'REG_final_price',
356
-
357
-        );
358
-        $att_fields_to_include = array(
359
-            'ATT_fname',
360
-            'ATT_lname',
361
-            'ATT_email',
362
-            'ATT_address',
363
-            'ATT_address2',
364
-            'ATT_city',
365
-            'STA_ID',
366
-            'CNT_ISO',
367
-            'ATT_zip',
368
-            'ATT_phone',
369
-        );
370
-
371
-        $registrations_csv_ready_array = array();
372
-        $reg_model = EE_Registry::instance()->load_model('Registration');
373
-        $query_params = apply_filters(
374
-            'FHEE__EE_Export__report_registration_for_event',
375
-            array(
376
-                array(
377
-                    'OR'                 => array(
378
-                        // don't include registrations from failed or abandoned transactions...
379
-                        'Transaction.STS_ID' => array(
380
-                            'NOT IN',
381
-                            array(EEM_Transaction::failed_status_code, EEM_Transaction::abandoned_status_code),
382
-                        ),
383
-                        // unless the registration is approved, in which case include it regardless of transaction status
384
-                        'STS_ID'             => EEM_Registration::status_id_approved,
385
-                    ),
386
-                    'Ticket.TKT_deleted' => array('IN', array(true, false)),
387
-                ),
388
-                'order_by'   => array('Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'),
389
-                'force_join' => array('Transaction', 'Ticket', 'Attendee'),
390
-                'caps'       => EEM_Base::caps_read_admin,
391
-            ),
392
-            $event_id
393
-        );
394
-        if ($event_id) {
395
-            $query_params[0]['EVT_ID'] = $event_id;
396
-        } else {
397
-            $query_params['force_join'][] = 'Event';
398
-        }
399
-        $registration_rows = $reg_model->get_all_wpdb_results($query_params);
400
-        // get all questions which relate to someone in this group
401
-        $registration_ids = array();
402
-        foreach ($registration_rows as $reg_row) {
403
-            $registration_ids[] = intval($reg_row['Registration.REG_ID']);
404
-        }
405
-        // EEM_Question::instance()->show_next_x_db_queries();
406
-        $questions_for_these_regs_rows = EEM_Question::instance()->get_all_wpdb_results(
407
-            array(array('Answer.REG_ID' => array('IN', $registration_ids)))
408
-        );
409
-        foreach ($registration_rows as $reg_row) {
410
-            if (is_array($reg_row)) {
411
-                $reg_csv_array = array();
412
-                if (! $event_id) {
413
-                    // get the event's name and Id
414
-                    $reg_csv_array[ __('Event', 'event_espresso') ] = sprintf(
415
-                        __('%1$s (%2$s)', 'event_espresso'),
416
-                        $this->_prepare_value_from_db_for_display(
417
-                            EEM_Event::instance(),
418
-                            'EVT_name',
419
-                            $reg_row['Event_CPT.post_title']
420
-                        ),
421
-                        $reg_row['Event_CPT.ID']
422
-                    );
423
-                }
424
-                $is_primary_reg = $reg_row['Registration.REG_count'] == '1' ? true : false;
425
-                /*@var $reg_row EE_Registration */
426
-                foreach ($reg_fields_to_include as $field_name) {
427
-                    $field = $reg_model->field_settings_for($field_name);
428
-                    if ($field_name == 'REG_final_price') {
429
-                        $value = $this->_prepare_value_from_db_for_display(
430
-                            $reg_model,
431
-                            $field_name,
432
-                            $reg_row['Registration.REG_final_price'],
433
-                            'localized_float'
434
-                        );
435
-                    } elseif ($field_name == 'REG_count') {
436
-                        $value = sprintf(
437
-                            __('%s of %s', 'event_espresso'),
438
-                            $this->_prepare_value_from_db_for_display(
439
-                                $reg_model,
440
-                                'REG_count',
441
-                                $reg_row['Registration.REG_count']
442
-                            ),
443
-                            $this->_prepare_value_from_db_for_display(
444
-                                $reg_model,
445
-                                'REG_group_size',
446
-                                $reg_row['Registration.REG_group_size']
447
-                            )
448
-                        );
449
-                    } elseif ($field_name == 'REG_date') {
450
-                        $value = $this->_prepare_value_from_db_for_display(
451
-                            $reg_model,
452
-                            $field_name,
453
-                            $reg_row['Registration.REG_date'],
454
-                            'no_html'
455
-                        );
456
-                    } else {
457
-                        $value = $this->_prepare_value_from_db_for_display(
458
-                            $reg_model,
459
-                            $field_name,
460
-                            $reg_row[ $field->get_qualified_column() ]
461
-                        );
462
-                    }
463
-                    $reg_csv_array[ $this->_get_column_name_for_field($field) ] = $value;
464
-                    if ($field_name == 'REG_final_price') {
465
-                        // add a column named Currency after the final price
466
-                        $reg_csv_array[ __("Currency", "event_espresso") ] = EE_Config::instance()->currency->code;
467
-                    }
468
-                }
469
-                // get pretty status
470
-                $stati = EEM_Status::instance()->localized_status(
471
-                    array(
472
-                        $reg_row['Registration.STS_ID']     => __('unknown', 'event_espresso'),
473
-                        $reg_row['TransactionTable.STS_ID'] => __('unknown', 'event_espresso'),
474
-                    ),
475
-                    false,
476
-                    'sentence'
477
-                );
478
-                $reg_csv_array[ __(
479
-                    "Registration Status",
480
-                    'event_espresso'
481
-                ) ] = $stati[ $reg_row['Registration.STS_ID'] ];
482
-                // get pretty trnasaction status
483
-                $reg_csv_array[ __(
484
-                    "Transaction Status",
485
-                    'event_espresso'
486
-                ) ] = $stati[ $reg_row['TransactionTable.STS_ID'] ];
487
-                $reg_csv_array[ __('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg
488
-                    ? $this->_prepare_value_from_db_for_display(
489
-                        EEM_Transaction::instance(),
490
-                        'TXN_total',
491
-                        $reg_row['TransactionTable.TXN_total'],
492
-                        'localized_float'
493
-                    ) : '0.00';
494
-                $reg_csv_array[ __('Amount Paid', 'event_espresso') ] = $is_primary_reg
495
-                    ? $this->_prepare_value_from_db_for_display(
496
-                        EEM_Transaction::instance(),
497
-                        'TXN_paid',
498
-                        $reg_row['TransactionTable.TXN_paid'],
499
-                        'localized_float'
500
-                    ) : '0.00';
501
-                $payment_methods = array();
502
-                $gateway_txn_ids_etc = array();
503
-                $payment_times = array();
504
-                if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) {
505
-                    $payments_info = EEM_Payment::instance()->get_all_wpdb_results(
506
-                        array(
507
-                            array(
508
-                                'TXN_ID' => $reg_row['TransactionTable.TXN_ID'],
509
-                                'STS_ID' => EEM_Payment::status_id_approved,
510
-                            ),
511
-                            'force_join' => array('Payment_Method'),
512
-                        ),
513
-                        ARRAY_A,
514
-                        'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time'
515
-                    );
516
-
517
-                    foreach ($payments_info as $payment_method_and_gateway_txn_id) {
518
-                        $payment_methods[] = isset($payment_method_and_gateway_txn_id['name'])
519
-                            ? $payment_method_and_gateway_txn_id['name'] : __('Unknown', 'event_espresso');
520
-                        $gateway_txn_ids_etc[] = isset($payment_method_and_gateway_txn_id['gateway_txn_id'])
521
-                            ? $payment_method_and_gateway_txn_id['gateway_txn_id'] : '';
522
-                        $payment_times[] = isset($payment_method_and_gateway_txn_id['payment_time'])
523
-                            ? $payment_method_and_gateway_txn_id['payment_time'] : '';
524
-                    }
525
-                }
526
-                $reg_csv_array[ __('Payment Date(s)', 'event_espresso') ] = implode(',', $payment_times);
527
-                $reg_csv_array[ __('Payment Method(s)', 'event_espresso') ] = implode(",", $payment_methods);
528
-                $reg_csv_array[ __('Gateway Transaction ID(s)', 'event_espresso') ] = implode(
529
-                    ',',
530
-                    $gateway_txn_ids_etc
531
-                );
532
-
533
-                // get whether or not the user has checked in
534
-                $reg_csv_array[ __("Check-Ins", "event_espresso") ] = $reg_model->count_related(
535
-                    $reg_row['Registration.REG_ID'],
536
-                    'Checkin'
537
-                );
538
-                // get ticket of registration and its price
539
-                $ticket_model = EE_Registry::instance()->load_model('Ticket');
540
-                if ($reg_row['Ticket.TKT_ID']) {
541
-                    $ticket_name = $this->_prepare_value_from_db_for_display(
542
-                        $ticket_model,
543
-                        'TKT_name',
544
-                        $reg_row['Ticket.TKT_name']
545
-                    );
546
-                    $datetimes_strings = array();
547
-                    foreach (EEM_Datetime::instance()->get_all_wpdb_results(
548
-                        array(
549
-                            array('Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']),
550
-                            'order_by'                 => array('DTT_EVT_start' => 'ASC'),
551
-                            'default_where_conditions' => 'none',
552
-                        )
553
-                    ) as $datetime) {
554
-                        $datetimes_strings[] = $this->_prepare_value_from_db_for_display(
555
-                            EEM_Datetime::instance(),
556
-                            'DTT_EVT_start',
557
-                            $datetime['Datetime.DTT_EVT_start']
558
-                        );
559
-                    }
560
-                } else {
561
-                    $ticket_name = __('Unknown', 'event_espresso');
562
-                    $datetimes_strings = array(__('Unknown', 'event_espresso'));
563
-                }
564
-                $reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name;
565
-                $reg_csv_array[ __("Datetimes of Ticket", "event_espresso") ] = implode(", ", $datetimes_strings);
566
-                // get datetime(s) of registration
567
-
568
-                // add attendee columns
569
-                foreach ($att_fields_to_include as $att_field_name) {
570
-                    $field_obj = EEM_Attendee::instance()->field_settings_for($att_field_name);
571
-                    if ($reg_row['Attendee_CPT.ID']) {
572
-                        if ($att_field_name == 'STA_ID') {
573
-                            $value = EEM_State::instance()->get_var(
574
-                                array(array('STA_ID' => $reg_row['Attendee_Meta.STA_ID'])),
575
-                                'STA_name'
576
-                            );
577
-                        } elseif ($att_field_name == 'CNT_ISO') {
578
-                            $value = EEM_Country::instance()->get_var(
579
-                                array(array('CNT_ISO' => $reg_row['Attendee_Meta.CNT_ISO'])),
580
-                                'CNT_name'
581
-                            );
582
-                        } else {
583
-                            $value = $this->_prepare_value_from_db_for_display(
584
-                                EEM_Attendee::instance(),
585
-                                $att_field_name,
586
-                                $reg_row[ $field_obj->get_qualified_column() ]
587
-                            );
588
-                        }
589
-                    } else {
590
-                        $value = '';
591
-                    }
592
-
593
-                    $reg_csv_array[ $this->_get_column_name_for_field($field_obj) ] = $value;
594
-                }
595
-
596
-                // make sure each registration has the same questions in the same order
597
-                foreach ($questions_for_these_regs_rows as $question_row) {
598
-                    if (! isset($reg_csv_array[ $question_row['Question.QST_admin_label'] ])) {
599
-                        $reg_csv_array[ $question_row['Question.QST_admin_label'] ] = null;
600
-                    }
601
-                }
602
-                // now fill out the questions THEY answered
603
-                foreach (EEM_Answer::instance()->get_all_wpdb_results(
604
-                    array(array('REG_ID' => $reg_row['Registration.REG_ID']), 'force_join' => array('Question'))
605
-                ) as $answer_row) {
606
-                    /* @var $answer EE_Answer */
607
-                    if ($answer_row['Question.QST_ID']) {
608
-                        $question_label = $this->_prepare_value_from_db_for_display(
609
-                            EEM_Question::instance(),
610
-                            'QST_admin_label',
611
-                            $answer_row['Question.QST_admin_label']
612
-                        );
613
-                    } else {
614
-                        $question_label = sprintf(__('Question $s', 'event_espresso'), $answer_row['Answer.QST_ID']);
615
-                    }
616
-                    if (isset($answer_row['Question.QST_type']) && $answer_row['Question.QST_type'] == EEM_Question::QST_type_state) {
617
-                        $reg_csv_array[ $question_label ] = EEM_State::instance()->get_state_name_by_ID(
618
-                            $answer_row['Answer.ANS_value']
619
-                        );
620
-                    } else {
621
-                        $reg_csv_array[ $question_label ] = $this->_prepare_value_from_db_for_display(
622
-                            EEM_Answer::instance(),
623
-                            'ANS_value',
624
-                            $answer_row['Answer.ANS_value']
625
-                        );
626
-                    }
627
-                }
628
-                $registrations_csv_ready_array[] = apply_filters(
629
-                    'FHEE__EE_Export__report_registrations__reg_csv_array',
630
-                    $reg_csv_array,
631
-                    $reg_row
632
-                );
633
-            }
634
-        }
635
-
636
-        // if we couldn't export anything, we want to at least show the column headers
637
-        if (empty($registrations_csv_ready_array)) {
638
-            $reg_csv_array = array();
639
-            $model_and_fields_to_include = array(
640
-                'Registration' => $reg_fields_to_include,
641
-                'Attendee'     => $att_fields_to_include,
642
-            );
643
-            foreach ($model_and_fields_to_include as $model_name => $field_list) {
644
-                $model = EE_Registry::instance()->load_model($model_name);
645
-                foreach ($field_list as $field_name) {
646
-                    $field = $model->field_settings_for($field_name);
647
-                    $reg_csv_array[ $this->_get_column_name_for_field(
648
-                        $field
649
-                    ) ] = null;// $registration->get($field->get_name());
650
-                }
651
-            }
652
-            $registrations_csv_ready_array [] = $reg_csv_array;
653
-        }
654
-        if ($event_id) {
655
-            $event_slug = EEM_Event::instance()->get_var(array(array('EVT_ID' => $event_id)), 'EVT_slug');
656
-            if (! $event_slug) {
657
-                $event_slug = __('unknown', 'event_espresso');
658
-            }
659
-        } else {
660
-            $event_slug = __('all', 'event_espresso');
661
-        }
662
-        $filename = sprintf("registrations-for-%s", $event_slug);
663
-
664
-        $handle = $this->EE_CSV->begin_sending_csv($filename);
665
-        $this->EE_CSV->write_data_array_to_csv($handle, $registrations_csv_ready_array);
666
-        $this->EE_CSV->end_sending_csv($handle);
667
-    }
668
-
669
-    /**
670
-     * Gets the 'normal' column named for fields
671
-     *
672
-     * @param EE_Model_Field_Base $field
673
-     * @return string
674
-     */
675
-    protected function _get_column_name_for_field(EE_Model_Field_Base $field)
676
-    {
677
-        return $field->get_nicename() . "[" . $field->get_name() . "]";
678
-    }
679
-
680
-
681
-    /**
682
-     * @Export data for ALL events
683
-     * @access public
684
-     * @return void
685
-     */
686
-    public function export_categories()
687
-    {
688
-        // are any Event IDs set?
689
-        $query_params = array();
690
-        if (isset($this->_req_data['EVT_CAT_ID'])) {
691
-            // do we have an array of IDs ?
692
-            if (is_array($this->_req_data['EVT_CAT_ID'])) {
693
-                // generate an "IN (CSV)" where clause
694
-                $EVT_CAT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_CAT_ID']);
695
-                $filename = 'event-categories';
696
-                $query_params[0]['term_taxonomy_id'] = array('IN', $EVT_CAT_IDs);
697
-            } else {
698
-                // generate regular where = clause
699
-                $EVT_CAT_ID = absint($this->_req_data['EVT_CAT_ID']);
700
-                $filename = 'event-category#' . $EVT_CAT_ID;
701
-                $query_params[0]['term_taxonomy_id'] = $EVT_CAT_ID;
702
-            }
703
-        } else {
704
-            // no IDs means we will d/l the entire table
705
-            $filename = 'all-categories';
706
-        }
707
-
708
-        $tables_to_export = array(
709
-            'Term_Taxonomy' => $query_params,
710
-        );
711
-
712
-        $table_data = $this->_get_export_data_for_models($tables_to_export);
713
-        $filename = $this->generate_filename($filename);
714
-
715
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $table_data)) {
716
-            EE_Error::add_error(
717
-                __(
718
-                    'An error occurred and the Category details could not be exported from the database.',
719
-                    'event_espresso'
720
-                ),
721
-                __FILE__,
722
-                __FUNCTION__,
723
-                __LINE__
724
-            );
725
-        }
726
-    }
727
-
728
-
729
-    /**
730
-     * @process export name to create a suitable filename
731
-     * @access  private
732
-     * @param string - export_name
733
-     * @return string on success, FALSE on fail
734
-     */
735
-    private function generate_filename($export_name = '')
736
-    {
737
-        if ($export_name != '') {
738
-            $filename = get_bloginfo('name') . '-' . $export_name;
739
-            $filename = sanitize_key($filename) . '-' . $this->today;
740
-            return $filename;
741
-        } else {
742
-            EE_Error::add_error(__("No filename was provided", "event_espresso"), __FILE__, __FUNCTION__, __LINE__);
743
-        }
744
-        return false;
745
-    }
746
-
747
-
748
-    /**
749
-     * @recursive function for exporting table data and merging the results with the next results
750
-     * @access    private
751
-     * @param array $models_to_export keys are model names (eg 'Event', 'Attendee', etc.) and values are arrays of
752
-     *                                query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
753
-     * @return array on success, FALSE on fail
754
-     */
755
-    private function _get_export_data_for_models($models_to_export = array())
756
-    {
757
-        $table_data = false;
758
-        if (is_array($models_to_export)) {
759
-            foreach ($models_to_export as $model_name => $query_params) {
760
-                // check for a numerically-indexed array. in that case, $model_name is the value!!
761
-                if (is_int($model_name)) {
762
-                    $model_name = $query_params;
763
-                    $query_params = array();
764
-                }
765
-                $model = EE_Registry::instance()->load_model($model_name);
766
-                $model_objects = $model->get_all($query_params);
767
-
768
-                $table_data[ $model_name ] = array();
769
-                foreach ($model_objects as $model_object) {
770
-                    $model_data_array = array();
771
-                    $fields = $model->field_settings();
772
-                    foreach ($fields as $field) {
773
-                        $column_name = $field->get_nicename() . "[" . $field->get_name() . "]";
774
-                        if ($field instanceof EE_Datetime_Field) {
775
-                            // $field->set_date_format('Y-m-d');
776
-                            // $field->set_time_format('H:i:s');
777
-                            $model_data_array[ $column_name ] = $model_object->get_datetime(
778
-                                $field->get_name(),
779
-                                'Y-m-d',
780
-                                'H:i:s'
781
-                            );
782
-                        } else {
783
-                            $model_data_array[ $column_name ] = $model_object->get($field->get_name());
784
-                        }
785
-                    }
786
-                    $table_data[ $model_name ][] = $model_data_array;
787
-                }
788
-            }
789
-        }
790
-        return $table_data;
791
-    }
19
+	const option_prefix = 'ee_report_job_';
20
+
21
+
22
+	// instance of the EE_Export object
23
+	private static $_instance = null;
24
+
25
+	// instance of the EE_CSV object
26
+	/**
27
+	 *
28
+	 * @var EE_CSV
29
+	 */
30
+	public $EE_CSV = null;
31
+
32
+
33
+	private $_req_data = array();
34
+
35
+
36
+	/**
37
+	 *        private constructor to prevent direct creation
38
+	 *
39
+	 * @Constructor
40
+	 * @access private
41
+	 * @param array $request_data
42
+	 */
43
+	private function __construct($request_data = array())
44
+	{
45
+		$this->_req_data = $request_data;
46
+		$this->today = date("Y-m-d", time());
47
+		require_once(EE_CLASSES . 'EE_CSV.class.php');
48
+		$this->EE_CSV = EE_CSV::instance();
49
+	}
50
+
51
+
52
+	/**
53
+	 *        @ singleton method used to instantiate class object
54
+	 *        @ access public
55
+	 *
56
+	 * @param array $request_data
57
+	 * @return \EE_Export
58
+	 */
59
+	public static function instance($request_data = array())
60
+	{
61
+		// check if class object is instantiated
62
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Export)) {
63
+			self::$_instance = new self($request_data);
64
+		}
65
+		return self::$_instance;
66
+	}
67
+
68
+
69
+	/**
70
+	 * @Export Event Espresso data - routes export requests
71
+	 * @access public
72
+	 * @return void | bool
73
+	 */
74
+	public function export()
75
+	{
76
+		// in case of bulk exports, the "actual" action will be in action2, but first check regular action for "export" keyword
77
+		if (isset($this->_req_data['action']) && strpos($this->_req_data['action'], 'export') === false) {
78
+			// check if action2 has export action
79
+			if (isset($this->_req_data['action2']) && strpos($this->_req_data['action2'], 'export') !== false) {
80
+				// whoop! there it is!
81
+				$this->_req_data['action'] = $this->_req_data['action2'];
82
+			}
83
+		}
84
+
85
+		$this->_req_data['export'] = isset($this->_req_data['export']) ? $this->_req_data['export'] : '';
86
+
87
+		switch ($this->_req_data['export']) {
88
+			case 'report':
89
+				switch ($this->_req_data['action']) {
90
+					case "event":
91
+					case "export_events":
92
+					case 'all_event_data':
93
+						$this->export_all_event_data();
94
+						break;
95
+
96
+					case 'registrations_report_for_event':
97
+						$this->report_registrations_for_event($this->_req_data['EVT_ID']);
98
+						break;
99
+
100
+					case 'attendees':
101
+						$this->export_attendees();
102
+						break;
103
+
104
+					case 'categories':
105
+						$this->export_categories();
106
+						break;
107
+
108
+					default:
109
+						EE_Error::add_error(
110
+							__('An error occurred! The requested export report could not be found.', 'event_espresso'),
111
+							__FILE__,
112
+							__FUNCTION__,
113
+							__LINE__
114
+						);
115
+						return false;
116
+						break;
117
+				}
118
+				break; // end of switch export : report
119
+			default:
120
+				break;
121
+		} // end of switch export
122
+
123
+		exit;
124
+	}
125
+
126
+	/**
127
+	 * Downloads a CSV file with all the columns, but no data. This should be used for importing
128
+	 *
129
+	 * @return null kills execution
130
+	 */
131
+	public function export_sample()
132
+	{
133
+		$event = EEM_Event::instance()->get_one();
134
+		$this->_req_data['EVT_ID'] = $event->ID();
135
+		$this->export_all_event_data();
136
+	}
137
+
138
+
139
+	/**
140
+	 * @Export data for ALL events
141
+	 * @access public
142
+	 * @return void
143
+	 */
144
+	public function export_all_event_data()
145
+	{
146
+		// are any Event IDs set?
147
+		$event_query_params = array();
148
+		$related_models_query_params = array();
149
+		$related_through_reg_query_params = array();
150
+		$datetime_ticket_query_params = array();
151
+		$price_query_params = array();
152
+		$price_type_query_params = array();
153
+		$term_query_params = array();
154
+		$state_country_query_params = array();
155
+		$question_group_query_params = array();
156
+		$question_query_params = array();
157
+		if (isset($this->_req_data['EVT_ID'])) {
158
+			// do we have an array of IDs ?
159
+
160
+			if (is_array($this->_req_data['EVT_ID'])) {
161
+				$EVT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_ID']);
162
+				$value_to_equal = array('IN', $EVT_IDs);
163
+				$filename = 'events';
164
+			} else {
165
+				// generate regular where = clause
166
+				$EVT_ID = absint($this->_req_data['EVT_ID']);
167
+				$value_to_equal = $EVT_ID;
168
+				$event = EE_Registry::instance()->load_model('Event')->get_one_by_ID($EVT_ID);
169
+
170
+				$filename = 'event-' . ($event instanceof EE_Event ? $event->slug() : __('unknown', 'event_espresso'));
171
+			}
172
+			$event_query_params[0]['EVT_ID'] = $value_to_equal;
173
+			$related_models_query_params[0]['Event.EVT_ID'] = $value_to_equal;
174
+			$related_through_reg_query_params[0]['Registration.EVT_ID'] = $value_to_equal;
175
+			$datetime_ticket_query_params[0]['Datetime.EVT_ID'] = $value_to_equal;
176
+			$price_query_params[0]['Ticket.Datetime.EVT_ID'] = $value_to_equal;
177
+			$price_type_query_params[0]['Price.Ticket.Datetime.EVT_ID'] = $value_to_equal;
178
+			$term_query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $value_to_equal;
179
+			$state_country_query_params[0]['Venue.Event.EVT_ID'] = $value_to_equal;
180
+			$question_group_query_params[0]['Event.EVT_ID'] = $value_to_equal;
181
+			$question_query_params[0]['Question_Group.Event.EVT_ID'] = $value_to_equal;
182
+		} else {
183
+			$filename = 'all-events';
184
+		}
185
+
186
+
187
+		// array in the format:  table name =>  query where clause
188
+		$models_to_export = array(
189
+			'Event'                   => $event_query_params,
190
+			'Datetime'                => $related_models_query_params,
191
+			'Ticket_Template'         => $price_query_params,
192
+			'Ticket'                  => $datetime_ticket_query_params,
193
+			'Datetime_Ticket'         => $datetime_ticket_query_params,
194
+			'Price_Type'              => $price_type_query_params,
195
+			'Price'                   => $price_query_params,
196
+			'Ticket_Price'            => $price_query_params,
197
+			'Term'                    => $term_query_params,
198
+			'Term_Taxonomy'           => $related_models_query_params,
199
+			'Term_Relationship'       => $related_models_query_params, // model has NO primary key...
200
+			'Country'                 => $state_country_query_params,
201
+			'State'                   => $state_country_query_params,
202
+			'Venue'                   => $related_models_query_params,
203
+			'Event_Venue'             => $related_models_query_params,
204
+			'Question_Group'          => $question_group_query_params,
205
+			'Event_Question_Group'    => $question_group_query_params,
206
+			'Question'                => $question_query_params,
207
+			'Question_Group_Question' => $question_query_params,
208
+			// 'Transaction'=>$related_through_reg_query_params,
209
+			// 'Registration'=>$related_models_query_params,
210
+			// 'Attendee'=>$related_through_reg_query_params,
211
+			// 'Line_Item'=>
212
+
213
+		);
214
+
215
+		$model_data = $this->_get_export_data_for_models($models_to_export);
216
+
217
+		$filename = $this->generate_filename($filename);
218
+
219
+		if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
220
+			EE_Error::add_error(
221
+				__(
222
+					"'An error occurred and the Event details could not be exported from the database.'",
223
+					"event_espresso"
224
+				),
225
+				__FILE__,
226
+				__FUNCTION__,
227
+				__LINE__
228
+			);
229
+		}
230
+	}
231
+
232
+	public function report_attendees()
233
+	{
234
+		$attendee_rows = EEM_Attendee::instance()->get_all_wpdb_results(
235
+			array(
236
+				'force_join' => array('State', 'Country'),
237
+				'caps'       => EEM_Base::caps_read_admin,
238
+			)
239
+		);
240
+		$csv_data = array();
241
+		foreach ($attendee_rows as $attendee_row) {
242
+			$csv_row = array();
243
+			foreach (EEM_Attendee::instance()->field_settings() as $field_name => $field_obj) {
244
+				if ($field_name == 'STA_ID') {
245
+					$state_name_field = EEM_State::instance()->field_settings_for('STA_name');
246
+					$csv_row[ __('State', 'event_espresso') ] = $attendee_row[ $state_name_field->get_qualified_column(
247
+					) ];
248
+				} elseif ($field_name == 'CNT_ISO') {
249
+					$country_name_field = EEM_Country::instance()->field_settings_for('CNT_name');
250
+					$csv_row[ __(
251
+						'Country',
252
+						'event_espresso'
253
+					) ] = $attendee_row[ $country_name_field->get_qualified_column() ];
254
+				} else {
255
+					$csv_row[ $field_obj->get_nicename() ] = $attendee_row[ $field_obj->get_qualified_column() ];
256
+				}
257
+			}
258
+			$csv_data[] = $csv_row;
259
+		}
260
+
261
+		$filename = $this->generate_filename('contact-list-report');
262
+
263
+		$handle = $this->EE_CSV->begin_sending_csv($filename);
264
+		$this->EE_CSV->write_data_array_to_csv($handle, $csv_data);
265
+		$this->EE_CSV->end_sending_csv($handle);
266
+	}
267
+
268
+
269
+	/**
270
+	 * @Export data for ALL attendees
271
+	 * @access public
272
+	 * @return void
273
+	 */
274
+	public function export_attendees()
275
+	{
276
+
277
+		$states_that_have_an_attendee = EEM_State::instance()->get_all(
278
+			array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
279
+		);
280
+		$countries_that_have_an_attendee = EEM_Country::instance()->get_all(
281
+			array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
282
+		);
283
+		// $states_to_export_query_params
284
+		$models_to_export = array(
285
+			'Country'  => array(array('CNT_ISO' => array('IN', array_keys($countries_that_have_an_attendee)))),
286
+			'State'    => array(array('STA_ID' => array('IN', array_keys($states_that_have_an_attendee)))),
287
+			'Attendee' => array(),
288
+		);
289
+
290
+
291
+		$model_data = $this->_get_export_data_for_models($models_to_export);
292
+		$filename = $this->generate_filename('all-attendees');
293
+
294
+		if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
295
+			EE_Error::add_error(
296
+				__(
297
+					'An error occurred and the Attendee data could not be exported from the database.',
298
+					'event_espresso'
299
+				),
300
+				__FILE__,
301
+				__FUNCTION__,
302
+				__LINE__
303
+			);
304
+		}
305
+	}
306
+
307
+	/**
308
+	 * Shortcut for preparing a database result for display
309
+	 *
310
+	 * @param EEM_Base       $model
311
+	 * @param string         $field_name
312
+	 * @param string         $raw_db_value
313
+	 * @param boolean|string $pretty_schema true to display pretty, a string to use a specific "Schema", or false to
314
+	 *                                      NOT display pretty
315
+	 * @return string
316
+	 */
317
+	protected function _prepare_value_from_db_for_display($model, $field_name, $raw_db_value, $pretty_schema = true)
318
+	{
319
+		$field_obj = $model->field_settings_for($field_name);
320
+		$value_on_model_obj = $field_obj->prepare_for_set_from_db($raw_db_value);
321
+		if ($field_obj instanceof EE_Datetime_Field) {
322
+			$field_obj->set_date_format(
323
+				EE_CSV::instance()->get_date_format_for_csv($field_obj->get_date_format($pretty_schema)),
324
+				$pretty_schema
325
+			);
326
+			$field_obj->set_time_format(
327
+				EE_CSV::instance()->get_time_format_for_csv($field_obj->get_time_format($pretty_schema)),
328
+				$pretty_schema
329
+			);
330
+		}
331
+		if ($pretty_schema === true) {
332
+			return $field_obj->prepare_for_pretty_echoing($value_on_model_obj);
333
+		} elseif (is_string($pretty_schema)) {
334
+			return $field_obj->prepare_for_pretty_echoing($value_on_model_obj, $pretty_schema);
335
+		} else {
336
+			return $field_obj->prepare_for_get($value_on_model_obj);
337
+		}
338
+	}
339
+
340
+	/**
341
+	 * Export a custom CSV of registration info including: A bunch of the reg fields, the time of the event, the price
342
+	 * name, and the questions associated with the registrations
343
+	 *
344
+	 * @param int $event_id
345
+	 */
346
+	public function report_registrations_for_event($event_id = null)
347
+	{
348
+		$reg_fields_to_include = array(
349
+			'TXN_ID',
350
+			'ATT_ID',
351
+			'REG_ID',
352
+			'REG_date',
353
+			'REG_code',
354
+			'REG_count',
355
+			'REG_final_price',
356
+
357
+		);
358
+		$att_fields_to_include = array(
359
+			'ATT_fname',
360
+			'ATT_lname',
361
+			'ATT_email',
362
+			'ATT_address',
363
+			'ATT_address2',
364
+			'ATT_city',
365
+			'STA_ID',
366
+			'CNT_ISO',
367
+			'ATT_zip',
368
+			'ATT_phone',
369
+		);
370
+
371
+		$registrations_csv_ready_array = array();
372
+		$reg_model = EE_Registry::instance()->load_model('Registration');
373
+		$query_params = apply_filters(
374
+			'FHEE__EE_Export__report_registration_for_event',
375
+			array(
376
+				array(
377
+					'OR'                 => array(
378
+						// don't include registrations from failed or abandoned transactions...
379
+						'Transaction.STS_ID' => array(
380
+							'NOT IN',
381
+							array(EEM_Transaction::failed_status_code, EEM_Transaction::abandoned_status_code),
382
+						),
383
+						// unless the registration is approved, in which case include it regardless of transaction status
384
+						'STS_ID'             => EEM_Registration::status_id_approved,
385
+					),
386
+					'Ticket.TKT_deleted' => array('IN', array(true, false)),
387
+				),
388
+				'order_by'   => array('Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'),
389
+				'force_join' => array('Transaction', 'Ticket', 'Attendee'),
390
+				'caps'       => EEM_Base::caps_read_admin,
391
+			),
392
+			$event_id
393
+		);
394
+		if ($event_id) {
395
+			$query_params[0]['EVT_ID'] = $event_id;
396
+		} else {
397
+			$query_params['force_join'][] = 'Event';
398
+		}
399
+		$registration_rows = $reg_model->get_all_wpdb_results($query_params);
400
+		// get all questions which relate to someone in this group
401
+		$registration_ids = array();
402
+		foreach ($registration_rows as $reg_row) {
403
+			$registration_ids[] = intval($reg_row['Registration.REG_ID']);
404
+		}
405
+		// EEM_Question::instance()->show_next_x_db_queries();
406
+		$questions_for_these_regs_rows = EEM_Question::instance()->get_all_wpdb_results(
407
+			array(array('Answer.REG_ID' => array('IN', $registration_ids)))
408
+		);
409
+		foreach ($registration_rows as $reg_row) {
410
+			if (is_array($reg_row)) {
411
+				$reg_csv_array = array();
412
+				if (! $event_id) {
413
+					// get the event's name and Id
414
+					$reg_csv_array[ __('Event', 'event_espresso') ] = sprintf(
415
+						__('%1$s (%2$s)', 'event_espresso'),
416
+						$this->_prepare_value_from_db_for_display(
417
+							EEM_Event::instance(),
418
+							'EVT_name',
419
+							$reg_row['Event_CPT.post_title']
420
+						),
421
+						$reg_row['Event_CPT.ID']
422
+					);
423
+				}
424
+				$is_primary_reg = $reg_row['Registration.REG_count'] == '1' ? true : false;
425
+				/*@var $reg_row EE_Registration */
426
+				foreach ($reg_fields_to_include as $field_name) {
427
+					$field = $reg_model->field_settings_for($field_name);
428
+					if ($field_name == 'REG_final_price') {
429
+						$value = $this->_prepare_value_from_db_for_display(
430
+							$reg_model,
431
+							$field_name,
432
+							$reg_row['Registration.REG_final_price'],
433
+							'localized_float'
434
+						);
435
+					} elseif ($field_name == 'REG_count') {
436
+						$value = sprintf(
437
+							__('%s of %s', 'event_espresso'),
438
+							$this->_prepare_value_from_db_for_display(
439
+								$reg_model,
440
+								'REG_count',
441
+								$reg_row['Registration.REG_count']
442
+							),
443
+							$this->_prepare_value_from_db_for_display(
444
+								$reg_model,
445
+								'REG_group_size',
446
+								$reg_row['Registration.REG_group_size']
447
+							)
448
+						);
449
+					} elseif ($field_name == 'REG_date') {
450
+						$value = $this->_prepare_value_from_db_for_display(
451
+							$reg_model,
452
+							$field_name,
453
+							$reg_row['Registration.REG_date'],
454
+							'no_html'
455
+						);
456
+					} else {
457
+						$value = $this->_prepare_value_from_db_for_display(
458
+							$reg_model,
459
+							$field_name,
460
+							$reg_row[ $field->get_qualified_column() ]
461
+						);
462
+					}
463
+					$reg_csv_array[ $this->_get_column_name_for_field($field) ] = $value;
464
+					if ($field_name == 'REG_final_price') {
465
+						// add a column named Currency after the final price
466
+						$reg_csv_array[ __("Currency", "event_espresso") ] = EE_Config::instance()->currency->code;
467
+					}
468
+				}
469
+				// get pretty status
470
+				$stati = EEM_Status::instance()->localized_status(
471
+					array(
472
+						$reg_row['Registration.STS_ID']     => __('unknown', 'event_espresso'),
473
+						$reg_row['TransactionTable.STS_ID'] => __('unknown', 'event_espresso'),
474
+					),
475
+					false,
476
+					'sentence'
477
+				);
478
+				$reg_csv_array[ __(
479
+					"Registration Status",
480
+					'event_espresso'
481
+				) ] = $stati[ $reg_row['Registration.STS_ID'] ];
482
+				// get pretty trnasaction status
483
+				$reg_csv_array[ __(
484
+					"Transaction Status",
485
+					'event_espresso'
486
+				) ] = $stati[ $reg_row['TransactionTable.STS_ID'] ];
487
+				$reg_csv_array[ __('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg
488
+					? $this->_prepare_value_from_db_for_display(
489
+						EEM_Transaction::instance(),
490
+						'TXN_total',
491
+						$reg_row['TransactionTable.TXN_total'],
492
+						'localized_float'
493
+					) : '0.00';
494
+				$reg_csv_array[ __('Amount Paid', 'event_espresso') ] = $is_primary_reg
495
+					? $this->_prepare_value_from_db_for_display(
496
+						EEM_Transaction::instance(),
497
+						'TXN_paid',
498
+						$reg_row['TransactionTable.TXN_paid'],
499
+						'localized_float'
500
+					) : '0.00';
501
+				$payment_methods = array();
502
+				$gateway_txn_ids_etc = array();
503
+				$payment_times = array();
504
+				if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) {
505
+					$payments_info = EEM_Payment::instance()->get_all_wpdb_results(
506
+						array(
507
+							array(
508
+								'TXN_ID' => $reg_row['TransactionTable.TXN_ID'],
509
+								'STS_ID' => EEM_Payment::status_id_approved,
510
+							),
511
+							'force_join' => array('Payment_Method'),
512
+						),
513
+						ARRAY_A,
514
+						'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time'
515
+					);
516
+
517
+					foreach ($payments_info as $payment_method_and_gateway_txn_id) {
518
+						$payment_methods[] = isset($payment_method_and_gateway_txn_id['name'])
519
+							? $payment_method_and_gateway_txn_id['name'] : __('Unknown', 'event_espresso');
520
+						$gateway_txn_ids_etc[] = isset($payment_method_and_gateway_txn_id['gateway_txn_id'])
521
+							? $payment_method_and_gateway_txn_id['gateway_txn_id'] : '';
522
+						$payment_times[] = isset($payment_method_and_gateway_txn_id['payment_time'])
523
+							? $payment_method_and_gateway_txn_id['payment_time'] : '';
524
+					}
525
+				}
526
+				$reg_csv_array[ __('Payment Date(s)', 'event_espresso') ] = implode(',', $payment_times);
527
+				$reg_csv_array[ __('Payment Method(s)', 'event_espresso') ] = implode(",", $payment_methods);
528
+				$reg_csv_array[ __('Gateway Transaction ID(s)', 'event_espresso') ] = implode(
529
+					',',
530
+					$gateway_txn_ids_etc
531
+				);
532
+
533
+				// get whether or not the user has checked in
534
+				$reg_csv_array[ __("Check-Ins", "event_espresso") ] = $reg_model->count_related(
535
+					$reg_row['Registration.REG_ID'],
536
+					'Checkin'
537
+				);
538
+				// get ticket of registration and its price
539
+				$ticket_model = EE_Registry::instance()->load_model('Ticket');
540
+				if ($reg_row['Ticket.TKT_ID']) {
541
+					$ticket_name = $this->_prepare_value_from_db_for_display(
542
+						$ticket_model,
543
+						'TKT_name',
544
+						$reg_row['Ticket.TKT_name']
545
+					);
546
+					$datetimes_strings = array();
547
+					foreach (EEM_Datetime::instance()->get_all_wpdb_results(
548
+						array(
549
+							array('Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']),
550
+							'order_by'                 => array('DTT_EVT_start' => 'ASC'),
551
+							'default_where_conditions' => 'none',
552
+						)
553
+					) as $datetime) {
554
+						$datetimes_strings[] = $this->_prepare_value_from_db_for_display(
555
+							EEM_Datetime::instance(),
556
+							'DTT_EVT_start',
557
+							$datetime['Datetime.DTT_EVT_start']
558
+						);
559
+					}
560
+				} else {
561
+					$ticket_name = __('Unknown', 'event_espresso');
562
+					$datetimes_strings = array(__('Unknown', 'event_espresso'));
563
+				}
564
+				$reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name;
565
+				$reg_csv_array[ __("Datetimes of Ticket", "event_espresso") ] = implode(", ", $datetimes_strings);
566
+				// get datetime(s) of registration
567
+
568
+				// add attendee columns
569
+				foreach ($att_fields_to_include as $att_field_name) {
570
+					$field_obj = EEM_Attendee::instance()->field_settings_for($att_field_name);
571
+					if ($reg_row['Attendee_CPT.ID']) {
572
+						if ($att_field_name == 'STA_ID') {
573
+							$value = EEM_State::instance()->get_var(
574
+								array(array('STA_ID' => $reg_row['Attendee_Meta.STA_ID'])),
575
+								'STA_name'
576
+							);
577
+						} elseif ($att_field_name == 'CNT_ISO') {
578
+							$value = EEM_Country::instance()->get_var(
579
+								array(array('CNT_ISO' => $reg_row['Attendee_Meta.CNT_ISO'])),
580
+								'CNT_name'
581
+							);
582
+						} else {
583
+							$value = $this->_prepare_value_from_db_for_display(
584
+								EEM_Attendee::instance(),
585
+								$att_field_name,
586
+								$reg_row[ $field_obj->get_qualified_column() ]
587
+							);
588
+						}
589
+					} else {
590
+						$value = '';
591
+					}
592
+
593
+					$reg_csv_array[ $this->_get_column_name_for_field($field_obj) ] = $value;
594
+				}
595
+
596
+				// make sure each registration has the same questions in the same order
597
+				foreach ($questions_for_these_regs_rows as $question_row) {
598
+					if (! isset($reg_csv_array[ $question_row['Question.QST_admin_label'] ])) {
599
+						$reg_csv_array[ $question_row['Question.QST_admin_label'] ] = null;
600
+					}
601
+				}
602
+				// now fill out the questions THEY answered
603
+				foreach (EEM_Answer::instance()->get_all_wpdb_results(
604
+					array(array('REG_ID' => $reg_row['Registration.REG_ID']), 'force_join' => array('Question'))
605
+				) as $answer_row) {
606
+					/* @var $answer EE_Answer */
607
+					if ($answer_row['Question.QST_ID']) {
608
+						$question_label = $this->_prepare_value_from_db_for_display(
609
+							EEM_Question::instance(),
610
+							'QST_admin_label',
611
+							$answer_row['Question.QST_admin_label']
612
+						);
613
+					} else {
614
+						$question_label = sprintf(__('Question $s', 'event_espresso'), $answer_row['Answer.QST_ID']);
615
+					}
616
+					if (isset($answer_row['Question.QST_type']) && $answer_row['Question.QST_type'] == EEM_Question::QST_type_state) {
617
+						$reg_csv_array[ $question_label ] = EEM_State::instance()->get_state_name_by_ID(
618
+							$answer_row['Answer.ANS_value']
619
+						);
620
+					} else {
621
+						$reg_csv_array[ $question_label ] = $this->_prepare_value_from_db_for_display(
622
+							EEM_Answer::instance(),
623
+							'ANS_value',
624
+							$answer_row['Answer.ANS_value']
625
+						);
626
+					}
627
+				}
628
+				$registrations_csv_ready_array[] = apply_filters(
629
+					'FHEE__EE_Export__report_registrations__reg_csv_array',
630
+					$reg_csv_array,
631
+					$reg_row
632
+				);
633
+			}
634
+		}
635
+
636
+		// if we couldn't export anything, we want to at least show the column headers
637
+		if (empty($registrations_csv_ready_array)) {
638
+			$reg_csv_array = array();
639
+			$model_and_fields_to_include = array(
640
+				'Registration' => $reg_fields_to_include,
641
+				'Attendee'     => $att_fields_to_include,
642
+			);
643
+			foreach ($model_and_fields_to_include as $model_name => $field_list) {
644
+				$model = EE_Registry::instance()->load_model($model_name);
645
+				foreach ($field_list as $field_name) {
646
+					$field = $model->field_settings_for($field_name);
647
+					$reg_csv_array[ $this->_get_column_name_for_field(
648
+						$field
649
+					) ] = null;// $registration->get($field->get_name());
650
+				}
651
+			}
652
+			$registrations_csv_ready_array [] = $reg_csv_array;
653
+		}
654
+		if ($event_id) {
655
+			$event_slug = EEM_Event::instance()->get_var(array(array('EVT_ID' => $event_id)), 'EVT_slug');
656
+			if (! $event_slug) {
657
+				$event_slug = __('unknown', 'event_espresso');
658
+			}
659
+		} else {
660
+			$event_slug = __('all', 'event_espresso');
661
+		}
662
+		$filename = sprintf("registrations-for-%s", $event_slug);
663
+
664
+		$handle = $this->EE_CSV->begin_sending_csv($filename);
665
+		$this->EE_CSV->write_data_array_to_csv($handle, $registrations_csv_ready_array);
666
+		$this->EE_CSV->end_sending_csv($handle);
667
+	}
668
+
669
+	/**
670
+	 * Gets the 'normal' column named for fields
671
+	 *
672
+	 * @param EE_Model_Field_Base $field
673
+	 * @return string
674
+	 */
675
+	protected function _get_column_name_for_field(EE_Model_Field_Base $field)
676
+	{
677
+		return $field->get_nicename() . "[" . $field->get_name() . "]";
678
+	}
679
+
680
+
681
+	/**
682
+	 * @Export data for ALL events
683
+	 * @access public
684
+	 * @return void
685
+	 */
686
+	public function export_categories()
687
+	{
688
+		// are any Event IDs set?
689
+		$query_params = array();
690
+		if (isset($this->_req_data['EVT_CAT_ID'])) {
691
+			// do we have an array of IDs ?
692
+			if (is_array($this->_req_data['EVT_CAT_ID'])) {
693
+				// generate an "IN (CSV)" where clause
694
+				$EVT_CAT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_CAT_ID']);
695
+				$filename = 'event-categories';
696
+				$query_params[0]['term_taxonomy_id'] = array('IN', $EVT_CAT_IDs);
697
+			} else {
698
+				// generate regular where = clause
699
+				$EVT_CAT_ID = absint($this->_req_data['EVT_CAT_ID']);
700
+				$filename = 'event-category#' . $EVT_CAT_ID;
701
+				$query_params[0]['term_taxonomy_id'] = $EVT_CAT_ID;
702
+			}
703
+		} else {
704
+			// no IDs means we will d/l the entire table
705
+			$filename = 'all-categories';
706
+		}
707
+
708
+		$tables_to_export = array(
709
+			'Term_Taxonomy' => $query_params,
710
+		);
711
+
712
+		$table_data = $this->_get_export_data_for_models($tables_to_export);
713
+		$filename = $this->generate_filename($filename);
714
+
715
+		if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $table_data)) {
716
+			EE_Error::add_error(
717
+				__(
718
+					'An error occurred and the Category details could not be exported from the database.',
719
+					'event_espresso'
720
+				),
721
+				__FILE__,
722
+				__FUNCTION__,
723
+				__LINE__
724
+			);
725
+		}
726
+	}
727
+
728
+
729
+	/**
730
+	 * @process export name to create a suitable filename
731
+	 * @access  private
732
+	 * @param string - export_name
733
+	 * @return string on success, FALSE on fail
734
+	 */
735
+	private function generate_filename($export_name = '')
736
+	{
737
+		if ($export_name != '') {
738
+			$filename = get_bloginfo('name') . '-' . $export_name;
739
+			$filename = sanitize_key($filename) . '-' . $this->today;
740
+			return $filename;
741
+		} else {
742
+			EE_Error::add_error(__("No filename was provided", "event_espresso"), __FILE__, __FUNCTION__, __LINE__);
743
+		}
744
+		return false;
745
+	}
746
+
747
+
748
+	/**
749
+	 * @recursive function for exporting table data and merging the results with the next results
750
+	 * @access    private
751
+	 * @param array $models_to_export keys are model names (eg 'Event', 'Attendee', etc.) and values are arrays of
752
+	 *                                query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
753
+	 * @return array on success, FALSE on fail
754
+	 */
755
+	private function _get_export_data_for_models($models_to_export = array())
756
+	{
757
+		$table_data = false;
758
+		if (is_array($models_to_export)) {
759
+			foreach ($models_to_export as $model_name => $query_params) {
760
+				// check for a numerically-indexed array. in that case, $model_name is the value!!
761
+				if (is_int($model_name)) {
762
+					$model_name = $query_params;
763
+					$query_params = array();
764
+				}
765
+				$model = EE_Registry::instance()->load_model($model_name);
766
+				$model_objects = $model->get_all($query_params);
767
+
768
+				$table_data[ $model_name ] = array();
769
+				foreach ($model_objects as $model_object) {
770
+					$model_data_array = array();
771
+					$fields = $model->field_settings();
772
+					foreach ($fields as $field) {
773
+						$column_name = $field->get_nicename() . "[" . $field->get_name() . "]";
774
+						if ($field instanceof EE_Datetime_Field) {
775
+							// $field->set_date_format('Y-m-d');
776
+							// $field->set_time_format('H:i:s');
777
+							$model_data_array[ $column_name ] = $model_object->get_datetime(
778
+								$field->get_name(),
779
+								'Y-m-d',
780
+								'H:i:s'
781
+							);
782
+						} else {
783
+							$model_data_array[ $column_name ] = $model_object->get($field->get_name());
784
+						}
785
+					}
786
+					$table_data[ $model_name ][] = $model_data_array;
787
+				}
788
+			}
789
+		}
790
+		return $table_data;
791
+	}
792 792
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Payment.class.php 2 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -13,7 +13,7 @@  discard block
 block discarded – undo
13 13
      * @param array  $props_n_values          incoming values
14 14
      * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
15 15
      *                                        used.)
16
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
16
+     * @param string[]  $date_formats            incoming date_formats in an array where the first value is the
17 17
      *                                        date_format and the second value is the time format
18 18
      * @return EE_Payment
19 19
      * @throws \EE_Error
@@ -588,7 +588,7 @@  discard block
 block discarded – undo
588 588
      * Gets all the extra meta info on this payment
589 589
      *
590 590
      * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
591
-     * @return EE_Extra_Meta
591
+     * @return EE_Base_Class[]
592 592
      * @throws \EE_Error
593 593
      */
594 594
     public function extra_meta($query_params = array())
@@ -836,7 +836,7 @@  discard block
 block discarded – undo
836 836
     /**
837 837
      * Returns the payment's transaction's primary registration
838 838
      *
839
-     * @return EE_Registration|null
839
+     * @return EE_Base_Class|null
840 840
      */
841 841
     public function get_primary_registration()
842 842
     {
Please login to merge, or discard this patch.
Indentation   +851 added lines, -851 removed lines patch added patch discarded remove patch
@@ -9,855 +9,855 @@
 block discarded – undo
9 9
 class EE_Payment extends EE_Base_Class implements EEI_Payment
10 10
 {
11 11
 
12
-    /**
13
-     * @param array  $props_n_values          incoming values
14
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
15
-     *                                        used.)
16
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
17
-     *                                        date_format and the second value is the time format
18
-     * @return EE_Payment
19
-     * @throws \EE_Error
20
-     */
21
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
22
-    {
23
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
24
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
25
-    }
26
-
27
-
28
-    /**
29
-     * @param array  $props_n_values  incoming values from the database
30
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
31
-     *                                the website will be used.
32
-     * @return EE_Payment
33
-     * @throws \EE_Error
34
-     */
35
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
36
-    {
37
-        return new self($props_n_values, true, $timezone);
38
-    }
39
-
40
-
41
-    /**
42
-     * Set Transaction ID
43
-     *
44
-     * @access public
45
-     * @param int $TXN_ID
46
-     * @throws \EE_Error
47
-     */
48
-    public function set_transaction_id($TXN_ID = 0)
49
-    {
50
-        $this->set('TXN_ID', $TXN_ID);
51
-    }
52
-
53
-
54
-    /**
55
-     * Gets the transaction related to this payment
56
-     *
57
-     * @return EE_Transaction
58
-     * @throws \EE_Error
59
-     */
60
-    public function transaction()
61
-    {
62
-        return $this->get_first_related('Transaction');
63
-    }
64
-
65
-
66
-    /**
67
-     * Set Status
68
-     *
69
-     * @access public
70
-     * @param string $STS_ID
71
-     * @throws \EE_Error
72
-     */
73
-    public function set_status($STS_ID = '')
74
-    {
75
-        $this->set('STS_ID', $STS_ID);
76
-    }
77
-
78
-
79
-    /**
80
-     * Set Payment Timestamp
81
-     *
82
-     * @access public
83
-     * @param int $timestamp
84
-     * @throws \EE_Error
85
-     */
86
-    public function set_timestamp($timestamp = 0)
87
-    {
88
-        $this->set('PAY_timestamp', $timestamp);
89
-    }
90
-
91
-
92
-    /**
93
-     * Set Payment Method
94
-     *
95
-     * @access public
96
-     * @param string $PAY_source
97
-     * @throws \EE_Error
98
-     */
99
-    public function set_source($PAY_source = '')
100
-    {
101
-        $this->set('PAY_source', $PAY_source);
102
-    }
103
-
104
-
105
-    /**
106
-     * Set Payment Amount
107
-     *
108
-     * @access public
109
-     * @param float $amount
110
-     * @throws \EE_Error
111
-     */
112
-    public function set_amount($amount = 0.00)
113
-    {
114
-        $this->set('PAY_amount', (float) $amount);
115
-    }
116
-
117
-
118
-    /**
119
-     * Set Payment Gateway Response
120
-     *
121
-     * @access public
122
-     * @param string $gateway_response
123
-     * @throws \EE_Error
124
-     */
125
-    public function set_gateway_response($gateway_response = '')
126
-    {
127
-        $this->set('PAY_gateway_response', $gateway_response);
128
-    }
129
-
130
-
131
-    /**
132
-     * Returns the name of the payment method used on this payment (previously known merely as 'gateway')
133
-     * but since 4.6.0, payment methods are models and the payment keeps a foreign key to the payment method
134
-     * used on it
135
-     *
136
-     * @deprecated
137
-     * @return string
138
-     * @throws \EE_Error
139
-     */
140
-    public function gateway()
141
-    {
142
-        EE_Error::doing_it_wrong(
143
-            'EE_Payment::gateway',
144
-            __(
145
-                'The method EE_Payment::gateway() has been deprecated. Consider instead using EE_Payment::payment_method()->name()',
146
-                'event_espresso'
147
-            ),
148
-            '4.6.0'
149
-        );
150
-        return $this->payment_method() ? $this->payment_method()->name() : __('Unknown', 'event_espresso');
151
-    }
152
-
153
-
154
-    /**
155
-     * Set Gateway Transaction ID
156
-     *
157
-     * @access public
158
-     * @param string $txn_id_chq_nmbr
159
-     * @throws \EE_Error
160
-     */
161
-    public function set_txn_id_chq_nmbr($txn_id_chq_nmbr = '')
162
-    {
163
-        $this->set('PAY_txn_id_chq_nmbr', $txn_id_chq_nmbr);
164
-    }
165
-
166
-
167
-    /**
168
-     * Set Purchase Order Number
169
-     *
170
-     * @access public
171
-     * @param string $po_number
172
-     * @throws \EE_Error
173
-     */
174
-    public function set_po_number($po_number = '')
175
-    {
176
-        $this->set('PAY_po_number', $po_number);
177
-    }
178
-
179
-
180
-    /**
181
-     * Set Extra Accounting Field
182
-     *
183
-     * @access public
184
-     * @param string $extra_accntng
185
-     * @throws \EE_Error
186
-     */
187
-    public function set_extra_accntng($extra_accntng = '')
188
-    {
189
-        $this->set('PAY_extra_accntng', $extra_accntng);
190
-    }
191
-
192
-
193
-    /**
194
-     * Set Payment made via admin flag
195
-     *
196
-     * @access public
197
-     * @param bool $via_admin
198
-     * @throws \EE_Error
199
-     */
200
-    public function set_payment_made_via_admin($via_admin = false)
201
-    {
202
-        if ($via_admin) {
203
-            $this->set('PAY_source', EEM_Payment_Method::scope_admin);
204
-        } else {
205
-            $this->set('PAY_source', EEM_Payment_Method::scope_cart);
206
-        }
207
-    }
208
-
209
-
210
-    /**
211
-     * Set Payment Details
212
-     *
213
-     * @access public
214
-     * @param string|array $details
215
-     * @throws \EE_Error
216
-     */
217
-    public function set_details($details = '')
218
-    {
219
-        if (is_array($details)) {
220
-            array_walk_recursive($details, array($this, '_strip_all_tags_within_array'));
221
-        } else {
222
-            $details = wp_strip_all_tags($details);
223
-        }
224
-        $this->set('PAY_details', $details);
225
-    }
226
-
227
-
228
-    /**
229
-     * Sets redirect_url
230
-     *
231
-     * @param string $redirect_url
232
-     * @throws \EE_Error
233
-     */
234
-    public function set_redirect_url($redirect_url)
235
-    {
236
-        $this->set('PAY_redirect_url', $redirect_url);
237
-    }
238
-
239
-
240
-    /**
241
-     * Sets redirect_args
242
-     *
243
-     * @param array $redirect_args
244
-     * @throws \EE_Error
245
-     */
246
-    public function set_redirect_args($redirect_args)
247
-    {
248
-        $this->set('PAY_redirect_args', $redirect_args);
249
-    }
250
-
251
-
252
-    /**
253
-     * get Payment Transaction ID
254
-     *
255
-     * @access public
256
-     * @throws \EE_Error
257
-     */
258
-    public function TXN_ID()
259
-    {
260
-        return $this->get('TXN_ID');
261
-    }
262
-
263
-
264
-    /**
265
-     * get Payment Status
266
-     *
267
-     * @access public
268
-     * @throws \EE_Error
269
-     */
270
-    public function status()
271
-    {
272
-        return $this->get('STS_ID');
273
-    }
274
-
275
-
276
-    /**
277
-     * get Payment Status
278
-     *
279
-     * @access public
280
-     * @throws \EE_Error
281
-     */
282
-    public function STS_ID()
283
-    {
284
-        return $this->get('STS_ID');
285
-    }
286
-
287
-
288
-    /**
289
-     * get Payment Timestamp
290
-     *
291
-     * @access public
292
-     * @param string $dt_frmt
293
-     * @param string $tm_frmt
294
-     * @return string
295
-     * @throws \EE_Error
296
-     */
297
-    public function timestamp($dt_frmt = '', $tm_frmt = '')
298
-    {
299
-        return $this->get_i18n_datetime('PAY_timestamp', trim($dt_frmt . ' ' . $tm_frmt));
300
-    }
301
-
302
-
303
-    /**
304
-     * get Payment Source
305
-     *
306
-     * @access public
307
-     * @throws \EE_Error
308
-     */
309
-    public function source()
310
-    {
311
-        return $this->get('PAY_source');
312
-    }
313
-
314
-
315
-    /**
316
-     * get Payment Amount
317
-     *
318
-     * @access public
319
-     * @return float
320
-     * @throws \EE_Error
321
-     */
322
-    public function amount()
323
-    {
324
-        return (float) $this->get('PAY_amount');
325
-    }
326
-
327
-
328
-    /**
329
-     * @return mixed
330
-     * @throws \EE_Error
331
-     */
332
-    public function amount_no_code()
333
-    {
334
-        return $this->get_pretty('PAY_amount', 'no_currency_code');
335
-    }
336
-
337
-
338
-    /**
339
-     * get Payment Gateway Response
340
-     *
341
-     * @access public
342
-     * @throws \EE_Error
343
-     */
344
-    public function gateway_response()
345
-    {
346
-        return $this->get('PAY_gateway_response');
347
-    }
348
-
349
-
350
-    /**
351
-     * get Payment Gateway Transaction ID
352
-     *
353
-     * @access public
354
-     * @throws \EE_Error
355
-     */
356
-    public function txn_id_chq_nmbr()
357
-    {
358
-        return $this->get('PAY_txn_id_chq_nmbr');
359
-    }
360
-
361
-
362
-    /**
363
-     * get Purchase Order Number
364
-     *
365
-     * @access public
366
-     * @throws \EE_Error
367
-     */
368
-    public function po_number()
369
-    {
370
-        return $this->get('PAY_po_number');
371
-    }
372
-
373
-
374
-    /**
375
-     * get Extra Accounting Field
376
-     *
377
-     * @access public
378
-     * @throws \EE_Error
379
-     */
380
-    public function extra_accntng()
381
-    {
382
-        return $this->get('PAY_extra_accntng');
383
-    }
384
-
385
-
386
-    /**
387
-     * get Payment made via admin source
388
-     *
389
-     * @access public
390
-     * @throws \EE_Error
391
-     */
392
-    public function payment_made_via_admin()
393
-    {
394
-        return ($this->get('PAY_source') === EEM_Payment_Method::scope_admin);
395
-    }
396
-
397
-
398
-    /**
399
-     * get Payment Details
400
-     *
401
-     * @access public
402
-     * @throws \EE_Error
403
-     */
404
-    public function details()
405
-    {
406
-        return $this->get('PAY_details');
407
-    }
408
-
409
-
410
-    /**
411
-     * Gets redirect_url
412
-     *
413
-     * @return string
414
-     * @throws \EE_Error
415
-     */
416
-    public function redirect_url()
417
-    {
418
-        return $this->get('PAY_redirect_url');
419
-    }
420
-
421
-
422
-    /**
423
-     * Gets redirect_args
424
-     *
425
-     * @return array
426
-     * @throws \EE_Error
427
-     */
428
-    public function redirect_args()
429
-    {
430
-        return $this->get('PAY_redirect_args');
431
-    }
432
-
433
-
434
-    /**
435
-     * echoes $this->pretty_status()
436
-     *
437
-     * @param bool $show_icons
438
-     * @return void
439
-     * @throws \EE_Error
440
-     */
441
-    public function e_pretty_status($show_icons = false)
442
-    {
443
-        echo $this->pretty_status($show_icons);
444
-    }
445
-
446
-
447
-    /**
448
-     * returns a pretty version of the status, good for displaying to users
449
-     *
450
-     * @param bool $show_icons
451
-     * @return string
452
-     * @throws \EE_Error
453
-     */
454
-    public function pretty_status($show_icons = false)
455
-    {
456
-        $status = EEM_Status::instance()->localized_status(
457
-            array($this->STS_ID() => __('unknown', 'event_espresso')),
458
-            false,
459
-            'sentence'
460
-        );
461
-        $icon = '';
462
-        switch ($this->STS_ID()) {
463
-            case EEM_Payment::status_id_approved:
464
-                $icon = $show_icons
465
-                    ? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>'
466
-                    : '';
467
-                break;
468
-            case EEM_Payment::status_id_pending:
469
-                $icon = $show_icons
470
-                    ? '<span class="dashicons dashicons-clock ee-icon-size-16 orange-text"></span>'
471
-                    : '';
472
-                break;
473
-            case EEM_Payment::status_id_cancelled:
474
-                $icon = $show_icons
475
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
476
-                    : '';
477
-                break;
478
-            case EEM_Payment::status_id_declined:
479
-                $icon = $show_icons
480
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
481
-                    : '';
482
-                break;
483
-        }
484
-        return $icon . $status[ $this->STS_ID() ];
485
-    }
486
-
487
-
488
-    /**
489
-     * For determining the status of the payment
490
-     *
491
-     * @return boolean whether the payment is approved or not
492
-     * @throws \EE_Error
493
-     */
494
-    public function is_approved()
495
-    {
496
-        return $this->status_is(EEM_Payment::status_id_approved);
497
-    }
498
-
499
-
500
-    /**
501
-     * Generally determines if the status of this payment equals
502
-     * the $STS_ID string
503
-     *
504
-     * @param string $STS_ID an ID from the esp_status table/
505
-     *                       one of the status_id_* on the EEM_Payment model
506
-     * @return boolean whether the status of this payment equals the status id
507
-     * @throws \EE_Error
508
-     */
509
-    protected function status_is($STS_ID)
510
-    {
511
-        return $STS_ID === $this->STS_ID() ? true : false;
512
-    }
513
-
514
-
515
-    /**
516
-     * For determining the status of the payment
517
-     *
518
-     * @return boolean whether the payment is pending or not
519
-     * @throws \EE_Error
520
-     */
521
-    public function is_pending()
522
-    {
523
-        return $this->status_is(EEM_Payment::status_id_pending);
524
-    }
525
-
526
-
527
-    /**
528
-     * For determining the status of the payment
529
-     *
530
-     * @return boolean
531
-     * @throws \EE_Error
532
-     */
533
-    public function is_cancelled()
534
-    {
535
-        return $this->status_is(EEM_Payment::status_id_cancelled);
536
-    }
537
-
538
-
539
-    /**
540
-     * For determining the status of the payment
541
-     *
542
-     * @return boolean
543
-     * @throws \EE_Error
544
-     */
545
-    public function is_declined()
546
-    {
547
-        return $this->status_is(EEM_Payment::status_id_declined);
548
-    }
549
-
550
-
551
-    /**
552
-     * For determining the status of the payment
553
-     *
554
-     * @return boolean
555
-     * @throws \EE_Error
556
-     */
557
-    public function is_failed()
558
-    {
559
-        return $this->status_is(EEM_Payment::status_id_failed);
560
-    }
561
-
562
-
563
-    /**
564
-     * For determining if the payment is actually a refund ( ie: has a negative value )
565
-     *
566
-     * @return boolean
567
-     * @throws \EE_Error
568
-     */
569
-    public function is_a_refund()
570
-    {
571
-        return $this->amount() < 0 ? true : false;
572
-    }
573
-
574
-
575
-    /**
576
-     * Get the status object of this object
577
-     *
578
-     * @return EE_Status
579
-     * @throws \EE_Error
580
-     */
581
-    public function status_obj()
582
-    {
583
-        return $this->get_first_related('Status');
584
-    }
585
-
586
-
587
-    /**
588
-     * Gets all the extra meta info on this payment
589
-     *
590
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
591
-     * @return EE_Extra_Meta
592
-     * @throws \EE_Error
593
-     */
594
-    public function extra_meta($query_params = array())
595
-    {
596
-        return $this->get_many_related('Extra_Meta', $query_params);
597
-    }
598
-
599
-
600
-    /**
601
-     * Gets the last-used payment method on this transaction
602
-     * (we COULD just use the last-made payment, but some payment methods, namely
603
-     * offline ones, dont' create payments)
604
-     *
605
-     * @return EE_Payment_Method
606
-     * @throws \EE_Error
607
-     */
608
-    public function payment_method()
609
-    {
610
-        return $this->get_first_related('Payment_Method');
611
-    }
612
-
613
-
614
-    /**
615
-     * Gets the HTML for redirecting the user to an offsite gateway
616
-     * You can pass it special content to put inside the form, or use
617
-     * the default inner content (or possibly generate this all yourself using
618
-     * redirect_url() and redirect_args() or redirect_args_as_inputs()).
619
-     * Creates a POST request by default, but if no redirect args are specified, creates a GET request instead
620
-     * (and any querystring variables in the redirect_url are converted into html inputs
621
-     * so browsers submit them properly)
622
-     *
623
-     * @param string $inside_form_html
624
-     * @return string html
625
-     * @throws \EE_Error
626
-     */
627
-    public function redirect_form($inside_form_html = null)
628
-    {
629
-        $redirect_url = $this->redirect_url();
630
-        if (! empty($redirect_url)) {
631
-            // what ? no inner form content?
632
-            if ($inside_form_html === null) {
633
-                $inside_form_html = EEH_HTML::p(
634
-                    sprintf(
635
-                        __(
636
-                            'If you are not automatically redirected to the payment website within 10 seconds... %1$s %2$s Click Here %3$s',
637
-                            'event_espresso'
638
-                        ),
639
-                        EEH_HTML::br(2),
640
-                        '<input type="submit" value="',
641
-                        '">'
642
-                    ),
643
-                    '',
644
-                    '',
645
-                    'text-align:center;'
646
-                );
647
-            }
648
-            $method = apply_filters(
649
-                'FHEE__EE_Payment__redirect_form__method',
650
-                $this->redirect_args() ? 'POST' : 'GET',
651
-                $this
652
-            );
653
-            // if it's a GET request, we need to remove all the GET params in the querystring
654
-            // and put them into the form instead
655
-            if ($method === 'GET') {
656
-                $querystring = parse_url($redirect_url, PHP_URL_QUERY);
657
-                $get_params = null;
658
-                parse_str($querystring, $get_params);
659
-                $inside_form_html .= $this->_args_as_inputs($get_params);
660
-                $redirect_url = str_replace('?' . $querystring, '', $redirect_url);
661
-            }
662
-            $form = EEH_HTML::nl(1)
663
-                    . '<form method="'
664
-                    . $method
665
-                    . '" name="gateway_form" action="'
666
-                    . $redirect_url
667
-                    . '">';
668
-            $form .= EEH_HTML::nl(1) . $this->redirect_args_as_inputs();
669
-            $form .= $inside_form_html;
670
-            $form .= EEH_HTML::nl(-1) . '</form>' . EEH_HTML::nl(-1);
671
-            return $form;
672
-        } else {
673
-            return null;
674
-        }
675
-    }
676
-
677
-
678
-    /**
679
-     * Changes all the name-value pairs of the redirect args into html inputs
680
-     * and returns the html as a string
681
-     *
682
-     * @return string
683
-     * @throws \EE_Error
684
-     */
685
-    public function redirect_args_as_inputs()
686
-    {
687
-        return $this->_args_as_inputs($this->redirect_args());
688
-    }
689
-
690
-
691
-    /**
692
-     * Converts a 1d array of key-value pairs into html hidden inputs
693
-     * and returns the string of html
694
-     *
695
-     * @param array $args key-value pairs
696
-     * @return string
697
-     */
698
-    protected function _args_as_inputs($args)
699
-    {
700
-        $html = '';
701
-        if ($args !== null && is_array($args)) {
702
-            foreach ($args as $name => $value) {
703
-                $html .= EEH_HTML::nl(0)
704
-                         . '<input type="hidden" name="'
705
-                         . $name
706
-                         . '" value="'
707
-                         . esc_attr($value)
708
-                         . '"/>';
709
-            }
710
-        }
711
-        return $html;
712
-    }
713
-
714
-
715
-    /**
716
-     * Returns the currency of the payment.
717
-     * (At the time of writing, this will always be the currency in the configuration;
718
-     * however in the future it is anticipated that this will be stored on the payment
719
-     * object itself)
720
-     *
721
-     * @return string for the currency code
722
-     */
723
-    public function currency_code()
724
-    {
725
-        return EE_Config::instance()->currency->code;
726
-    }
727
-
728
-
729
-    /**
730
-     * apply wp_strip_all_tags to all elements within an array
731
-     *
732
-     * @access private
733
-     * @param mixed $item
734
-     */
735
-    private function _strip_all_tags_within_array(&$item)
736
-    {
737
-        if (is_object($item)) {
738
-            $item = (array) $item;
739
-        }
740
-        if (is_array($item)) {
741
-            array_walk_recursive($item, array($this, '_strip_all_tags_within_array'));
742
-        } else {
743
-            $item = wp_strip_all_tags($item);
744
-        }
745
-    }
746
-
747
-
748
-    /**
749
-     * Returns TRUE is this payment was set to approved during this request (or
750
-     * is approved and was created during this request). False otherwise.
751
-     *
752
-     * @return boolean
753
-     * @throws \EE_Error
754
-     */
755
-    public function just_approved()
756
-    {
757
-        $original_status = EEH_Array::is_set(
758
-            $this->_props_n_values_provided_in_constructor,
759
-            'STS_ID',
760
-            $this->get_model()->field_settings_for('STS_ID')->get_default_value()
761
-        );
762
-        $current_status = $this->status();
763
-        if ($original_status !== EEM_Payment::status_id_approved
764
-            && $current_status === EEM_Payment::status_id_approved
765
-        ) {
766
-            return true;
767
-        } else {
768
-            return false;
769
-        }
770
-    }
771
-
772
-
773
-    /**
774
-     * Overrides parents' get_pretty() function just for legacy reasons
775
-     * (to allow ticket https://events.codebasehq.com/projects/event-espresso/tickets/7420)
776
-     *
777
-     * @param string $field_name
778
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
779
-     *                                (in cases where the same property may be used for different outputs
780
-     *                                - i.e. datetime, money etc.)
781
-     * @return mixed
782
-     * @throws \EE_Error
783
-     */
784
-    public function get_pretty($field_name, $extra_cache_ref = null)
785
-    {
786
-        if ($field_name === 'PAY_gateway') {
787
-            return $this->payment_method() ? $this->payment_method()->name() : __('Unknown', 'event_espresso');
788
-        }
789
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
790
-    }
791
-
792
-
793
-    /**
794
-     * Gets details regarding which registrations this payment was applied to
795
-     *
796
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
797
-     * @return EE_Registration_Payment[]
798
-     * @throws \EE_Error
799
-     */
800
-    public function registration_payments($query_params = array())
801
-    {
802
-        return $this->get_many_related('Registration_Payment', $query_params);
803
-    }
804
-
805
-
806
-    /**
807
-     * Gets the first event for this payment (it's possible that it could be for multiple)
808
-     *
809
-     * @return EE_Event|null
810
-     */
811
-    public function get_first_event()
812
-    {
813
-        $transaction = $this->transaction();
814
-        if ($transaction instanceof EE_Transaction) {
815
-            $primary_registrant = $transaction->primary_registration();
816
-            if ($primary_registrant instanceof EE_Registration) {
817
-                return $primary_registrant->event_obj();
818
-            }
819
-        }
820
-        return null;
821
-    }
822
-
823
-
824
-    /**
825
-     * Gets the name of the first event for which is being paid
826
-     *
827
-     * @return string
828
-     */
829
-    public function get_first_event_name()
830
-    {
831
-        $event = $this->get_first_event();
832
-        return $event instanceof EE_Event ? $event->name() : __('Event', 'event_espresso');
833
-    }
834
-
835
-
836
-    /**
837
-     * Returns the payment's transaction's primary registration
838
-     *
839
-     * @return EE_Registration|null
840
-     */
841
-    public function get_primary_registration()
842
-    {
843
-        if ($this->transaction() instanceof EE_Transaction) {
844
-            return $this->transaction()->primary_registration();
845
-        }
846
-        return null;
847
-    }
848
-
849
-
850
-    /**
851
-     * Gets the payment's transaction's primary registration's attendee, or null
852
-     *
853
-     * @return EE_Attendee|null
854
-     */
855
-    public function get_primary_attendee()
856
-    {
857
-        $primary_reg = $this->get_primary_registration();
858
-        if ($primary_reg instanceof EE_Registration) {
859
-            return $primary_reg->attendee();
860
-        }
861
-        return null;
862
-    }
12
+	/**
13
+	 * @param array  $props_n_values          incoming values
14
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
15
+	 *                                        used.)
16
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
17
+	 *                                        date_format and the second value is the time format
18
+	 * @return EE_Payment
19
+	 * @throws \EE_Error
20
+	 */
21
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
22
+	{
23
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
24
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
25
+	}
26
+
27
+
28
+	/**
29
+	 * @param array  $props_n_values  incoming values from the database
30
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
31
+	 *                                the website will be used.
32
+	 * @return EE_Payment
33
+	 * @throws \EE_Error
34
+	 */
35
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
36
+	{
37
+		return new self($props_n_values, true, $timezone);
38
+	}
39
+
40
+
41
+	/**
42
+	 * Set Transaction ID
43
+	 *
44
+	 * @access public
45
+	 * @param int $TXN_ID
46
+	 * @throws \EE_Error
47
+	 */
48
+	public function set_transaction_id($TXN_ID = 0)
49
+	{
50
+		$this->set('TXN_ID', $TXN_ID);
51
+	}
52
+
53
+
54
+	/**
55
+	 * Gets the transaction related to this payment
56
+	 *
57
+	 * @return EE_Transaction
58
+	 * @throws \EE_Error
59
+	 */
60
+	public function transaction()
61
+	{
62
+		return $this->get_first_related('Transaction');
63
+	}
64
+
65
+
66
+	/**
67
+	 * Set Status
68
+	 *
69
+	 * @access public
70
+	 * @param string $STS_ID
71
+	 * @throws \EE_Error
72
+	 */
73
+	public function set_status($STS_ID = '')
74
+	{
75
+		$this->set('STS_ID', $STS_ID);
76
+	}
77
+
78
+
79
+	/**
80
+	 * Set Payment Timestamp
81
+	 *
82
+	 * @access public
83
+	 * @param int $timestamp
84
+	 * @throws \EE_Error
85
+	 */
86
+	public function set_timestamp($timestamp = 0)
87
+	{
88
+		$this->set('PAY_timestamp', $timestamp);
89
+	}
90
+
91
+
92
+	/**
93
+	 * Set Payment Method
94
+	 *
95
+	 * @access public
96
+	 * @param string $PAY_source
97
+	 * @throws \EE_Error
98
+	 */
99
+	public function set_source($PAY_source = '')
100
+	{
101
+		$this->set('PAY_source', $PAY_source);
102
+	}
103
+
104
+
105
+	/**
106
+	 * Set Payment Amount
107
+	 *
108
+	 * @access public
109
+	 * @param float $amount
110
+	 * @throws \EE_Error
111
+	 */
112
+	public function set_amount($amount = 0.00)
113
+	{
114
+		$this->set('PAY_amount', (float) $amount);
115
+	}
116
+
117
+
118
+	/**
119
+	 * Set Payment Gateway Response
120
+	 *
121
+	 * @access public
122
+	 * @param string $gateway_response
123
+	 * @throws \EE_Error
124
+	 */
125
+	public function set_gateway_response($gateway_response = '')
126
+	{
127
+		$this->set('PAY_gateway_response', $gateway_response);
128
+	}
129
+
130
+
131
+	/**
132
+	 * Returns the name of the payment method used on this payment (previously known merely as 'gateway')
133
+	 * but since 4.6.0, payment methods are models and the payment keeps a foreign key to the payment method
134
+	 * used on it
135
+	 *
136
+	 * @deprecated
137
+	 * @return string
138
+	 * @throws \EE_Error
139
+	 */
140
+	public function gateway()
141
+	{
142
+		EE_Error::doing_it_wrong(
143
+			'EE_Payment::gateway',
144
+			__(
145
+				'The method EE_Payment::gateway() has been deprecated. Consider instead using EE_Payment::payment_method()->name()',
146
+				'event_espresso'
147
+			),
148
+			'4.6.0'
149
+		);
150
+		return $this->payment_method() ? $this->payment_method()->name() : __('Unknown', 'event_espresso');
151
+	}
152
+
153
+
154
+	/**
155
+	 * Set Gateway Transaction ID
156
+	 *
157
+	 * @access public
158
+	 * @param string $txn_id_chq_nmbr
159
+	 * @throws \EE_Error
160
+	 */
161
+	public function set_txn_id_chq_nmbr($txn_id_chq_nmbr = '')
162
+	{
163
+		$this->set('PAY_txn_id_chq_nmbr', $txn_id_chq_nmbr);
164
+	}
165
+
166
+
167
+	/**
168
+	 * Set Purchase Order Number
169
+	 *
170
+	 * @access public
171
+	 * @param string $po_number
172
+	 * @throws \EE_Error
173
+	 */
174
+	public function set_po_number($po_number = '')
175
+	{
176
+		$this->set('PAY_po_number', $po_number);
177
+	}
178
+
179
+
180
+	/**
181
+	 * Set Extra Accounting Field
182
+	 *
183
+	 * @access public
184
+	 * @param string $extra_accntng
185
+	 * @throws \EE_Error
186
+	 */
187
+	public function set_extra_accntng($extra_accntng = '')
188
+	{
189
+		$this->set('PAY_extra_accntng', $extra_accntng);
190
+	}
191
+
192
+
193
+	/**
194
+	 * Set Payment made via admin flag
195
+	 *
196
+	 * @access public
197
+	 * @param bool $via_admin
198
+	 * @throws \EE_Error
199
+	 */
200
+	public function set_payment_made_via_admin($via_admin = false)
201
+	{
202
+		if ($via_admin) {
203
+			$this->set('PAY_source', EEM_Payment_Method::scope_admin);
204
+		} else {
205
+			$this->set('PAY_source', EEM_Payment_Method::scope_cart);
206
+		}
207
+	}
208
+
209
+
210
+	/**
211
+	 * Set Payment Details
212
+	 *
213
+	 * @access public
214
+	 * @param string|array $details
215
+	 * @throws \EE_Error
216
+	 */
217
+	public function set_details($details = '')
218
+	{
219
+		if (is_array($details)) {
220
+			array_walk_recursive($details, array($this, '_strip_all_tags_within_array'));
221
+		} else {
222
+			$details = wp_strip_all_tags($details);
223
+		}
224
+		$this->set('PAY_details', $details);
225
+	}
226
+
227
+
228
+	/**
229
+	 * Sets redirect_url
230
+	 *
231
+	 * @param string $redirect_url
232
+	 * @throws \EE_Error
233
+	 */
234
+	public function set_redirect_url($redirect_url)
235
+	{
236
+		$this->set('PAY_redirect_url', $redirect_url);
237
+	}
238
+
239
+
240
+	/**
241
+	 * Sets redirect_args
242
+	 *
243
+	 * @param array $redirect_args
244
+	 * @throws \EE_Error
245
+	 */
246
+	public function set_redirect_args($redirect_args)
247
+	{
248
+		$this->set('PAY_redirect_args', $redirect_args);
249
+	}
250
+
251
+
252
+	/**
253
+	 * get Payment Transaction ID
254
+	 *
255
+	 * @access public
256
+	 * @throws \EE_Error
257
+	 */
258
+	public function TXN_ID()
259
+	{
260
+		return $this->get('TXN_ID');
261
+	}
262
+
263
+
264
+	/**
265
+	 * get Payment Status
266
+	 *
267
+	 * @access public
268
+	 * @throws \EE_Error
269
+	 */
270
+	public function status()
271
+	{
272
+		return $this->get('STS_ID');
273
+	}
274
+
275
+
276
+	/**
277
+	 * get Payment Status
278
+	 *
279
+	 * @access public
280
+	 * @throws \EE_Error
281
+	 */
282
+	public function STS_ID()
283
+	{
284
+		return $this->get('STS_ID');
285
+	}
286
+
287
+
288
+	/**
289
+	 * get Payment Timestamp
290
+	 *
291
+	 * @access public
292
+	 * @param string $dt_frmt
293
+	 * @param string $tm_frmt
294
+	 * @return string
295
+	 * @throws \EE_Error
296
+	 */
297
+	public function timestamp($dt_frmt = '', $tm_frmt = '')
298
+	{
299
+		return $this->get_i18n_datetime('PAY_timestamp', trim($dt_frmt . ' ' . $tm_frmt));
300
+	}
301
+
302
+
303
+	/**
304
+	 * get Payment Source
305
+	 *
306
+	 * @access public
307
+	 * @throws \EE_Error
308
+	 */
309
+	public function source()
310
+	{
311
+		return $this->get('PAY_source');
312
+	}
313
+
314
+
315
+	/**
316
+	 * get Payment Amount
317
+	 *
318
+	 * @access public
319
+	 * @return float
320
+	 * @throws \EE_Error
321
+	 */
322
+	public function amount()
323
+	{
324
+		return (float) $this->get('PAY_amount');
325
+	}
326
+
327
+
328
+	/**
329
+	 * @return mixed
330
+	 * @throws \EE_Error
331
+	 */
332
+	public function amount_no_code()
333
+	{
334
+		return $this->get_pretty('PAY_amount', 'no_currency_code');
335
+	}
336
+
337
+
338
+	/**
339
+	 * get Payment Gateway Response
340
+	 *
341
+	 * @access public
342
+	 * @throws \EE_Error
343
+	 */
344
+	public function gateway_response()
345
+	{
346
+		return $this->get('PAY_gateway_response');
347
+	}
348
+
349
+
350
+	/**
351
+	 * get Payment Gateway Transaction ID
352
+	 *
353
+	 * @access public
354
+	 * @throws \EE_Error
355
+	 */
356
+	public function txn_id_chq_nmbr()
357
+	{
358
+		return $this->get('PAY_txn_id_chq_nmbr');
359
+	}
360
+
361
+
362
+	/**
363
+	 * get Purchase Order Number
364
+	 *
365
+	 * @access public
366
+	 * @throws \EE_Error
367
+	 */
368
+	public function po_number()
369
+	{
370
+		return $this->get('PAY_po_number');
371
+	}
372
+
373
+
374
+	/**
375
+	 * get Extra Accounting Field
376
+	 *
377
+	 * @access public
378
+	 * @throws \EE_Error
379
+	 */
380
+	public function extra_accntng()
381
+	{
382
+		return $this->get('PAY_extra_accntng');
383
+	}
384
+
385
+
386
+	/**
387
+	 * get Payment made via admin source
388
+	 *
389
+	 * @access public
390
+	 * @throws \EE_Error
391
+	 */
392
+	public function payment_made_via_admin()
393
+	{
394
+		return ($this->get('PAY_source') === EEM_Payment_Method::scope_admin);
395
+	}
396
+
397
+
398
+	/**
399
+	 * get Payment Details
400
+	 *
401
+	 * @access public
402
+	 * @throws \EE_Error
403
+	 */
404
+	public function details()
405
+	{
406
+		return $this->get('PAY_details');
407
+	}
408
+
409
+
410
+	/**
411
+	 * Gets redirect_url
412
+	 *
413
+	 * @return string
414
+	 * @throws \EE_Error
415
+	 */
416
+	public function redirect_url()
417
+	{
418
+		return $this->get('PAY_redirect_url');
419
+	}
420
+
421
+
422
+	/**
423
+	 * Gets redirect_args
424
+	 *
425
+	 * @return array
426
+	 * @throws \EE_Error
427
+	 */
428
+	public function redirect_args()
429
+	{
430
+		return $this->get('PAY_redirect_args');
431
+	}
432
+
433
+
434
+	/**
435
+	 * echoes $this->pretty_status()
436
+	 *
437
+	 * @param bool $show_icons
438
+	 * @return void
439
+	 * @throws \EE_Error
440
+	 */
441
+	public function e_pretty_status($show_icons = false)
442
+	{
443
+		echo $this->pretty_status($show_icons);
444
+	}
445
+
446
+
447
+	/**
448
+	 * returns a pretty version of the status, good for displaying to users
449
+	 *
450
+	 * @param bool $show_icons
451
+	 * @return string
452
+	 * @throws \EE_Error
453
+	 */
454
+	public function pretty_status($show_icons = false)
455
+	{
456
+		$status = EEM_Status::instance()->localized_status(
457
+			array($this->STS_ID() => __('unknown', 'event_espresso')),
458
+			false,
459
+			'sentence'
460
+		);
461
+		$icon = '';
462
+		switch ($this->STS_ID()) {
463
+			case EEM_Payment::status_id_approved:
464
+				$icon = $show_icons
465
+					? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>'
466
+					: '';
467
+				break;
468
+			case EEM_Payment::status_id_pending:
469
+				$icon = $show_icons
470
+					? '<span class="dashicons dashicons-clock ee-icon-size-16 orange-text"></span>'
471
+					: '';
472
+				break;
473
+			case EEM_Payment::status_id_cancelled:
474
+				$icon = $show_icons
475
+					? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
476
+					: '';
477
+				break;
478
+			case EEM_Payment::status_id_declined:
479
+				$icon = $show_icons
480
+					? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
481
+					: '';
482
+				break;
483
+		}
484
+		return $icon . $status[ $this->STS_ID() ];
485
+	}
486
+
487
+
488
+	/**
489
+	 * For determining the status of the payment
490
+	 *
491
+	 * @return boolean whether the payment is approved or not
492
+	 * @throws \EE_Error
493
+	 */
494
+	public function is_approved()
495
+	{
496
+		return $this->status_is(EEM_Payment::status_id_approved);
497
+	}
498
+
499
+
500
+	/**
501
+	 * Generally determines if the status of this payment equals
502
+	 * the $STS_ID string
503
+	 *
504
+	 * @param string $STS_ID an ID from the esp_status table/
505
+	 *                       one of the status_id_* on the EEM_Payment model
506
+	 * @return boolean whether the status of this payment equals the status id
507
+	 * @throws \EE_Error
508
+	 */
509
+	protected function status_is($STS_ID)
510
+	{
511
+		return $STS_ID === $this->STS_ID() ? true : false;
512
+	}
513
+
514
+
515
+	/**
516
+	 * For determining the status of the payment
517
+	 *
518
+	 * @return boolean whether the payment is pending or not
519
+	 * @throws \EE_Error
520
+	 */
521
+	public function is_pending()
522
+	{
523
+		return $this->status_is(EEM_Payment::status_id_pending);
524
+	}
525
+
526
+
527
+	/**
528
+	 * For determining the status of the payment
529
+	 *
530
+	 * @return boolean
531
+	 * @throws \EE_Error
532
+	 */
533
+	public function is_cancelled()
534
+	{
535
+		return $this->status_is(EEM_Payment::status_id_cancelled);
536
+	}
537
+
538
+
539
+	/**
540
+	 * For determining the status of the payment
541
+	 *
542
+	 * @return boolean
543
+	 * @throws \EE_Error
544
+	 */
545
+	public function is_declined()
546
+	{
547
+		return $this->status_is(EEM_Payment::status_id_declined);
548
+	}
549
+
550
+
551
+	/**
552
+	 * For determining the status of the payment
553
+	 *
554
+	 * @return boolean
555
+	 * @throws \EE_Error
556
+	 */
557
+	public function is_failed()
558
+	{
559
+		return $this->status_is(EEM_Payment::status_id_failed);
560
+	}
561
+
562
+
563
+	/**
564
+	 * For determining if the payment is actually a refund ( ie: has a negative value )
565
+	 *
566
+	 * @return boolean
567
+	 * @throws \EE_Error
568
+	 */
569
+	public function is_a_refund()
570
+	{
571
+		return $this->amount() < 0 ? true : false;
572
+	}
573
+
574
+
575
+	/**
576
+	 * Get the status object of this object
577
+	 *
578
+	 * @return EE_Status
579
+	 * @throws \EE_Error
580
+	 */
581
+	public function status_obj()
582
+	{
583
+		return $this->get_first_related('Status');
584
+	}
585
+
586
+
587
+	/**
588
+	 * Gets all the extra meta info on this payment
589
+	 *
590
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
591
+	 * @return EE_Extra_Meta
592
+	 * @throws \EE_Error
593
+	 */
594
+	public function extra_meta($query_params = array())
595
+	{
596
+		return $this->get_many_related('Extra_Meta', $query_params);
597
+	}
598
+
599
+
600
+	/**
601
+	 * Gets the last-used payment method on this transaction
602
+	 * (we COULD just use the last-made payment, but some payment methods, namely
603
+	 * offline ones, dont' create payments)
604
+	 *
605
+	 * @return EE_Payment_Method
606
+	 * @throws \EE_Error
607
+	 */
608
+	public function payment_method()
609
+	{
610
+		return $this->get_first_related('Payment_Method');
611
+	}
612
+
613
+
614
+	/**
615
+	 * Gets the HTML for redirecting the user to an offsite gateway
616
+	 * You can pass it special content to put inside the form, or use
617
+	 * the default inner content (or possibly generate this all yourself using
618
+	 * redirect_url() and redirect_args() or redirect_args_as_inputs()).
619
+	 * Creates a POST request by default, but if no redirect args are specified, creates a GET request instead
620
+	 * (and any querystring variables in the redirect_url are converted into html inputs
621
+	 * so browsers submit them properly)
622
+	 *
623
+	 * @param string $inside_form_html
624
+	 * @return string html
625
+	 * @throws \EE_Error
626
+	 */
627
+	public function redirect_form($inside_form_html = null)
628
+	{
629
+		$redirect_url = $this->redirect_url();
630
+		if (! empty($redirect_url)) {
631
+			// what ? no inner form content?
632
+			if ($inside_form_html === null) {
633
+				$inside_form_html = EEH_HTML::p(
634
+					sprintf(
635
+						__(
636
+							'If you are not automatically redirected to the payment website within 10 seconds... %1$s %2$s Click Here %3$s',
637
+							'event_espresso'
638
+						),
639
+						EEH_HTML::br(2),
640
+						'<input type="submit" value="',
641
+						'">'
642
+					),
643
+					'',
644
+					'',
645
+					'text-align:center;'
646
+				);
647
+			}
648
+			$method = apply_filters(
649
+				'FHEE__EE_Payment__redirect_form__method',
650
+				$this->redirect_args() ? 'POST' : 'GET',
651
+				$this
652
+			);
653
+			// if it's a GET request, we need to remove all the GET params in the querystring
654
+			// and put them into the form instead
655
+			if ($method === 'GET') {
656
+				$querystring = parse_url($redirect_url, PHP_URL_QUERY);
657
+				$get_params = null;
658
+				parse_str($querystring, $get_params);
659
+				$inside_form_html .= $this->_args_as_inputs($get_params);
660
+				$redirect_url = str_replace('?' . $querystring, '', $redirect_url);
661
+			}
662
+			$form = EEH_HTML::nl(1)
663
+					. '<form method="'
664
+					. $method
665
+					. '" name="gateway_form" action="'
666
+					. $redirect_url
667
+					. '">';
668
+			$form .= EEH_HTML::nl(1) . $this->redirect_args_as_inputs();
669
+			$form .= $inside_form_html;
670
+			$form .= EEH_HTML::nl(-1) . '</form>' . EEH_HTML::nl(-1);
671
+			return $form;
672
+		} else {
673
+			return null;
674
+		}
675
+	}
676
+
677
+
678
+	/**
679
+	 * Changes all the name-value pairs of the redirect args into html inputs
680
+	 * and returns the html as a string
681
+	 *
682
+	 * @return string
683
+	 * @throws \EE_Error
684
+	 */
685
+	public function redirect_args_as_inputs()
686
+	{
687
+		return $this->_args_as_inputs($this->redirect_args());
688
+	}
689
+
690
+
691
+	/**
692
+	 * Converts a 1d array of key-value pairs into html hidden inputs
693
+	 * and returns the string of html
694
+	 *
695
+	 * @param array $args key-value pairs
696
+	 * @return string
697
+	 */
698
+	protected function _args_as_inputs($args)
699
+	{
700
+		$html = '';
701
+		if ($args !== null && is_array($args)) {
702
+			foreach ($args as $name => $value) {
703
+				$html .= EEH_HTML::nl(0)
704
+						 . '<input type="hidden" name="'
705
+						 . $name
706
+						 . '" value="'
707
+						 . esc_attr($value)
708
+						 . '"/>';
709
+			}
710
+		}
711
+		return $html;
712
+	}
713
+
714
+
715
+	/**
716
+	 * Returns the currency of the payment.
717
+	 * (At the time of writing, this will always be the currency in the configuration;
718
+	 * however in the future it is anticipated that this will be stored on the payment
719
+	 * object itself)
720
+	 *
721
+	 * @return string for the currency code
722
+	 */
723
+	public function currency_code()
724
+	{
725
+		return EE_Config::instance()->currency->code;
726
+	}
727
+
728
+
729
+	/**
730
+	 * apply wp_strip_all_tags to all elements within an array
731
+	 *
732
+	 * @access private
733
+	 * @param mixed $item
734
+	 */
735
+	private function _strip_all_tags_within_array(&$item)
736
+	{
737
+		if (is_object($item)) {
738
+			$item = (array) $item;
739
+		}
740
+		if (is_array($item)) {
741
+			array_walk_recursive($item, array($this, '_strip_all_tags_within_array'));
742
+		} else {
743
+			$item = wp_strip_all_tags($item);
744
+		}
745
+	}
746
+
747
+
748
+	/**
749
+	 * Returns TRUE is this payment was set to approved during this request (or
750
+	 * is approved and was created during this request). False otherwise.
751
+	 *
752
+	 * @return boolean
753
+	 * @throws \EE_Error
754
+	 */
755
+	public function just_approved()
756
+	{
757
+		$original_status = EEH_Array::is_set(
758
+			$this->_props_n_values_provided_in_constructor,
759
+			'STS_ID',
760
+			$this->get_model()->field_settings_for('STS_ID')->get_default_value()
761
+		);
762
+		$current_status = $this->status();
763
+		if ($original_status !== EEM_Payment::status_id_approved
764
+			&& $current_status === EEM_Payment::status_id_approved
765
+		) {
766
+			return true;
767
+		} else {
768
+			return false;
769
+		}
770
+	}
771
+
772
+
773
+	/**
774
+	 * Overrides parents' get_pretty() function just for legacy reasons
775
+	 * (to allow ticket https://events.codebasehq.com/projects/event-espresso/tickets/7420)
776
+	 *
777
+	 * @param string $field_name
778
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
779
+	 *                                (in cases where the same property may be used for different outputs
780
+	 *                                - i.e. datetime, money etc.)
781
+	 * @return mixed
782
+	 * @throws \EE_Error
783
+	 */
784
+	public function get_pretty($field_name, $extra_cache_ref = null)
785
+	{
786
+		if ($field_name === 'PAY_gateway') {
787
+			return $this->payment_method() ? $this->payment_method()->name() : __('Unknown', 'event_espresso');
788
+		}
789
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
790
+	}
791
+
792
+
793
+	/**
794
+	 * Gets details regarding which registrations this payment was applied to
795
+	 *
796
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
797
+	 * @return EE_Registration_Payment[]
798
+	 * @throws \EE_Error
799
+	 */
800
+	public function registration_payments($query_params = array())
801
+	{
802
+		return $this->get_many_related('Registration_Payment', $query_params);
803
+	}
804
+
805
+
806
+	/**
807
+	 * Gets the first event for this payment (it's possible that it could be for multiple)
808
+	 *
809
+	 * @return EE_Event|null
810
+	 */
811
+	public function get_first_event()
812
+	{
813
+		$transaction = $this->transaction();
814
+		if ($transaction instanceof EE_Transaction) {
815
+			$primary_registrant = $transaction->primary_registration();
816
+			if ($primary_registrant instanceof EE_Registration) {
817
+				return $primary_registrant->event_obj();
818
+			}
819
+		}
820
+		return null;
821
+	}
822
+
823
+
824
+	/**
825
+	 * Gets the name of the first event for which is being paid
826
+	 *
827
+	 * @return string
828
+	 */
829
+	public function get_first_event_name()
830
+	{
831
+		$event = $this->get_first_event();
832
+		return $event instanceof EE_Event ? $event->name() : __('Event', 'event_espresso');
833
+	}
834
+
835
+
836
+	/**
837
+	 * Returns the payment's transaction's primary registration
838
+	 *
839
+	 * @return EE_Registration|null
840
+	 */
841
+	public function get_primary_registration()
842
+	{
843
+		if ($this->transaction() instanceof EE_Transaction) {
844
+			return $this->transaction()->primary_registration();
845
+		}
846
+		return null;
847
+	}
848
+
849
+
850
+	/**
851
+	 * Gets the payment's transaction's primary registration's attendee, or null
852
+	 *
853
+	 * @return EE_Attendee|null
854
+	 */
855
+	public function get_primary_attendee()
856
+	{
857
+		$primary_reg = $this->get_primary_registration();
858
+		if ($primary_reg instanceof EE_Registration) {
859
+			return $primary_reg->attendee();
860
+		}
861
+		return null;
862
+	}
863 863
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Soft_Delete_Base.model.php 2 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -201,7 +201,7 @@  discard block
 block discarded – undo
201 201
      *
202 202
      * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
203 203
      * @param string $field_to_sum
204
-     * @return int
204
+     * @return double
205 205
      */
206 206
     public function sum_deleted($query_params = null, $field_to_sum = null)
207 207
     {
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
      * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info
267 267
      *                                that blocks it (ie, there' sno other data that depends on this data); if false, deletes regardless of other objects
268 268
      *                                which may depend on it. Its generally advisable to always leave this as TRUE, otherwise you could easily corrupt your DB
269
-     * @return boolean success
269
+     * @return integer success
270 270
      */
271 271
     public function delete_permanently($query_params = array(), $allow_blocking = true)
272 272
     {
Please login to merge, or discard this patch.
Indentation   +359 added lines, -359 removed lines patch added patch discarded remove patch
@@ -26,363 +26,363 @@
 block discarded – undo
26 26
 abstract class EEM_Soft_Delete_Base extends EEM_Base
27 27
 {
28 28
 
29
-    /**
30
-     * @param null $timezone
31
-     */
32
-    protected function __construct($timezone = null)
33
-    {
34
-        if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
35
-            $this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions();
36
-        }
37
-        parent::__construct($timezone);
38
-    }
39
-
40
-
41
-
42
-    /**
43
-     * Searches for field on this model of type 'deleted_flag'. if it is found,
44
-     * returns it's name.
45
-     *
46
-     * @return string
47
-     * @throws EE_Error
48
-     */
49
-    public function deleted_field_name()
50
-    {
51
-        $field = $this->get_a_field_of_type('EE_Trashed_Flag_Field');
52
-        if ($field) {
53
-            return $field->get_name();
54
-        } else {
55
-            throw new EE_Error(sprintf(__(
56
-                'We are trying to find the deleted flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
57
-                'event_espresso'
58
-            ), get_class($this), get_class($this)));
59
-        }
60
-    }
61
-
62
-
63
-
64
-    /**
65
-     * Gets one item that's been deleted, according to $query_params
66
-     *
67
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
68
-     * @return EE_Soft_Delete_Base_Class
69
-     */
70
-    public function get_one_deleted($query_params = array())
71
-    {
72
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
73
-        return parent::get_one($query_params);
74
-    }
75
-
76
-
77
-
78
-    /**
79
-     * Gets one item from the DB, regardless of whether it's been soft-deleted or not
80
-     *
81
-     * @param array $query_params like EEM_base::get_all's $query_params
82
-     * @return EE_Soft_Delete_Base_Class
83
-     */
84
-    public function get_one_deleted_or_undeleted($query_params = array())
85
-    {
86
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
87
-        return parent::get_one($query_params);
88
-    }
89
-
90
-
91
-
92
-    /**
93
-     * Gets the item indicated by its ID. But if it's soft-deleted, pretends it doesn't exist.
94
-     *
95
-     * @param int|string $id
96
-     * @return EE_Soft_Delete_Base_Class
97
-     */
98
-    public function get_one_by_ID_but_ignore_deleted($id)
99
-    {
100
-        return $this->get_one(
101
-            $this->alter_query_params_to_restrict_by_ID(
102
-                $id,
103
-                array('default_where_conditions' => 'default')
104
-            )
105
-        );
106
-    }
107
-
108
-
109
-
110
-    /**
111
-     * Counts all the deleted/trashed items
112
-     *
113
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
114
-     * @param string $field_to_count
115
-     * @param bool   $distinct     if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE;
116
-     * @return int
117
-     */
118
-    public function count_deleted($query_params = null, $field_to_count = null, $distinct = false)
119
-    {
120
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
121
-        return parent::count($query_params, $field_to_count, $distinct);
122
-    }
123
-
124
-
125
-
126
-    /**
127
-     * Alters the query params so that only trashed/soft-deleted items are considered
128
-     *
129
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
130
-     * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
131
-     */
132
-    protected function _alter_query_params_so_only_trashed_items_included($query_params)
133
-    {
134
-        $deletedFlagFieldName = $this->deleted_field_name();
135
-        $query_params[0][ $deletedFlagFieldName ] = true;
136
-        return $query_params;
137
-    }
138
-
139
-
140
-
141
-    /**
142
-     * Alters the query params so that only trashed/soft-deleted items are considered
143
-     *
144
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
145
-     * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
146
-     */
147
-    public function alter_query_params_so_only_trashed_items_included($query_params)
148
-    {
149
-        return $this->_alter_query_params_so_only_trashed_items_included($query_params);
150
-    }
151
-
152
-
153
-
154
-    /**
155
-     * Alters the query params so each item's deleted status is ignored.
156
-     *
157
-     * @param array $query_params
158
-     * @return array
159
-     */
160
-    public function alter_query_params_so_deleted_and_undeleted_items_included($query_params = array())
161
-    {
162
-        return $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
163
-    }
164
-
165
-
166
-
167
-    /**
168
-     * Alters the query params so each item's deleted status is ignored.
169
-     *
170
-     * @param array $query_params
171
-     * @return array
172
-     */
173
-    protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
174
-    {
175
-        if (! isset($query_params['default_where_conditions'])) {
176
-            $query_params['default_where_conditions'] = 'minimum';
177
-        }
178
-        return $query_params;
179
-    }
180
-
181
-
182
-
183
-    /**
184
-     * Counts all deleted and undeleted items
185
-     *
186
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
187
-     * @param string $field_to_count
188
-     * @param bool   $distinct     if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE;
189
-     * @return int
190
-     */
191
-    public function count_deleted_and_undeleted($query_params = null, $field_to_count = null, $distinct = false)
192
-    {
193
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
194
-        return parent::count($query_params, $field_to_count, $distinct);
195
-    }
196
-
197
-
198
-
199
-    /**
200
-     * Sum all the deleted items.
201
-     *
202
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
203
-     * @param string $field_to_sum
204
-     * @return int
205
-     */
206
-    public function sum_deleted($query_params = null, $field_to_sum = null)
207
-    {
208
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
209
-        return parent::sum($query_params, $field_to_sum);
210
-    }
211
-
212
-
213
-
214
-    /**
215
-     * Sums all the deleted and undeleted items.
216
-     *
217
-     * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
218
-     * @param string $field_to_sum
219
-     * @return int
220
-     */
221
-    public function sum_deleted_and_undeleted($query_params = null, $field_to_sum = null)
222
-    {
223
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
224
-        parent::sum($query_params, $field_to_sum);
225
-    }
226
-
227
-
228
-
229
-    /**
230
-     * Gets all deleted and undeleted mode objects from the db that meet the criteria, regardless of
231
-     * whether they've been soft-deleted or not
232
-     *
233
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
234
-     * @return EE_Soft_Delete_Base_Class[]
235
-     */
236
-    public function get_all_deleted_and_undeleted($query_params = array())
237
-    {
238
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
239
-        return parent::get_all($query_params);
240
-    }
241
-
242
-
243
-
244
-    /**
245
-     * For 'soft deletable' models, gets all which ARE deleted, according to conditions specified in $query_params.
246
-     *
247
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
248
-     * @return EE_Soft_Delete_Base_Class[]
249
-     */
250
-    public function get_all_deleted($query_params = array())
251
-    {
252
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
253
-        return parent::get_all($query_params);
254
-    }
255
-
256
-
257
-
258
-    /**
259
-     * Permanently deletes the selected rows. When selecting rows for deletion, ignores
260
-     * whether they've been soft-deleted or not. (ie, you don't have to soft-delete objects
261
-     * before you can permanently delete them).
262
-     * Because this will cause a real deletion, related models may block this deletion (ie, add an error
263
-     * and abort the delete)
264
-     *
265
-     * @param array   $query_params   @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
266
-     * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info
267
-     *                                that blocks it (ie, there' sno other data that depends on this data); if false, deletes regardless of other objects
268
-     *                                which may depend on it. Its generally advisable to always leave this as TRUE, otherwise you could easily corrupt your DB
269
-     * @return boolean success
270
-     */
271
-    public function delete_permanently($query_params = array(), $allow_blocking = true)
272
-    {
273
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
274
-        return parent::delete_permanently($query_params, $allow_blocking);
275
-    }
276
-
277
-
278
-
279
-    /**
280
-     * Restores a particular item by its ID (primary key). Ignores the fact whether the item
281
-     * has been soft-deleted or not.
282
-     *
283
-     * @param mixed $ID int if primary key is an int, string otherwise
284
-     * @return boolean success
285
-     */
286
-    public function restore_by_ID($ID = false)
287
-    {
288
-        return $this->delete_or_restore_by_ID(false, $ID);
289
-    }
290
-
291
-
292
-
293
-    /**
294
-     * For deleting or restoring a particular item. Note that this model is a SOFT-DELETABLE model! However,
295
-     * this function will ignore whether the items have been soft-deleted or not.
296
-     *
297
-     * @param boolean $delete true for delete, false for restore
298
-     * @param mixed   $ID     int if primary key is an int, string otherwise
299
-     * @return boolean
300
-     */
301
-    public function delete_or_restore_by_ID($delete = true, $ID = false)
302
-    {
303
-        if (! $ID) {
304
-            return false;
305
-        }
306
-        if ($this->delete_or_restore(
307
-            $delete,
308
-            $this->alter_query_params_to_restrict_by_ID($ID)
309
-        )
310
-        ) {
311
-            return true;
312
-        } else {
313
-            return false;
314
-        }
315
-    }
316
-
317
-
318
-
319
-    /**
320
-     * Overrides parent's 'delete' method to instead do a soft delete on all rows that
321
-     * meet the criteria in $where_col_n_values. This particular function ignores whether the items have been soft-deleted or not.
322
-     * Note: because this item will be soft-deleted only,
323
-     * doesn't block because of model dependencies
324
-     *
325
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
326
-     * @param bool  $block_deletes
327
-     * @return boolean
328
-     */
329
-    public function delete($query_params = array(), $block_deletes = false)
330
-    {
331
-        // no matter what, we WON'T block soft deletes.
332
-        return $this->delete_or_restore(true, $query_params);
333
-    }
334
-
335
-
336
-
337
-    /**
338
-     * 'Un-deletes' the chosen items. Note that this model is a SOFT-DELETABLE model! That means that, by default, trashed/soft-deleted
339
-     * items are ignored in queries. However, this particular function ignores whether the items have been soft-deleted or not.
340
-     *
341
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
342
-     * @return boolean
343
-     */
344
-    public function restore($query_params = array())
345
-    {
346
-        return $this->delete_or_restore(false, $query_params);
347
-    }
348
-
349
-
350
-
351
-    /**
352
-     * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
353
-     *
354
-     * @param boolean $delete       true to indicate deletion, false to indicate restoration
355
-     * @param array   $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
356
-     * @return boolean
357
-     */
358
-    public function delete_or_restore($delete = true, $query_params = array())
359
-    {
360
-        $deletedFlagFieldName = $this->deleted_field_name();
361
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
362
-        if ($this->update(array($deletedFlagFieldName => $delete), $query_params)) {
363
-            return true;
364
-        } else {
365
-            return false;
366
-        }
367
-    }
368
-
369
-
370
-
371
-    /**
372
-     * Updates all the items of this model which match the $query params, regardless of whether
373
-     * they've been soft-deleted or not
374
-     *
375
-     * @param array   $fields_n_values         like EEM_Base::update's $fields_n_value
376
-     * @param array   $query_params            like EEM_base::get_all's $query_params
377
-     * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects
378
-     *                                         in this model's entity map according to $fields_n_values that match $query_params. This
379
-     *                                         obviously has some overhead, so you can disable it by setting this to FALSE, but
380
-     *                                         be aware that model objects being used could get out-of-sync with the database
381
-     * @return int number of items updated
382
-     */
383
-    public function update_deleted_and_undeleted($fields_n_values, $query_params, $keep_model_objs_in_sync = true)
384
-    {
385
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
386
-        return $this->update($fields_n_values, $query_params, $keep_model_objs_in_sync);
387
-    }
29
+	/**
30
+	 * @param null $timezone
31
+	 */
32
+	protected function __construct($timezone = null)
33
+	{
34
+		if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
35
+			$this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions();
36
+		}
37
+		parent::__construct($timezone);
38
+	}
39
+
40
+
41
+
42
+	/**
43
+	 * Searches for field on this model of type 'deleted_flag'. if it is found,
44
+	 * returns it's name.
45
+	 *
46
+	 * @return string
47
+	 * @throws EE_Error
48
+	 */
49
+	public function deleted_field_name()
50
+	{
51
+		$field = $this->get_a_field_of_type('EE_Trashed_Flag_Field');
52
+		if ($field) {
53
+			return $field->get_name();
54
+		} else {
55
+			throw new EE_Error(sprintf(__(
56
+				'We are trying to find the deleted flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
57
+				'event_espresso'
58
+			), get_class($this), get_class($this)));
59
+		}
60
+	}
61
+
62
+
63
+
64
+	/**
65
+	 * Gets one item that's been deleted, according to $query_params
66
+	 *
67
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
68
+	 * @return EE_Soft_Delete_Base_Class
69
+	 */
70
+	public function get_one_deleted($query_params = array())
71
+	{
72
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
73
+		return parent::get_one($query_params);
74
+	}
75
+
76
+
77
+
78
+	/**
79
+	 * Gets one item from the DB, regardless of whether it's been soft-deleted or not
80
+	 *
81
+	 * @param array $query_params like EEM_base::get_all's $query_params
82
+	 * @return EE_Soft_Delete_Base_Class
83
+	 */
84
+	public function get_one_deleted_or_undeleted($query_params = array())
85
+	{
86
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
87
+		return parent::get_one($query_params);
88
+	}
89
+
90
+
91
+
92
+	/**
93
+	 * Gets the item indicated by its ID. But if it's soft-deleted, pretends it doesn't exist.
94
+	 *
95
+	 * @param int|string $id
96
+	 * @return EE_Soft_Delete_Base_Class
97
+	 */
98
+	public function get_one_by_ID_but_ignore_deleted($id)
99
+	{
100
+		return $this->get_one(
101
+			$this->alter_query_params_to_restrict_by_ID(
102
+				$id,
103
+				array('default_where_conditions' => 'default')
104
+			)
105
+		);
106
+	}
107
+
108
+
109
+
110
+	/**
111
+	 * Counts all the deleted/trashed items
112
+	 *
113
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
114
+	 * @param string $field_to_count
115
+	 * @param bool   $distinct     if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE;
116
+	 * @return int
117
+	 */
118
+	public function count_deleted($query_params = null, $field_to_count = null, $distinct = false)
119
+	{
120
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
121
+		return parent::count($query_params, $field_to_count, $distinct);
122
+	}
123
+
124
+
125
+
126
+	/**
127
+	 * Alters the query params so that only trashed/soft-deleted items are considered
128
+	 *
129
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
130
+	 * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
131
+	 */
132
+	protected function _alter_query_params_so_only_trashed_items_included($query_params)
133
+	{
134
+		$deletedFlagFieldName = $this->deleted_field_name();
135
+		$query_params[0][ $deletedFlagFieldName ] = true;
136
+		return $query_params;
137
+	}
138
+
139
+
140
+
141
+	/**
142
+	 * Alters the query params so that only trashed/soft-deleted items are considered
143
+	 *
144
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
145
+	 * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
146
+	 */
147
+	public function alter_query_params_so_only_trashed_items_included($query_params)
148
+	{
149
+		return $this->_alter_query_params_so_only_trashed_items_included($query_params);
150
+	}
151
+
152
+
153
+
154
+	/**
155
+	 * Alters the query params so each item's deleted status is ignored.
156
+	 *
157
+	 * @param array $query_params
158
+	 * @return array
159
+	 */
160
+	public function alter_query_params_so_deleted_and_undeleted_items_included($query_params = array())
161
+	{
162
+		return $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
163
+	}
164
+
165
+
166
+
167
+	/**
168
+	 * Alters the query params so each item's deleted status is ignored.
169
+	 *
170
+	 * @param array $query_params
171
+	 * @return array
172
+	 */
173
+	protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
174
+	{
175
+		if (! isset($query_params['default_where_conditions'])) {
176
+			$query_params['default_where_conditions'] = 'minimum';
177
+		}
178
+		return $query_params;
179
+	}
180
+
181
+
182
+
183
+	/**
184
+	 * Counts all deleted and undeleted items
185
+	 *
186
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
187
+	 * @param string $field_to_count
188
+	 * @param bool   $distinct     if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE;
189
+	 * @return int
190
+	 */
191
+	public function count_deleted_and_undeleted($query_params = null, $field_to_count = null, $distinct = false)
192
+	{
193
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
194
+		return parent::count($query_params, $field_to_count, $distinct);
195
+	}
196
+
197
+
198
+
199
+	/**
200
+	 * Sum all the deleted items.
201
+	 *
202
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
203
+	 * @param string $field_to_sum
204
+	 * @return int
205
+	 */
206
+	public function sum_deleted($query_params = null, $field_to_sum = null)
207
+	{
208
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
209
+		return parent::sum($query_params, $field_to_sum);
210
+	}
211
+
212
+
213
+
214
+	/**
215
+	 * Sums all the deleted and undeleted items.
216
+	 *
217
+	 * @param array  $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
218
+	 * @param string $field_to_sum
219
+	 * @return int
220
+	 */
221
+	public function sum_deleted_and_undeleted($query_params = null, $field_to_sum = null)
222
+	{
223
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
224
+		parent::sum($query_params, $field_to_sum);
225
+	}
226
+
227
+
228
+
229
+	/**
230
+	 * Gets all deleted and undeleted mode objects from the db that meet the criteria, regardless of
231
+	 * whether they've been soft-deleted or not
232
+	 *
233
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
234
+	 * @return EE_Soft_Delete_Base_Class[]
235
+	 */
236
+	public function get_all_deleted_and_undeleted($query_params = array())
237
+	{
238
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
239
+		return parent::get_all($query_params);
240
+	}
241
+
242
+
243
+
244
+	/**
245
+	 * For 'soft deletable' models, gets all which ARE deleted, according to conditions specified in $query_params.
246
+	 *
247
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
248
+	 * @return EE_Soft_Delete_Base_Class[]
249
+	 */
250
+	public function get_all_deleted($query_params = array())
251
+	{
252
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
253
+		return parent::get_all($query_params);
254
+	}
255
+
256
+
257
+
258
+	/**
259
+	 * Permanently deletes the selected rows. When selecting rows for deletion, ignores
260
+	 * whether they've been soft-deleted or not. (ie, you don't have to soft-delete objects
261
+	 * before you can permanently delete them).
262
+	 * Because this will cause a real deletion, related models may block this deletion (ie, add an error
263
+	 * and abort the delete)
264
+	 *
265
+	 * @param array   $query_params   @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
266
+	 * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info
267
+	 *                                that blocks it (ie, there' sno other data that depends on this data); if false, deletes regardless of other objects
268
+	 *                                which may depend on it. Its generally advisable to always leave this as TRUE, otherwise you could easily corrupt your DB
269
+	 * @return boolean success
270
+	 */
271
+	public function delete_permanently($query_params = array(), $allow_blocking = true)
272
+	{
273
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
274
+		return parent::delete_permanently($query_params, $allow_blocking);
275
+	}
276
+
277
+
278
+
279
+	/**
280
+	 * Restores a particular item by its ID (primary key). Ignores the fact whether the item
281
+	 * has been soft-deleted or not.
282
+	 *
283
+	 * @param mixed $ID int if primary key is an int, string otherwise
284
+	 * @return boolean success
285
+	 */
286
+	public function restore_by_ID($ID = false)
287
+	{
288
+		return $this->delete_or_restore_by_ID(false, $ID);
289
+	}
290
+
291
+
292
+
293
+	/**
294
+	 * For deleting or restoring a particular item. Note that this model is a SOFT-DELETABLE model! However,
295
+	 * this function will ignore whether the items have been soft-deleted or not.
296
+	 *
297
+	 * @param boolean $delete true for delete, false for restore
298
+	 * @param mixed   $ID     int if primary key is an int, string otherwise
299
+	 * @return boolean
300
+	 */
301
+	public function delete_or_restore_by_ID($delete = true, $ID = false)
302
+	{
303
+		if (! $ID) {
304
+			return false;
305
+		}
306
+		if ($this->delete_or_restore(
307
+			$delete,
308
+			$this->alter_query_params_to_restrict_by_ID($ID)
309
+		)
310
+		) {
311
+			return true;
312
+		} else {
313
+			return false;
314
+		}
315
+	}
316
+
317
+
318
+
319
+	/**
320
+	 * Overrides parent's 'delete' method to instead do a soft delete on all rows that
321
+	 * meet the criteria in $where_col_n_values. This particular function ignores whether the items have been soft-deleted or not.
322
+	 * Note: because this item will be soft-deleted only,
323
+	 * doesn't block because of model dependencies
324
+	 *
325
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
326
+	 * @param bool  $block_deletes
327
+	 * @return boolean
328
+	 */
329
+	public function delete($query_params = array(), $block_deletes = false)
330
+	{
331
+		// no matter what, we WON'T block soft deletes.
332
+		return $this->delete_or_restore(true, $query_params);
333
+	}
334
+
335
+
336
+
337
+	/**
338
+	 * 'Un-deletes' the chosen items. Note that this model is a SOFT-DELETABLE model! That means that, by default, trashed/soft-deleted
339
+	 * items are ignored in queries. However, this particular function ignores whether the items have been soft-deleted or not.
340
+	 *
341
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
342
+	 * @return boolean
343
+	 */
344
+	public function restore($query_params = array())
345
+	{
346
+		return $this->delete_or_restore(false, $query_params);
347
+	}
348
+
349
+
350
+
351
+	/**
352
+	 * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
353
+	 *
354
+	 * @param boolean $delete       true to indicate deletion, false to indicate restoration
355
+	 * @param array   $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
356
+	 * @return boolean
357
+	 */
358
+	public function delete_or_restore($delete = true, $query_params = array())
359
+	{
360
+		$deletedFlagFieldName = $this->deleted_field_name();
361
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
362
+		if ($this->update(array($deletedFlagFieldName => $delete), $query_params)) {
363
+			return true;
364
+		} else {
365
+			return false;
366
+		}
367
+	}
368
+
369
+
370
+
371
+	/**
372
+	 * Updates all the items of this model which match the $query params, regardless of whether
373
+	 * they've been soft-deleted or not
374
+	 *
375
+	 * @param array   $fields_n_values         like EEM_Base::update's $fields_n_value
376
+	 * @param array   $query_params            like EEM_base::get_all's $query_params
377
+	 * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects
378
+	 *                                         in this model's entity map according to $fields_n_values that match $query_params. This
379
+	 *                                         obviously has some overhead, so you can disable it by setting this to FALSE, but
380
+	 *                                         be aware that model objects being used could get out-of-sync with the database
381
+	 * @return int number of items updated
382
+	 */
383
+	public function update_deleted_and_undeleted($fields_n_values, $query_params, $keep_model_objs_in_sync = true)
384
+	{
385
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
386
+		return $this->update($fields_n_values, $query_params, $keep_model_objs_in_sync);
387
+	}
388 388
 }
Please login to merge, or discard this patch.
core/db_models/strategies/EE_CPT_Minimum_Where_Conditions.strategy.php 2 patches
Doc Comments   +4 added lines, -1 removed lines patch added patch discarded remove patch
@@ -18,6 +18,10 @@  discard block
 block discarded – undo
18 18
 
19 19
     protected $_post_type;
20 20
     protected $_meta_field;
21
+
22
+    /**
23
+     * @param string $post_type
24
+     */
21 25
     public function __construct($post_type, $meta_field_to_chk = '')
22 26
     {
23 27
         $this->_post_type = $post_type;
@@ -40,7 +44,6 @@  discard block
 block discarded – undo
40 44
     }
41 45
     /**
42 46
      * Gets the where default where conditions for a custom post type model
43
-     * @param string $model_relation_path. Eg, from Event to Payment, this should be "Registration.Transaction.Payment"
44 47
      * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
45 48
      */
46 49
     protected function _get_default_where_conditions()
Please login to merge, or discard this patch.
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 /**
4 4
  *
5 5
  * Class EE_CPT_Minimum_Where_Conditions
6
-  *
6
+ *
7 7
  * Strategy specifically for adding where conditions specific to CPT models.
8 8
  * But only sets the minimum, so any row of the right type will get used
9 9
  *
@@ -16,39 +16,39 @@  discard block
 block discarded – undo
16 16
 class EE_CPT_Minimum_Where_Conditions extends EE_Default_Where_Conditions
17 17
 {
18 18
 
19
-    protected $_post_type;
20
-    protected $_meta_field;
21
-    public function __construct($post_type, $meta_field_to_chk = '')
22
-    {
23
-        $this->_post_type = $post_type;
24
-        $this->_meta_field = $meta_field_to_chk;
25
-    }
26
-    /**
27
-     * Gets the field with the specified column. Note, this function might not work
28
-     * properly if two fields refer to columns with the same name on different tables
29
-     * @param string $column column name
30
-     * @return EE_Model_Field_Base
31
-     */
32
-    protected function _get_field_on_column($column)
33
-    {
34
-        $all_fields = $this->_model->field_settings(true);
35
-        foreach ($all_fields as $field_name => $field_obj) {
36
-            if ($column == $field_obj->get_table_column()) {
37
-                return $field_obj;
38
-            }
39
-        }
40
-    }
41
-    /**
42
-     * Gets the where default where conditions for a custom post type model
43
-     * @param string $model_relation_path. Eg, from Event to Payment, this should be "Registration.Transaction.Payment"
44
-     * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
45
-     */
46
-    protected function _get_default_where_conditions()
47
-    {
48
-        // find post_type field
49
-        $post_type_field = $this->_get_field_on_column('post_type');
50
-        return array(
51
-            $post_type_field->get_name() => $this->_post_type
52
-        );
53
-    }
19
+	protected $_post_type;
20
+	protected $_meta_field;
21
+	public function __construct($post_type, $meta_field_to_chk = '')
22
+	{
23
+		$this->_post_type = $post_type;
24
+		$this->_meta_field = $meta_field_to_chk;
25
+	}
26
+	/**
27
+	 * Gets the field with the specified column. Note, this function might not work
28
+	 * properly if two fields refer to columns with the same name on different tables
29
+	 * @param string $column column name
30
+	 * @return EE_Model_Field_Base
31
+	 */
32
+	protected function _get_field_on_column($column)
33
+	{
34
+		$all_fields = $this->_model->field_settings(true);
35
+		foreach ($all_fields as $field_name => $field_obj) {
36
+			if ($column == $field_obj->get_table_column()) {
37
+				return $field_obj;
38
+			}
39
+		}
40
+	}
41
+	/**
42
+	 * Gets the where default where conditions for a custom post type model
43
+	 * @param string $model_relation_path. Eg, from Event to Payment, this should be "Registration.Transaction.Payment"
44
+	 * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
45
+	 */
46
+	protected function _get_default_where_conditions()
47
+	{
48
+		// find post_type field
49
+		$post_type_field = $this->_get_field_on_column('post_type');
50
+		return array(
51
+			$post_type_field->get_name() => $this->_post_type
52
+		);
53
+	}
54 54
 }
Please login to merge, or discard this patch.