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