Completed
Branch FET/rest-relation-endpoints (393bb8)
by
unknown
30:20 queued 20:04
created

Write::getBothModelObjects()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26

Duplication

Lines 15
Ratio 57.69 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 15
loc 26
rs 9.504
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\libraries\rest_api\controllers\model;
4
5
use EE_DB_Only_Field_Base;
6
use EE_Model_Relation_Base;
7
use EventEspresso\core\exceptions\InvalidDataTypeException;
8
use EventEspresso\core\exceptions\InvalidInterfaceException;
9
use EventEspresso\core\services\loaders\LoaderFactory;
10
use Exception;
11
use InvalidArgumentException;
12
use ReflectionException;
13
use \WP_REST_Request;
14
use \WP_REST_Response;
15
use EventEspresso\core\libraries\rest_api\Capabilities;
16
use EventEspresso\core\libraries\rest_api\ModelDataTranslator;
17
use EventEspresso\core\libraries\rest_api\RestException;
18
use \EEM_Base;
19
use \EE_Base_Class;
20
use \EE_Registry;
21
use \EE_Datetime_Field;
22
use \EEM_Soft_Delete_Base;
23
use EE_Restriction_Generator_Base;
24
use EED_Core_Rest_Api;
25
use EEH_Inflector;
26
use EE_Error;
27
28
/**
29
 * Write controller for models
30
 * Handles requests relating to GET-ting model information
31
 *
32
 * @package               Event Espresso
33
 * @subpackage
34
 * @author                Mike Nelson
35
 */
36
class Write extends Base
37
{
38
39
40
    public function __construct()
41
    {
42
        parent::__construct();
43
        EE_Registry::instance()->load_helper('Inflector');
44
    }
45
46
47
    /**
48
     * Handles requests to get all (or a filtered subset) of entities for a particular model
49
     *
50
     * @param WP_REST_Request $request
51
     * @param string          $version
52
     * @param string          $model_name
53
     * @return WP_REST_Response|\WP_Error
54
     */
55 View Code Duplication
    public static function handleRequestInsert(WP_REST_Request $request, $version, $model_name)
56
    {
57
        $controller = new Write();
58
        try {
59
            $controller->setRequestedVersion($version);
60
            return $controller->sendResponse(
61
                $controller->insert(
62
                    $controller->getModelVersionInfo()->loadModel($model_name),
0 ignored issues
show
Bug introduced by
It seems like $controller->getModelVer...>loadModel($model_name) can be null; however, insert() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
63
                    $request
64
                )
65
            );
66
        } catch (Exception $e) {
67
            return $controller->sendResponse($e);
68
        }
69
    }
70
71
72
    /**
73
     * Handles a request from \WP_REST_Server to update an EE model
74
     *
75
     * @param WP_REST_Request $request
76
     * @param string          $version
77
     * @param string          $model_name
78
     * @return WP_REST_Response|\WP_Error
79
     */
80 View Code Duplication
    public static function handleRequestUpdate(WP_REST_Request $request, $version, $model_name)
81
    {
82
        $controller = new Write();
83
        try {
84
            $controller->setRequestedVersion($version);
85
            return $controller->sendResponse(
86
                $controller->update(
87
                    $controller->getModelVersionInfo()->loadModel($model_name),
0 ignored issues
show
Bug introduced by
It seems like $controller->getModelVer...>loadModel($model_name) can be null; however, update() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
88
                    $request
89
                )
90
            );
91
        } catch (Exception $e) {
92
            return $controller->sendResponse($e);
93
        }
94
    }
95
96
97
    /**
98
     * Deletes a single model object and returns it. Unless
99
     *
100
     * @param WP_REST_Request $request
101
     * @param string          $version
102
     * @param string          $model_name
103
     * @return WP_REST_Response|\WP_Error
104
     */
105 View Code Duplication
    public static function handleRequestDelete(WP_REST_Request $request, $version, $model_name)
106
    {
107
        $controller = new Write();
108
        try {
109
            $controller->setRequestedVersion($version);
110
            return $controller->sendResponse(
111
                $controller->delete(
112
                    $controller->getModelVersionInfo()->loadModel($model_name),
0 ignored issues
show
Bug introduced by
It seems like $controller->getModelVer...>loadModel($model_name) can be null; however, delete() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
113
                    $request
114
                )
115
            );
116
        } catch (Exception $e) {
117
            return $controller->sendResponse($e);
118
        }
119
    }
120
121
122
    /**
123
     * Inserts a new model object according to the $request
124
     *
125
     * @param EEM_Base        $model
126
     * @param WP_REST_Request $request
127
     * @return array
128
     * @throws EE_Error
129
     * @throws RestException
130
     */
131
    public function insert(EEM_Base $model, WP_REST_Request $request)
132
    {
133
        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
134
        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
135 View Code Duplication
        if (! current_user_can($default_cap_to_check_for)) {
136
            throw new RestException(
137
                'rest_cannot_create_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
138
                sprintf(
139
                    esc_html__(
140
                    // @codingStandardsIgnoreStart
141
                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to insert data into Event Espresso.',
142
                        // @codingStandardsIgnoreEnd
143
                        'event_espresso'
144
                    ),
145
                    $default_cap_to_check_for
146
                ),
147
                array('status' => 403)
148
            );
149
        }
150
        $submitted_json_data = array_merge((array) $request->get_body_params(), (array) $request->get_json_params());
151
        $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
152
            $submitted_json_data,
153
            $model,
154
            $this->getModelVersionInfo()->requestedVersion(),
155
            true
156
        );
157
        $model_obj = EE_Registry::instance()->load_class(
158
            $model->get_this_model_name(),
159
            array($model_data, $model->get_timezone()),
160
            false,
161
            false
162
        );
163
        $model_obj->save();
164
        $new_id = $model_obj->ID();
165
        if (! $new_id) {
166
            throw new RestException(
167
                'rest_insertion_failed',
168
                sprintf(__('Could not insert new %1$s', 'event_espresso'), $model->get_this_model_name())
169
            );
170
        }
171
        return $this->returnModelObjAsJsonResponse($model_obj, $request);
172
    }
