Completed
Branch BUG/reg-status-change-recursio... (66d1a3)
by
unknown
16:58 queued 08:55
created

setQueryParamValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\libraries\rest_api;
4
5
use DomainException;
6
use EE_Datetime_Field;
7
use EE_Error;
8
use EE_Model_Field_Base;
9
use EEH_Array;
10
use EEH_DTT_Helper;
11
use EventEspresso\core\exceptions\InvalidDataTypeException;
12
use EventEspresso\core\exceptions\InvalidInterfaceException;
13
use InvalidArgumentException;
14
use EED_Core_Rest_Api;
15
16
/**
17
 * Class RestQueryParamMetadata
18
 *
19
 * Object for passing around metadata derived from the query parameters passed in via the REST API.
20
 * This is convenient when interpreting REST API query params and generating model query params.
21
 *
22
 * @package     Event Espresso
23
 * @author         Mike Nelson
24
 * @since         4.9.72.p
25
 *
26
 */
27
class RestIncomingQueryParamMetadata
28
{
29
    private $query_param_key;
30
    private $query_param_value;
31
    /**
32
     * @var RestIncomingQueryParamContext
33
     */
34
    private $context;
35
36
    /**
37
     * @var EE_Model_Field_Base|null
38
     */
39
    private $field;
40
41
    /**
42
     * @var string same as $query_param_key but has the * and anything after it removed
43
     */
44
    private $query_param_key_sans_stars;
45
46
    /**
47
     * @var string for timezone or timezone offset
48
     */
49
    private $timezone;
50
51
    /**
52
     * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`)
53
     */
54
    private $is_gmt_field = false;
55
56
    /**
57
     * RestIncomingQueryParamMetadata constructor.
58
     * You probably want to call
59
     * @param string $query_param_key
60
     * @param string $query_param_value
61
     * @param RestIncomingQueryParamContext $context
62
     */
63
    public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context)
64
    {
65
        $this->query_param_key = $query_param_key;
66
        $this->query_param_value = $query_param_value;
67
        $this->context = $context;
68
        $this->determineFieldAndTimezone();
69
    }
70
71
    /**
72
     * Gets the query parameter key. This may have been modified (see setQueryParamValue())
73
     * @return string
74
     */
75
    public function getQueryParamKey()
76
    {
77
        return $this->query_param_key;
78
    }
79
80
    /**
81
     * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST
82
     * query parameters into the legacy structure)
83
     * @param string|array|int|float $query_param_value
84
     */
85
    private function setQueryParamValue($query_param_value)
86
    {
87
        $this->query_param_value = $query_param_value;
88
    }
89
90
    /**
91
     * Gets the original query parameter value passed in.
92
     * @return string
93
     */
94
    public function getQueryParamValue()
95
    {
96
        return $this->query_param_value;
97
    }
98
99
    /**
100
     * Gets the context object.
101
     * @return RestIncomingQueryParamContext
102
     */
103
    public function getContext()
104
    {
105
        return $this->context;
106
    }
107
108
    /**
109
     * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative.
110
     * @param string $query_param_key
111
     */
112
    private function setQueryParamKey($query_param_key)
113
    {
114
        $this->query_param_key = $query_param_key;
115
    }
116
117
    /**
118
     * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key
119
     * did not indicate a field, eg if it were `OR`).
120
     * @return EE_Model_Field_Base|null
121
     */
122
    public function getField()
123
    {
124
        return $this->field;
125
    }
126
127
    /**
128
     * Gets the query parameter key (with the star and everything afterwards removed).
129
     * @return string
130
     */
131
    public function getQueryParamKeySansStars()
132
    {
133
        return $this->query_param_key_sans_stars;
134
    }
135
136
    /**
137
     * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields).
138
     * @return string
139
     */
140
    public function getTimezone()
141
    {
142
        return $this->timezone;
143
    }
144
145
    /**
146
     * Returns whether or not this is a GMT field
147
     * @return boolean
148
     */
149
    public function isGmtField()
150
    {
151
        return $this->is_gmt_field;
152
    }
153
154
    /**
155
     * Sets the field indicated by the query parameter key (might be null).
156
     * @param EE_Model_Field_Base|null $field
157
     */
158
    private function setField(EE_Model_Field_Base $field = null)
159
    {
160
        $this->field = $field;
161
    }
162
163
    /**
164
     * Sets the query parameter key-with-stars-removed.
165
     * @param string $query_param_key_sans_stars
166
     */
