Completed
Branch FET/simplify-rest-api-passing-... (d968c1)
by
unknown
88:32 queued 78:52
created
core/libraries/rest_api/ModelDataTranslator.php 3 patches
Doc Comments   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -436,11 +436,11 @@  discard block
 block discarded – undo
436 436
      * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
437 437
      * @since $VID:$
438 438
      * @param EEM_Base $model
439
-     * @param $query_param_key
440
-     * @param $query_param_sans_stars
439
+     * @param string $query_param_key
440
+     * @param string $query_param_sans_stars
441 441
      * @param $query_param_value
442
-     * @param $requested_version
443
-     * @param $writing
442
+     * @param string $requested_version
443
+     * @param boolean $writing
444 444
      * @return array
445 445
      * @throws DomainException
446 446
      * @throws EE_Error
@@ -560,9 +560,9 @@  discard block
 block discarded – undo
560 560
      * @since $VID:$
561 561
      * @param EEM_Base $model
562 562
      * @param EE_Model_Field_Base $field
563
-     * @param $requested_version
564
-     * @param $timezone
565
-     * @param $query_param_key
563
+     * @param string $requested_version
564
+     * @param string $timezone
565
+     * @param string $query_param_key
566 566
      * @param $query_param_value
567 567
      * @param bool $writing
568 568
      * @return array|null
Please login to merge, or discard this patch.
Indentation   +951 added lines, -951 removed lines patch added patch discarded remove patch
@@ -32,995 +32,995 @@
 block discarded – undo
32 32
 class ModelDataTranslator
33 33
 {
34 34
 
35
-    /**
36
-     * We used to use -1 for infinity in the rest api, but that's ambiguous for
37
-     * fields that COULD contain -1; so we use null
38
-     */
39
-    const EE_INF_IN_REST = null;
35
+	/**
36
+	 * We used to use -1 for infinity in the rest api, but that's ambiguous for
37
+	 * fields that COULD contain -1; so we use null
38
+	 */
39
+	const EE_INF_IN_REST = null;
40 40
 
41 41
 
42
-    /**
43
-     * Prepares a possible array of input values from JSON for use by the models
44
-     *
45
-     * @param EE_Model_Field_Base $field_obj
46
-     * @param mixed               $original_value_maybe_array
47
-     * @param string              $requested_version
48
-     * @param string              $timezone_string treat values as being in this timezone
49
-     * @return mixed
50
-     * @throws RestException
51
-     */
52
-    public static function prepareFieldValuesFromJson(
53
-        $field_obj,
54
-        $original_value_maybe_array,
55
-        $requested_version,
56
-        $timezone_string = 'UTC'
57
-    ) {
58
-        if (is_array($original_value_maybe_array)
59
-            && ! $field_obj instanceof EE_Serialized_Text_Field
60
-        ) {
61
-            $new_value_maybe_array = array();
62
-            foreach ($original_value_maybe_array as $array_key => $array_item) {
63
-                $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
64
-                    $field_obj,
65
-                    $array_item,
66
-                    $requested_version,
67
-                    $timezone_string
68
-                );
69
-            }
70
-        } else {
71
-            $new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson(
72
-                $field_obj,
73
-                $original_value_maybe_array,
74
-                $requested_version,
75
-                $timezone_string
76
-            );
77
-        }
78
-        return $new_value_maybe_array;
79
-    }
42
+	/**
43
+	 * Prepares a possible array of input values from JSON for use by the models
44
+	 *
45
+	 * @param EE_Model_Field_Base $field_obj
46
+	 * @param mixed               $original_value_maybe_array
47
+	 * @param string              $requested_version
48
+	 * @param string              $timezone_string treat values as being in this timezone
49
+	 * @return mixed
50
+	 * @throws RestException
51
+	 */
52
+	public static function prepareFieldValuesFromJson(
53
+		$field_obj,
54
+		$original_value_maybe_array,
55
+		$requested_version,
56
+		$timezone_string = 'UTC'
57
+	) {
58
+		if (is_array($original_value_maybe_array)
59
+			&& ! $field_obj instanceof EE_Serialized_Text_Field
60
+		) {
61
+			$new_value_maybe_array = array();
62
+			foreach ($original_value_maybe_array as $array_key => $array_item) {
63
+				$new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
64
+					$field_obj,
65
+					$array_item,
66
+					$requested_version,
67
+					$timezone_string
68
+				);
69
+			}
70
+		} else {
71
+			$new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson(
72
+				$field_obj,
73
+				$original_value_maybe_array,
74
+				$requested_version,
75
+				$timezone_string
76
+			);
77
+		}
78
+		return $new_value_maybe_array;
79
+	}
80 80
 
81 81
 
82
-    /**
83
-     * Prepares an array of field values FOR use in JSON/REST API
84
-     *
85
-     * @param EE_Model_Field_Base $field_obj
86
-     * @param mixed               $original_value_maybe_array
87
-     * @param string              $request_version (eg 4.8.36)
88
-     * @return array
89
-     */
90
-    public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version)
91
-    {
92
-        if (is_array($original_value_maybe_array)) {
93
-            $new_value = array();
94
-            foreach ($original_value_maybe_array as $key => $value) {
95
-                $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
96
-                    $field_obj,
97
-                    $value,
98
-                    $request_version
99
-                );
100
-            }
101
-        } else {
102
-            $new_value = ModelDataTranslator::prepareFieldValueForJson(
103
-                $field_obj,
104
-                $original_value_maybe_array,
105
-                $request_version
106
-            );
107
-        }
108
-        return $new_value;
109
-    }
82
+	/**
83
+	 * Prepares an array of field values FOR use in JSON/REST API
84
+	 *
85
+	 * @param EE_Model_Field_Base $field_obj
86
+	 * @param mixed               $original_value_maybe_array
87
+	 * @param string              $request_version (eg 4.8.36)
88
+	 * @return array
89
+	 */
90
+	public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version)
91
+	{
92
+		if (is_array($original_value_maybe_array)) {
93
+			$new_value = array();
94
+			foreach ($original_value_maybe_array as $key => $value) {
95
+				$new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
96
+					$field_obj,
97
+					$value,
98
+					$request_version
99
+				);
100
+			}
101
+		} else {
102
+			$new_value = ModelDataTranslator::prepareFieldValueForJson(
103
+				$field_obj,
104
+				$original_value_maybe_array,
105
+				$request_version
106
+			);
107
+		}
108
+		return $new_value;
109
+	}
110 110
 
111 111
 
112
-    /**
113
-     * Prepares incoming data from the json or $_REQUEST parameters for the models'
114
-     * "$query_params".
115
-     *
116
-     * @param EE_Model_Field_Base $field_obj
117
-     * @param mixed               $original_value
118
-     * @param string              $requested_version
119
-     * @param string              $timezone_string treat values as being in this timezone
120
-     * @return mixed
121
-     * @throws RestException
122
-     * @throws DomainException
123
-     * @throws EE_Error
124
-     */
125
-    public static function prepareFieldValueFromJson(
126
-        $field_obj,
127
-        $original_value,
128
-        $requested_version,
129
-        $timezone_string = 'UTC' // UTC
130
-    ) {
131
-        // check if they accidentally submitted an error value. If so throw an exception
132
-        if (is_array($original_value)
133
-            && isset($original_value['error_code'], $original_value['error_message'])) {
134
-            throw new RestException(
135
-                'rest_submitted_error_value',
136
-                sprintf(
137
-                    esc_html__(
138
-                        'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.',
139
-                        'event_espresso'
140
-                    ),
141
-                    $field_obj->get_name()
142
-                ),
143
-                array(
144
-                    'status' => 400,
145
-                )
146
-            );
147
-        }
148
-        // double-check for serialized PHP. We never accept serialized PHP. No way Jose.
149
-        ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
150
-        $timezone_string = $timezone_string !== '' ? $timezone_string : get_option('timezone_string', '');
151
-        $new_value = null;
152
-        // walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No
153
-        // way Jose.
154
-        ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
155
-        if ($field_obj instanceof EE_Infinite_Integer_Field
156
-            && in_array($original_value, array(null, ''), true)
157
-        ) {
158
-            $new_value = EE_INF;
159
-        } elseif ($field_obj instanceof EE_Datetime_Field) {
160
-            $new_value = rest_parse_date(
161
-                self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string)
162
-            );
163
-            if ($new_value === false) {
164
-                throw new RestException(
165
-                    'invalid_format_for_timestamp',
166
-                    sprintf(
167
-                        esc_html__(
168
-                            'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format.  The timestamp provided (%3$s) is not that format.',
169
-                            'event_espresso'
170
-                        ),
171
-                        'RFC3339',
172
-                        'ISO8601',
173
-                        $original_value
174
-                    ),
175
-                    array(
176
-                        'status' => 400,
177
-                    )
178
-                );
179
-            }
180
-        } else {
181
-            $new_value = $original_value;
182
-        }
183
-        return $new_value;
184
-    }
112
+	/**
113
+	 * Prepares incoming data from the json or $_REQUEST parameters for the models'
114
+	 * "$query_params".
115
+	 *
116
+	 * @param EE_Model_Field_Base $field_obj
117
+	 * @param mixed               $original_value
118
+	 * @param string              $requested_version
119
+	 * @param string              $timezone_string treat values as being in this timezone
120
+	 * @return mixed
121
+	 * @throws RestException
122
+	 * @throws DomainException
123
+	 * @throws EE_Error
124
+	 */
125
+	public static function prepareFieldValueFromJson(
126
+		$field_obj,
127
+		$original_value,
128
+		$requested_version,
129
+		$timezone_string = 'UTC' // UTC
130
+	) {
131
+		// check if they accidentally submitted an error value. If so throw an exception
132
+		if (is_array($original_value)
133
+			&& isset($original_value['error_code'], $original_value['error_message'])) {
134
+			throw new RestException(
135
+				'rest_submitted_error_value',
136
+				sprintf(
137
+					esc_html__(
138
+						'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.',
139
+						'event_espresso'
140
+					),
141
+					$field_obj->get_name()
142
+				),
143
+				array(
144
+					'status' => 400,
145
+				)
146
+			);
147
+		}
148
+		// double-check for serialized PHP. We never accept serialized PHP. No way Jose.
149
+		ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
150
+		$timezone_string = $timezone_string !== '' ? $timezone_string : get_option('timezone_string', '');
151
+		$new_value = null;
152
+		// walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No
153
+		// way Jose.
154
+		ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value);
155
+		if ($field_obj instanceof EE_Infinite_Integer_Field
156
+			&& in_array($original_value, array(null, ''), true)
157
+		) {
158
+			$new_value = EE_INF;
159
+		} elseif ($field_obj instanceof EE_Datetime_Field) {
160
+			$new_value = rest_parse_date(
161
+				self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string)
162
+			);
163
+			if ($new_value === false) {
164
+				throw new RestException(
165
+					'invalid_format_for_timestamp',
166
+					sprintf(
167
+						esc_html__(
168
+							'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format.  The timestamp provided (%3$s) is not that format.',
169
+							'event_espresso'
170
+						),
171
+						'RFC3339',
172
+						'ISO8601',
173
+						$original_value
174
+					),
175
+					array(
176
+						'status' => 400,
177
+					)
178
+				);
179
+			}
180
+		} else {
181
+			$new_value = $original_value;
182
+		}
183
+		return $new_value;
184
+	}
185 185
 