173
174
175
    /**
176
     * Updates an existing model object according to the $request
177
     *
178
     * @param EEM_Base        $model
179
     * @param WP_REST_Request $request
180
     * @return array
181
     * @throws EE_Error
182
     */
183
    public function update(EEM_Base $model, WP_REST_Request $request)
184
    {
185
        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'edit');
186
        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
187 View Code Duplication
        if (! current_user_can($default_cap_to_check_for)) {
188
            throw new RestException(
189
                'rest_cannot_edit_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
190
                sprintf(
191
                    esc_html__(
192
                    // @codingStandardsIgnoreStart
193
                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to update data into Event Espresso.',
194
                        // @codingStandardsIgnoreEnd
195
                        'event_espresso'
196
                    ),
197
                    $default_cap_to_check_for
198
                ),
199
                array('status' => 403)
200
            );
201
        }
202
        $obj_id = $request->get_param('id');
203
        if (! $obj_id) {
204
            throw new RestException(
205
                'rest_edit_failed',
206
                sprintf(__('Could not edit %1$s', 'event_espresso'), $model->get_this_model_name())
207
            );
208
        }
209
        $model_data = ModelDataTranslator::prepareConditionsQueryParamsForModels(
210
            $this->getBodyParams($request),
211
            $model,
212
            $this->getModelVersionInfo()->requestedVersion(),
213
            true
214
        );
215
        $model_obj = $model->get_one_by_ID($obj_id);
216 View Code Duplication
        if (! $model_obj instanceof EE_Base_Class) {
217
            $lowercase_model_name = strtolower($model->get_this_model_name());
218
            throw new RestException(
219
                sprintf('rest_%s_invalid_id', $lowercase_model_name),
220
                sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
221
                array('status' => 404)
222
            );
223
        }
224
        $model_obj->save($model_data);
225
        return $this->returnModelObjAsJsonResponse($model_obj, $request);
226
    }