167
    private function setQueryParamKeySansStars($query_param_key_sans_stars)
168
    {
169
        $this->query_param_key_sans_stars = $query_param_key_sans_stars;
170
    }
171
172
    /**
173
     * Sets the timezone (this could be a timezeon offset string).
174
     * @param string $timezone
175
     */
176
    private function setTimezone($timezone)
177
    {
178
        $this->timezone = $timezone;
179
    }
180
181
    /**
182
     * @param mixed $is_gmt_field
183
     */
184
    private function setIsGmtField($is_gmt_field)
185
    {
186
        $this->is_gmt_field = $is_gmt_field;
187
    }
188
189
    /**
190
     * Determines what field, query param name, and query param name without stars, and timezone to use.
191
     * @since 4.9.72.p
192
     * @type EE_Model_Field_Base $field
193
     * @return void {
194
     * @throws EE_Error
195
     * @throws InvalidDataTypeException
196
     * @throws InvalidInterfaceException
197
     * @throws InvalidArgumentException
198
     */
199
    private function determineFieldAndTimezone()
200
    {
201
        $this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
202
            $this->getQueryParamKey()
203
        ));
204
        $this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
205
            $this->getQueryParamKeySansStars(),
206
            $this->getContext()->getModel()
207
        ));
208
        // double-check is it a *_gmt field?
209
        if (!$this->getField() instanceof EE_Model_Field_Base
210
            && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
211
        ) {
212
            // yep, take off '_gmt', and find the field
213
            $this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars()));
214
            $this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
215
                $this->getQueryParamKey(),
216
                $this->context->getModel()
217
            ));
218
            $this->setTimezone('UTC');
219
            $this->setIsGmtField(true);
220
        } elseif ($this->getField() instanceof EE_Datetime_Field) {
221
            // so it's not a GMT field. Set the timezone on the model to the default
222
            $this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string());
223
        } else {
224
            // just keep using what's already set for the timezone
225
            $this->setTimezone($this->context->getModel()->get_timezone());
226
        }
227
    }
228
229
    /**
230
     * Given a ton of input, determines the value to use for the models.
231
     * @since 4.9.72.p
232
     * @return array|null
233
     * @throws DomainException
234
     * @throws EE_Error
235
     * @throws RestException
236
     * @throws DomainException
237
     */
238
    public function determineConditionsQueryParameterValue()
239
    {
240
        if ($this->valueIsArrayDuringRead()) {
241
            return $this->determineModelValueGivenRestInputArray();
242
        }
243
        return ModelDataTranslator::prepareFieldValueFromJson(
244
            $this->getField(),
0 ignored issues
show
Bug introduced by
It seems like $this->getField() can be null; however, prepareFieldValueFromJson() 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...
245
            $this->getQueryParamValue(),
246
            $this->getContext()->getRequestedVersion(),
247
            $this->getTimezone()
248
        );
249
    }
250
251
    /**
252
     * Given that the array value provided was itself an array, handles finding the correct value to pass to the model.
253
     * @since 4.9.72.p
254
     * @return array|null
255
     * @throws RestException
256
     */
257
    private function determineModelValueGivenRestInputArray()
258
    {
259
        $this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax();
260
        // did they specify an operator?
261
        if ($this->valueIsLegacySpecifiedOperator()) {
262
            $query_param_value = $this->getQueryParamValue();
263
            $sub_array_key = $query_param_value[0];
264
            $translated_value = array($sub_array_key);
265
            if ($this->operatorIsNAry($sub_array_key)) {
266
                $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
267
            } elseif ($this->operatorIsTernary($sub_array_key)) {
268
                $translated_value[] = array(
269
                    $this->prepareValuesFromJson($query_param_value[1][0]),
270
                    $this->prepareValuesFromJson($query_param_value[1][1])
271
                );
272
            } elseif ($this->operatorIsLike($sub_array_key)) {
273
                // we want to leave this value mostly-as-is (eg don't force it to be a float
274
                // or a boolean or an enum value. Leave it as-is with wildcards etc)
275
                // but do verify it at least doesn't have any serialized data
276
                ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
277
                $translated_value[] = $query_param_value[1];
278
            } elseif ($this->operatorIsUnary($sub_array_key)) {
279
                // no arguments should have been provided, so don't look for any
280
            } elseif ($this->operatorisBinary($sub_array_key)) {
281
                // it's a valid operator, but none of the exceptions. Treat it normally.
282
                $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
283
            } else {
284
                // so they provided a valid operator, but wrong number of arguments
285
                $this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key);
286
                $translated_value = null;
287
            }
288
        } else {
289
            // so they didn't provide a valid operator
290
            // if we aren't in debug mode, then just try our best to fulfill the user's request
291
            $this->throwInvalidOperatorExceptionIfDebugging();
292
            $translated_value = null;
293
        }