186 186
 
187
-    /**
188
-     * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone
189
-     * information via details obtained from the host site.
190
-     *
191
-     * @param string            $original_timestamp
192
-     * @param EE_Datetime_Field $datetime_field
193
-     * @param                   $timezone_string
194
-     * @return string
195
-     * @throws DomainException
196
-     */
197
-    private static function getTimestampWithTimezoneOffset(
198
-        $original_timestamp,
199
-        EE_Datetime_Field $datetime_field,
200
-        $timezone_string
201
-    ) {
202
-        // already have timezone information?
203
-        if (preg_match('/Z|(\+|\-)(\d{2}:\d{2})/', $original_timestamp)) {
204
-            // yes, we're ignoring the timezone.
205
-            return $original_timestamp;
206
-        }
207
-        // need to append timezone
208
-        list($offset_sign, $offset_secs) = self::parseTimezoneOffset(
209
-            $datetime_field->get_timezone_offset(
210
-                new \DateTimeZone($timezone_string),
211
-                $original_timestamp
212
-            )
213
-        );
214
-        $offset_string =
215
-            str_pad(
216
-                floor($offset_secs / HOUR_IN_SECONDS),
217
-                2,
218
-                '0',
219
-                STR_PAD_LEFT
220
-            )
221
-            . ':'
222
-            . str_pad(
223
-                ($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
224
-                2,
225
-                '0',
226
-                STR_PAD_LEFT
227
-            );
228
-        return $original_timestamp . $offset_sign . $offset_string;
229
-    }
187
+	/**
188
+	 * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone
189
+	 * information via details obtained from the host site.
190
+	 *
191
+	 * @param string            $original_timestamp
192
+	 * @param EE_Datetime_Field $datetime_field
193
+	 * @param                   $timezone_string
194
+	 * @return string
195
+	 * @throws DomainException
196
+	 */
197
+	private static function getTimestampWithTimezoneOffset(
198
+		$original_timestamp,
199
+		EE_Datetime_Field $datetime_field,
200
+		$timezone_string
201
+	) {
202
+		// already have timezone information?
203
+		if (preg_match('/Z|(\+|\-)(\d{2}:\d{2})/', $original_timestamp)) {
204
+			// yes, we're ignoring the timezone.
205
+			return $original_timestamp;
206
+		}
207
+		// need to append timezone
208
+		list($offset_sign, $offset_secs) = self::parseTimezoneOffset(
209
+			$datetime_field->get_timezone_offset(
210
+				new \DateTimeZone($timezone_string),
211
+				$original_timestamp
212
+			)
213
+		);
214
+		$offset_string =
215
+			str_pad(
216
+				floor($offset_secs / HOUR_IN_SECONDS),
217
+				2,
218
+				'0',
219
+				STR_PAD_LEFT
220
+			)
221
+			. ':'
222
+			. str_pad(
223
+				($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS,
224
+				2,
225
+				'0',
226
+				STR_PAD_LEFT
227
+			);
228
+		return $original_timestamp . $offset_sign . $offset_string;
229
+	}
230 230
 
231 231
 
232
-    /**
233
-     * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't
234
-     * think that can happen). If $data is an array, recurses into its keys and values
235
-     *
236
-     * @param mixed $data
237
-     * @throws RestException
238
-     * @return void
239
-     */
240
-    public static function throwExceptionIfContainsSerializedData($data)
241
-    {
242
-        if (is_array($data)) {
243
-            foreach ($data as $key => $value) {
244
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($key);
245
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($value);
246
-            }
247
-        } else {
248
-            if (is_serialized($data) || is_object($data)) {
249
-                throw new RestException(
250
-                    'serialized_data_submission_prohibited',
251
-                    esc_html__(
252
-                    // @codingStandardsIgnoreStart
253
-                        'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.',
254
-                        // @codingStandardsIgnoreEnd
255
-                        'event_espresso'
256
-                    )
257
-                );
258
-            }
259
-        }
260
-    }
232
+	/**
233
+	 * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't
234
+	 * think that can happen). If $data is an array, recurses into its keys and values
235
+	 *
236
+	 * @param mixed $data
237
+	 * @throws RestException
238
+	 * @return void
239
+	 */
240
+	public static function throwExceptionIfContainsSerializedData($data)
241
+	{
242
+		if (is_array($data)) {
243
+			foreach ($data as $key => $value) {
244
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($key);
245
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($value);
246
+			}
247
+		} else {
248
+			if (is_serialized($data) || is_object($data)) {
249
+				throw new RestException(
250
+					'serialized_data_submission_prohibited',
251
+					esc_html__(
252
+					// @codingStandardsIgnoreStart
253
+						'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.',
254
+						// @codingStandardsIgnoreEnd
255
+						'event_espresso'
256
+					)
257
+				);
258
+			}
259
+		}
260
+	}
261 261
 
262 262
 
263
-    /**
264
-     * determines what's going on with them timezone strings
265
-     *
266
-     * @param int $timezone_offset
267
-     * @return array
268
-     */
269
-    private static function parseTimezoneOffset($timezone_offset)
270
-    {
271
-        $first_char = substr((string) $timezone_offset, 0, 1);
272
-        if ($first_char === '+' || $first_char === '-') {
273
-            $offset_sign = $first_char;
274
-            $offset_secs = substr((string) $timezone_offset, 1);
275
-        } else {
276
-            $offset_sign = '+';
277
-            $offset_secs = $timezone_offset;
278
-        }
279
-        return array($offset_sign, $offset_secs);
280
-    }
263
+	/**
264
+	 * determines what's going on with them timezone strings
265
+	 *
266
+	 * @param int $timezone_offset
267
+	 * @return array
268
+	 */
269
+	private static function parseTimezoneOffset($timezone_offset)
270
+	{
271
+		$first_char = substr((string) $timezone_offset, 0, 1);
272
+		if ($first_char === '+' || $first_char === '-') {
273
+			$offset_sign = $first_char;
274
+			$offset_secs = substr((string) $timezone_offset, 1);
275
+		} else {
276
+			$offset_sign = '+';
277
+			$offset_secs = $timezone_offset;
278
+		}
279
+		return array($offset_sign, $offset_secs);
280
+	}
281 281
 
282 282
 
283
-    /**
284
-     * Prepares a field's value for display in the API
285
-     *
286
-     * @param EE_Model_Field_Base $field_obj
287
-     * @param mixed               $original_value
288
-     * @param string              $requested_version
289
-     * @return mixed
290
-     */
291
-    public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version)
292
-    {
293
-        if ($original_value === EE_INF) {
294
-            $new_value = ModelDataTranslator::EE_INF_IN_REST;
295
-        } elseif ($field_obj instanceof EE_Datetime_Field) {
296
-            if (is_string($original_value)) {
297
-                // did they submit a string of a unix timestamp?
298
-                if (is_numeric($original_value)) {
299
-                    $datetime_obj = new \DateTime();
300
-                    $datetime_obj->setTimestamp((int) $original_value);
301
-                } else {
302
-                    // first, check if its a MySQL timestamp in GMT
303
-                    $datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
304
-                }
305
-                if (! $datetime_obj instanceof \DateTime) {
306
-                    // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
307
-                    $datetime_obj = $field_obj->prepare_for_set($original_value);
308
-                }
309
-                $original_value = $datetime_obj;
310
-            }
311
-            if ($original_value instanceof \DateTime) {
312
-                $new_value = $original_value->format('Y-m-d H:i:s');
313
-            } elseif (is_int($original_value) || is_float($original_value)) {
314
-                $new_value = date('Y-m-d H:i:s', $original_value);
315
-            } elseif ($original_value === null || $original_value === '') {
316
-                $new_value = null;
317
-            } else {
318
-                // so it's not a datetime object, unix timestamp (as string or int),
319
-                // MySQL timestamp, or even a string in the field object's format. So no idea what it is
320
-                throw new \EE_Error(
321
-                    sprintf(
322
-                        esc_html__(
323
-                        // @codingStandardsIgnoreStart
324
-                            'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
325
-                            // @codingStandardsIgnoreEnd
326
-                            'event_espresso'
327
-                        ),
328
-                        $original_value,
329
-                        $field_obj->get_name(),
330
-                        $field_obj->get_model_name(),
331
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
332
-                    )
333
-                );
334
-            }
335
-            if ($new_value !== null) {
336
-                $new_value = mysql_to_rfc3339($new_value);
337
-            }
338
-        } else {
339
-            $new_value = $original_value;
340
-        }
341
-        // are we about to send an object? just don't. We have no good way to represent it in JSON.
342
-        // can't just check using is_object() because that missed PHP incomplete objects
343
-        if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
344
-            $new_value = array(
345
-                'error_code'    => 'php_object_not_return',
346
-                'error_message' => esc_html__(
347
-                    'The value of this field in the database is a PHP object, which can\'t be represented in JSON.',
348
-                    'event_espresso'
349
-                ),
350
-            );
351
-        }
352
-        return apply_filters(
353
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
354
-            $new_value,
355
-            $field_obj,
356
-            $original_value,
357
-            $requested_version
358
-        );
359
-    }
283
+	/**
284
+	 * Prepares a field's value for display in the API
285
+	 *
286
+	 * @param EE_Model_Field_Base $field_obj
287
+	 * @param mixed               $original_value
288
+	 * @param string              $requested_version
289
+	 * @return mixed
290
+	 */
291
+	public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version)
292
+	{
293
+		if ($original_value === EE_INF) {
294
+			$new_value = ModelDataTranslator::EE_INF_IN_REST;
295
+		} elseif ($field_obj instanceof EE_Datetime_Field) {
296
+			if (is_string($original_value)) {
297
+				// did they submit a string of a unix timestamp?
298
+				if (is_numeric($original_value)) {
299
+					$datetime_obj = new \DateTime();
300
+					$datetime_obj->setTimestamp((int) $original_value);
301
+				} else {
302
+					// first, check if its a MySQL timestamp in GMT
303
+					$datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
304
+				}
305
+				if (! $datetime_obj instanceof \DateTime) {
306
+					// so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
307
+					$datetime_obj = $field_obj->prepare_for_set($original_value);
308
+				}
309
+				$original_value = $datetime_obj;
310
+			}
311
+			if ($original_value instanceof \DateTime) {
312
+				$new_value = $original_value->format('Y-m-d H:i:s');
313
+			} elseif (is_int($original_value) || is_float($original_value)) {
314
+				$new_value = date('Y-m-d H:i:s', $original_value);
315
+			} elseif ($original_value === null || $original_value === '') {
316
+				$new_value = null;
317
+			} else {
318
+				// so it's not a datetime object, unix timestamp (as string or int),
319
+				// MySQL timestamp, or even a string in the field object's format. So no idea what it is
320
+				throw new \EE_Error(
321
+					sprintf(
322
+						esc_html__(
323
+						// @codingStandardsIgnoreStart
324
+							'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".',
325
+							// @codingStandardsIgnoreEnd
326
+							'event_espresso'
327
+						),
328
+						$original_value,
329
+						$field_obj->get_name(),
330
+						$field_obj->get_model_name(),
331
+						$field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
332
+					)
333
+				);
334
+			}
335
+			if ($new_value !== null) {
336
+				$new_value = mysql_to_rfc3339($new_value);
337
+			}
338
+		} else {
339
+			$new_value = $original_value;
340
+		}
341
+		// are we about to send an object? just don't. We have no good way to represent it in JSON.
342
+		// can't just check using is_object() because that missed PHP incomplete objects
343
+		if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
344
+			$new_value = array(
345
+				'error_code'    => 'php_object_not_return',
346
+				'error_message' => esc_html__(
347
+					'The value of this field in the database is a PHP object, which can\'t be represented in JSON.',
348
+					'event_espresso'
349
+				),
350
+			);
351
+		}
352
+		return apply_filters(
353
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api',
354
+			$new_value,
355
+			$field_obj,
356
+			$original_value,
357
+			$requested_version
358
+		);
359
+	}
360 360
 