227
228
229
    /**
230
     * Updates an existing model object according to the $request
231
     *
232
     * @param EEM_Base        $model
233
     * @param WP_REST_Request $request
234
     * @return array of either the soft-deleted item, or
235
     * @throws EE_Error
236
     */
237
    public function delete(EEM_Base $model, WP_REST_Request $request)
238
    {
239
        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_delete, 'delete');
240
        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
241 View Code Duplication
        if (! current_user_can($default_cap_to_check_for)) {
242
            throw new RestException(
243
                'rest_cannot_delete_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
244
                sprintf(
245
                    esc_html__(
246
                    // @codingStandardsIgnoreStart
247
                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to delete data into Event Espresso.',
248
                        // @codingStandardsIgnoreEnd
249
                        'event_espresso'
250
                    ),
251
                    $default_cap_to_check_for
252
                ),
253
                array('status' => 403)
254
            );
255
        }
256
        $obj_id = $request->get_param('id');
257
        // this is where we would apply more fine-grained caps
258
        $model_obj = $model->get_one_by_ID($obj_id);
259 View Code Duplication
        if (! $model_obj instanceof EE_Base_Class) {
260
            $lowercase_model_name = strtolower($model->get_this_model_name());
261
            throw new RestException(
262
                sprintf('rest_%s_invalid_id', $lowercase_model_name),
263
                sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
264
                array('status' => 404)
265
            );
266
        }
267
        $requested_permanent_delete = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN);
268
        $requested_allow_blocking = filter_var($request->get_param('allow_blocking'), FILTER_VALIDATE_BOOLEAN);
269
        if ($requested_permanent_delete) {
270
            $previous = $this->returnModelObjAsJsonResponse($model_obj, $request);
271
            $deleted = (bool) $model->delete_permanently_by_ID($obj_id, $requested_allow_blocking);
272
            return array(
273
                'deleted'  => $deleted,
274
                'previous' => $previous,
275
            );
276
        } else {
277
            if ($model instanceof EEM_Soft_Delete_Base) {
278
                $model->delete_by_ID($obj_id, $requested_allow_blocking);
279
                return $this->returnModelObjAsJsonResponse($model_obj, $request);
280
            } else {
281
                throw new RestException(
282
                    'rest_trash_not_supported',
283
                    501,
284
                    sprintf(
285
                        esc_html__('%1$s do not support trashing. Set force=1 to delete.', 'event_espresso'),
286
                        EEH_Inflector::pluralize($model->get_this_model_name())
287
                    )
288
                );
289
            }
290
        }
291
    }
292
293
294
    /**
295
     * Returns an array ready to be converted into a JSON response, based solely on the model object
296
     *
297
     * @param EE_Base_Class   $model_obj
298
     * @param WP_REST_Request $request
299
     * @return array ready for a response
300
     */
301
    protected function returnModelObjAsJsonResponse(EE_Base_Class $model_obj, WP_REST_Request $request)
302
    {
303
        $model = $model_obj->get_model();
304
        // create an array exactly like the wpdb results row,
305
        // so we can pass it to controllers/model/Read::create_entity_from_wpdb_result()
306
        $simulated_db_row = array();
307
        foreach ($model->field_settings(true) as $field_name => $field_obj) {
308
            // we need to reconstruct the normal wpdb results, including the db-only fields
309
            // like a secondary table's primary key. The models expect those (but don't care what value they have)
310
            if ($field_obj instanceof EE_DB_Only_Field_Base) {
311
                $raw_value = true;
312
            } elseif ($field_obj instanceof EE_Datetime_Field) {
313
                $raw_value = $model_obj->get_DateTime_object($field_name);
314
            } else {
315
                $raw_value = $model_obj->get_raw($field_name);
316
            }
317
            $simulated_db_row[ $field_obj->get_qualified_column() ] = $field_obj->prepare_for_use_in_db($raw_value);
318
        }
319
        $read_controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
320
        $read_controller->setRequestedVersion($this->getRequestedVersion());
321
        // the simulates request really doesn't need any info downstream
322
        $simulated_request = new WP_REST_Request('GET');
323
        return $read_controller->createEntityFromWpdbResult(
324
            $model_obj->get_model(),
325
            $simulated_db_row,
326
            $simulated_request
327
        );
328
    }