294
        return $translated_value;
295
    }
296
297
    /**
298
     * Returns if this request is a "read" request and the value provided was an array.
299
     * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not.
300
     * @since 4.9.72.p
301
     * @return boolean
302
     */
303
    private function valueIsArrayDuringRead()
304
    {
305
        return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
306
    }
307
308
    /**
309
     * Returns if the value provided was an associative array (we should have already verified it's an array of some
310
     * sort). If the value is an associative array, it had better be in the simplified specified operator structure.
311
     * @since 4.9.72.p
312
     * @return boolean
313
     */
314
    private function valueIsAssociativeArray()
315
    {
316
        return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
317
    }
318
319
    /**
320
     * Checks if the array value is itself an array that fits into the simplified specified operator structure
321
     * (eg `array('!=' => 123)`).
322
     * @since 4.9.72.p
323
     * @return boolean
324
     */
325
    private function valueIsSimplifiedSpecifiedOperator()
326
    {
327
        return count($this->getQueryParamValue()) === 1
328
            && array_key_exists(
329
                key($this->getQueryParamValue()),
330
                $this->getContext()->getModel()->valid_operators()
331
            );
332
    }
333
334
    /**
335
     * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string,
336
     * of either comma-separated-values, or a JSON array.
337
     * @since 4.9.72.p
338
     * @param $sub_array_key
339
     * @param $sub_array_value
340
     * @throws RestException
341
     */
342
    private function assertSubValueIsntArray($sub_array_key, $sub_array_value)
343
    {
344
        if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) {
345
            throw new RestException(
346
                'csv_or_json_string_only',
347
                sprintf(
348
                    /* translators: 1: variable name*/
349
                    esc_html__(
350
                        'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.',
351
                        'event_espresso'
352
                    ),
353
                    $sub_array_key
354
                ),
355
                array(
356
                    'status' => 400,
357
                )
358
            );
359
        }
360
    }
361
362
    /**
363
     * Determines if the sub-array key is an operator taking 3 or more operators.
364
     * @since 4.9.72.p
365
     * @param $sub_array_key
366
     * @return boolean
367
     */
368
    private function subArrayKeyIsNonBinaryOperator($sub_array_key)
369
    {
370
        return array_key_exists(
371
            $sub_array_key,
372
            array_merge(
373
                $this->getContext()->getModel()->valid_in_style_operators(),
374
                $this->getContext()->getModel()->valid_between_style_operators()
375
            )
376
        );
377
    }
378
379
    /**
380
     * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument.
381
     * @since 4.9.72.p
382
     * @param string $sub_array_key
383
     * @return boolean
384
     */
385
    private function subArrayKeyIsUnaryOperator($sub_array_key)
386
    {
387
        return array_key_exists(
388
            $sub_array_key,
389
            $this->getContext()->getModel()->valid_null_style_operators()
390
        );
391
    }
392
393
    /**
394
     * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON
395
     * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`.
396
     * @since 4.9.72.p
397
     * @param $sub_array_value
398
     * @return array|mixed|object
399
     */
400
    private function extractQuickStyleSpecifiedOperatorValue($sub_array_value)
401
    {
402
        // the value should be JSON or CSV
403
        $values = json_decode($sub_array_value);
404
        if (!is_array($values)) {
405
            $values = array_filter(
406
                array_map(
407
                    'trim',
408
                    explode(
409
                        ',',
410
                        $sub_array_value
411
                    )
412
                )
413
            );
414
        }
415
        return $values;
416
    }
417
418
    /**
419
     * Throws an exception if the value isn't a simplified specified operator (only called when we expect that).
420
     * @since 4.9.72.p
421
     * @throws RestException
422
     */
423 View Code Duplication
    private function assertSimplifiedSpecifiedOperator()