361 361
 
362
-    /**
363
-     * Prepares condition-query-parameters (like what's in where and having) from
364
-     * the format expected in the API to use in the models
365
-     *
366
-     * @param array $inputted_query_params_of_this_type
367
-     * @param EEM_Base $model
368
-     * @param string $requested_version
369
-     * @param boolean $writing whether this data will be written to the DB, or if we're just building a query.
370
-     *                          If we're writing to the DB, we don't expect any operators, or any logic query
371
-     *                          parameters, and we also won't accept serialized data unless the current user has
372
-     *                          unfiltered_html.
373
-     * @return array
374
-     * @throws DomainException
375
-     * @throws EE_Error
376
-     * @throws RestException
377
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
378
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
379
-     * @throws \InvalidArgumentException
380
-     */
381
-    public static function prepareConditionsQueryParamsForModels(
382
-        $inputted_query_params_of_this_type,
383
-        EEM_Base $model,
384
-        $requested_version,
385
-        $writing = false
386
-    ) {
387
-        $query_param_for_models = array();
388
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
389
-            list(
390
-                $field,
391
-                $query_param_key,
392
-                $query_param_sans_stars,
393
-                $timezone,
394
-                $is_gmt_datetime_field
395
-                ) = self::determineFieldAndTimezone(
396
-                    $model,
397
-                    $query_param_key
398
-                );
399
-            if ($field instanceof EE_Model_Field_Base) {
400
-                $translated_value = self::determineConditionsQueryParameterValue(
401
-                    $model,
402
-                    $field,
403
-                    $requested_version,
404
-                    $timezone,
405
-                    $query_param_key,
406
-                    $query_param_value,
407
-                    $writing
408
-                );
409
-                if ((isset($query_param_for_models[ $query_param_key ]) && $is_gmt_datetime_field)
410
-                    || $translated_value === null
411
-                ) {
412
-                    // they have already provided a non-gmt field, ignore the gmt one. That's what WP core
413
-                    // currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954
414
-                    // OR we couldn't create a translated value from their input
415
-                    continue;
416
-                }
417
-                $query_param_for_models[ $query_param_key ] = $translated_value;
418
-            } else {
419
-                $nested_query_params = self::determineNestedConditionQueryParameters(
420
-                    $model,
421
-                    $query_param_key,
422
-                    $query_param_sans_stars,
423
-                    $query_param_value,
424
-                    $requested_version,
425
-                    $writing
426
-                );
427
-                if ($nested_query_params) {
428
-                    $query_param_for_models[$query_param_key] = $nested_query_params;
429
-                }
430
-            }
431
-        }
432
-        return $query_param_for_models;
433
-    }
362
+	/**
363
+	 * Prepares condition-query-parameters (like what's in where and having) from
364
+	 * the format expected in the API to use in the models
365
+	 *
366
+	 * @param array $inputted_query_params_of_this_type
367
+	 * @param EEM_Base $model
368
+	 * @param string $requested_version
369
+	 * @param boolean $writing whether this data will be written to the DB, or if we're just building a query.
370
+	 *                          If we're writing to the DB, we don't expect any operators, or any logic query
371
+	 *                          parameters, and we also won't accept serialized data unless the current user has
372
+	 *                          unfiltered_html.
373
+	 * @return array
374
+	 * @throws DomainException
375
+	 * @throws EE_Error
376
+	 * @throws RestException
377
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
378
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
379
+	 * @throws \InvalidArgumentException
380
+	 */
381
+	public static function prepareConditionsQueryParamsForModels(
382
+		$inputted_query_params_of_this_type,
383
+		EEM_Base $model,
384
+		$requested_version,
385
+		$writing = false
386
+	) {
387
+		$query_param_for_models = array();
388
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
389
+			list(
390
+				$field,
391
+				$query_param_key,
392
+				$query_param_sans_stars,
393
+				$timezone,
394
+				$is_gmt_datetime_field
395
+				) = self::determineFieldAndTimezone(
396
+					$model,
397
+					$query_param_key
398
+				);
399
+			if ($field instanceof EE_Model_Field_Base) {
400
+				$translated_value = self::determineConditionsQueryParameterValue(
401
+					$model,
402
+					$field,
403
+					$requested_version,
404
+					$timezone,
405
+					$query_param_key,
406
+					$query_param_value,
407
+					$writing
408
+				);
409
+				if ((isset($query_param_for_models[ $query_param_key ]) && $is_gmt_datetime_field)
410
+					|| $translated_value === null
411
+				) {
412
+					// they have already provided a non-gmt field, ignore the gmt one. That's what WP core
413
+					// currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954
414
+					// OR we couldn't create a translated value from their input
415
+					continue;
416
+				}
417
+				$query_param_for_models[ $query_param_key ] = $translated_value;
418
+			} else {
419
+				$nested_query_params = self::determineNestedConditionQueryParameters(
420
+					$model,
421
+					$query_param_key,
422
+					$query_param_sans_stars,
423
+					$query_param_value,
424
+					$requested_version,
425
+					$writing
426
+				);
427
+				if ($nested_query_params) {
428
+					$query_param_for_models[$query_param_key] = $nested_query_params;
429
+				}
430
+			}
431
+		}
432
+		return $query_param_for_models;
433
+	}
434 434
 