329
330
331
    /**
332
     * Gets the item affected by this request
333
     *
334
     * @param EEM_Base        $model
335
     * @param WP_REST_Request $request
336
     * @param  int|string     $obj_id
337
     * @return \WP_Error|array
338
     */
339
    protected function getOneBasedOnRequest(EEM_Base $model, WP_REST_Request $request, $obj_id)
340
    {
341
        $requested_version = $this->getRequestedVersion($request->get_route());
342
        $get_request = new WP_REST_Request(
343
            'GET',
344
            EED_Core_Rest_Api::ee_api_namespace
345
            . $requested_version
346
            . '/'
347
            . EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
348
            . '/'
349
            . $obj_id
350
        );
351
        $get_request->set_url_params(
352
            array(
353
                'id'      => $obj_id,
354
                'include' => $request->get_param('include'),
355
            )
356
        );
357
        $read_controller = new Read();
0 ignored issues
show
Bug introduced by
The call to Read::__construct() misses a required argument $fields_calculator.

This check looks for function calls that miss required arguments.

Loading history...
358
        $read_controller->setRequestedVersion($this->getRequestedVersion());
359
        return $read_controller->getEntityFromModel($model, $get_request);
360
    }
361
362
    /**
363
     * Adds a relation between the specified models (if it doesn't already exist.)
364
     * @since $VID:$
365
     * @param WP_REST_Request $request
366
     * @return WP_REST_Response
367
     */
368
    public static function handleRequestAddRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
369
    {
370
        $controller = new Write();
371
        try {
372
            $controller->setRequestedVersion($version);
373
            $main_model = $controller->validateModel($model_name);
374
            $controller->validateModel($related_model_name);
375
            return $controller->sendResponse(
376
                $controller->addRelation(
0 ignored issues
show
Bug introduced by
The call to addRelation() misses a required argument $request.

This check looks for function calls that miss required arguments.

Loading history...
377
                    $main_model,
378
                    $request
379
                )
380
            );
381
        } catch (Exception $e) {
382
            return $controller->sendResponse($e);
383
        }
384
    }
385
386
    /**
387
     * Adds a relation between the two model specified model objects.
388
     * @since $VID:$
389
     * @param EEM_Base $model
390
     * @param EE_Model_Relation_Base $relation
391
     * @param WP_REST_Request $request
392
     * @return array
393
     * @throws EE_Error
394
     * @throws RestException
395
     */
396 View Code Duplication
    public function addRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
397
    {
398
        list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
399
        // Add a relation.
400
        $related_obj = $model_obj->_add_relation_to($other_obj,$relation->get_other_model()->get_this_model_name());
401
        return array(
402
            'success' => $related_obj === $other_obj,
403
            'related_obj' => $this->returnModelObjAsJsonResponse($related_obj)
0 ignored issues
show
Bug introduced by
The call to returnModelObjAsJsonResponse() misses a required argument $request.

This check looks for function calls that miss required arguments.

Loading history...
404
        );
405
    }
406
407
408
    /**
409
     * Removes the relation between the specified models (if it exists).
410
     * @since $VID:$
411
     * @param WP_REST_Request $request
412
     * @return WP_REST_Response
413
     */
414 View Code Duplication
    public static function handleRequestRemoveRelation(WP_REST_Request $request, $version, $model_name, $related_model_name)
415
    {
416
        $controller = new Write();
417
        try {
418
            $controller->setRequestedVersion($version);
419
            return $controller->sendResponse(
420
                $controller->insert(
421
                    $controller->getModelVersionInfo()->loadModel($model_name),
0 ignored issues
show
Bug introduced by
It seems like $controller->getModelVer...>loadModel($model_name) can be null; however, insert() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
422
                    $request
423
                )
424
            );
425
        } catch (Exception $e) {
426
            return $controller->sendResponse($e);
427
        }
428
    }