424
    {
425
        if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
426
            throw new RestException(
427
                'numerically_indexed_array_of_values_only',
428
                sprintf(
429
                    /* translators: 1: variable name*/
430
                    esc_html__(
431
                        'The array provided for the parameter "%1$s" should be numerically indexed.',
432
                        'event_espresso'
433
                    ),
434
                    $this->getQueryParamKey()
435
                ),
436
                array(
437
                    'status' => 400,
438
                )
439
            );
440
        }
441
    }
442
443
    /**
444
     * If query_param_value were in the simplified specific operator structure, change it into the legacy structure.
445
     * @since 4.9.72.p
446
     * @throws RestException
447
     */
448
    private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax()
449
    {
450
        if ($this->valueIsAssociativeArray()) {
451
            $this->assertSimplifiedSpecifiedOperator();
452
            $query_param_value = $this->getQueryParamValue();
453
            $sub_array_value = reset($query_param_value);
454
            $sub_array_key = key($query_param_value);
455
            $this->assertSubValueIsntArray($sub_array_key, $sub_array_value);
456
            // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
457
            if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) {
458
                $this->setQueryParamValue(array(
459
                    $sub_array_key,
460
                    $this->extractQuickStyleSpecifiedOperatorValue($sub_array_value)
461
                ));
462
            } elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) {
463
                $this->setQueryParamValue(array($sub_array_key));
464
            } else {
465
                $this->setQueryParamValue(array($sub_array_key, $sub_array_value));
466
            }
467
        }
468
    }
469
470
    /**
471
     * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`.
472
     * @since 4.9.72.p
473
     * @return boolean
474
     */
475
    private function valueIsLegacySpecifiedOperator()
476
    {
477
        $valid_operators = $this->getContext()->getModel()->valid_operators();
478
        $query_param_value = $this->getQueryParamValue();
479
        return isset($query_param_value[0])
480
            && isset($valid_operators[ $query_param_value[0] ]);
481
    }
482
483
    /**
484
     * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN".
485
     * @since 4.9.72.p
486
     * @param $operator
487
     * @return boolean
488
     */
489 View Code Duplication
    private function operatorIsNAry($operator)
490
    {
491
        $valueArray = $this->getQueryParamValue();
492
        return array_key_exists(
493
            $operator,
494
            $this->getContext()->getModel()->valid_in_style_operators()
495
        )
496
            && isset($valueArray[1])
497
            && is_array($valueArray[1])
498
            && !isset($valueArray[2]);
499
    }
500
501
    /**
502
     * Returns true if the operator accepts 3 arguments (eg "BETWEEN").
503
     * So we're looking for a value that looks like
504
     * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`.
505
     * @since 4.9.72.p
506
     * @param $operator
507
     * @return boolean
508
     */
509
    private function operatorIsTernary($operator)
510
    {
511
        $query_param_value = $this->getQueryParamValue();
512
        return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators())
513
            && isset($query_param_value[1])
514
            && is_array($query_param_value[1])
515
            && isset($query_param_value[1][0], $query_param_value[1][1])
516
            && !isset($query_param_value[1][2])
517
            && !isset($query_param_value[2]);
518
    }
519
520
    /**
521
     * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone.
522
     * @since 4.9.72.p
523
     * @param $operator
524
     * @return boolean
525
     */
526 View Code Duplication
    private function operatorIsLike($operator)
527
    {
528
        $query_param_value = $this->getQueryParamValue();
529
        return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
530
            && isset($query_param_value[1])
531
            && !isset($query_param_value[2]);
532
    }
533
534
    /**
535
     * Returns true if the operator only takes one argument (eg it's like `IS NULL`).
536
     * @since 4.9.72.p
537
     * @param $operator
538
     * @return boolean
539
     */
540
    private function operatorIsUnary($operator)
541
    {
542
        $query_param_value = $this->getQueryParamValue();
543
        return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
544
            && !isset($query_param_value[1]);
545
    }
546
547
    /**
548
     * Returns true if the operator specified is a binary opeator (eg `=`, `!=`)
549
     * @since 4.9.72.p
550
     * @param $operator
551
     * @return boolean
552
     */
553
    private function operatorisBinary($operator)
554
    {
555
        $query_param_value = $this->getQueryParamValue();
556
        $model = $this->getContext()->getModel();
557
        return isset($query_param_value[1])
558
            && !isset($query_param_value[2])
559
            && !array_key_exists(
560
                $operator,
561
                array_merge(
562
                    $model->valid_in_style_operators(),
563
                    $model->valid_null_style_operators(),
564
                    $model->valid_like_style_operators(),
565
                    $model->valid_between_style_operators()
566
                )
567
            );
568
    }