435
-    /**
436
-     * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
437
-     * @since $VID:$
438
-     * @param EEM_Base $model
439
-     * @param $query_param_key
440
-     * @param $query_param_sans_stars
441
-     * @param $query_param_value
442
-     * @param $requested_version
443
-     * @param $writing
444
-     * @return array
445
-     * @throws DomainException
446
-     * @throws EE_Error
447
-     * @throws RestException
448
-     */
449
-    private static function determineNestedConditionQueryParameters(
450
-        EEM_Base $model,
451
-        $query_param_key,
452
-        $query_param_sans_stars,
453
-        $query_param_value,
454
-        $requested_version,
455
-        $writing
456
-    ) {
435
+	/**
436
+	 * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
437
+	 * @since $VID:$
438
+	 * @param EEM_Base $model
439
+	 * @param $query_param_key
440
+	 * @param $query_param_sans_stars
441
+	 * @param $query_param_value
442
+	 * @param $requested_version
443
+	 * @param $writing
444
+	 * @return array
445
+	 * @throws DomainException
446
+	 * @throws EE_Error
447
+	 * @throws RestException
448
+	 */
449
+	private static function determineNestedConditionQueryParameters(
450
+		EEM_Base $model,
451
+		$query_param_key,
452
+		$query_param_sans_stars,
453
+		$query_param_value,
454
+		$requested_version,
455
+		$writing
456
+	) {
457 457
 
458
-        // so this param doesn't correspond to a field eh?
459
-        if ($writing) {
460
-            // always tell API clients about invalid parameters when they're creating data. Otherwise,
461
-            // they are probably going to create invalid data
462
-            throw new RestException(
463
-                'invalid_field',
464
-                sprintf(
465
-                    /* translators: 1: variable name */
466
-                    esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
467
-                    $query_param_key
468
-                )
469
-            );
470
-        } else {
471
-            // so it's not for a field, is it a logic query param key?
472
-            if (in_array(
473
-                $query_param_sans_stars,
474
-                $model->logic_query_param_keys()
475
-            )) {
476
-                return ModelDataTranslator::prepareConditionsQueryParamsForModels(
477
-                    $query_param_value,
478
-                    $model,
479
-                    $requested_version
480
-                );
481
-            } elseif (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
482
-                // only tell API clients they got it wrong if we're in debug mode
483
-                // otherwise try our best ot fulfill their request by ignoring this invalid data
484
-                throw new RestException(
485
-                    'invalid_parameter',
486
-                    sprintf(
487
-                        /* translators: 1: variable name */
488
-                        esc_html__(
489
-                            'You provided an invalid parameter, with key "%1$s"',
490
-                            'event_espresso'
491
-                        ),
492
-                        $query_param_key
493
-                    ),
494
-                    array(
495
-                        'status' => 400,
496
-                    )
497
-                );
498
-            }
499
-        }
500
-        return null;
501
-    }
458
+		// so this param doesn't correspond to a field eh?
459
+		if ($writing) {
460
+			// always tell API clients about invalid parameters when they're creating data. Otherwise,
461
+			// they are probably going to create invalid data
462
+			throw new RestException(
463
+				'invalid_field',
464
+				sprintf(
465
+					/* translators: 1: variable name */
466
+					esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
467
+					$query_param_key
468
+				)
469
+			);
470
+		} else {
471
+			// so it's not for a field, is it a logic query param key?
472
+			if (in_array(
473
+				$query_param_sans_stars,
474
+				$model->logic_query_param_keys()
475
+			)) {
476
+				return ModelDataTranslator::prepareConditionsQueryParamsForModels(
477
+					$query_param_value,
478
+					$model,
479
+					$requested_version
480
+				);
481
+			} elseif (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
482
+				// only tell API clients they got it wrong if we're in debug mode
483
+				// otherwise try our best ot fulfill their request by ignoring this invalid data
484
+				throw new RestException(
485
+					'invalid_parameter',
486
+					sprintf(
487
+						/* translators: 1: variable name */
488
+						esc_html__(
489
+							'You provided an invalid parameter, with key "%1$s"',
490
+							'event_espresso'
491
+						),
492
+						$query_param_key
493
+					),
494
+					array(
495
+						'status' => 400,
496
+					)
497
+				);
498
+			}
499
+		}
500
+		return null;
501
+	}
502 502
 
503
-    /**
504
-     * Determines what field, query param name, and query param name without stars, and timezone to use.
505
-     * @since $VID:$
506
-     * @param EEM_Base $model
507
-     * @param $query_param_sans_stars
508
-     * @return array {
509
-     * @type EE_Model_Field_Base $field
510
-     * @type string $query_param_key
511
-     * @type string $query_param_sans_stars
512
-     * @type string $timezone
513
-     * @type boolean $is_gmt_datetime_field
514
-     * }
515
-     * @throws EE_Error
516
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
517
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
518
-     * @throws \InvalidArgumentException
519
-     */
520
-    private static function determineFieldAndTimezone(EEM_Base $model, $query_param_key)
521
-    {
522
-        $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
523
-            $query_param_key
524
-        );
525
-        $is_gmt_datetime_field = false;
526
-        $field = ModelDataTranslator::deduceFieldFromQueryParam(
527
-            $query_param_sans_stars,
528
-            $model
529
-        );
530
-        // double-check is it a *_gmt field?
531
-        if (! $field instanceof EE_Model_Field_Base
532
-            && ModelDataTranslator::isGmtDateFieldName($query_param_sans_stars)
533
-        ) {
534
-            // yep, take off '_gmt', and find the field
535
-            $query_param_key = ModelDataTranslator::removeGmtFromFieldName($query_param_sans_stars);
536
-            $field = ModelDataTranslator::deduceFieldFromQueryParam(
537
-                $query_param_key,
538
-                $model
539
-            );
540
-            $timezone = 'UTC';
541
-            $is_gmt_datetime_field = true;
542
-        } elseif ($field instanceof EE_Datetime_Field) {
543
-            // so it's not a GMT field. Set the timezone on the model to the default
544
-            $timezone = \EEH_DTT_Helper::get_valid_timezone_string();
545
-        } else {
546
-            // just keep using what's already set for the timezone
547
-            $timezone = $model->get_timezone();
548
-        }
549
-        return array(
550
-            $field,
551
-            $query_param_key,
552
-            $query_param_sans_stars,
553
-            $timezone,
554
-            $is_gmt_datetime_field
555
-        );
556
-    }
503
+	/**
504
+	 * Determines what field, query param name, and query param name without stars, and timezone to use.
505
+	 * @since $VID:$
506
+	 * @param EEM_Base $model
507
+	 * @param $query_param_sans_stars
508
+	 * @return array {
509
+	 * @type EE_Model_Field_Base $field
510
+	 * @type string $query_param_key
511
+	 * @type string $query_param_sans_stars
512
+	 * @type string $timezone
513
+	 * @type boolean $is_gmt_datetime_field
514
+	 * }
515
+	 * @throws EE_Error
516
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
517
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
518
+	 * @throws \InvalidArgumentException
519
+	 */
520
+	private static function determineFieldAndTimezone(EEM_Base $model, $query_param_key)
521
+	{
522
+		$query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
523
+			$query_param_key
524
+		);
525
+		$is_gmt_datetime_field = false;
526
+		$field = ModelDataTranslator::deduceFieldFromQueryParam(
527
+			$query_param_sans_stars,
528
+			$model
529
+		);
530
+		// double-check is it a *_gmt field?
531
+		if (! $field instanceof EE_Model_Field_Base
532
+			&& ModelDataTranslator::isGmtDateFieldName($query_param_sans_stars)
533
+		) {
534
+			// yep, take off '_gmt', and find the field
535
+			$query_param_key = ModelDataTranslator::removeGmtFromFieldName($query_param_sans_stars);
536
+			$field = ModelDataTranslator::deduceFieldFromQueryParam(
537
+				$query_param_key,
538
+				$model
539
+			);
540
+			$timezone = 'UTC';
541
+			$is_gmt_datetime_field = true;
542
+		} elseif ($field instanceof EE_Datetime_Field) {
543
+			// so it's not a GMT field. Set the timezone on the model to the default
544
+			$timezone = \EEH_DTT_Helper::get_valid_timezone_string();
545
+		} else {
546
+			// just keep using what's already set for the timezone
547
+			$timezone = $model->get_timezone();
548
+		}
549
+		return array(
550
+			$field,
551
+			$query_param_key,
552
+			$query_param_sans_stars,
553
+			$timezone,
554
+			$is_gmt_datetime_field
555
+		);
556
+	}
557 557
 