429
430
    /**
431
     * Adds a relation between the two model specified model objects.
432
     * @since $VID:$
433
     * @param EEM_Base $model
434
     * @param EE_Model_Relation_Base $relation
435
     * @param WP_REST_Request $request
436
     * @return array
437
     * @throws EE_Error
438
     * @throws RestException
439
     */
440 View Code Duplication
    public function removeRelation(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
441
    {
442
        list($model_obj, $other_obj) = $this->getBothModelObjects($model, $relation, $request);
443
        // Remove the relation.
444
        $related_obj = $model_obj->_remove_relation($other_obj, $relation->get_other_model()->get_this_model_name());
445
        return array(
446
            'success' => $related_obj === $other_obj,
447
            'related_obj' => $this->returnModelObjAsJsonResponse($related_obj)
0 ignored issues
show
Bug introduced by
The call to returnModelObjAsJsonResponse() misses a required argument $request.

This check looks for function calls that miss required arguments.

Loading history...
448
        );
449
    }
450
451
    /**
452
     * Gets the model objects indicated by the model, relation object, and request.
453
     * Throws an exception if the first object doesn't exist, and currently if the related object also doesn't exist.
454
     * However, this behaviour may change, as we may add support for simultaneously creating and relating data.
455
     * @since $VID:$
456
     * @param EEM_Base $model
457
     * @param EE_Model_Relation_Base $relation
458
     * @param WP_REST_Request $request
459
     * @return array {
460
     * @type EE_Base_Class $model_obj
461
     * @type EE_Base_Class|null $other_model_obj
462
     * }
463
     * @throws RestException
464
     */
465
    protected function getBothModelObjects(EEM_Base $model, EE_Model_Relation_Base $relation, WP_REST_Request $request)
466
    {
467
        // Check generic caps. For now, we're only allowing access to this endpoint to full admins.
468
        Capabilities::verifyAtLeastPartialAccessTo($model, EEM_Base::caps_edit, 'create');
469
        $default_cap_to_check_for = EE_Restriction_Generator_Base::get_default_restrictions_cap();
470 View Code Duplication
        if (! current_user_can($default_cap_to_check_for)) {
471
            throw new RestException(
472
                'rest_cannot_add_relation_from_' . EEH_Inflector::pluralize_and_lower(($model->get_this_model_name())),
473
                sprintf(
474
                    esc_html__(
475
                        // @codingStandardsIgnoreStart
476
                        'For now, only those with the admin capability to "%1$s" are allowed to use the REST API to add relations in Event Espresso.',
477
                        // @codingStandardsIgnoreEnd
478
                        'event_espresso'
479
                    ),
480
                    $default_cap_to_check_for
481
                ),
482
                array('status' => 403)
483
            );
484
        }
485
        // Get the main model object.
486
        $model_obj = $this->getOneOrThrowException($model, $request->get_param('id'));
487
        // For now, we require the other model object to exist too. This might be relaxed later.
488
        $other_obj = $this->getOneOrThrowException($relation->get_other_model(), $relation->get_param('request_id'));
0 ignored issues
show
Bug introduced by
It seems like $relation->get_other_model() can be null; however, getOneOrThrowException() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
489
        return array($model_obj,$other_obj);
490
    }
491
492
    /**
493
     * Gets the model with that ID or throws a REST exception.
494
     * @since $VID:$
495
     * @param EEM_Base $model
496
     * @param $id
497
     * @return EE_Base_Class
498
     * @throws RestException
499
     */
500
    protected function getOneOrThrowException(EEM_Base $model, $id)
501
    {
502
        $model_obj = $model->get_one_by_ID($id);
503
        // @todo: check they can permission for it. For now unnecessary because only full admins can use this endpoint.
504
        if( $model_obj instanceof EE_Base_Class) {
505
            return $model_obj;
506
        }
507
            $lowercase_model_name = strtolower($model->get_this_model_name());
508
            throw new RestException(
509
                sprintf('rest_%s_invalid_id', $lowercase_model_name),
510
                sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
511
                array('status' => 404)
512
            );
513
        }
514
}
515