569
570
    /**
571
     * If we're debugging, throws an exception saying that the wrong number of arguments was provided.
572
     * @since 4.9.72.p
573
     * @param $operator
574
     * @throws RestException
575
     */
576
    private function throwWrongNumberOfArgsExceptionIfDebugging($operator)
577
    {
578
        if (EED_Core_Rest_Api::debugMode()) {
579
            throw new RestException(
580
                'wrong_number_of_arguments',
581
                sprintf(
582
                    esc_html__(
583
                        'The operator you provided, "%1$s" had the wrong number of arguments',
584
                        'event_espresso'
585
                    ),
586
                    $operator
587
                ),
588
                array(
589
                    'status' => 400,
590
                )
591
            );
592
        }
593
    }
594
595
    /**
596
     * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY.
597
     * @since 4.9.72.p
598
     * @param $value
599
     * @return mixed
600
     * @throws RestException
601
     */
602
    private function prepareValuesFromJson($value)
603
    {
604
        return ModelDataTranslator::prepareFieldValuesFromJson(
605
            $this->getField(),
0 ignored issues
show
Bug introduced by
It seems like $this->getField() can be null; however, prepareFieldValuesFromJson() 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...
606
            $value,
607
            $this->getContext()->getRequestedVersion(),
608
            $this->getTimezone()
609
        );
610
    }
611
612
    /**
613
     * Throws an exception if an invalid operator was specified and we're debugging.
614
     * @since 4.9.72.p
615
     * @throws RestException
616
     */
617 View Code Duplication
    private function throwInvalidOperatorExceptionIfDebugging()
618
    {
619
        // so they didn't provide a valid operator
620
        if (EED_Core_Rest_Api::debugMode()) {
621
            throw new RestException(
622
                'invalid_operator',
623
                sprintf(
624
                    esc_html__(
625
                        'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
626
                        'event_espresso'
627
                    ),
628
                    $this->getQueryParamKey(),
629
                    $this->getQueryParamValue()
630
                ),
631
                array(
632
                    'status' => 400,
633
                )
634
            );
635
        }
636
    }
637
638
    /**
639
     * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc.
640
     * @since 4.9.72.p
641
     * @return boolean
642
     */
643
    private function isLogicQueryParam()
644
    {
645
        return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys());
646
    }
647
648
649
    /**
650
     * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
651
     * @since 4.9.72.p
652
     * @return array
653
     * @throws DomainException
654
     * @throws EE_Error
655
     * @throws RestException
656
     * @throws InvalidDataTypeException
657
     * @throws InvalidInterfaceException
658
     * @throws InvalidArgumentException
659
     */
660
    public function determineNestedConditionQueryParameters()
661
    {
662
663
        // so this param doesn't correspond to a field eh?
664
        if ($this->getContext()->isWriting()) {
665
            // always tell API clients about invalid parameters when they're creating data. Otherwise,
666
            // they are probably going to create invalid data
667
            throw new RestException(
668
                'invalid_field',
669
                sprintf(
670
                    /* translators: 1: variable name */
671
                    esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
672
                    $this->getQueryParamKey()
673
                )
674
            );
675
        }
676
        // so it's not for a field, is it a logic query param key?
677
        if ($this->isLogicQueryParam()) {
678
            return ModelDataTranslator::prepareConditionsQueryParamsForModels(
679
                $this->getQueryParamValue(),
680
                $this->getContext()->getModel(),
681
                $this->getContext()->getRequestedVersion()
682
            );
683
        }
684
        if (EED_Core_Rest_Api::debugMode()) {
685
            // only tell API clients they got it wrong if we're in debug mode
686
            // otherwise try our best ot fulfill their request by ignoring this invalid data
687
            throw new RestException(
688
                'invalid_parameter',
689
                sprintf(
690
                    /* translators: 1: variable name */
691
                    esc_html__(
692
                        'You provided an invalid parameter, with key "%1$s"',
693
                        'event_espresso'
694
                    ),
695
                    $this->getQueryParamKey()
696
                ),
697
                array(
698
                    'status' => 400,
699
                )
700
            );
701
        }
702
        return null;
703
    }
704
}
705
// End of file RestQueryParamMetadata.php
706
// Location: EventEspresso\core\libraries\rest_api/RestQueryParamMetadata.php
707