558
-    /**
559
-     * Given a ton of input, determines the value to use for the models.
560
-     * @since $VID:$
561
-     * @param EEM_Base $model
562
-     * @param EE_Model_Field_Base $field
563
-     * @param $requested_version
564
-     * @param $timezone
565
-     * @param $query_param_key
566
-     * @param $query_param_value
567
-     * @param bool $writing
568
-     * @return array|null
569
-     * @throws DomainException
570
-     * @throws EE_Error
571
-     * @throws RestException
572
-     */
573
-    private static function determineConditionsQueryParameterValue(
574
-        EEM_Base $model,
575
-        EE_Model_Field_Base $field,
576
-        $requested_version,
577
-        $timezone,
578
-        $query_param_key,
579
-        $query_param_value,
580
-        $writing = false
581
-    ) {
582
-        if (! $writing && is_array($query_param_value)) {
583
-            if (! \EEH_Array::is_array_numerically_and_sequentially_indexed($query_param_value)) {
584
-                if (is_array($query_param_value)
585
-                    && count($query_param_value) === 1
586
-                    && array_key_exists(
587
-                        key($query_param_value),
588
-                        $model->valid_operators()
589
-                    )
590
-                ) {
591
-                    $sub_array_value =  reset($query_param_value);
592
-                    $sub_array_key = key($query_param_value);
593
-                    // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
594
-                    if (array_key_exists(
595
-                        $sub_array_key,
596
-                        array_merge(
597
-                            $model->valid_in_style_operators(),
598
-                            $model->valid_between_style_operators()
599
-                        )
600
-                    )) {
601
-                        // the value should be JSON or CSV
602
-                        $values = json_decode($sub_array_value);
603
-                        if (! is_array($values)) {
604
-                            $values = array_filter(
605
-                                array_map(
606
-                                    'trim',
607
-                                    explode(
608
-                                        ',',
609
-                                        $sub_array_value
610
-                                    )
611
-                                )
612
-                            );
613
-                        }
614
-                        $query_param_value = array(
615
-                            $sub_array_key,
616
-                            $values
617
-                        );
618
-                    } elseif (array_key_exists(
619
-                        $sub_array_key,
620
-                        $model->valid_null_style_operators()
621
-                    )) {
622
-                        $query_param_value = array($sub_array_key);
623
-                    } else {
624
-                        $query_param_value = array($sub_array_key, $sub_array_value);
625
-                    }
626
-                } elseif (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
627
-                    throw new RestException(
628
-                        'numerically_indexed_array_of_values_only',
629
-                        sprintf(
630
-                            /* translators: 1: variable name*/
631
-                            esc_html__(
632
-                                'The array provided for the parameter "%1$s" should be numerically indexed.',
633
-                                'event_espresso'
634
-                            ),
635
-                            $query_param_key
636
-                        ),
637
-                        array(
638
-                            'status' => 400,
639
-                        )
640
-                    );
641
-                }
642
-            }
643
-            $valid_operators = $model->valid_operators();
644
-            // did they specify an operator?
645
-            if (isset($query_param_value[0])
646
-                && isset($valid_operators[ $query_param_value[0] ])
647
-            ) {
648
-                $sub_array_key = $query_param_value[0];
649
-                $translated_value = array($sub_array_key);
650
-                if (array_key_exists($sub_array_key, $model->valid_in_style_operators())
651
-                    && isset($query_param_value[1])
652
-                    && ! isset($query_param_value[2])
653
-                ) {
654
-                    $translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
655
-                        $field,
656
-                        $query_param_value[1],
657
-                        $requested_version,
658
-                        $timezone
659
-                    );
660
-                } elseif (array_key_exists($sub_array_key, $model->valid_between_style_operators())
661
-                    && isset($query_param_value[1])
662
-                    && is_array($query_param_value[1])
663
-                    && isset($query_param_key[1][0], $query_param_value[1][1])
664
-                    && ! isset($query_param_value[1][2])
665
-                    && ! isset($query_param_value[2])
666
-                ) {
667
-                    $translated_value[] = array(
668
-                        ModelDataTranslator::prepareFieldValuesFromJson(
669
-                            $field,
670
-                            $query_param_value[1][0],
671
-                            $requested_version,
672
-                            $timezone
673
-                        ),
674
-                        ModelDataTranslator::prepareFieldValuesFromJson(
675
-                            $field,
676
-                            $query_param_value[1][1],
677
-                            $requested_version,
678
-                            $timezone
679
-                        )
680
-                    );
681
-                } elseif (array_key_exists($sub_array_key, $model->valid_like_style_operators())
682
-                    && isset($query_param_value[1])
683
-                    && ! isset($query_param_value[2])
684
-                ) {
685
-                    // we want to leave this value mostly-as-is (eg don't force it to be a float
686
-                    // or a boolean or an enum value. Leave it as-is with wildcards etc)
687
-                    // but do verify it at least doesn't have any serialized data
688
-                    ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
689
-                    $translated_value[] = $query_param_value[1];
690
-                } elseif (array_key_exists($sub_array_key, $model->valid_null_style_operators())
691
-                    && ! isset($query_param_value[1])) {
692
-                    // no arguments should have been provided, so don't look for any
693
-                } elseif (isset($query_param_value[1])
694
-                    && ! isset($query_param_value[2])
695
-                    && ! array_key_exists(
696
-                        $sub_array_key,
697
-                        array_merge(
698
-                            $model->valid_in_style_operators(),
699
-                            $model->valid_null_style_operators(),
700
-                            $model->valid_like_style_operators(),
701
-                            $model->valid_between_style_operators()
702
-                        )
703
-                    )
704
-                ) {
705
-                    // it's a valid operator, but none of the exceptions. Treat it normally.
706
-                    $translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
707
-                        $field,
708
-                        $query_param_value[1],
709
-                        $requested_version,
710
-                        $timezone
711
-                    );
712
-                } else {
713
-                    // so they provided a valid operator, but wrong number of arguments
714
-                    if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
715
-                        throw new RestException(
716
-                            'wrong_number_of_arguments',
717
-                            sprintf(
718
-                                esc_html__(
719
-                                    'The operator you provided, "%1$s" had the wrong number of arguments',
720
-                                    'event_espresso'
721
-                                ),
722
-                                $sub_array_key
723
-                            ),
724
-                            array(
725
-                                'status' => 400,
726
-                            )
727
-                        );
728
-                    }
729
-                    $translated_value = null;
730
-                }
731
-            } else {
732
-                // so they didn't provide a valid operator
733
-                if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
734
-                    throw new RestException(
735
-                        'invalid_operator',
736
-                        sprintf(
737
-                            esc_html__(
738
-                                'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
739
-                                'event_espresso'
740
-                            ),
741
-                            $query_param_key,
742
-                            $query_param_value
743
-                        ),
744
-                        array(
745
-                            'status' => 400,
746
-                        )
747
-                    );
748
-                }
749
-                // if we aren't in debug mode, then just try our best to fulfill the user's request
750
-                $translated_value = null;
751
-            }
752
-        } else {
753
-            $translated_value = ModelDataTranslator::prepareFieldValueFromJson(
754
-                $field,
755
-                $query_param_value,
756
-                $requested_version,
757
-                $timezone
758
-            );
759
-        }
760
-        return $translated_value;
761
-    }
558
+	/**
559
+	 * Given a ton of input, determines the value to use for the models.
560
+	 * @since $VID:$
561
+	 * @param EEM_Base $model
562
+	 * @param EE_Model_Field_Base $field
563
+	 * @param $requested_version
564
+	 * @param $timezone
565
+	 * @param $query_param_key
566
+	 * @param $query_param_value
567
+	 * @param bool $writing
568
+	 * @return array|null
569
+	 * @throws DomainException
570
+	 * @throws EE_Error
571
+	 * @throws RestException
572
+	 */
573
+	private static function determineConditionsQueryParameterValue(
574
+		EEM_Base $model,
575
+		EE_Model_Field_Base $field,
576
+		$requested_version,
577
+		$timezone,
578
+		$query_param_key,
579
+		$query_param_value,
580
+		$writing = false
581
+	) {
582
+		if (! $writing && is_array($query_param_value)) {
583
+			if (! \EEH_Array::is_array_numerically_and_sequentially_indexed($query_param_value)) {
584
+				if (is_array($query_param_value)
585
+					&& count($query_param_value) === 1
586
+					&& array_key_exists(
587
+						key($query_param_value),
588
+						$model->valid_operators()
589
+					)
590
+				) {
591
+					$sub_array_value =  reset($query_param_value);
592
+					$sub_array_key = key($query_param_value);
593
+					// they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
594
+					if (array_key_exists(
595
+						$sub_array_key,
596
+						array_merge(
597
+							$model->valid_in_style_operators(),
598
+							$model->valid_between_style_operators()
599
+						)
600
+					)) {
601
+						// the value should be JSON or CSV
602
+						$values = json_decode($sub_array_value);
603
+						if (! is_array($values)) {
604
+							$values = array_filter(
605
+								array_map(
606
+									'trim',
607
+									explode(
608
+										',',
609
+										$sub_array_value
610
+									)
611
+								)
612
+							);
613
+						}
614
+						$query_param_value = array(
615
+							$sub_array_key,
616
+							$values
617
+						);
618
+					} elseif (array_key_exists(
619
+						$sub_array_key,
620
+						$model->valid_null_style_operators()
621
+					)) {
622
+						$query_param_value = array($sub_array_key);
623
+					} else {
624
+						$query_param_value = array($sub_array_key, $sub_array_value);
625
+					}
626
+				} elseif (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
627
+					throw new RestException(
628
+						'numerically_indexed_array_of_values_only',
629
+						sprintf(
630
+							/* translators: 1: variable name*/
631
+							esc_html__(
632
+								'The array provided for the parameter "%1$s" should be numerically indexed.',
633
+								'event_espresso'
634
+							),
635
+							$query_param_key
636
+						),
637
+						array(
638
+							'status' => 400,
639
+						)
640
+					);
641
+				}
642
+			}
643
+			$valid_operators = $model->valid_operators();
644
+			// did they specify an operator?
645
+			if (isset($query_param_value[0])
646
+				&& isset($valid_operators[ $query_param_value[0] ])
647
+			) {
648
+				$sub_array_key = $query_param_value[0];
649
+				$translated_value = array($sub_array_key);
650
+				if (array_key_exists($sub_array_key, $model->valid_in_style_operators())
651
+					&& isset($query_param_value[1])
652
+					&& ! isset($query_param_value[2])
653
+				) {
654
+					$translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
655
+						$field,
656
+						$query_param_value[1],
657
+						$requested_version,
658
+						$timezone
659
+					);
660
+				} elseif (array_key_exists($sub_array_key, $model->valid_between_style_operators())
661
+					&& isset($query_param_value[1])
662
+					&& is_array($query_param_value[1])
663
+					&& isset($query_param_key[1][0], $query_param_value[1][1])
664
+					&& ! isset($query_param_value[1][2])
665
+					&& ! isset($query_param_value[2])
666
+				) {
667
+					$translated_value[] = array(
668
+						ModelDataTranslator::prepareFieldValuesFromJson(
669
+							$field,
670
+							$query_param_value[1][0],
671
+							$requested_version,
672
+							$timezone
673
+						),
674
+						ModelDataTranslator::prepareFieldValuesFromJson(
675
+							$field,
676
+							$query_param_value[1][1],
677
+							$requested_version,
678
+							$timezone
679
+						)
680
+					);
681
+				} elseif (array_key_exists($sub_array_key, $model->valid_like_style_operators())
682
+					&& isset($query_param_value[1])
683
+					&& ! isset($query_param_value[2])
684
+				) {
685
+					// we want to leave this value mostly-as-is (eg don't force it to be a float
686
+					// or a boolean or an enum value. Leave it as-is with wildcards etc)
687
+					// but do verify it at least doesn't have any serialized data
688
+					ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
689
+					$translated_value[] = $query_param_value[1];
690
+				} elseif (array_key_exists($sub_array_key, $model->valid_null_style_operators())
691
+					&& ! isset($query_param_value[1])) {
692
+					// no arguments should have been provided, so don't look for any
693
+				} elseif (isset($query_param_value[1])
694
+					&& ! isset($query_param_value[2])
695
+					&& ! array_key_exists(
696
+						$sub_array_key,
697
+						array_merge(
698
+							$model->valid_in_style_operators(),
699
+							$model->valid_null_style_operators(),
700
+							$model->valid_like_style_operators(),
701
+							$model->valid_between_style_operators()
702
+						)
703
+					)
704
+				) {
705
+					// it's a valid operator, but none of the exceptions. Treat it normally.
706
+					$translated_value[] = ModelDataTranslator::prepareFieldValuesFromJson(
707
+						$field,
708
+						$query_param_value[1],
709
+						$requested_version,
710
+						$timezone
711
+					);
712
+				} else {
713
+					// so they provided a valid operator, but wrong number of arguments
714
+					if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
715
+						throw new RestException(
716
+							'wrong_number_of_arguments',
717
+							sprintf(
718
+								esc_html__(
719
+									'The operator you provided, "%1$s" had the wrong number of arguments',
720
+									'event_espresso'
721
+								),
722
+								$sub_array_key
723
+							),
724
+							array(
725
+								'status' => 400,
726
+							)
727
+						);
728
+					}
729
+					$translated_value = null;
730
+				}
731
+			} else {
732
+				// so they didn't provide a valid operator
733
+				if (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE) {
734
+					throw new RestException(
735
+						'invalid_operator',
736
+						sprintf(
737
+							esc_html__(
738
+								'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
739
+								'event_espresso'
740
+							),
741
+							$query_param_key,
742
+							$query_param_value
743
+						),
744
+						array(
745
+							'status' => 400,
746
+						)
747
+					);
748
+				}
749
+				// if we aren't in debug mode, then just try our best to fulfill the user's request
750
+				$translated_value = null;
751
+			}
752
+		} else {
753
+			$translated_value = ModelDataTranslator::prepareFieldValueFromJson(
754
+				$field,
755
+				$query_param_value,
756
+				$requested_version,
757
+				$timezone
758
+			);
759
+		}
760
+		return $translated_value;
761
+	}
762 762
 
763 763
 
764
-    /**
765
-     * Mostly checks if the last 4 characters are "_gmt", indicating its a
766
-     * gmt date field name
767
-     *
768
-     * @param string $field_name
769
-     * @return boolean
770
-     */
771
-    public static function isGmtDateFieldName($field_name)
772
-    {
773
-        return substr(
774
-            ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name),
775
-            -4,
776
-            4
777
-        ) === '_gmt';
778
-    }
764
+	/**
765
+	 * Mostly checks if the last 4 characters are "_gmt", indicating its a
766
+	 * gmt date field name
767
+	 *
768
+	 * @param string $field_name
769
+	 * @return boolean
770
+	 */
771
+	public static function isGmtDateFieldName($field_name)
772
+	{
773
+		return substr(
774
+			ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name),
775
+			-4,
776
+			4
777
+		) === '_gmt';
778
+	}
779 779
 
780 780
 
781
-    /**
782
-     * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
783
-     *
784
-     * @param string $field_name
785
-     * @return string
786
-     */
787
-    public static function removeGmtFromFieldName($field_name)
788
-    {
789
-        if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
790
-            return $field_name;
791
-        }
792
-        $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
793
-            $field_name
794
-        );
795
-        $query_param_sans_gmt_and_sans_stars = substr(
796
-            $query_param_sans_stars,
797
-            0,
798
-            strrpos(
799
-                $field_name,
800
-                '_gmt'
801
-            )
802
-        );
803
-        return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
804
-    }
781
+	/**
782
+	 * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone)
783
+	 *
784
+	 * @param string $field_name
785
+	 * @return string
786
+	 */
787
+	public static function removeGmtFromFieldName($field_name)
788
+	{
789
+		if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
790
+			return $field_name;
791
+		}
792
+		$query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
793
+			$field_name
794
+		);
795
+		$query_param_sans_gmt_and_sans_stars = substr(
796
+			$query_param_sans_stars,
797
+			0,
798
+			strrpos(
799
+				$field_name,
800
+				'_gmt'
801
+			)
802
+		);
803
+		return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name);
804
+	}
805 805
 
806 806
 
807
-    /**
808
-     * Takes a field name from the REST API and prepares it for the model querying
809
-     *
810
-     * @param string $field_name
811
-     * @return string
812
-     */
813
-    public static function prepareFieldNameFromJson($field_name)
814
-    {
815
-        if (ModelDataTranslator::isGmtDateFieldName($field_name)) {
816
-            return ModelDataTranslator::removeGmtFromFieldName($field_name);
817
-        }
818
-        return $field_name;
819
-    }
807
+	/**
808
+	 * Takes a field name from the REST API and prepares it for the model querying
809
+	 *
810
+	 * @param string $field_name
811
+	 * @return string
812
+	 */
813
+	public static function prepareFieldNameFromJson($field_name)
814
+	{
815
+		if (ModelDataTranslator::isGmtDateFieldName($field_name)) {
816
+			return ModelDataTranslator::removeGmtFromFieldName($field_name);
817
+		}
818
+		return $field_name;
819
+	}
820 820
 
821 821
 
822
-    /**
823
-     * Takes array of field names from REST API and prepares for models
824
-     *
825
-     * @param array $field_names
826
-     * @return array of field names (possibly include model prefixes)
827
-     */
828
-    public static function prepareFieldNamesFromJson(array $field_names)
829
-    {
830
-        $new_array = array();
831
-        foreach ($field_names as $key => $field_name) {
832
-            $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
833
-        }
834
-        return $new_array;
835
-    }
822
+	/**
823
+	 * Takes array of field names from REST API and prepares for models
824
+	 *
825
+	 * @param array $field_names
826
+	 * @return array of field names (possibly include model prefixes)
827
+	 */
828
+	public static function prepareFieldNamesFromJson(array $field_names)
829
+	{
830
+		$new_array = array();
831
+		foreach ($field_names as $key => $field_name) {
832
+			$new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
833
+		}
834
+		return $new_array;
835
+	}
836 836
 
837 837
 
838
-    /**
839
-     * Takes array where array keys are field names (possibly with model path prefixes)
840
-     * from the REST API and prepares them for model querying
841
-     *
842
-     * @param array $field_names_as_keys
843
-     * @return array
844
-     */
845
-    public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys)
846
-    {
847
-        $new_array = array();
848
-        foreach ($field_names_as_keys as $field_name => $value) {
849
-            $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
850
-        }
851
-        return $new_array;
852
-    }
838
+	/**
839
+	 * Takes array where array keys are field names (possibly with model path prefixes)
840
+	 * from the REST API and prepares them for model querying
841
+	 *
842
+	 * @param array $field_names_as_keys
843
+	 * @return array
844
+	 */
845
+	public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys)
846
+	{
847
+		$new_array = array();
848
+		foreach ($field_names_as_keys as $field_name => $value) {
849
+			$new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
850
+		}
851
+		return $new_array;
852
+	}
853 853
 
854 854
 
855
-    /**
856
-     * Prepares an array of model query params for use in the REST API
857
-     *
858
-     * @param array    $model_query_params
859
-     * @param EEM_Base $model
860
-     * @param string   $requested_version  eg "4.8.36". If null is provided, defaults to the latest release of the EE4
861
-     *                                     REST API
862
-     * @return array which can be passed into the EE4 REST API when querying a model resource
863
-     * @throws EE_Error
864
-     */
865
-    public static function prepareQueryParamsForRestApi(
866
-        array $model_query_params,
867
-        EEM_Base $model,
868
-        $requested_version = null
869
-    ) {
870
-        if ($requested_version === null) {
871
-            $requested_version = \EED_Core_Rest_Api::latest_rest_api_version();
872
-        }
873
-        $rest_query_params = $model_query_params;
874
-        if (isset($model_query_params[0])) {
875
-            $rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
876
-                $model_query_params[0],
877
-                $model,
878
-                $requested_version
879
-            );
880
-            unset($rest_query_params[0]);
881
-        }
882
-        if (isset($model_query_params['having'])) {
883
-            $rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
884
-                $model_query_params['having'],
885
-                $model,
886
-                $requested_version
887
-            );
888
-        }
889
-        return apply_filters(
890
-            'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
891
-            $rest_query_params,
892
-            $model_query_params,
893
-            $model,
894
-            $requested_version
895
-        );
896
-    }
855
+	/**
856
+	 * Prepares an array of model query params for use in the REST API
857
+	 *
858
+	 * @param array    $model_query_params
859
+	 * @param EEM_Base $model
860
+	 * @param string   $requested_version  eg "4.8.36". If null is provided, defaults to the latest release of the EE4
861
+	 *                                     REST API
862
+	 * @return array which can be passed into the EE4 REST API when querying a model resource
863
+	 * @throws EE_Error
864
+	 */
865
+	public static function prepareQueryParamsForRestApi(
866
+		array $model_query_params,
867
+		EEM_Base $model,
868
+		$requested_version = null
869
+	) {
870
+		if ($requested_version === null) {
871
+			$requested_version = \EED_Core_Rest_Api::latest_rest_api_version();
872
+		}
873
+		$rest_query_params = $model_query_params;
874
+		if (isset($model_query_params[0])) {
875
+			$rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
876
+				$model_query_params[0],
877
+				$model,
878
+				$requested_version
879
+			);
880
+			unset($rest_query_params[0]);
881
+		}
882
+		if (isset($model_query_params['having'])) {
883
+			$rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
884
+				$model_query_params['having'],
885
+				$model,
886
+				$requested_version
887
+			);
888
+		}
889
+		return apply_filters(
890
+			'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api',
891
+			$rest_query_params,
892
+			$model_query_params,
893
+			$model,
894
+			$requested_version
895
+		);
896
+	}
897 897
 
898 898
 
899
-    /**
900
-     * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
901
-     *
902
-     * @param array    $inputted_query_params_of_this_type  eg like the "where" or "having" conditions query params
903
-     *                                                      passed into EEM_Base::get_all()
904
-     * @param EEM_Base $model
905
-     * @param string   $requested_version                   eg "4.8.36"
906
-     * @return array ready for use in the rest api query params
907
-     * @throws EE_Error
908
-     * @throws ObjectDetectedException if somehow a PHP object were in the query params' values,
909
-     *                                                      (which would be really unusual)
910
-     */
911
-    public static function prepareConditionsQueryParamsForRestApi(
912
-        $inputted_query_params_of_this_type,
913
-        EEM_Base $model,
914
-        $requested_version
915
-    ) {
916
-        $query_param_for_models = array();
917
-        foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
918
-            $field = ModelDataTranslator::deduceFieldFromQueryParam(
919
-                ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key),
920
-                $model
921
-            );
922
-            if ($field instanceof EE_Model_Field_Base) {
923
-                // did they specify an operator?
924
-                if (is_array($query_param_value)) {
925
-                    $op = $query_param_value[0];
926
-                    $translated_value = array($op);
927
-                    if (isset($query_param_value[1])) {
928
-                        $value = $query_param_value[1];
929
-                        $translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson(
930
-                            $field,
931
-                            $value,
932
-                            $requested_version
933
-                        );
934
-                    }
935
-                } else {
936
-                    $translated_value = ModelDataTranslator::prepareFieldValueForJson(
937
-                        $field,
938
-                        $query_param_value,
939
-                        $requested_version
940
-                    );
941
-                }
942
-                $query_param_for_models[ $query_param_key ] = $translated_value;
943
-            } else {
944
-                // so it's not for a field, assume it's a logic query param key
945
-                $query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
946
-                    $query_param_value,
947
-                    $model,
948
-                    $requested_version
949
-                );
950
-            }
951
-        }
952
-        return $query_param_for_models;
953
-    }
899
+	/**
900
+	 * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api
901
+	 *
902
+	 * @param array    $inputted_query_params_of_this_type  eg like the "where" or "having" conditions query params
903
+	 *                                                      passed into EEM_Base::get_all()
904
+	 * @param EEM_Base $model
905
+	 * @param string   $requested_version                   eg "4.8.36"
906
+	 * @return array ready for use in the rest api query params
907
+	 * @throws EE_Error
908
+	 * @throws ObjectDetectedException if somehow a PHP object were in the query params' values,
909
+	 *                                                      (which would be really unusual)
910
+	 */
911
+	public static function prepareConditionsQueryParamsForRestApi(
912
+		$inputted_query_params_of_this_type,
913
+		EEM_Base $model,
914
+		$requested_version
915
+	) {
916
+		$query_param_for_models = array();
917
+		foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) {
918
+			$field = ModelDataTranslator::deduceFieldFromQueryParam(
919
+				ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key),
920
+				$model
921
+			);
922
+			if ($field instanceof EE_Model_Field_Base) {
923
+				// did they specify an operator?
924
+				if (is_array($query_param_value)) {
925
+					$op = $query_param_value[0];
926
+					$translated_value = array($op);
927
+					if (isset($query_param_value[1])) {
928
+						$value = $query_param_value[1];
929
+						$translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson(
930
+							$field,
931
+							$value,
932
+							$requested_version
933
+						);
934
+					}
935
+				} else {
936
+					$translated_value = ModelDataTranslator::prepareFieldValueForJson(
937
+						$field,
938
+						$query_param_value,
939
+						$requested_version
940
+					);
941
+				}
942
+				$query_param_for_models[ $query_param_key ] = $translated_value;
943
+			} else {
944
+				// so it's not for a field, assume it's a logic query param key
945
+				$query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
946
+					$query_param_value,
947
+					$model,
948
+					$requested_version
949
+				);
950
+			}
951
+		}
952
+		return $query_param_for_models;
953
+	}
954 954
 
955 955
 
956
-    /**
957
-     * @param $condition_query_param_key
958
-     * @return string
959
-     */
960
-    public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key)
961
-    {
962
-        $pos_of_star = strpos($condition_query_param_key, '*');
963
-        if ($pos_of_star === false) {
964
-            return $condition_query_param_key;
965
-        } else {
966
-            $condition_query_param_sans_star = substr($condition_query_param_key, 0, $pos_of_star);
967
-            return $condition_query_param_sans_star;
968
-        }
969
-    }
956
+	/**
957
+	 * @param $condition_query_param_key
958
+	 * @return string
959
+	 */
960
+	public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key)
961
+	{
962
+		$pos_of_star = strpos($condition_query_param_key, '*');
963
+		if ($pos_of_star === false) {
964
+			return $condition_query_param_key;
965
+		} else {
966
+			$condition_query_param_sans_star = substr($condition_query_param_key, 0, $pos_of_star);
967
+			return $condition_query_param_sans_star;
968
+		}
969
+	}
970 970
 
971 971
 
972
-    /**
973
-     * Takes the input parameter and finds the model field that it indicates.
974
-     *
975
-     * @param string   $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
976
-     * @param EEM_Base $model
977
-     * @return EE_Model_Field_Base
978
-     * @throws EE_Error
979
-     */
980
-    public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model)
981
-    {
982
-        // ok, now proceed with deducing which part is the model's name, and which is the field's name
983
-        // which will help us find the database table and column
984
-        $query_param_parts = explode('.', $query_param_name);
985
-        if (empty($query_param_parts)) {
986
-            throw new EE_Error(
987
-                sprintf(
988
-                    __(
989
-                        '_extract_column_name is empty when trying to extract column and table name from %s',
990
-                        'event_espresso'
991
-                    ),
992
-                    $query_param_name
993
-                )
994
-            );
995
-        }
996
-        $number_of_parts = count($query_param_parts);
997
-        $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
998
-        if ($number_of_parts === 1) {
999
-            $field_name = $last_query_param_part;
1000
-        } else {// $number_of_parts >= 2
1001
-            // the last part is the column name, and there are only 2parts. therefore...
1002
-            $field_name = $last_query_param_part;
1003
-            $model = \EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
1004
-        }
1005
-        try {
1006
-            return $model->field_settings_for($field_name, false);
1007
-        } catch (EE_Error $e) {
1008
-            return null;
1009
-        }
1010
-    }
972
+	/**
973
+	 * Takes the input parameter and finds the model field that it indicates.
974
+	 *
975
+	 * @param string   $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID
976
+	 * @param EEM_Base $model
977
+	 * @return EE_Model_Field_Base
978
+	 * @throws EE_Error
979
+	 */
980
+	public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model)
981
+	{
982
+		// ok, now proceed with deducing which part is the model's name, and which is the field's name
983
+		// which will help us find the database table and column
984
+		$query_param_parts = explode('.', $query_param_name);
985
+		if (empty($query_param_parts)) {
986
+			throw new EE_Error(
987
+				sprintf(
988
+					__(
989
+						'_extract_column_name is empty when trying to extract column and table name from %s',
990
+						'event_espresso'
991
+					),
992
+					$query_param_name
993
+				)
994
+			);
995
+		}
996
+		$number_of_parts = count($query_param_parts);
997
+		$last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
998
+		if ($number_of_parts === 1) {
999
+			$field_name = $last_query_param_part;
1000
+		} else {// $number_of_parts >= 2
1001
+			// the last part is the column name, and there are only 2parts. therefore...
1002
+			$field_name = $last_query_param_part;
1003
+			$model = \EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
1004
+		}
1005
+		try {
1006
+			return $model->field_settings_for($field_name, false);
1007
+		} catch (EE_Error $e) {
1008
+			return null;
1009
+		}
1010
+	}
1011 1011
 
1012 1012
 
1013
-    /**
1014
-     * Returns true if $data can be easily represented in JSON.
1015
-     * Basically, objects and resources can't be represented in JSON easily.
1016
-     *
1017
-     * @param mixed $data
1018
-     * @return bool
1019
-     */
1020
-    protected static function isRepresentableInJson($data)
1021
-    {
1022
-        return is_scalar($data)
1023
-               || is_array($data)
1024
-               || is_null($data);
1025
-    }
1013
+	/**
1014
+	 * Returns true if $data can be easily represented in JSON.
1015
+	 * Basically, objects and resources can't be represented in JSON easily.
1016
+	 *
1017
+	 * @param mixed $data
1018
+	 * @return bool
1019
+	 */
1020
+	protected static function isRepresentableInJson($data)
1021
+	{
1022
+		return is_scalar($data)
1023
+			   || is_array($data)
1024
+			   || is_null($data);
1025
+	}
1026 1026
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -60,7 +60,7 @@  discard block
 block discarded – undo
60 60
         ) {
61 61
             $new_value_maybe_array = array();
62 62
             foreach ($original_value_maybe_array as $array_key => $array_item) {
63
-                $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson(
63
+                $new_value_maybe_array[$array_key] = ModelDataTranslator::prepareFieldValueFromJson(
64 64
                     $field_obj,
65 65
                     $array_item,
66 66
                     $requested_version,
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
         if (is_array($original_value_maybe_array)) {
93 93
             $new_value = array();
94 94
             foreach ($original_value_maybe_array as $key => $value) {
95
-                $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson(
95
+                $new_value[$key] = ModelDataTranslator::prepareFieldValuesForJson(
96 96
                     $field_obj,
97 97
                     $value,
98 98
                     $request_version
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
                 '0',
226 226
                 STR_PAD_LEFT
227 227
             );
228
-        return $original_timestamp . $offset_sign . $offset_string;
228
+        return $original_timestamp.$offset_sign.$offset_string;
229 229
     }
230 230
 
231 231
 
@@ -302,7 +302,7 @@  discard block
 block discarded – undo
302 302
                     // first, check if its a MySQL timestamp in GMT
303 303
                     $datetime_obj = \DateTime::createFromFormat('Y-m-d H:i:s', $original_value);
304 304
                 }
305
-                if (! $datetime_obj instanceof \DateTime) {
305
+                if ( ! $datetime_obj instanceof \DateTime) {
306 306
                     // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format?
307 307
                     $datetime_obj = $field_obj->prepare_for_set($original_value);
308 308
                 }
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
                         $original_value,
329 329
                         $field_obj->get_name(),
330 330
                         $field_obj->get_model_name(),
331
-                        $field_obj->get_time_format() . ' ' . $field_obj->get_time_format()
331
+                        $field_obj->get_time_format().' '.$field_obj->get_time_format()
332 332
                     )
333 333
                 );
334 334
             }
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
         }
341 341
         // are we about to send an object? just don't. We have no good way to represent it in JSON.
342 342
         // can't just check using is_object() because that missed PHP incomplete objects
343
-        if (! ModelDataTranslator::isRepresentableInJson($new_value)) {
343
+        if ( ! ModelDataTranslator::isRepresentableInJson($new_value)) {
344 344
             $new_value = array(
345 345
                 'error_code'    => 'php_object_not_return',
346 346
                 'error_message' => esc_html__(
@@ -406,7 +406,7 @@  discard block
 block discarded – undo
406 406
                     $query_param_value,
407 407
                     $writing
408 408
                 );
409
-                if ((isset($query_param_for_models[ $query_param_key ]) && $is_gmt_datetime_field)
409
+                if ((isset($query_param_for_models[$query_param_key]) && $is_gmt_datetime_field)
410 410
                     || $translated_value === null
411 411
                 ) {
412 412
                     // they have already provided a non-gmt field, ignore the gmt one. That's what WP core
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
                     // OR we couldn't create a translated value from their input
415 415
                     continue;
416 416
                 }
417
-                $query_param_for_models[ $query_param_key ] = $translated_value;
417
+                $query_param_for_models[$query_param_key] = $translated_value;
418 418
             } else {
419 419
                 $nested_query_params = self::determineNestedConditionQueryParameters(
420 420
                     $model,
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
             $model
529 529
         );
530 530
         // double-check is it a *_gmt field?
531
-        if (! $field instanceof EE_Model_Field_Base
531
+        if ( ! $field instanceof EE_Model_Field_Base
532 532
             && ModelDataTranslator::isGmtDateFieldName($query_param_sans_stars)
533 533
         ) {
534 534
             // yep, take off '_gmt', and find the field
@@ -579,8 +579,8 @@  discard block
 block discarded – undo
579 579
         $query_param_value,
580 580
         $writing = false
581 581
     ) {
582
-        if (! $writing && is_array($query_param_value)) {
583
-            if (! \EEH_Array::is_array_numerically_and_sequentially_indexed($query_param_value)) {
582
+        if ( ! $writing && is_array($query_param_value)) {
583
+            if ( ! \EEH_Array::is_array_numerically_and_sequentially_indexed($query_param_value)) {
584 584
                 if (is_array($query_param_value)
585 585
                     && count($query_param_value) === 1
586 586
                     && array_key_exists(
@@ -588,7 +588,7 @@  discard block
 block discarded – undo
588 588
                         $model->valid_operators()
589 589
                     )
590 590
                 ) {
591
-                    $sub_array_value =  reset($query_param_value);
591
+                    $sub_array_value = reset($query_param_value);
592 592
                     $sub_array_key = key($query_param_value);
593 593
                     // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
594 594
                     if (array_key_exists(
@@ -600,7 +600,7 @@  discard block
 block discarded – undo
600 600
                     )) {
601 601
                         // the value should be JSON or CSV
602 602
                         $values = json_decode($sub_array_value);
603
-                        if (! is_array($values)) {
603
+                        if ( ! is_array($values)) {
604 604
                             $values = array_filter(
605 605
                                 array_map(
606 606
                                     'trim',
@@ -643,7 +643,7 @@  discard block
 block discarded – undo
643 643
             $valid_operators = $model->valid_operators();
644 644
             // did they specify an operator?
645 645
             if (isset($query_param_value[0])
646
-                && isset($valid_operators[ $query_param_value[0] ])
646
+                && isset($valid_operators[$query_param_value[0]])
647 647
             ) {
648 648
                 $sub_array_key = $query_param_value[0];
649 649
                 $translated_value = array($sub_array_key);
@@ -786,7 +786,7 @@  discard block
 block discarded – undo
786 786
      */
787 787
     public static function removeGmtFromFieldName($field_name)
788 788
     {
789
-        if (! ModelDataTranslator::isGmtDateFieldName($field_name)) {
789
+        if ( ! ModelDataTranslator::isGmtDateFieldName($field_name)) {
790 790
             return $field_name;
791 791
         }
792 792
         $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
@@ -829,7 +829,7 @@  discard block
 block discarded – undo
829 829
     {
830 830
         $new_array = array();
831 831
         foreach ($field_names as $key => $field_name) {
832
-            $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
832
+            $new_array[$key] = ModelDataTranslator::prepareFieldNameFromJson($field_name);
833 833
         }
834 834
         return $new_array;
835 835
     }
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
     {
847 847
         $new_array = array();
848 848
         foreach ($field_names_as_keys as $field_name => $value) {
849
-            $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value;
849
+            $new_array[ModelDataTranslator::prepareFieldNameFromJson($field_name)] = $value;
850 850
         }
851 851
         return $new_array;
852 852
     }
@@ -939,10 +939,10 @@  discard block
 block discarded – undo
939 939
                         $requested_version
940 940
                     );
941 941
                 }
942
-                $query_param_for_models[ $query_param_key ] = $translated_value;
942
+                $query_param_for_models[$query_param_key] = $translated_value;
943 943
             } else {
944 944
                 // so it's not for a field, assume it's a logic query param key
945
-                $query_param_for_models[ $query_param_key ] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
945
+                $query_param_for_models[$query_param_key] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi(
946 946
                     $query_param_value,
947 947
                     $model,
948 948
                     $requested_version
@@ -994,13 +994,13 @@  discard block
 block discarded – undo
994 994
             );
995 995
         }
996 996
         $number_of_parts = count($query_param_parts);
997
-        $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ];
997
+        $last_query_param_part = $query_param_parts[count($query_param_parts) - 1];
998 998
         if ($number_of_parts === 1) {
999 999
             $field_name = $last_query_param_part;
1000 1000
         } else {// $number_of_parts >= 2
1001 1001
             // the last part is the column name, and there are only 2parts. therefore...
1002 1002
             $field_name = $last_query_param_part;
1003
-            $model = \EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]);
1003
+            $model = \EE_Registry::instance()->load_model($query_param_parts[$number_of_parts - 2]);
1004 1004
         }
1005 1005
         try {
1006 1006
             return $model->field_settings_for($field_name, false);
Please login to merge, or discard this patch.