Completed
Branch BUG/chicken-is-a-required-ques... (12feb4)
by
unknown
27:48 queued 14:38
created
core/services/commands/attendee/CreateAttendeeCommand.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -81,7 +81,7 @@
 block discarded – undo
81 81
     public function getCapCheck()
82 82
     {
83 83
         // need cap for non-AJAX admin requests
84
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
84
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
85 85
             return new CapCheck('ee_edit_contacts', 'create_new_contact');
86 86
         }
87 87
         return new PublicCapabilities('', 'create_new_contact');
Please login to merge, or discard this patch.
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -20,62 +20,62 @@
 block discarded – undo
20 20
 class CreateAttendeeCommand extends Command implements CommandRequiresCapCheckInterface
21 21
 {
22 22
 
23
-    /**
24
-     * array of details where keys are names of EEM_Attendee model fields
25
-     *
26
-     * @var array $attendee_details
27
-     */
28
-    protected $attendee_details;
23
+	/**
24
+	 * array of details where keys are names of EEM_Attendee model fields
25
+	 *
26
+	 * @var array $attendee_details
27
+	 */
28
+	protected $attendee_details;
29 29
 
30
-    /**
31
-     * an existing registration to associate this attendee with
32
-     *
33
-     * @var EE_Registration $registration
34
-     */
35
-    protected $registration;
30
+	/**
31
+	 * an existing registration to associate this attendee with
32
+	 *
33
+	 * @var EE_Registration $registration
34
+	 */
35
+	protected $registration;
36 36
 
37 37
 
38
-    /**
39
-     * CreateAttendeeCommand constructor.
40
-     *
41
-     * @param array           $attendee_details
42
-     * @param EE_Registration $registration
43
-     */
44
-    public function __construct(array $attendee_details, EE_Registration $registration)
45
-    {
46
-        $this->attendee_details = $attendee_details;
47
-        $this->registration = $registration;
48
-    }
38
+	/**
39
+	 * CreateAttendeeCommand constructor.
40
+	 *
41
+	 * @param array           $attendee_details
42
+	 * @param EE_Registration $registration
43
+	 */
44
+	public function __construct(array $attendee_details, EE_Registration $registration)
45
+	{
46
+		$this->attendee_details = $attendee_details;
47
+		$this->registration = $registration;
48
+	}
49 49
 
50 50
 
51
-    /**
52
-     * @return array
53
-     */
54
-    public function attendeeDetails()
55
-    {
56
-        return $this->attendee_details;
57
-    }
51
+	/**
52
+	 * @return array
53
+	 */
54
+	public function attendeeDetails()
55
+	{
56
+		return $this->attendee_details;
57
+	}
58 58
 
59 59
 
60
-    /**
61
-     * @return EE_Registration
62
-     */
63
-    public function registration()
64
-    {
65
-        return $this->registration;
66
-    }
60
+	/**
61
+	 * @return EE_Registration
62
+	 */
63
+	public function registration()
64
+	{
65
+		return $this->registration;
66
+	}
67 67
 
68 68
 
69
-    /**
70
-     * @return CapCheckInterface
71
-     * @throws InvalidDataTypeException
72
-     */
73
-    public function getCapCheck()
74
-    {
75
-        // need cap for non-AJAX admin requests
76
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
77
-            return new CapCheck('ee_edit_contacts', 'create_new_contact');
78
-        }
79
-        return new PublicCapabilities('', 'create_new_contact');
80
-    }
69
+	/**
70
+	 * @return CapCheckInterface
71
+	 * @throws InvalidDataTypeException
72
+	 */
73
+	public function getCapCheck()
74
+	{
75
+		// need cap for non-AJAX admin requests
76
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
77
+			return new CapCheck('ee_edit_contacts', 'create_new_contact');
78
+		}
79
+		return new PublicCapabilities('', 'create_new_contact');
80
+	}
81 81
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/Base.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -314,7 +314,7 @@
 block discarded – undo
314 314
      *
315 315
      * @param string $route
316 316
      * @param string $regex
317
-     * @param array  $match_keys EXCLUDING matching the entire regex
317
+     * @param string[]  $match_keys EXCLUDING matching the entire regex
318 318
      * @return array where  $match_keys are the keys (the first value of $match_keys
319 319
      *                           becomes the first key of the return value, etc. Eg passing in $match_keys of
320 320
      *                           array( 'model', 'id' ), will, if the regex is successful, will return
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -5,7 +5,6 @@
 block discarded – undo
5 5
 use WP_Error;
6 6
 use WP_REST_Response;
7 7
 use EventEspresso\core\libraries\rest_api\RestException;
8
-
9 8
 use EE_Error;
10 9
 use EED_Core_Rest_Api;
11 10
 use EEH_Inflector;
Please login to merge, or discard this patch.
Indentation   +334 added lines, -334 removed lines patch added patch discarded remove patch
@@ -22,338 +22,338 @@
 block discarded – undo
22 22
 class Base
23 23
 {
24 24
 
25
-    /**
26
-     * @deprecated use all-caps version
27
-     */
28
-    // @codingStandardsIgnoreStart
29
-    const header_prefix_for_ee = 'X-EE-';
30
-    // @codingStandardsIgnoreEnd
31
-
32
-    const HEADER_PREFIX_FOR_EE = 'X-EE-';
33
-
34
-    /**
35
-     * @deprecated use all-caps version instead
36
-     */
37
-    // @codingStandardsIgnoreStart
38
-    const header_prefix_for_wp = 'X-WP-';
39
-    // @codingStandardsIgnoreEnd
40
-
41
-    const HEADER_PREFIX_FOR_WP = 'X-WP-';
42
-
43
-    /**
44
-     * Contains debug info we'll send back in the response headers
45
-     *
46
-     * @var array
47
-     */
48
-    protected $debug_info = array();
49
-
50
-    /**
51
-     * Indicates whether or not the API is in debug mode
52
-     *
53
-     * @var boolean
54
-     */
55
-    protected $debug_mode = false;
56
-
57
-    /**
58
-     * Indicates the version that was requested
59
-     *
60
-     * @var string
61
-     */
62
-    protected $requested_version;
63
-
64
-    /**
65
-     * flat array of headers to send in the response
66
-     *
67
-     * @var array
68
-     */
69
-    protected $response_headers = array();
70
-
71
-
72
-    public function __construct()
73
-    {
74
-        $this->debug_mode = defined('EE_REST_API_DEBUG_MODE') ? EE_REST_API_DEBUG_MODE : false;
75
-        // we are handling a REST request. Don't show a fancy HTML error message is any error comes up
76
-        add_filter('FHEE__EE_Error__get_error__show_normal_exceptions', '__return_true');
77
-    }
78
-
79
-
80
-    /**
81
-     * Sets the version the user requested
82
-     *
83
-     * @param string $version eg '4.8'
84
-     */
85
-    public function setRequestedVersion($version)
86
-    {
87
-        $this->requested_version = $version;
88
-    }
89
-
90
-
91
-    /**
92
-     * Sets some debug info that we'll send back in headers
93
-     *
94
-     * @param string       $key
95
-     * @param string|array $info
96
-     */
97
-    protected function setDebugInfo($key, $info)
98
-    {
99
-        $this->debug_info[ $key ] = $info;
100
-    }
101
-
102
-
103
-    /**
104
-     * Sets headers for the response
105
-     *
106
-     * @param string       $header_key    , excluding the "X-EE-" part
107
-     * @param array|string $value         if an array, multiple headers will be added, one
108
-     *                                    for each key in the array
109
-     * @param boolean      $use_ee_prefix whether to use the EE prefix on the header, or fallback to
110
-     *                                    the standard WP one
111
-     */
112
-    protected function setResponseHeader($header_key, $value, $use_ee_prefix = true)
113
-    {
114
-        if (is_array($value)) {
115
-            foreach ($value as $value_key => $value_value) {
116
-                $this->setResponseHeader($header_key . '[' . $value_key . ']', $value_value);
117
-            }
118
-        } else {
119
-            $prefix = $use_ee_prefix ? Base::HEADER_PREFIX_FOR_EE : Base::HEADER_PREFIX_FOR_WP;
120
-            $this->response_headers[ $prefix . $header_key ] = $value;
121
-        }
122
-    }
123
-
124
-
125
-    /**
126
-     * Returns a flat array of headers to be added to the response
127
-     *
128
-     * @return array
129
-     */
130
-    protected function getResponseHeaders()
131
-    {
132
-        return apply_filters(
133
-            'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers',
134
-            $this->response_headers,
135
-            $this,
136
-            $this->requested_version
137
-        );
138
-    }
139
-
140
-
141
-    /**
142
-     * Adds error notices from EE_Error onto the provided \WP_Error
143
-     *
144
-     * @param WP_Error $wp_error_response
145
-     * @return WP_Error
146
-     */
147
-    protected function addEeErrorsToResponse(WP_Error $wp_error_response)
148
-    {
149
-        $notices_during_checkin = EE_Error::get_raw_notices();
150
-        if (! empty($notices_during_checkin['errors'])) {
151
-            foreach ($notices_during_checkin['errors'] as $error_code => $error_message) {
152
-                $wp_error_response->add(
153
-                    sanitize_key($error_code),
154
-                    strip_tags($error_message)
155
-                );
156
-            }
157
-        }
158
-        return $wp_error_response;
159
-    }
160
-
161
-
162
-    /**
163
-     * Sends a response, but also makes sure to attach headers that
164
-     * are handy for debugging.
165
-     * Specifically, we assume folks will want to know what exactly was the DB query that got run,
166
-     * what exactly was the Models query that got run, what capabilities came into play, what fields were omitted from
167
-     * the response, others?
168
-     *
169
-     * @param array|WP_Error|Exception|RestException $response
170
-     * @return WP_REST_Response
171
-     */
172
-    public function sendResponse($response)
173
-    {
174
-        if ($response instanceof RestException) {
175
-            $response = new WP_Error($response->getStringCode(), $response->getMessage(), $response->getData());
176
-        }
177
-        if ($response instanceof Exception) {
178
-            $code = $response->getCode() ? $response->getCode() : 'error_occurred';
179
-            $response = new WP_Error($code, $response->getMessage());
180
-        }
181
-        if ($response instanceof WP_Error) {
182
-            $response = $this->addEeErrorsToResponse($response);
183
-            $rest_response = $this->createRestResponseFromWpError($response);
184
-        } else {
185
-            $rest_response = new WP_REST_Response($response, 200);
186
-        }
187
-        $headers = array();
188
-        if ($this->debug_mode && is_array($this->debug_info)) {
189
-            foreach ($this->debug_info as $debug_key => $debug_info) {
190
-                if (is_array($debug_info)) {
191
-                    $debug_info = wp_json_encode($debug_info);
192
-                }
193
-                $headers[ 'X-EE4-Debug-' . ucwords($debug_key) ] = $debug_info;
194
-            }
195
-        }
196
-        $headers = array_merge(
197
-            $headers,
198
-            $this->getResponseHeaders(),
199
-            $this->getHeadersFromEeNotices()
200
-        );
201
-        $rest_response->set_headers($headers);
202
-        return $rest_response;
203
-    }
204
-
205
-
206
-    /**
207
-     * Converts the \WP_Error into `WP_REST_Response.
208
-     * Mostly this is just a copy-and-paste from \WP_REST_Server::error_to_response
209
-     * (which is protected)
210
-     *
211
-     * @param WP_Error $wp_error
212
-     * @return WP_REST_Response
213
-     */
214
-    protected function createRestResponseFromWpError(WP_Error $wp_error)
215
-    {
216
-        $error_data = $wp_error->get_error_data();
217
-        if (is_array($error_data) && isset($error_data['status'])) {
218
-            $status = $error_data['status'];
219
-        } else {
220
-            $status = 500;
221
-        }
222
-        $errors = array();
223
-        foreach ((array) $wp_error->errors as $code => $messages) {
224
-            foreach ((array) $messages as $message) {
225
-                $errors[] = array(
226
-                    'code'    => $code,
227
-                    'message' => $message,
228
-                    'data'    => $wp_error->get_error_data($code),
229
-                );
230
-            }
231
-        }
232
-        $data = isset($errors[0]) ? $errors[0] : array();
233
-        if (count($errors) > 1) {
234
-            // Remove the primary error.
235
-            array_shift($errors);
236
-            $data['additional_errors'] = $errors;
237
-        }
238
-        return new WP_REST_Response($data, $status);
239
-    }
240
-
241
-
242
-    /**
243
-     * Array of headers derived from EE success, attention, and error messages
244
-     *
245
-     * @return array
246
-     */
247
-    protected function getHeadersFromEeNotices()
248
-    {
249
-        $headers = array();
250
-        $notices = EE_Error::get_raw_notices();
251
-        foreach ($notices as $notice_type => $sub_notices) {
252
-            if (! is_array($sub_notices)) {
253
-                continue;
254
-            }
255
-            foreach ($sub_notices as $notice_code => $sub_notice) {
256
-                $headers[ 'X-EE4-Notices-'
257
-                          . EEH_Inflector::humanize($notice_type)
258
-                          . '['
259
-                          . $notice_code
260
-                          . ']' ] = strip_tags($sub_notice);
261
-            }
262
-        }
263
-        return apply_filters(
264
-            'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_headers_from_ee_notices__return',
265
-            $headers,
266
-            $this->requested_version,
267
-            $notices
268
-        );
269
-    }
270
-
271
-
272
-    /**
273
-     * Finds which version of the API was requested given the route, and returns it.
274
-     * eg in a request to "mysite.com/wp-json/ee/v4.8.29/events/123" this would return
275
-     * "4.8.29".
276
-     * We should know hte requested version in this model though, so if no route is
277
-     * provided just use what we set earlier
278
-     *
279
-     * @param string $route
280
-     * @return string
281
-     */
282
-    public function getRequestedVersion($route = null)
283
-    {
284
-        if ($route === null) {
285
-            return $this->requested_version;
286
-        }
287
-        $matches = $this->parseRoute(
288
-            $route,
289
-            '~' . EED_Core_Rest_Api::ee_api_namespace_for_regex . '~',
290
-            array('version')
291
-        );
292
-        if (isset($matches['version'])) {
293
-            return $matches['version'];
294
-        } else {
295
-            return EED_Core_Rest_Api::latest_rest_api_version();
296
-        }
297
-    }
298
-
299
-
300
-    /**
301
-     * Applies the regex to the route, then creates an array using the values of
302
-     * $match_keys as keys (but ignores the full pattern match). Returns the array of matches.
303
-     * For example, if you call
304
-     * parse_route( '/ee/v4.8/events', '~\/ee\/v([^/]*)\/(.*)~', array( 'version', 'model' ) )
305
-     * it will return array( 'version' => '4.8', 'model' => 'events' )
306
-     *
307
-     * @param string $route
308
-     * @param string $regex
309
-     * @param array  $match_keys EXCLUDING matching the entire regex
310
-     * @return array where  $match_keys are the keys (the first value of $match_keys
311
-     *                           becomes the first key of the return value, etc. Eg passing in $match_keys of
312
-     *                           array( 'model', 'id' ), will, if the regex is successful, will return
313
-     *                           array( 'model' => 'foo', 'id' => 'bar' )
314
-     * @throws EE_Error if it couldn't be parsed
315
-     */
316
-    public function parseRoute($route, $regex, $match_keys)
317
-    {
318
-        $indexed_matches = array();
319
-        $success = preg_match($regex, $route, $matches);
320
-        if (is_array($matches)) {
321
-            // skip the overall regex match. Who cares
322
-            for ($i = 1; $i <= count($match_keys); $i++) {
323
-                if (! isset($matches[ $i ])) {
324
-                    $success = false;
325
-                } else {
326
-                    $indexed_matches[ $match_keys[ $i - 1 ] ] = $matches[ $i ];
327
-                }
328
-            }
329
-        }
330
-        if (! $success) {
331
-            throw new EE_Error(
332
-                __('We could not parse the URL. Please contact Event Espresso Support', 'event_espresso'),
333
-                'endpoint_parsing_error'
334
-            );
335
-        }
336
-        return $indexed_matches;
337
-    }
338
-
339
-
340
-    /**
341
-     * Gets the body's params (either from JSON or parsed body), which EXCLUDES the GET params and URL params
342
-     *
343
-     * @param \WP_REST_Request $request
344
-     * @return array
345
-     */
346
-    protected function getBodyParams(\WP_REST_Request $request)
347
-    {
348
-        // $request->get_params();
349
-        return array_merge(
350
-            (array) $request->get_body_params(),
351
-            (array) $request->get_json_params()
352
-        );
353
-        // return array_diff_key(
354
-        //    $request->get_params(),
355
-        //     $request->get_url_params(),
356
-        //     $request->get_query_params()
357
-        // );
358
-    }
25
+	/**
26
+	 * @deprecated use all-caps version
27
+	 */
28
+	// @codingStandardsIgnoreStart
29
+	const header_prefix_for_ee = 'X-EE-';
30
+	// @codingStandardsIgnoreEnd
31
+
32
+	const HEADER_PREFIX_FOR_EE = 'X-EE-';
33
+
34
+	/**
35
+	 * @deprecated use all-caps version instead
36
+	 */
37
+	// @codingStandardsIgnoreStart
38
+	const header_prefix_for_wp = 'X-WP-';
39
+	// @codingStandardsIgnoreEnd
40
+
41
+	const HEADER_PREFIX_FOR_WP = 'X-WP-';
42
+
43
+	/**
44
+	 * Contains debug info we'll send back in the response headers
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $debug_info = array();
49
+
50
+	/**
51
+	 * Indicates whether or not the API is in debug mode
52
+	 *
53
+	 * @var boolean
54
+	 */
55
+	protected $debug_mode = false;
56
+
57
+	/**
58
+	 * Indicates the version that was requested
59
+	 *
60
+	 * @var string
61
+	 */
62
+	protected $requested_version;
63
+
64
+	/**
65
+	 * flat array of headers to send in the response
66
+	 *
67
+	 * @var array
68
+	 */
69
+	protected $response_headers = array();
70
+
71
+
72
+	public function __construct()
73
+	{
74
+		$this->debug_mode = defined('EE_REST_API_DEBUG_MODE') ? EE_REST_API_DEBUG_MODE : false;
75
+		// we are handling a REST request. Don't show a fancy HTML error message is any error comes up
76
+		add_filter('FHEE__EE_Error__get_error__show_normal_exceptions', '__return_true');
77
+	}
78
+
79
+
80
+	/**
81
+	 * Sets the version the user requested
82
+	 *
83
+	 * @param string $version eg '4.8'
84
+	 */
85
+	public function setRequestedVersion($version)
86
+	{
87
+		$this->requested_version = $version;
88
+	}
89
+
90
+
91
+	/**
92
+	 * Sets some debug info that we'll send back in headers
93
+	 *
94
+	 * @param string       $key
95
+	 * @param string|array $info
96
+	 */
97
+	protected function setDebugInfo($key, $info)
98
+	{
99
+		$this->debug_info[ $key ] = $info;
100
+	}
101
+
102
+
103
+	/**
104
+	 * Sets headers for the response
105
+	 *
106
+	 * @param string       $header_key    , excluding the "X-EE-" part
107
+	 * @param array|string $value         if an array, multiple headers will be added, one
108
+	 *                                    for each key in the array
109
+	 * @param boolean      $use_ee_prefix whether to use the EE prefix on the header, or fallback to
110
+	 *                                    the standard WP one
111
+	 */
112
+	protected function setResponseHeader($header_key, $value, $use_ee_prefix = true)
113
+	{
114
+		if (is_array($value)) {
115
+			foreach ($value as $value_key => $value_value) {
116
+				$this->setResponseHeader($header_key . '[' . $value_key . ']', $value_value);
117
+			}
118
+		} else {
119
+			$prefix = $use_ee_prefix ? Base::HEADER_PREFIX_FOR_EE : Base::HEADER_PREFIX_FOR_WP;
120
+			$this->response_headers[ $prefix . $header_key ] = $value;
121
+		}
122
+	}
123
+
124
+
125
+	/**
126
+	 * Returns a flat array of headers to be added to the response
127
+	 *
128
+	 * @return array
129
+	 */
130
+	protected function getResponseHeaders()
131
+	{
132
+		return apply_filters(
133
+			'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers',
134
+			$this->response_headers,
135
+			$this,
136
+			$this->requested_version
137
+		);
138
+	}
139
+
140
+
141
+	/**
142
+	 * Adds error notices from EE_Error onto the provided \WP_Error
143
+	 *
144
+	 * @param WP_Error $wp_error_response
145
+	 * @return WP_Error
146
+	 */
147
+	protected function addEeErrorsToResponse(WP_Error $wp_error_response)
148
+	{
149
+		$notices_during_checkin = EE_Error::get_raw_notices();
150
+		if (! empty($notices_during_checkin['errors'])) {
151
+			foreach ($notices_during_checkin['errors'] as $error_code => $error_message) {
152
+				$wp_error_response->add(
153
+					sanitize_key($error_code),
154
+					strip_tags($error_message)
155
+				);
156
+			}
157
+		}
158
+		return $wp_error_response;
159
+	}
160
+
161
+
162
+	/**
163
+	 * Sends a response, but also makes sure to attach headers that
164
+	 * are handy for debugging.
165
+	 * Specifically, we assume folks will want to know what exactly was the DB query that got run,
166
+	 * what exactly was the Models query that got run, what capabilities came into play, what fields were omitted from
167
+	 * the response, others?
168
+	 *
169
+	 * @param array|WP_Error|Exception|RestException $response
170
+	 * @return WP_REST_Response
171
+	 */
172
+	public function sendResponse($response)
173
+	{
174
+		if ($response instanceof RestException) {
175
+			$response = new WP_Error($response->getStringCode(), $response->getMessage(), $response->getData());
176
+		}
177
+		if ($response instanceof Exception) {
178
+			$code = $response->getCode() ? $response->getCode() : 'error_occurred';
179
+			$response = new WP_Error($code, $response->getMessage());
180
+		}
181
+		if ($response instanceof WP_Error) {
182
+			$response = $this->addEeErrorsToResponse($response);
183
+			$rest_response = $this->createRestResponseFromWpError($response);
184
+		} else {
185
+			$rest_response = new WP_REST_Response($response, 200);
186
+		}
187
+		$headers = array();
188
+		if ($this->debug_mode && is_array($this->debug_info)) {
189
+			foreach ($this->debug_info as $debug_key => $debug_info) {
190
+				if (is_array($debug_info)) {
191
+					$debug_info = wp_json_encode($debug_info);
192
+				}
193
+				$headers[ 'X-EE4-Debug-' . ucwords($debug_key) ] = $debug_info;
194
+			}
195
+		}
196
+		$headers = array_merge(
197
+			$headers,
198
+			$this->getResponseHeaders(),
199
+			$this->getHeadersFromEeNotices()
200
+		);
201
+		$rest_response->set_headers($headers);
202
+		return $rest_response;
203
+	}
204
+
205
+
206
+	/**
207
+	 * Converts the \WP_Error into `WP_REST_Response.
208
+	 * Mostly this is just a copy-and-paste from \WP_REST_Server::error_to_response
209
+	 * (which is protected)
210
+	 *
211
+	 * @param WP_Error $wp_error
212
+	 * @return WP_REST_Response
213
+	 */
214
+	protected function createRestResponseFromWpError(WP_Error $wp_error)
215
+	{
216
+		$error_data = $wp_error->get_error_data();
217
+		if (is_array($error_data) && isset($error_data['status'])) {
218
+			$status = $error_data['status'];
219
+		} else {
220
+			$status = 500;
221
+		}
222
+		$errors = array();
223
+		foreach ((array) $wp_error->errors as $code => $messages) {
224
+			foreach ((array) $messages as $message) {
225
+				$errors[] = array(
226
+					'code'    => $code,
227
+					'message' => $message,
228
+					'data'    => $wp_error->get_error_data($code),
229
+				);
230
+			}
231
+		}
232
+		$data = isset($errors[0]) ? $errors[0] : array();
233
+		if (count($errors) > 1) {
234
+			// Remove the primary error.
235
+			array_shift($errors);
236
+			$data['additional_errors'] = $errors;
237
+		}
238
+		return new WP_REST_Response($data, $status);
239
+	}
240
+
241
+
242
+	/**
243
+	 * Array of headers derived from EE success, attention, and error messages
244
+	 *
245
+	 * @return array
246
+	 */
247
+	protected function getHeadersFromEeNotices()
248
+	{
249
+		$headers = array();
250
+		$notices = EE_Error::get_raw_notices();
251
+		foreach ($notices as $notice_type => $sub_notices) {
252
+			if (! is_array($sub_notices)) {
253
+				continue;
254
+			}
255
+			foreach ($sub_notices as $notice_code => $sub_notice) {
256
+				$headers[ 'X-EE4-Notices-'
257
+						  . EEH_Inflector::humanize($notice_type)
258
+						  . '['
259
+						  . $notice_code
260
+						  . ']' ] = strip_tags($sub_notice);
261
+			}
262
+		}
263
+		return apply_filters(
264
+			'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_headers_from_ee_notices__return',
265
+			$headers,
266
+			$this->requested_version,
267
+			$notices
268
+		);
269
+	}
270
+
271
+
272
+	/**
273
+	 * Finds which version of the API was requested given the route, and returns it.
274
+	 * eg in a request to "mysite.com/wp-json/ee/v4.8.29/events/123" this would return
275
+	 * "4.8.29".
276
+	 * We should know hte requested version in this model though, so if no route is
277
+	 * provided just use what we set earlier
278
+	 *
279
+	 * @param string $route
280
+	 * @return string
281
+	 */
282
+	public function getRequestedVersion($route = null)
283
+	{
284
+		if ($route === null) {
285
+			return $this->requested_version;
286
+		}
287
+		$matches = $this->parseRoute(
288
+			$route,
289
+			'~' . EED_Core_Rest_Api::ee_api_namespace_for_regex . '~',
290
+			array('version')
291
+		);
292
+		if (isset($matches['version'])) {
293
+			return $matches['version'];
294
+		} else {
295
+			return EED_Core_Rest_Api::latest_rest_api_version();
296
+		}
297
+	}
298
+
299
+
300
+	/**
301
+	 * Applies the regex to the route, then creates an array using the values of
302
+	 * $match_keys as keys (but ignores the full pattern match). Returns the array of matches.
303
+	 * For example, if you call
304
+	 * parse_route( '/ee/v4.8/events', '~\/ee\/v([^/]*)\/(.*)~', array( 'version', 'model' ) )
305
+	 * it will return array( 'version' => '4.8', 'model' => 'events' )
306
+	 *
307
+	 * @param string $route
308
+	 * @param string $regex
309
+	 * @param array  $match_keys EXCLUDING matching the entire regex
310
+	 * @return array where  $match_keys are the keys (the first value of $match_keys
311
+	 *                           becomes the first key of the return value, etc. Eg passing in $match_keys of
312
+	 *                           array( 'model', 'id' ), will, if the regex is successful, will return
313
+	 *                           array( 'model' => 'foo', 'id' => 'bar' )
314
+	 * @throws EE_Error if it couldn't be parsed
315
+	 */
316
+	public function parseRoute($route, $regex, $match_keys)
317
+	{
318
+		$indexed_matches = array();
319
+		$success = preg_match($regex, $route, $matches);
320
+		if (is_array($matches)) {
321
+			// skip the overall regex match. Who cares
322
+			for ($i = 1; $i <= count($match_keys); $i++) {
323
+				if (! isset($matches[ $i ])) {
324
+					$success = false;
325
+				} else {
326
+					$indexed_matches[ $match_keys[ $i - 1 ] ] = $matches[ $i ];
327
+				}
328
+			}
329
+		}
330
+		if (! $success) {
331
+			throw new EE_Error(
332
+				__('We could not parse the URL. Please contact Event Espresso Support', 'event_espresso'),
333
+				'endpoint_parsing_error'
334
+			);
335
+		}
336
+		return $indexed_matches;
337
+	}
338
+
339
+
340
+	/**
341
+	 * Gets the body's params (either from JSON or parsed body), which EXCLUDES the GET params and URL params
342
+	 *
343
+	 * @param \WP_REST_Request $request
344
+	 * @return array
345
+	 */
346
+	protected function getBodyParams(\WP_REST_Request $request)
347
+	{
348
+		// $request->get_params();
349
+		return array_merge(
350
+			(array) $request->get_body_params(),
351
+			(array) $request->get_json_params()
352
+		);
353
+		// return array_diff_key(
354
+		//    $request->get_params(),
355
+		//     $request->get_url_params(),
356
+		//     $request->get_query_params()
357
+		// );
358
+	}
359 359
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
      */
97 97
     protected function setDebugInfo($key, $info)
98 98
     {
99
-        $this->debug_info[ $key ] = $info;
99
+        $this->debug_info[$key] = $info;
100 100
     }
101 101
 
102 102
 
@@ -113,11 +113,11 @@  discard block
 block discarded – undo
113 113
     {
114 114
         if (is_array($value)) {
115 115
             foreach ($value as $value_key => $value_value) {
116
-                $this->setResponseHeader($header_key . '[' . $value_key . ']', $value_value);
116
+                $this->setResponseHeader($header_key.'['.$value_key.']', $value_value);
117 117
             }
118 118
         } else {
119 119
             $prefix = $use_ee_prefix ? Base::HEADER_PREFIX_FOR_EE : Base::HEADER_PREFIX_FOR_WP;
120
-            $this->response_headers[ $prefix . $header_key ] = $value;
120
+            $this->response_headers[$prefix.$header_key] = $value;
121 121
         }
122 122
     }
123 123
 
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
     protected function addEeErrorsToResponse(WP_Error $wp_error_response)
148 148
     {
149 149
         $notices_during_checkin = EE_Error::get_raw_notices();
150
-        if (! empty($notices_during_checkin['errors'])) {
150
+        if ( ! empty($notices_during_checkin['errors'])) {
151 151
             foreach ($notices_during_checkin['errors'] as $error_code => $error_message) {
152 152
                 $wp_error_response->add(
153 153
                     sanitize_key($error_code),
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
                 if (is_array($debug_info)) {
191 191
                     $debug_info = wp_json_encode($debug_info);
192 192
                 }
193
-                $headers[ 'X-EE4-Debug-' . ucwords($debug_key) ] = $debug_info;
193
+                $headers['X-EE4-Debug-'.ucwords($debug_key)] = $debug_info;
194 194
             }
195 195
         }
196 196
         $headers = array_merge(
@@ -249,15 +249,15 @@  discard block
 block discarded – undo
249 249
         $headers = array();
250 250
         $notices = EE_Error::get_raw_notices();
251 251
         foreach ($notices as $notice_type => $sub_notices) {
252
-            if (! is_array($sub_notices)) {
252
+            if ( ! is_array($sub_notices)) {
253 253
                 continue;
254 254
             }
255 255
             foreach ($sub_notices as $notice_code => $sub_notice) {
256
-                $headers[ 'X-EE4-Notices-'
256
+                $headers['X-EE4-Notices-'
257 257
                           . EEH_Inflector::humanize($notice_type)
258 258
                           . '['
259 259
                           . $notice_code
260
-                          . ']' ] = strip_tags($sub_notice);
260
+                          . ']'] = strip_tags($sub_notice);
261 261
             }
262 262
         }
263 263
         return apply_filters(
@@ -286,7 +286,7 @@  discard block
 block discarded – undo
286 286
         }
287 287
         $matches = $this->parseRoute(
288 288
             $route,
289
-            '~' . EED_Core_Rest_Api::ee_api_namespace_for_regex . '~',
289
+            '~'.EED_Core_Rest_Api::ee_api_namespace_for_regex.'~',
290 290
             array('version')
291 291
         );
292 292
         if (isset($matches['version'])) {
@@ -320,14 +320,14 @@  discard block
 block discarded – undo
320 320
         if (is_array($matches)) {
321 321
             // skip the overall regex match. Who cares
322 322
             for ($i = 1; $i <= count($match_keys); $i++) {
323
-                if (! isset($matches[ $i ])) {
323
+                if ( ! isset($matches[$i])) {
324 324
                     $success = false;
325 325
                 } else {
326
-                    $indexed_matches[ $match_keys[ $i - 1 ] ] = $matches[ $i ];
326
+                    $indexed_matches[$match_keys[$i - 1]] = $matches[$i];
327 327
                 }
328 328
             }
329 329
         }
330
-        if (! $success) {
330
+        if ( ! $success) {
331 331
             throw new EE_Error(
332 332
                 __('We could not parse the URL. Please contact Event Espresso Support', 'event_espresso'),
333 333
                 'endpoint_parsing_error'
Please login to merge, or discard this patch.
core/services/container/CoffeeMaker.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 
70 70
 
71 71
     /**
72
-     * @param $type
72
+     * @param string $type
73 73
      * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
74 74
      */
75 75
     public static function validateType($type)
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
      * Examines the constructor to determine which method should be used for instantiation
128 128
      *
129 129
      * @param \ReflectionClass $reflector
130
-     * @return mixed
130
+     * @return string
131 131
      * @throws InstantiationException
132 132
      */
133 133
     protected function resolveInstantiationMethod(\ReflectionClass $reflector)
Please login to merge, or discard this patch.
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -18,156 +18,156 @@
 block discarded – undo
18 18
 abstract class CoffeeMaker implements CoffeeMakerInterface
19 19
 {
20 20
 
21
-    /**
22
-     * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given)
23
-     */
24
-    const BREW_NEW = 'new';
25
-
26
-    /**
27
-     * Indicates that CoffeeMaker should always return a SHARED instance
28
-     */
29
-    const BREW_SHARED = 'shared';
30
-
31
-    /**
32
-     * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate
33
-     */
34
-    const BREW_LOAD_ONLY = 'load_only';
35
-
36
-
37
-    /**
38
-     * @var CoffeePotInterface $coffee_pot
39
-     */
40
-    private $coffee_pot;
41
-
42
-    /**
43
-     * @var DependencyInjector $injector
44
-     */
45
-    private $injector;
46
-
47
-
48
-    /**
49
-     * @return array
50
-     */
51
-    public static function getTypes()
52
-    {
53
-        return (array) apply_filters(
54
-            'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes',
55
-            array(
56
-                CoffeeMaker::BREW_NEW,
57
-                CoffeeMaker::BREW_SHARED,
58
-                CoffeeMaker::BREW_LOAD_ONLY,
59
-            )
60
-        );
61
-    }
62
-
63
-
64
-    /**
65
-     * @param $type
66
-     * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
67
-     */
68
-    public static function validateType($type)
69
-    {
70
-        $types = CoffeeMaker::getTypes();
71
-        if (! in_array($type, $types, true)) {
72
-            throw new InvalidIdentifierException(
73
-                is_object($type) ? get_class($type) : gettype($type),
74
-                __(
75
-                    'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)',
76
-                    'event_espresso'
77
-                )
78
-            );
79
-        }
80
-        return $type;
81
-    }
82
-
83
-
84
-    /**
85
-     * CoffeeMaker constructor.
86
-     *
87
-     * @param CoffeePotInterface $coffee_pot
88
-     * @param InjectorInterface  $injector
89
-     */
90
-    public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector)
91
-    {
92
-        $this->coffee_pot = $coffee_pot;
93
-        $this->injector = $injector;
94
-    }
95
-
96
-
97
-    /**
98
-     * @return \EventEspresso\core\services\container\CoffeePotInterface
99
-     */
100
-    protected function coffeePot()
101
-    {
102
-        return $this->coffee_pot;
103
-    }
104
-
105
-
106
-    /**
107
-     * @return \EventEspresso\core\services\container\DependencyInjector
108
-     */
109
-    protected function injector()
110
-    {
111
-        return $this->injector;
112
-    }
113
-
114
-
115
-    /**
116
-     * Examines the constructor to determine which method should be used for instantiation
117
-     *
118
-     * @param \ReflectionClass $reflector
119
-     * @return mixed
120
-     * @throws InstantiationException
121
-     */
122
-    protected function resolveInstantiationMethod(\ReflectionClass $reflector)
123
-    {
124
-        if ($reflector->getConstructor() === null) {
125
-            return 'NewInstance';
126
-        }
127
-        if ($reflector->isInstantiable()) {
128
-            return 'NewInstanceArgs';
129
-        }
130
-        if (method_exists($reflector->getName(), 'instance')) {
131
-            return 'instance';
132
-        }
133
-        if (method_exists($reflector->getName(), 'new_instance')) {
134
-            return 'new_instance';
135
-        }
136
-        if (method_exists($reflector->getName(), 'new_instance_from_db')) {
137
-            return 'new_instance_from_db';
138
-        }
139
-        throw new InstantiationException($reflector->getName());
140
-    }
141
-
142
-
143
-    /**
144
-     * Ensures files for classes that are not PSR-4 compatible are loaded
145
-     * and then verifies that classes exist where applicable
146
-     *
147
-     * @param RecipeInterface $recipe
148
-     * @return bool
149
-     * @throws InvalidClassException
150
-     */
151
-    protected function resolveClassAndFilepath(RecipeInterface $recipe)
152
-    {
153
-        $paths = $recipe->paths();
154
-        if (! empty($paths)) {
155
-            foreach ($paths as $path) {
156
-                if (strpos($path, '*') === false && is_readable($path)) {
157
-                    require_once($path);
158
-                }
159
-            }
160
-        }
161
-        // re: using "false" for class_exists() second param:
162
-        // if a class name is not already known to PHP, then class_exists() will run through
163
-        // all of the registered spl_autoload functions until it either finds the class,
164
-        // or gets to the end of the registered spl_autoload functions.
165
-        // When the second parameter is true, it will also attempt to load the class file,
166
-        // but it will also trigger an error if the class can not be loaded.
167
-        // We don't want that extra error in the mix, so we have set the second param to "false"
168
-        if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) {
169
-            throw new InvalidClassException($recipe->identifier());
170
-        }
171
-        return true;
172
-    }
21
+	/**
22
+	 * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given)
23
+	 */
24
+	const BREW_NEW = 'new';
25
+
26
+	/**
27
+	 * Indicates that CoffeeMaker should always return a SHARED instance
28
+	 */
29
+	const BREW_SHARED = 'shared';
30
+
31
+	/**
32
+	 * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate
33
+	 */
34
+	const BREW_LOAD_ONLY = 'load_only';
35
+
36
+
37
+	/**
38
+	 * @var CoffeePotInterface $coffee_pot
39
+	 */
40
+	private $coffee_pot;
41
+
42
+	/**
43
+	 * @var DependencyInjector $injector
44
+	 */
45
+	private $injector;
46
+
47
+
48
+	/**
49
+	 * @return array
50
+	 */
51
+	public static function getTypes()
52
+	{
53
+		return (array) apply_filters(
54
+			'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes',
55
+			array(
56
+				CoffeeMaker::BREW_NEW,
57
+				CoffeeMaker::BREW_SHARED,
58
+				CoffeeMaker::BREW_LOAD_ONLY,
59
+			)
60
+		);
61
+	}
62
+
63
+
64
+	/**
65
+	 * @param $type
66
+	 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
67
+	 */
68
+	public static function validateType($type)
69
+	{
70
+		$types = CoffeeMaker::getTypes();
71
+		if (! in_array($type, $types, true)) {
72
+			throw new InvalidIdentifierException(
73
+				is_object($type) ? get_class($type) : gettype($type),
74
+				__(
75
+					'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)',
76
+					'event_espresso'
77
+				)
78
+			);
79
+		}
80
+		return $type;
81
+	}
82
+
83
+
84
+	/**
85
+	 * CoffeeMaker constructor.
86
+	 *
87
+	 * @param CoffeePotInterface $coffee_pot
88
+	 * @param InjectorInterface  $injector
89
+	 */
90
+	public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector)
91
+	{
92
+		$this->coffee_pot = $coffee_pot;
93
+		$this->injector = $injector;
94
+	}
95
+
96
+
97
+	/**
98
+	 * @return \EventEspresso\core\services\container\CoffeePotInterface
99
+	 */
100
+	protected function coffeePot()
101
+	{
102
+		return $this->coffee_pot;
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return \EventEspresso\core\services\container\DependencyInjector
108
+	 */
109
+	protected function injector()
110
+	{
111
+		return $this->injector;
112
+	}
113
+
114
+
115
+	/**
116
+	 * Examines the constructor to determine which method should be used for instantiation
117
+	 *
118
+	 * @param \ReflectionClass $reflector
119
+	 * @return mixed
120
+	 * @throws InstantiationException
121
+	 */
122
+	protected function resolveInstantiationMethod(\ReflectionClass $reflector)
123
+	{
124
+		if ($reflector->getConstructor() === null) {
125
+			return 'NewInstance';
126
+		}
127
+		if ($reflector->isInstantiable()) {
128
+			return 'NewInstanceArgs';
129
+		}
130
+		if (method_exists($reflector->getName(), 'instance')) {
131
+			return 'instance';
132
+		}
133
+		if (method_exists($reflector->getName(), 'new_instance')) {
134
+			return 'new_instance';
135
+		}
136
+		if (method_exists($reflector->getName(), 'new_instance_from_db')) {
137
+			return 'new_instance_from_db';
138
+		}
139
+		throw new InstantiationException($reflector->getName());
140
+	}
141
+
142
+
143
+	/**
144
+	 * Ensures files for classes that are not PSR-4 compatible are loaded
145
+	 * and then verifies that classes exist where applicable
146
+	 *
147
+	 * @param RecipeInterface $recipe
148
+	 * @return bool
149
+	 * @throws InvalidClassException
150
+	 */
151
+	protected function resolveClassAndFilepath(RecipeInterface $recipe)
152
+	{
153
+		$paths = $recipe->paths();
154
+		if (! empty($paths)) {
155
+			foreach ($paths as $path) {
156
+				if (strpos($path, '*') === false && is_readable($path)) {
157
+					require_once($path);
158
+				}
159
+			}
160
+		}
161
+		// re: using "false" for class_exists() second param:
162
+		// if a class name is not already known to PHP, then class_exists() will run through
163
+		// all of the registered spl_autoload functions until it either finds the class,
164
+		// or gets to the end of the registered spl_autoload functions.
165
+		// When the second parameter is true, it will also attempt to load the class file,
166
+		// but it will also trigger an error if the class can not be loaded.
167
+		// We don't want that extra error in the mix, so we have set the second param to "false"
168
+		if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) {
169
+			throw new InvalidClassException($recipe->identifier());
170
+		}
171
+		return true;
172
+	}
173 173
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
     public static function validateType($type)
69 69
     {
70 70
         $types = CoffeeMaker::getTypes();
71
-        if (! in_array($type, $types, true)) {
71
+        if ( ! in_array($type, $types, true)) {
72 72
             throw new InvalidIdentifierException(
73 73
                 is_object($type) ? get_class($type) : gettype($type),
74 74
                 __(
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
     protected function resolveClassAndFilepath(RecipeInterface $recipe)
152 152
     {
153 153
         $paths = $recipe->paths();
154
-        if (! empty($paths)) {
154
+        if ( ! empty($paths)) {
155 155
             foreach ($paths as $path) {
156 156
                 if (strpos($path, '*') === false && is_readable($path)) {
157 157
                     require_once($path);
Please login to merge, or discard this patch.
core/services/container/CoffeeShop.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
      * Adds instructions on how to brew objects
362 362
      *
363 363
      * @param RecipeInterface $recipe
364
-     * @return mixed
364
+     * @return boolean
365 365
      * @throws InvalidIdentifierException
366 366
      */
367 367
     public function addRecipe(RecipeInterface $recipe)
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
     /**
462 462
      * Adds a service to one of the internal collections
463 463
      *
464
-     * @param        $identifier
464
+     * @param        string $identifier
465 465
      * @param array  $arguments
466 466
      * @param string $type
467 467
      * @return mixed
Please login to merge, or discard this patch.
Indentation   +565 added lines, -565 removed lines patch added patch discarded remove patch
@@ -30,569 +30,569 @@
 block discarded – undo
30 30
 {
31 31
 
32 32
 
33
-    /**
34
-     * This was the best coffee related name I could think of to represent class name "aliases"
35
-     * So classes can be found via an alias identifier,
36
-     * that is revealed when it is run through... the filters... eh? get it?
37
-     *
38
-     * @var array $filters
39
-     */
40
-    private $filters;
41
-
42
-    /**
43
-     * These are the classes that will actually build the objects (to order of course)
44
-     *
45
-     * @var array $coffee_makers
46
-     */
47
-    private $coffee_makers;
48
-
49
-    /**
50
-     * where the instantiated "singleton" objects are stored
51
-     *
52
-     * @var CollectionInterface $carafe
53
-     */
54
-    private $carafe;
55
-
56
-    /**
57
-     * collection of Recipes that instruct us how to brew objects
58
-     *
59
-     * @var CollectionInterface $recipes
60
-     */
61
-    private $recipes;
62
-
63
-    /**
64
-     * collection of closures for brewing objects
65
-     *
66
-     * @var CollectionInterface $reservoir
67
-     */
68
-    private $reservoir;
69
-
70
-
71
-    /**
72
-     * CoffeeShop constructor
73
-     *
74
-     * @throws InvalidInterfaceException
75
-     */
76
-    public function __construct()
77
-    {
78
-        // array for storing class aliases
79
-        $this->filters = array();
80
-        // create collection for storing shared services
81
-        $this->carafe = new LooseCollection('');
82
-        // create collection for storing recipes that tell us how to build services and entities
83
-        $this->recipes = new Collection('EventEspresso\core\services\container\RecipeInterface');
84
-        // create collection for storing closures for constructing new entities
85
-        $this->reservoir = new Collection('Closure');
86
-        // create collection for storing the generators that build our services and entity closures
87
-        $this->coffee_makers = new Collection('EventEspresso\core\services\container\CoffeeMakerInterface');
88
-    }
89
-
90
-
91
-    /**
92
-     * Returns true if the container can return an entry for the given identifier.
93
-     * Returns false otherwise.
94
-     * `has($identifier)` returning true does not mean that `get($identifier)` will not throw an exception.
95
-     * It does however mean that `get($identifier)` will not throw a `ServiceNotFoundException`.
96
-     *
97
-     * @param string $identifier  Identifier of the entry to look for.
98
-     *                            Typically a Fully Qualified Class Name
99
-     * @return boolean
100
-     * @throws InvalidIdentifierException
101
-     */
102
-    public function has($identifier)
103
-    {
104
-        $identifier = $this->filterIdentifier($identifier);
105
-        return $this->carafe->has($identifier);
106
-    }
107
-
108
-
109
-    /**
110
-     * finds a previously brewed (SHARED) service and returns it
111
-     *
112
-     * @param  string $identifier Identifier for the entity class to be constructed.
113
-     *                            Typically a Fully Qualified Class Name
114
-     * @return mixed
115
-     * @throws InvalidIdentifierException
116
-     * @throws ServiceNotFoundException No service was found for this identifier.
117
-     */
118
-    public function get($identifier)
119
-    {
120
-        $identifier = $this->filterIdentifier($identifier);
121
-        if ($this->carafe->has($identifier)) {
122
-            return $this->carafe->get($identifier);
123
-        }
124
-        throw new ServiceNotFoundException($identifier);
125
-    }
126
-
127
-
128
-    /**
129
-     * returns an instance of the requested entity type using the supplied arguments.
130
-     * If a shared service is requested and an instance is already in the carafe, then it will be returned.
131
-     * If it is not already in the carafe, then the service will be constructed, added to the carafe, and returned
132
-     * If the request is for a new entity and a closure exists in the reservoir for creating it,
133
-     * then a new entity will be instantiated from the closure and returned.
134
-     * If a closure does not exist, then one will be built and added to the reservoir
135
-     * before instantiating the requested entity.
136
-     *
137
-     * @param  string $identifier Identifier for the entity class to be constructed.
138
-     *                            Typically a Fully Qualified Class Name
139
-     * @param array   $arguments  an array of arguments to be passed to the entity constructor
140
-     * @param string  $type
141
-     * @return mixed
142
-     * @throws OutOfBoundsException
143
-     * @throws InstantiationException
144
-     * @throws InvalidDataTypeException
145
-     * @throws InvalidClassException
146
-     * @throws InvalidIdentifierException
147
-     * @throws ServiceExistsException
148
-     * @throws ServiceNotFoundException No service was found for this identifier.
149
-     */
150
-    public function brew($identifier, $arguments = array(), $type = '')
151
-    {
152
-        // resolve any class aliases that may exist
153
-        $identifier = $this->filterIdentifier($identifier);
154
-        // is a shared service being requested and already exists in the carafe?
155
-        $brewed = $this->getShared($identifier, $type);
156
-        // then return whatever was found
157
-        if ($brewed !== false) {
158
-            return $brewed;
159
-        }
160
-        // if the reservoir doesn't have a closure already for the requested identifier,
161
-        // then neither a shared service nor a closure for making entities has been built yet
162
-        if (! $this->reservoir->has($identifier)) {
163
-            // so let's brew something up and add it to the proper collection
164
-            $brewed = $this->makeCoffee($identifier, $arguments, $type);
165
-        }
166
-        // did the requested class only require loading, and if so, was that successful?
167
-        if ($this->brewedLoadOnly($brewed, $identifier, $type) === true) {
168
-            return true;
169
-        }
170
-        // was the brewed item a callable factory function ?
171
-        if (is_callable($brewed)) {
172
-            // then instantiate a new entity from the cached closure
173
-            return $brewed($arguments);
174
-        }
175
-        if ($brewed) {
176
-            // requested object was a shared entity, so attempt to get it from the carafe again
177
-            // because if it wasn't there before, then it should have just been brewed and added,
178
-            // but if it still isn't there, then this time the thrown ServiceNotFoundException will not be caught
179
-            return $this->get($identifier);
180
-        }
181
-        // if identifier is for a non-shared entity,
182
-        // then either a cached closure already existed, or was just brewed
183
-        return $this->brewedClosure($identifier, $arguments);
184
-    }
185
-
186
-
187
-    /**
188
-     * @param string $identifier
189
-     * @param string $type
190
-     * @return bool|mixed
191
-     * @throws InvalidIdentifierException
192
-     */
193
-    protected function getShared($identifier, $type)
194
-    {
195
-        try {
196
-            if (empty($type) || $type === CoffeeMaker::BREW_SHARED) {
197
-                // if a shared service was requested and an instance is in the carafe, then return it
198
-                return $this->get($identifier);
199
-            }
200
-        } catch (ServiceNotFoundException $e) {
201
-            // if not then we'll just catch the ServiceNotFoundException but not do anything just yet,
202
-            // and instead, attempt to build whatever was requested
203
-        }
204
-        return false;
205
-    }
206
-
207
-
208
-    /**
209
-     * @param mixed  $brewed
210
-     * @param string $identifier
211
-     * @param string $type
212
-     * @return bool
213
-     * @throws InvalidClassException
214
-     * @throws InvalidDataTypeException
215
-     * @throws InvalidIdentifierException
216
-     * @throws OutOfBoundsException
217
-     * @throws ServiceExistsException
218
-     * @throws ServiceNotFoundException
219
-     */
220
-    protected function brewedLoadOnly($brewed, $identifier, $type)
221
-    {
222
-        if ($type === CoffeeMaker::BREW_LOAD_ONLY) {
223
-            if ($brewed !== true) {
224
-                throw new ServiceNotFoundException(
225
-                    sprintf(
226
-                        esc_html__(
227
-                            'The "%1$s" class could not be loaded.',
228
-                            'event_espresso'
229
-                        ),
230
-                        $identifier
231
-                    )
232
-                );
233
-            }
234
-            return true;
235
-        }
236
-        return false;
237
-    }
238
-
239
-
240
-    /**
241
-     * @param string $identifier
242
-     * @param array  $arguments
243
-     * @return mixed
244
-     * @throws InstantiationException
245
-     */
246
-    protected function brewedClosure($identifier, array $arguments)
247
-    {
248
-        $closure = $this->reservoir->get($identifier);
249
-        if (empty($closure)) {
250
-            throw new InstantiationException(
251
-                sprintf(
252
-                    esc_html__(
253
-                        'Could not brew an instance of "%1$s".',
254
-                        'event_espresso'
255
-                    ),
256
-                    $identifier
257
-                )
258
-            );
259
-        }
260
-        return $closure($arguments);
261
-    }
262
-
263
-
264
-    /**
265
-     * @param CoffeeMakerInterface $coffee_maker
266
-     * @param string               $type
267
-     * @return bool
268
-     * @throws InvalidIdentifierException
269
-     * @throws InvalidEntityException
270
-     */
271
-    public function addCoffeeMaker(CoffeeMakerInterface $coffee_maker, $type)
272
-    {
273
-        $type = CoffeeMaker::validateType($type);
274
-        return $this->coffee_makers->add($coffee_maker, $type);
275
-    }
276
-
277
-
278
-    /**
279
-     * @param string   $identifier
280
-     * @param callable $closure
281
-     * @return callable|null
282
-     * @throws InvalidIdentifierException
283
-     * @throws InvalidDataTypeException
284
-     */
285
-    public function addClosure($identifier, $closure)
286
-    {
287
-        if (! is_callable($closure)) {
288
-            throw new InvalidDataTypeException('$closure', $closure, 'Closure');
289
-        }
290
-        $identifier = $this->processIdentifier($identifier);
291
-        if ($this->reservoir->add($closure, $identifier)) {
292
-            return $closure;
293
-        }
294
-        return null;
295
-    }
296
-
297
-
298
-    /**
299
-     * @param string $identifier
300
-     * @return boolean
301
-     * @throws InvalidIdentifierException
302
-     */
303
-    public function removeClosure($identifier)
304
-    {
305
-        $identifier = $this->processIdentifier($identifier);
306
-        if ($this->reservoir->has($identifier)) {
307
-            return $this->reservoir->remove($this->reservoir->get($identifier));
308
-        }
309
-        return false;
310
-    }
311
-
312
-
313
-    /**
314
-     * @param  string $identifier Identifier for the entity class that the service applies to
315
-     *                            Typically a Fully Qualified Class Name
316
-     * @param mixed   $service
317
-     * @return bool
318
-     * @throws \EventEspresso\core\services\container\exceptions\InvalidServiceException
319
-     * @throws InvalidIdentifierException
320
-     */
321
-    public function addService($identifier, $service)
322
-    {
323
-        $identifier = $this->processIdentifier($identifier);
324
-        $service = $this->validateService($identifier, $service);
325
-        return $this->carafe->add($service, $identifier);
326
-    }
327
-
328
-
329
-    /**
330
-     * @param string $identifier
331
-     * @return boolean
332
-     * @throws InvalidIdentifierException
333
-     */
334
-    public function removeService($identifier)
335
-    {
336
-        $identifier = $this->processIdentifier($identifier);
337
-        if ($this->carafe->has($identifier)) {
338
-            return $this->carafe->remove($this->carafe->get($identifier));
339
-        }
340
-        return false;
341
-    }
342
-
343
-
344
-    /**
345
-     * Adds instructions on how to brew objects
346
-     *
347
-     * @param RecipeInterface $recipe
348
-     * @return mixed
349
-     * @throws InvalidIdentifierException
350
-     */
351
-    public function addRecipe(RecipeInterface $recipe)
352
-    {
353
-        $this->addAliases($recipe->identifier(), $recipe->filters());
354
-        $identifier = $this->processIdentifier($recipe->identifier());
355
-        return $this->recipes->add($recipe, $identifier);
356
-    }
357
-
358
-
359
-    /**
360
-     * @param string $identifier The Recipe's identifier
361
-     * @return boolean
362
-     * @throws InvalidIdentifierException
363
-     */
364
-    public function removeRecipe($identifier)
365
-    {
366
-        $identifier = $this->processIdentifier($identifier);
367
-        if ($this->recipes->has($identifier)) {
368
-            return $this->recipes->remove($this->recipes->get($identifier));
369
-        }
370
-        return false;
371
-    }
372
-
373
-
374
-    /**
375
-     * Get instructions on how to brew objects
376
-     *
377
-     * @param  string $identifier Identifier for the entity class that the recipe applies to
378
-     *                            Typically a Fully Qualified Class Name
379
-     * @param string  $type
380
-     * @return RecipeInterface
381
-     * @throws OutOfBoundsException
382
-     * @throws InvalidIdentifierException
383
-     */
384
-    public function getRecipe($identifier, $type = '')
385
-    {
386
-        $identifier = $this->processIdentifier($identifier);
387
-        if ($this->recipes->has($identifier)) {
388
-            return $this->recipes->get($identifier);
389
-        }
390
-        $default_recipes = $this->getDefaultRecipes();
391
-        $matches = array();
392
-        foreach ($default_recipes as $wildcard => $default_recipe) {
393
-            // is the wildcard recipe prefix in the identifier ?
394
-            if (strpos($identifier, $wildcard) !== false) {
395
-                // track matches and use the number of wildcard characters matched for the key
396
-                $matches[ strlen($wildcard) ] = $default_recipe;
397
-            }
398
-        }
399
-        if (count($matches) > 0) {
400
-            // sort our recipes by the number of wildcard characters matched
401
-            ksort($matches);
402
-            // then grab the last recipe form the list, since it had the most matching characters
403
-            $match = array_pop($matches);
404
-            // since we are using a default recipe, we need to set it's identifier and fqcn
405
-            return $this->copyDefaultRecipe($match, $identifier, $type);
406
-        }
407
-        if ($this->recipes->has(Recipe::DEFAULT_ID)) {
408
-            // since we are using a default recipe, we need to set it's identifier and fqcn
409
-            return $this->copyDefaultRecipe($this->recipes->get(Recipe::DEFAULT_ID), $identifier, $type);
410
-        }
411
-        throw new OutOfBoundsException(
412
-            sprintf(
413
-                __('Could not brew coffee because no recipes were found for class "%1$s".', 'event_espresso'),
414
-                $identifier
415
-            )
416
-        );
417
-    }
418
-
419
-
420
-    /**
421
-     * adds class name aliases to list of filters
422
-     *
423
-     * @param  string       $identifier Identifier for the entity class that the alias applies to
424
-     *                                  Typically a Fully Qualified Class Name
425
-     * @param  array|string $aliases
426
-     * @return void
427
-     * @throws InvalidIdentifierException
428
-     */
429
-    public function addAliases($identifier, $aliases)
430
-    {
431
-        if (empty($aliases)) {
432
-            return;
433
-        }
434
-        $identifier = $this->processIdentifier($identifier);
435
-        foreach ((array) $aliases as $alias) {
436
-            $this->filters[ $this->processIdentifier($alias) ] = $identifier;
437
-        }
438
-    }
439
-
440
-
441
-    /**
442
-     * Adds a service to one of the internal collections
443
-     *
444
-     * @param        $identifier
445
-     * @param array  $arguments
446
-     * @param string $type
447
-     * @return mixed
448
-     * @throws InvalidDataTypeException
449
-     * @throws InvalidClassException
450
-     * @throws OutOfBoundsException
451
-     * @throws InvalidIdentifierException
452
-     * @throws ServiceExistsException
453
-     */
454
-    private function makeCoffee($identifier, $arguments = array(), $type = '')
455
-    {
456
-        if ((empty($type) || $type === CoffeeMaker::BREW_SHARED) && $this->has($identifier)) {
457
-            throw new ServiceExistsException($identifier);
458
-        }
459
-        $identifier = $this->filterIdentifier($identifier);
460
-        $recipe = $this->getRecipe($identifier, $type);
461
-        $type = ! empty($type) ? $type : $recipe->type();
462
-        $coffee_maker = $this->getCoffeeMaker($type);
463
-        return $coffee_maker->brew($recipe, $arguments);
464
-    }
465
-
466
-
467
-    /**
468
-     * filters alias identifiers to find the real class name
469
-     *
470
-     * @param  string $identifier Identifier for the entity class that the filter applies to
471
-     *                            Typically a Fully Qualified Class Name
472
-     * @return string
473
-     * @throws InvalidIdentifierException
474
-     */
475
-    private function filterIdentifier($identifier)
476
-    {
477
-        $identifier = $this->processIdentifier($identifier);
478
-        return isset($this->filters[ $identifier ]) && ! empty($this->filters[ $identifier ])
479
-            ? $this->filters[ $identifier ]
480
-            : $identifier;
481
-    }
482
-
483
-
484
-    /**
485
-     * verifies and standardizes identifiers
486
-     *
487
-     * @param  string $identifier Identifier for the entity class
488
-     *                            Typically a Fully Qualified Class Name
489
-     * @return string
490
-     * @throws InvalidIdentifierException
491
-     */
492
-    private function processIdentifier($identifier)
493
-    {
494
-        if (! is_string($identifier)) {
495
-            throw new InvalidIdentifierException(
496
-                is_object($identifier) ? get_class($identifier) : gettype($identifier),
497
-                '\Fully\Qualified\ClassName'
498
-            );
499
-        }
500
-        return ltrim($identifier, '\\');
501
-    }
502
-
503
-
504
-    /**
505
-     * @param string $type
506
-     * @return CoffeeMakerInterface
507
-     * @throws OutOfBoundsException
508
-     * @throws InvalidDataTypeException
509
-     * @throws InvalidClassException
510
-     */
511
-    private function getCoffeeMaker($type)
512
-    {
513
-        if (! $this->coffee_makers->has($type)) {
514
-            throw new OutOfBoundsException(
515
-                __('The requested coffee maker is either missing or invalid.', 'event_espresso')
516
-            );
517
-        }
518
-        return $this->coffee_makers->get($type);
519
-    }
520
-
521
-
522
-    /**
523
-     * Retrieves all recipes that use a wildcard "*" in their identifier
524
-     * This allows recipes to be set up for handling
525
-     * legacy classes that do not support PSR-4 autoloading.
526
-     * for example:
527
-     * using "EEM_*" for a recipe identifier would target all legacy models like EEM_Attendee
528
-     *
529
-     * @return array
530
-     */
531
-    private function getDefaultRecipes()
532
-    {
533
-        $default_recipes = array();
534
-        $this->recipes->rewind();
535
-        while ($this->recipes->valid()) {
536
-            $identifier = $this->recipes->getInfo();
537
-            // does this recipe use a wildcard ? (but is NOT the global default)
538
-            if ($identifier !== Recipe::DEFAULT_ID && strpos($identifier, '*') !== false) {
539
-                // strip the wildcard and use identifier as key
540
-                $default_recipes[ str_replace('*', '', $identifier) ] = $this->recipes->current();
541
-            }
542
-            $this->recipes->next();
543
-        }
544
-        return $default_recipes;
545
-    }
546
-
547
-
548
-    /**
549
-     * clones a default recipe and then copies details
550
-     * from the incoming request to it so that it can be used
551
-     *
552
-     * @param RecipeInterface $default_recipe
553
-     * @param string          $identifier
554
-     * @param string          $type
555
-     * @return RecipeInterface
556
-     */
557
-    private function copyDefaultRecipe(RecipeInterface $default_recipe, $identifier, $type = '')
558
-    {
559
-        $recipe = clone $default_recipe;
560
-        if (! empty($type)) {
561
-            $recipe->setType($type);
562
-        }
563
-        // is this the base default recipe ?
564
-        if ($default_recipe->identifier() === Recipe::DEFAULT_ID) {
565
-            $recipe->setIdentifier($identifier);
566
-            $recipe->setFqcn($identifier);
567
-            return $recipe;
568
-        }
569
-        $recipe->setIdentifier($identifier);
570
-        foreach ($default_recipe->paths() as $path) {
571
-            $path = str_replace('*', $identifier, $path);
572
-            if (is_readable($path)) {
573
-                $recipe->setPaths($path);
574
-            }
575
-        }
576
-        $recipe->setFqcn($identifier);
577
-        return $recipe;
578
-    }
579
-
580
-
581
-    /**
582
-     * @param  string $identifier Identifier for the entity class that the service applies to
583
-     *                            Typically a Fully Qualified Class Name
584
-     * @param mixed   $service
585
-     * @return mixed
586
-     * @throws InvalidServiceException
587
-     */
588
-    private function validateService($identifier, $service)
589
-    {
590
-        if (! is_object($service)) {
591
-            throw new InvalidServiceException(
592
-                $identifier,
593
-                $service
594
-            );
595
-        }
596
-        return $service;
597
-    }
33
+	/**
34
+	 * This was the best coffee related name I could think of to represent class name "aliases"
35
+	 * So classes can be found via an alias identifier,
36
+	 * that is revealed when it is run through... the filters... eh? get it?
37
+	 *
38
+	 * @var array $filters
39
+	 */
40
+	private $filters;
41
+
42
+	/**
43
+	 * These are the classes that will actually build the objects (to order of course)
44
+	 *
45
+	 * @var array $coffee_makers
46
+	 */
47
+	private $coffee_makers;
48
+
49
+	/**
50
+	 * where the instantiated "singleton" objects are stored
51
+	 *
52
+	 * @var CollectionInterface $carafe
53
+	 */
54
+	private $carafe;
55
+
56
+	/**
57
+	 * collection of Recipes that instruct us how to brew objects
58
+	 *
59
+	 * @var CollectionInterface $recipes
60
+	 */
61
+	private $recipes;
62
+
63
+	/**
64
+	 * collection of closures for brewing objects
65
+	 *
66
+	 * @var CollectionInterface $reservoir
67
+	 */
68
+	private $reservoir;
69
+
70
+
71
+	/**
72
+	 * CoffeeShop constructor
73
+	 *
74
+	 * @throws InvalidInterfaceException
75
+	 */
76
+	public function __construct()
77
+	{
78
+		// array for storing class aliases
79
+		$this->filters = array();
80
+		// create collection for storing shared services
81
+		$this->carafe = new LooseCollection('');
82
+		// create collection for storing recipes that tell us how to build services and entities
83
+		$this->recipes = new Collection('EventEspresso\core\services\container\RecipeInterface');
84
+		// create collection for storing closures for constructing new entities
85
+		$this->reservoir = new Collection('Closure');
86
+		// create collection for storing the generators that build our services and entity closures
87
+		$this->coffee_makers = new Collection('EventEspresso\core\services\container\CoffeeMakerInterface');
88
+	}
89
+
90
+
91
+	/**
92
+	 * Returns true if the container can return an entry for the given identifier.
93
+	 * Returns false otherwise.
94
+	 * `has($identifier)` returning true does not mean that `get($identifier)` will not throw an exception.
95
+	 * It does however mean that `get($identifier)` will not throw a `ServiceNotFoundException`.
96
+	 *
97
+	 * @param string $identifier  Identifier of the entry to look for.
98
+	 *                            Typically a Fully Qualified Class Name
99
+	 * @return boolean
100
+	 * @throws InvalidIdentifierException
101
+	 */
102
+	public function has($identifier)
103
+	{
104
+		$identifier = $this->filterIdentifier($identifier);
105
+		return $this->carafe->has($identifier);
106
+	}
107
+
108
+
109
+	/**
110
+	 * finds a previously brewed (SHARED) service and returns it
111
+	 *
112
+	 * @param  string $identifier Identifier for the entity class to be constructed.
113
+	 *                            Typically a Fully Qualified Class Name
114
+	 * @return mixed
115
+	 * @throws InvalidIdentifierException
116
+	 * @throws ServiceNotFoundException No service was found for this identifier.
117
+	 */
118
+	public function get($identifier)
119
+	{
120
+		$identifier = $this->filterIdentifier($identifier);
121
+		if ($this->carafe->has($identifier)) {
122
+			return $this->carafe->get($identifier);
123
+		}
124
+		throw new ServiceNotFoundException($identifier);
125
+	}
126
+
127
+
128
+	/**
129
+	 * returns an instance of the requested entity type using the supplied arguments.
130
+	 * If a shared service is requested and an instance is already in the carafe, then it will be returned.
131
+	 * If it is not already in the carafe, then the service will be constructed, added to the carafe, and returned
132
+	 * If the request is for a new entity and a closure exists in the reservoir for creating it,
133
+	 * then a new entity will be instantiated from the closure and returned.
134
+	 * If a closure does not exist, then one will be built and added to the reservoir
135
+	 * before instantiating the requested entity.
136
+	 *
137
+	 * @param  string $identifier Identifier for the entity class to be constructed.
138
+	 *                            Typically a Fully Qualified Class Name
139
+	 * @param array   $arguments  an array of arguments to be passed to the entity constructor
140
+	 * @param string  $type
141
+	 * @return mixed
142
+	 * @throws OutOfBoundsException
143
+	 * @throws InstantiationException
144
+	 * @throws InvalidDataTypeException
145
+	 * @throws InvalidClassException
146
+	 * @throws InvalidIdentifierException
147
+	 * @throws ServiceExistsException
148
+	 * @throws ServiceNotFoundException No service was found for this identifier.
149
+	 */
150
+	public function brew($identifier, $arguments = array(), $type = '')
151
+	{
152
+		// resolve any class aliases that may exist
153
+		$identifier = $this->filterIdentifier($identifier);
154
+		// is a shared service being requested and already exists in the carafe?
155
+		$brewed = $this->getShared($identifier, $type);
156
+		// then return whatever was found
157
+		if ($brewed !== false) {
158
+			return $brewed;
159
+		}
160
+		// if the reservoir doesn't have a closure already for the requested identifier,
161
+		// then neither a shared service nor a closure for making entities has been built yet
162
+		if (! $this->reservoir->has($identifier)) {
163
+			// so let's brew something up and add it to the proper collection
164
+			$brewed = $this->makeCoffee($identifier, $arguments, $type);
165
+		}
166
+		// did the requested class only require loading, and if so, was that successful?
167
+		if ($this->brewedLoadOnly($brewed, $identifier, $type) === true) {
168
+			return true;
169
+		}
170
+		// was the brewed item a callable factory function ?
171
+		if (is_callable($brewed)) {
172
+			// then instantiate a new entity from the cached closure
173
+			return $brewed($arguments);
174
+		}
175
+		if ($brewed) {
176
+			// requested object was a shared entity, so attempt to get it from the carafe again
177
+			// because if it wasn't there before, then it should have just been brewed and added,
178
+			// but if it still isn't there, then this time the thrown ServiceNotFoundException will not be caught
179
+			return $this->get($identifier);
180
+		}
181
+		// if identifier is for a non-shared entity,
182
+		// then either a cached closure already existed, or was just brewed
183
+		return $this->brewedClosure($identifier, $arguments);
184
+	}
185
+
186
+
187
+	/**
188
+	 * @param string $identifier
189
+	 * @param string $type
190
+	 * @return bool|mixed
191
+	 * @throws InvalidIdentifierException
192
+	 */
193
+	protected function getShared($identifier, $type)
194
+	{
195
+		try {
196
+			if (empty($type) || $type === CoffeeMaker::BREW_SHARED) {
197
+				// if a shared service was requested and an instance is in the carafe, then return it
198
+				return $this->get($identifier);
199
+			}
200
+		} catch (ServiceNotFoundException $e) {
201
+			// if not then we'll just catch the ServiceNotFoundException but not do anything just yet,
202
+			// and instead, attempt to build whatever was requested
203
+		}
204
+		return false;
205
+	}
206
+
207
+
208
+	/**
209
+	 * @param mixed  $brewed
210
+	 * @param string $identifier
211
+	 * @param string $type
212
+	 * @return bool
213
+	 * @throws InvalidClassException
214
+	 * @throws InvalidDataTypeException
215
+	 * @throws InvalidIdentifierException
216
+	 * @throws OutOfBoundsException
217
+	 * @throws ServiceExistsException
218
+	 * @throws ServiceNotFoundException
219
+	 */
220
+	protected function brewedLoadOnly($brewed, $identifier, $type)
221
+	{
222
+		if ($type === CoffeeMaker::BREW_LOAD_ONLY) {
223
+			if ($brewed !== true) {
224
+				throw new ServiceNotFoundException(
225
+					sprintf(
226
+						esc_html__(
227
+							'The "%1$s" class could not be loaded.',
228
+							'event_espresso'
229
+						),
230
+						$identifier
231
+					)
232
+				);
233
+			}
234
+			return true;
235
+		}
236
+		return false;
237
+	}
238
+
239
+
240
+	/**
241
+	 * @param string $identifier
242
+	 * @param array  $arguments
243
+	 * @return mixed
244
+	 * @throws InstantiationException
245
+	 */
246
+	protected function brewedClosure($identifier, array $arguments)
247
+	{
248
+		$closure = $this->reservoir->get($identifier);
249
+		if (empty($closure)) {
250
+			throw new InstantiationException(
251
+				sprintf(
252
+					esc_html__(
253
+						'Could not brew an instance of "%1$s".',
254
+						'event_espresso'
255
+					),
256
+					$identifier
257
+				)
258
+			);
259
+		}
260
+		return $closure($arguments);
261
+	}
262
+
263
+
264
+	/**
265
+	 * @param CoffeeMakerInterface $coffee_maker
266
+	 * @param string               $type
267
+	 * @return bool
268
+	 * @throws InvalidIdentifierException
269
+	 * @throws InvalidEntityException
270
+	 */
271
+	public function addCoffeeMaker(CoffeeMakerInterface $coffee_maker, $type)
272
+	{
273
+		$type = CoffeeMaker::validateType($type);
274
+		return $this->coffee_makers->add($coffee_maker, $type);
275
+	}
276
+
277
+
278
+	/**
279
+	 * @param string   $identifier
280
+	 * @param callable $closure
281
+	 * @return callable|null
282
+	 * @throws InvalidIdentifierException
283
+	 * @throws InvalidDataTypeException
284
+	 */
285
+	public function addClosure($identifier, $closure)
286
+	{
287
+		if (! is_callable($closure)) {
288
+			throw new InvalidDataTypeException('$closure', $closure, 'Closure');
289
+		}
290
+		$identifier = $this->processIdentifier($identifier);
291
+		if ($this->reservoir->add($closure, $identifier)) {
292
+			return $closure;
293
+		}
294
+		return null;
295
+	}
296
+
297
+
298
+	/**
299
+	 * @param string $identifier
300
+	 * @return boolean
301
+	 * @throws InvalidIdentifierException
302
+	 */
303
+	public function removeClosure($identifier)
304
+	{
305
+		$identifier = $this->processIdentifier($identifier);
306
+		if ($this->reservoir->has($identifier)) {
307
+			return $this->reservoir->remove($this->reservoir->get($identifier));
308
+		}
309
+		return false;
310
+	}
311
+
312
+
313
+	/**
314
+	 * @param  string $identifier Identifier for the entity class that the service applies to
315
+	 *                            Typically a Fully Qualified Class Name
316
+	 * @param mixed   $service
317
+	 * @return bool
318
+	 * @throws \EventEspresso\core\services\container\exceptions\InvalidServiceException
319
+	 * @throws InvalidIdentifierException
320
+	 */
321
+	public function addService($identifier, $service)
322
+	{
323
+		$identifier = $this->processIdentifier($identifier);
324
+		$service = $this->validateService($identifier, $service);
325
+		return $this->carafe->add($service, $identifier);
326
+	}
327
+
328
+
329
+	/**
330
+	 * @param string $identifier
331
+	 * @return boolean
332
+	 * @throws InvalidIdentifierException
333
+	 */
334
+	public function removeService($identifier)
335
+	{
336
+		$identifier = $this->processIdentifier($identifier);
337
+		if ($this->carafe->has($identifier)) {
338
+			return $this->carafe->remove($this->carafe->get($identifier));
339
+		}
340
+		return false;
341
+	}
342
+
343
+
344
+	/**
345
+	 * Adds instructions on how to brew objects
346
+	 *
347
+	 * @param RecipeInterface $recipe
348
+	 * @return mixed
349
+	 * @throws InvalidIdentifierException
350
+	 */
351
+	public function addRecipe(RecipeInterface $recipe)
352
+	{
353
+		$this->addAliases($recipe->identifier(), $recipe->filters());
354
+		$identifier = $this->processIdentifier($recipe->identifier());
355
+		return $this->recipes->add($recipe, $identifier);
356
+	}
357
+
358
+
359
+	/**
360
+	 * @param string $identifier The Recipe's identifier
361
+	 * @return boolean
362
+	 * @throws InvalidIdentifierException
363
+	 */
364
+	public function removeRecipe($identifier)
365
+	{
366
+		$identifier = $this->processIdentifier($identifier);
367
+		if ($this->recipes->has($identifier)) {
368
+			return $this->recipes->remove($this->recipes->get($identifier));
369
+		}
370
+		return false;
371
+	}
372
+
373
+
374
+	/**
375
+	 * Get instructions on how to brew objects
376
+	 *
377
+	 * @param  string $identifier Identifier for the entity class that the recipe applies to
378
+	 *                            Typically a Fully Qualified Class Name
379
+	 * @param string  $type
380
+	 * @return RecipeInterface
381
+	 * @throws OutOfBoundsException
382
+	 * @throws InvalidIdentifierException
383
+	 */
384
+	public function getRecipe($identifier, $type = '')
385
+	{
386
+		$identifier = $this->processIdentifier($identifier);
387
+		if ($this->recipes->has($identifier)) {
388
+			return $this->recipes->get($identifier);
389
+		}
390
+		$default_recipes = $this->getDefaultRecipes();
391
+		$matches = array();
392
+		foreach ($default_recipes as $wildcard => $default_recipe) {
393
+			// is the wildcard recipe prefix in the identifier ?
394
+			if (strpos($identifier, $wildcard) !== false) {
395
+				// track matches and use the number of wildcard characters matched for the key
396
+				$matches[ strlen($wildcard) ] = $default_recipe;
397
+			}
398
+		}
399
+		if (count($matches) > 0) {
400
+			// sort our recipes by the number of wildcard characters matched
401
+			ksort($matches);
402
+			// then grab the last recipe form the list, since it had the most matching characters
403
+			$match = array_pop($matches);
404
+			// since we are using a default recipe, we need to set it's identifier and fqcn
405
+			return $this->copyDefaultRecipe($match, $identifier, $type);
406
+		}
407
+		if ($this->recipes->has(Recipe::DEFAULT_ID)) {
408
+			// since we are using a default recipe, we need to set it's identifier and fqcn
409
+			return $this->copyDefaultRecipe($this->recipes->get(Recipe::DEFAULT_ID), $identifier, $type);
410
+		}
411
+		throw new OutOfBoundsException(
412
+			sprintf(
413
+				__('Could not brew coffee because no recipes were found for class "%1$s".', 'event_espresso'),
414
+				$identifier
415
+			)
416
+		);
417
+	}
418
+
419
+
420
+	/**
421
+	 * adds class name aliases to list of filters
422
+	 *
423
+	 * @param  string       $identifier Identifier for the entity class that the alias applies to
424
+	 *                                  Typically a Fully Qualified Class Name
425
+	 * @param  array|string $aliases
426
+	 * @return void
427
+	 * @throws InvalidIdentifierException
428
+	 */
429
+	public function addAliases($identifier, $aliases)
430
+	{
431
+		if (empty($aliases)) {
432
+			return;
433
+		}
434
+		$identifier = $this->processIdentifier($identifier);
435
+		foreach ((array) $aliases as $alias) {
436
+			$this->filters[ $this->processIdentifier($alias) ] = $identifier;
437
+		}
438
+	}
439
+
440
+
441
+	/**
442
+	 * Adds a service to one of the internal collections
443
+	 *
444
+	 * @param        $identifier
445
+	 * @param array  $arguments
446
+	 * @param string $type
447
+	 * @return mixed
448
+	 * @throws InvalidDataTypeException
449
+	 * @throws InvalidClassException
450
+	 * @throws OutOfBoundsException
451
+	 * @throws InvalidIdentifierException
452
+	 * @throws ServiceExistsException
453
+	 */
454
+	private function makeCoffee($identifier, $arguments = array(), $type = '')
455
+	{
456
+		if ((empty($type) || $type === CoffeeMaker::BREW_SHARED) && $this->has($identifier)) {
457
+			throw new ServiceExistsException($identifier);
458
+		}
459
+		$identifier = $this->filterIdentifier($identifier);
460
+		$recipe = $this->getRecipe($identifier, $type);
461
+		$type = ! empty($type) ? $type : $recipe->type();
462
+		$coffee_maker = $this->getCoffeeMaker($type);
463
+		return $coffee_maker->brew($recipe, $arguments);
464
+	}
465
+
466
+
467
+	/**
468
+	 * filters alias identifiers to find the real class name
469
+	 *
470
+	 * @param  string $identifier Identifier for the entity class that the filter applies to
471
+	 *                            Typically a Fully Qualified Class Name
472
+	 * @return string
473
+	 * @throws InvalidIdentifierException
474
+	 */
475
+	private function filterIdentifier($identifier)
476
+	{
477
+		$identifier = $this->processIdentifier($identifier);
478
+		return isset($this->filters[ $identifier ]) && ! empty($this->filters[ $identifier ])
479
+			? $this->filters[ $identifier ]
480
+			: $identifier;
481
+	}
482
+
483
+
484
+	/**
485
+	 * verifies and standardizes identifiers
486
+	 *
487
+	 * @param  string $identifier Identifier for the entity class
488
+	 *                            Typically a Fully Qualified Class Name
489
+	 * @return string
490
+	 * @throws InvalidIdentifierException
491
+	 */
492
+	private function processIdentifier($identifier)
493
+	{
494
+		if (! is_string($identifier)) {
495
+			throw new InvalidIdentifierException(
496
+				is_object($identifier) ? get_class($identifier) : gettype($identifier),
497
+				'\Fully\Qualified\ClassName'
498
+			);
499
+		}
500
+		return ltrim($identifier, '\\');
501
+	}
502
+
503
+
504
+	/**
505
+	 * @param string $type
506
+	 * @return CoffeeMakerInterface
507
+	 * @throws OutOfBoundsException
508
+	 * @throws InvalidDataTypeException
509
+	 * @throws InvalidClassException
510
+	 */
511
+	private function getCoffeeMaker($type)
512
+	{
513
+		if (! $this->coffee_makers->has($type)) {
514
+			throw new OutOfBoundsException(
515
+				__('The requested coffee maker is either missing or invalid.', 'event_espresso')
516
+			);
517
+		}
518
+		return $this->coffee_makers->get($type);
519
+	}
520
+
521
+
522
+	/**
523
+	 * Retrieves all recipes that use a wildcard "*" in their identifier
524
+	 * This allows recipes to be set up for handling
525
+	 * legacy classes that do not support PSR-4 autoloading.
526
+	 * for example:
527
+	 * using "EEM_*" for a recipe identifier would target all legacy models like EEM_Attendee
528
+	 *
529
+	 * @return array
530
+	 */
531
+	private function getDefaultRecipes()
532
+	{
533
+		$default_recipes = array();
534
+		$this->recipes->rewind();
535
+		while ($this->recipes->valid()) {
536
+			$identifier = $this->recipes->getInfo();
537
+			// does this recipe use a wildcard ? (but is NOT the global default)
538
+			if ($identifier !== Recipe::DEFAULT_ID && strpos($identifier, '*') !== false) {
539
+				// strip the wildcard and use identifier as key
540
+				$default_recipes[ str_replace('*', '', $identifier) ] = $this->recipes->current();
541
+			}
542
+			$this->recipes->next();
543
+		}
544
+		return $default_recipes;
545
+	}
546
+
547
+
548
+	/**
549
+	 * clones a default recipe and then copies details
550
+	 * from the incoming request to it so that it can be used
551
+	 *
552
+	 * @param RecipeInterface $default_recipe
553
+	 * @param string          $identifier
554
+	 * @param string          $type
555
+	 * @return RecipeInterface
556
+	 */
557
+	private function copyDefaultRecipe(RecipeInterface $default_recipe, $identifier, $type = '')
558
+	{
559
+		$recipe = clone $default_recipe;
560
+		if (! empty($type)) {
561
+			$recipe->setType($type);
562
+		}
563
+		// is this the base default recipe ?
564
+		if ($default_recipe->identifier() === Recipe::DEFAULT_ID) {
565
+			$recipe->setIdentifier($identifier);
566
+			$recipe->setFqcn($identifier);
567
+			return $recipe;
568
+		}
569
+		$recipe->setIdentifier($identifier);
570
+		foreach ($default_recipe->paths() as $path) {
571
+			$path = str_replace('*', $identifier, $path);
572
+			if (is_readable($path)) {
573
+				$recipe->setPaths($path);
574
+			}
575
+		}
576
+		$recipe->setFqcn($identifier);
577
+		return $recipe;
578
+	}
579
+
580
+
581
+	/**
582
+	 * @param  string $identifier Identifier for the entity class that the service applies to
583
+	 *                            Typically a Fully Qualified Class Name
584
+	 * @param mixed   $service
585
+	 * @return mixed
586
+	 * @throws InvalidServiceException
587
+	 */
588
+	private function validateService($identifier, $service)
589
+	{
590
+		if (! is_object($service)) {
591
+			throw new InvalidServiceException(
592
+				$identifier,
593
+				$service
594
+			);
595
+		}
596
+		return $service;
597
+	}
598 598
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
         }
160 160
         // if the reservoir doesn't have a closure already for the requested identifier,
161 161
         // then neither a shared service nor a closure for making entities has been built yet
162
-        if (! $this->reservoir->has($identifier)) {
162
+        if ( ! $this->reservoir->has($identifier)) {
163 163
             // so let's brew something up and add it to the proper collection
164 164
             $brewed = $this->makeCoffee($identifier, $arguments, $type);
165 165
         }
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
      */
285 285
     public function addClosure($identifier, $closure)
286 286
     {
287
-        if (! is_callable($closure)) {
287
+        if ( ! is_callable($closure)) {
288 288
             throw new InvalidDataTypeException('$closure', $closure, 'Closure');
289 289
         }
290 290
         $identifier = $this->processIdentifier($identifier);
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
             // is the wildcard recipe prefix in the identifier ?
394 394
             if (strpos($identifier, $wildcard) !== false) {
395 395
                 // track matches and use the number of wildcard characters matched for the key
396
-                $matches[ strlen($wildcard) ] = $default_recipe;
396
+                $matches[strlen($wildcard)] = $default_recipe;
397 397
             }
398 398
         }
399 399
         if (count($matches) > 0) {
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
         }
434 434
         $identifier = $this->processIdentifier($identifier);
435 435
         foreach ((array) $aliases as $alias) {
436
-            $this->filters[ $this->processIdentifier($alias) ] = $identifier;
436
+            $this->filters[$this->processIdentifier($alias)] = $identifier;
437 437
         }
438 438
     }
439 439
 
@@ -475,8 +475,8 @@  discard block
 block discarded – undo
475 475
     private function filterIdentifier($identifier)
476 476
     {
477 477
         $identifier = $this->processIdentifier($identifier);
478
-        return isset($this->filters[ $identifier ]) && ! empty($this->filters[ $identifier ])
479
-            ? $this->filters[ $identifier ]
478
+        return isset($this->filters[$identifier]) && ! empty($this->filters[$identifier])
479
+            ? $this->filters[$identifier]
480 480
             : $identifier;
481 481
     }
482 482
 
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
      */
492 492
     private function processIdentifier($identifier)
493 493
     {
494
-        if (! is_string($identifier)) {
494
+        if ( ! is_string($identifier)) {
495 495
             throw new InvalidIdentifierException(
496 496
                 is_object($identifier) ? get_class($identifier) : gettype($identifier),
497 497
                 '\Fully\Qualified\ClassName'
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
      */
511 511
     private function getCoffeeMaker($type)
512 512
     {
513
-        if (! $this->coffee_makers->has($type)) {
513
+        if ( ! $this->coffee_makers->has($type)) {
514 514
             throw new OutOfBoundsException(
515 515
                 __('The requested coffee maker is either missing or invalid.', 'event_espresso')
516 516
             );
@@ -537,7 +537,7 @@  discard block
 block discarded – undo
537 537
             // does this recipe use a wildcard ? (but is NOT the global default)
538 538
             if ($identifier !== Recipe::DEFAULT_ID && strpos($identifier, '*') !== false) {
539 539
                 // strip the wildcard and use identifier as key
540
-                $default_recipes[ str_replace('*', '', $identifier) ] = $this->recipes->current();
540
+                $default_recipes[str_replace('*', '', $identifier)] = $this->recipes->current();
541 541
             }
542 542
             $this->recipes->next();
543 543
         }
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
     private function copyDefaultRecipe(RecipeInterface $default_recipe, $identifier, $type = '')
558 558
     {
559 559
         $recipe = clone $default_recipe;
560
-        if (! empty($type)) {
560
+        if ( ! empty($type)) {
561 561
             $recipe->setType($type);
562 562
         }
563 563
         // is this the base default recipe ?
@@ -587,7 +587,7 @@  discard block
 block discarded – undo
587 587
      */
588 588
     private function validateService($identifier, $service)
589 589
     {
590
-        if (! is_object($service)) {
590
+        if ( ! is_object($service)) {
591 591
             throw new InvalidServiceException(
592 592
                 $identifier,
593 593
                 $service
Please login to merge, or discard this patch.
core/interfaces/line_items/EEI_Line_Item_Display.interface.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -9,12 +9,12 @@
 block discarded – undo
9 9
 interface EEI_Line_Item_Display
10 10
 {
11 11
 
12
-    /**
13
-     * @param EE_Line_Item $line_item
14
-     * @param array        $options
15
-     * @return mixed
16
-     */
17
-    public function display_line_item(EE_Line_Item $line_item, $options = array());
12
+	/**
13
+	 * @param EE_Line_Item $line_item
14
+	 * @param array        $options
15
+	 * @return mixed
16
+	 */
17
+	public function display_line_item(EE_Line_Item $line_item, $options = array());
18 18
 
19 19
 }
20 20
 
Please login to merge, or discard this patch.
form_sections/strategies/normalization/EE_Int_Normalization.strategy.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@
 block discarded – undo
17 17
 
18 18
     /**
19 19
      * @param string $value_to_normalize
20
-     * @return int|mixed|string
20
+     * @return null|integer
21 21
      * @throws \EE_Validation_Error
22 22
      */
23 23
     public function normalize($value_to_normalize)
Please login to merge, or discard this patch.
Indentation   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -10,88 +10,88 @@
 block discarded – undo
10 10
 class EE_Int_Normalization extends EE_Normalization_Strategy_Base
11 11
 {
12 12
 
13
-    /*
13
+	/*
14 14
      * regex pattern that matches for the following:
15 15
      *      * optional negative sign
16 16
      *      * one or more digits
17 17
      */
18
-    const REGEX = '/^(-?)(\d+)(?:\.0+)?$/';
18
+	const REGEX = '/^(-?)(\d+)(?:\.0+)?$/';
19 19
 
20 20
 
21 21
 
22
-    /**
23
-     * @param string $value_to_normalize
24
-     * @return int|mixed|string
25
-     * @throws \EE_Validation_Error
26
-     */
27
-    public function normalize($value_to_normalize)
28
-    {
29
-        if ($value_to_normalize === null) {
30
-            return null;
31
-        }
32
-        if (is_int($value_to_normalize) || is_float($value_to_normalize)) {
33
-            return (int) $value_to_normalize;
34
-        }
35
-        if (! is_string($value_to_normalize)) {
36
-            throw new EE_Validation_Error(
37
-                sprintf(
38
-                    __('The value "%s" must be a string submitted for normalization, it was %s', 'event_espresso'),
39
-                    print_r($value_to_normalize, true),
40
-                    gettype($value_to_normalize)
41
-                )
42
-            );
43
-        }
44
-        $value_to_normalize = filter_var(
45
-            $value_to_normalize,
46
-            FILTER_SANITIZE_NUMBER_FLOAT,
47
-            FILTER_FLAG_ALLOW_FRACTION
48
-        );
49
-        if ($value_to_normalize === '') {
50
-            return null;
51
-        }
52
-        $matches = array();
53
-        if (preg_match(EE_Int_Normalization::REGEX, $value_to_normalize, $matches)) {
54
-            if (count($matches) === 3) {
55
-                // if first match is the negative sign,
56
-                // then the number needs to be multiplied by -1 to remain negative
57
-                return $matches[1] === '-'
58
-                    ? (int) $matches[2] * -1
59
-                    : (int) $matches[2];
60
-            }
61
-        }
62
-        // find if this input has a int validation strategy
63
-        // in which case, use its message
64
-        $validation_error_message = null;
65
-        foreach ($this->_input->get_validation_strategies() as $validation_strategy) {
66
-            if ($validation_strategy instanceof EE_Int_Validation_Strategy) {
67
-                $validation_error_message = $validation_strategy->get_validation_error_message();
68
-            }
69
-        }
70
-        // this really shouldn't ever happen because fields with a int normalization strategy
71
-        // should also have a int validation strategy, but in case it doesn't use the default
72
-        if (! $validation_error_message) {
73
-            $default_validation_strategy = new EE_Int_Validation_Strategy();
74
-            $validation_error_message = $default_validation_strategy->get_validation_error_message();
75
-        }
76
-        throw new EE_Validation_Error($validation_error_message, 'numeric_only');
77
-    }
22
+	/**
23
+	 * @param string $value_to_normalize
24
+	 * @return int|mixed|string
25
+	 * @throws \EE_Validation_Error
26
+	 */
27
+	public function normalize($value_to_normalize)
28
+	{
29
+		if ($value_to_normalize === null) {
30
+			return null;
31
+		}
32
+		if (is_int($value_to_normalize) || is_float($value_to_normalize)) {
33
+			return (int) $value_to_normalize;
34
+		}
35
+		if (! is_string($value_to_normalize)) {
36
+			throw new EE_Validation_Error(
37
+				sprintf(
38
+					__('The value "%s" must be a string submitted for normalization, it was %s', 'event_espresso'),
39
+					print_r($value_to_normalize, true),
40
+					gettype($value_to_normalize)
41
+				)
42
+			);
43
+		}
44
+		$value_to_normalize = filter_var(
45
+			$value_to_normalize,
46
+			FILTER_SANITIZE_NUMBER_FLOAT,
47
+			FILTER_FLAG_ALLOW_FRACTION
48
+		);
49
+		if ($value_to_normalize === '') {
50
+			return null;
51
+		}
52
+		$matches = array();
53
+		if (preg_match(EE_Int_Normalization::REGEX, $value_to_normalize, $matches)) {
54
+			if (count($matches) === 3) {
55
+				// if first match is the negative sign,
56
+				// then the number needs to be multiplied by -1 to remain negative
57
+				return $matches[1] === '-'
58
+					? (int) $matches[2] * -1
59
+					: (int) $matches[2];
60
+			}
61
+		}
62
+		// find if this input has a int validation strategy
63
+		// in which case, use its message
64
+		$validation_error_message = null;
65
+		foreach ($this->_input->get_validation_strategies() as $validation_strategy) {
66
+			if ($validation_strategy instanceof EE_Int_Validation_Strategy) {
67
+				$validation_error_message = $validation_strategy->get_validation_error_message();
68
+			}
69
+		}
70
+		// this really shouldn't ever happen because fields with a int normalization strategy
71
+		// should also have a int validation strategy, but in case it doesn't use the default
72
+		if (! $validation_error_message) {
73
+			$default_validation_strategy = new EE_Int_Validation_Strategy();
74
+			$validation_error_message = $default_validation_strategy->get_validation_error_message();
75
+		}
76
+		throw new EE_Validation_Error($validation_error_message, 'numeric_only');
77
+	}
78 78
 
79 79
 
80 80
 
81
-    /**
82
-     * Converts the int into a string for use in teh html form
83
-     *
84
-     * @param int $normalized_value
85
-     * @return string
86
-     */
87
-    public function unnormalize($normalized_value)
88
-    {
89
-        if ($normalized_value === null || $normalized_value === '') {
90
-            return '';
91
-        }
92
-        if (empty($normalized_value)) {
93
-            return '0';
94
-        }
95
-        return "$normalized_value";
96
-    }
81
+	/**
82
+	 * Converts the int into a string for use in teh html form
83
+	 *
84
+	 * @param int $normalized_value
85
+	 * @return string
86
+	 */
87
+	public function unnormalize($normalized_value)
88
+	{
89
+		if ($normalized_value === null || $normalized_value === '') {
90
+			return '';
91
+		}
92
+		if (empty($normalized_value)) {
93
+			return '0';
94
+		}
95
+		return "$normalized_value";
96
+	}
97 97
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
         if (is_int($value_to_normalize) || is_float($value_to_normalize)) {
33 33
             return (int) $value_to_normalize;
34 34
         }
35
-        if (! is_string($value_to_normalize)) {
35
+        if ( ! is_string($value_to_normalize)) {
36 36
             throw new EE_Validation_Error(
37 37
                 sprintf(
38 38
                     __('The value "%s" must be a string submitted for normalization, it was %s', 'event_espresso'),
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
         }
70 70
         // this really shouldn't ever happen because fields with a int normalization strategy
71 71
         // should also have a int validation strategy, but in case it doesn't use the default
72
-        if (! $validation_error_message) {
72
+        if ( ! $validation_error_message) {
73 73
             $default_validation_strategy = new EE_Int_Validation_Strategy();
74 74
             $validation_error_message = $default_validation_strategy->get_validation_error_message();
75 75
         }
Please login to merge, or discard this patch.
core/db_models/EEM_Event.model.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -217,7 +217,7 @@
 block discarded – undo
217 217
 
218 218
     /**
219 219
      * Used to override the default for the additional limit field.
220
-     * @param $additional_limit
220
+     * @param integer $additional_limit
221 221
      */
222 222
     public static function set_default_additional_limit($additional_limit)
223 223
     {
Please login to merge, or discard this patch.
Unused Use Statements   -2 removed lines patch added patch discarded remove patch
@@ -1,7 +1,5 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-use EventEspresso\core\services\orm\ModelFieldFactory;
4
-
5 3
 /**
6 4
  * EEM_Event Model
7 5
  * extends EEM_CPT_Base which extends EEM_Base
Please login to merge, or discard this patch.
Indentation   +873 added lines, -873 removed lines patch added patch discarded remove patch
@@ -13,877 +13,877 @@
 block discarded – undo
13 13
 class EEM_Event extends EEM_CPT_Base
14 14
 {
15 15
 
16
-    /**
17
-     * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
18
-     * event
19
-     */
20
-    const sold_out = 'sold_out';
21
-
22
-    /**
23
-     * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
24
-     * date)
25
-     */
26
-    const postponed = 'postponed';
27
-
28
-    /**
29
-     * constant used by status(), indicating that the event will no longer occur
30
-     */
31
-    const cancelled = 'cancelled';
32
-
33
-
34
-    /**
35
-     * @var string
36
-     */
37
-    protected static $_default_reg_status;
38
-
39
-
40
-    /**
41
-     * This is the default for the additional limit field.
42
-     * @var int
43
-     */
44
-    protected static $_default_additional_limit = 10;
45
-
46
-
47
-    /**
48
-     * private instance of the Event object
49
-     *
50
-     * @var EEM_Event
51
-     */
52
-    protected static $_instance;
53
-
54
-
55
-
56
-
57
-    /**
58
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
59
-     *
60
-     * @param string $timezone
61
-     * @throws \EE_Error
62
-     */
63
-    protected function __construct($timezone = null)
64
-    {
65
-        EE_Registry::instance()->load_model('Registration');
66
-        $this->singular_item = esc_html__('Event', 'event_espresso');
67
-        $this->plural_item = esc_html__('Events', 'event_espresso');
68
-        // to remove Cancelled events from the frontend, copy the following filter to your functions.php file
69
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
70
-        // to remove Postponed events from the frontend, copy the following filter to your functions.php file
71
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
72
-        // to remove Sold Out events from the frontend, copy the following filter to your functions.php file
73
-        //  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
74
-        $this->_custom_stati = apply_filters(
75
-            'AFEE__EEM_Event__construct___custom_stati',
76
-            array(
77
-                EEM_Event::cancelled => array(
78
-                    'label'  => esc_html__('Cancelled', 'event_espresso'),
79
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
80
-                ),
81
-                EEM_Event::postponed => array(
82
-                    'label'  => esc_html__('Postponed', 'event_espresso'),
83
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
84
-                ),
85
-                EEM_Event::sold_out  => array(
86
-                    'label'  => esc_html__('Sold Out', 'event_espresso'),
87
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
88
-                ),
89
-            )
90
-        );
91
-        self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
92
-            : self::$_default_reg_status;
93
-        $this->_tables = array(
94
-            'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
95
-            'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
96
-        );
97
-        $this->_fields = array(
98
-            'Event_CPT'  => array(
99
-                'EVT_ID'         => new EE_Primary_Key_Int_Field(
100
-                    'ID',
101
-                    esc_html__('Post ID for Event', 'event_espresso')
102
-                ),
103
-                'EVT_name'       => new EE_Plain_Text_Field(
104
-                    'post_title',
105
-                    esc_html__('Event Name', 'event_espresso'),
106
-                    false,
107
-                    ''
108
-                ),
109
-                'EVT_desc'       => new EE_Post_Content_Field(
110
-                    'post_content',
111
-                    esc_html__('Event Description', 'event_espresso'),
112
-                    false,
113
-                    ''
114
-                ),
115
-                'EVT_slug'       => new EE_Slug_Field(
116
-                    'post_name',
117
-                    esc_html__('Event Slug', 'event_espresso'),
118
-                    false,
119
-                    ''
120
-                ),
121
-                'EVT_created'    => new EE_Datetime_Field(
122
-                    'post_date',
123
-                    esc_html__('Date/Time Event Created', 'event_espresso'),
124
-                    false,
125
-                    EE_Datetime_Field::now
126
-                ),
127
-                'EVT_short_desc' => new EE_Simple_HTML_Field(
128
-                    'post_excerpt',
129
-                    esc_html__('Event Short Description', 'event_espresso'),
130
-                    false,
131
-                    ''
132
-                ),
133
-                'EVT_modified'   => new EE_Datetime_Field(
134
-                    'post_modified',
135
-                    esc_html__('Date/Time Event Modified', 'event_espresso'),
136
-                    false,
137
-                    EE_Datetime_Field::now
138
-                ),
139
-                'EVT_wp_user'    => new EE_WP_User_Field(
140
-                    'post_author',
141
-                    esc_html__('Event Creator ID', 'event_espresso'),
142
-                    false
143
-                ),
144
-                'parent'         => new EE_Integer_Field(
145
-                    'post_parent',
146
-                    esc_html__('Event Parent ID', 'event_espresso'),
147
-                    false,
148
-                    0
149
-                ),
150
-                'EVT_order'      => new EE_Integer_Field(
151
-                    'menu_order',
152
-                    esc_html__('Event Menu Order', 'event_espresso'),
153
-                    false,
154
-                    1
155
-                ),
156
-                'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
157
-                // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
158
-                'status'         => new EE_WP_Post_Status_Field(
159
-                    'post_status',
160
-                    esc_html__('Event Status', 'event_espresso'),
161
-                    false,
162
-                    'draft',
163
-                    $this->_custom_stati
164
-                ),
165
-            ),
166
-            'Event_Meta' => array(
167
-                'EVTM_ID'                         => new EE_DB_Only_Float_Field(
168
-                    'EVTM_ID',
169
-                    esc_html__('Event Meta Row ID', 'event_espresso'),
170
-                    false
171
-                ),
172
-                'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
173
-                    'EVT_ID',
174
-                    esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
175
-                    false
176
-                ),
177
-                'EVT_display_desc'                => new EE_Boolean_Field(
178
-                    'EVT_display_desc',
179
-                    esc_html__('Display Description Flag', 'event_espresso'),
180
-                    false,
181
-                    1
182
-                ),
183
-                'EVT_display_ticket_selector'     => new EE_Boolean_Field(
184
-                    'EVT_display_ticket_selector',
185
-                    esc_html__('Display Ticket Selector Flag', 'event_espresso'),
186
-                    false,
187
-                    1
188
-                ),
189
-                'EVT_visible_on'                  => new EE_Datetime_Field(
190
-                    'EVT_visible_on',
191
-                    esc_html__('Event Visible Date', 'event_espresso'),
192
-                    true,
193
-                    EE_Datetime_Field::now
194
-                ),
195
-                'EVT_additional_limit'            => new EE_Integer_Field(
196
-                    'EVT_additional_limit',
197
-                    esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
198
-                    true,
199
-                    self::$_default_additional_limit
200
-                ),
201
-                'EVT_default_registration_status' => new EE_Enum_Text_Field(
202
-                    'EVT_default_registration_status',
203
-                    esc_html__('Default Registration Status on this Event', 'event_espresso'),
204
-                    false,
205
-                    EEM_Event::$_default_reg_status,
206
-                    EEM_Registration::reg_status_array()
207
-                ),
208
-                'EVT_member_only'                 => new EE_Boolean_Field(
209
-                    'EVT_member_only',
210
-                    esc_html__('Member-Only Event Flag', 'event_espresso'),
211
-                    false,
212
-                    false
213
-                ),
214
-                'EVT_phone'                       => new EE_Plain_Text_Field(
215
-                    'EVT_phone',
216
-                    esc_html__('Event Phone Number', 'event_espresso'),
217
-                    false,
218
-                    ''
219
-                ),
220
-                'EVT_allow_overflow'              => new EE_Boolean_Field(
221
-                    'EVT_allow_overflow',
222
-                    esc_html__('Allow Overflow on Event', 'event_espresso'),
223
-                    false,
224
-                    false
225
-                ),
226
-                'EVT_timezone_string'             => new EE_Plain_Text_Field(
227
-                    'EVT_timezone_string',
228
-                    esc_html__('Timezone (name) for Event times', 'event_espresso'),
229
-                    false,
230
-                    ''
231
-                ),
232
-                'EVT_external_URL'                => new EE_Plain_Text_Field(
233
-                    'EVT_external_URL',
234
-                    esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
235
-                    true
236
-                ),
237
-                'EVT_donations'                   => new EE_Boolean_Field(
238
-                    'EVT_donations',
239
-                    esc_html__('Accept Donations?', 'event_espresso'),
240
-                    false,
241
-                    false
242
-                ),
243
-            ),
244
-        );
245
-        $this->_model_relations = array(
246
-            'Registration'           => new EE_Has_Many_Relation(),
247
-            'Datetime'               => new EE_Has_Many_Relation(),
248
-            'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
249
-            'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
250
-            'Term_Relationship'      => new EE_Has_Many_Relation(),
251
-            'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
252
-            'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
253
-            'Attendee'               => new EE_HABTM_Relation('Registration'),
254
-            'WP_User'                => new EE_Belongs_To_Relation(),
255
-        );
256
-        // this model is generally available for reading
257
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
258
-        parent::__construct($timezone);
259
-    }
260
-
261
-
262
-
263
-    /**
264
-     * @param string $default_reg_status
265
-     */
266
-    public static function set_default_reg_status($default_reg_status)
267
-    {
268
-        self::$_default_reg_status = $default_reg_status;
269
-        // if EEM_Event has already been instantiated,
270
-        // then we need to reset the `EVT_default_reg_status` field to use the new default.
271
-        if (self::$_instance instanceof EEM_Event) {
272
-            $default_reg_status = new EE_Enum_Text_Field(
273
-                'EVT_default_registration_status',
274
-                esc_html__('Default Registration Status on this Event', 'event_espresso'),
275
-                false,
276
-                $default_reg_status,
277
-                EEM_Registration::reg_status_array()
278
-            );
279
-            $default_reg_status->_construct_finalize(
280
-                'Event_Meta',
281
-                'EVT_default_registration_status',
282
-                'EEM_Event'
283
-            );
284
-            self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
285
-        }
286
-    }
287
-
288
-
289
-    /**
290
-     * Used to override the default for the additional limit field.
291
-     * @param $additional_limit
292
-     */
293
-    public static function set_default_additional_limit($additional_limit)
294
-    {
295
-        self::$_default_additional_limit = (int) $additional_limit;
296
-        if (self::$_instance instanceof EEM_Event) {
297
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
298
-                'EVT_additional_limit',
299
-                __('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
300
-                true,
301
-                self::$_default_additional_limit
302
-            );
303
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
304
-                'Event_Meta',
305
-                'EVT_additional_limit',
306
-                'EEM_Event'
307
-            );
308
-        }
309
-    }
310
-
311
-
312
-    /**
313
-     * Return what is currently set as the default additional limit for the event.
314
-     * @return int
315
-     */
316
-    public static function get_default_additional_limit()
317
-    {
318
-        return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
319
-    }
320
-
321
-
322
-    /**
323
-     * get_question_groups
324
-     *
325
-     * @return array
326
-     * @throws \EE_Error
327
-     */
328
-    public function get_all_question_groups()
329
-    {
330
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
331
-            array(
332
-                array('QSG_deleted' => false),
333
-                'order_by' => array('QSG_order' => 'ASC'),
334
-            )
335
-        );
336
-    }
337
-
338
-
339
-
340
-    /**
341
-     * get_question_groups
342
-     *
343
-     * @param int $EVT_ID
344
-     * @return array|bool
345
-     * @throws \EE_Error
346
-     */
347
-    public function get_all_event_question_groups($EVT_ID = 0)
348
-    {
349
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
350
-            EE_Error::add_error(
351
-                esc_html__(
352
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
353
-                    'event_espresso'
354
-                ),
355
-                __FILE__,
356
-                __FUNCTION__,
357
-                __LINE__
358
-            );
359
-            return false;
360
-        }
361
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
362
-            array(
363
-                array('EVT_ID' => $EVT_ID),
364
-            )
365
-        );
366
-    }
367
-
368
-
369
-
370
-    /**
371
-     * get_question_groups
372
-     *
373
-     * @param int     $EVT_ID
374
-     * @param boolean $for_primary_attendee
375
-     * @return array|bool
376
-     * @throws \EE_Error
377
-     */
378
-    public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
379
-    {
380
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
381
-            EE_Error::add_error(
382
-                esc_html__(
383
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
384
-                    'event_espresso'
385
-                ),
386
-                __FILE__,
387
-                __FUNCTION__,
388
-                __LINE__
389
-            );
390
-            return false;
391
-        }
392
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
393
-            array(
394
-                array(
395
-                    'EVT_ID'      => $EVT_ID,
396
-                    'EQG_primary' => $for_primary_attendee,
397
-                ),
398
-            )
399
-        );
400
-    }
401
-
402
-
403
-
404
-    /**
405
-     * get_question_groups
406
-     *
407
-     * @param int             $EVT_ID
408
-     * @param EE_Registration $registration
409
-     * @return array|bool
410
-     * @throws \EE_Error
411
-     */
412
-    public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
413
-    {
414
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
415
-            EE_Error::add_error(
416
-                esc_html__(
417
-                    'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
418
-                    'event_espresso'
419
-                ),
420
-                __FILE__,
421
-                __FUNCTION__,
422
-                __LINE__
423
-            );
424
-            return false;
425
-        }
426
-        $where_params = array(
427
-            'Event_Question_Group.EVT_ID'      => $EVT_ID,
428
-            'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false,
429
-            'QSG_deleted'                      => false,
430
-        );
431
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
432
-            array(
433
-                $where_params,
434
-                'order_by' => array('QSG_order' => 'ASC'),
435
-            )
436
-        );
437
-    }
438
-
439
-
440
-
441
-    /**
442
-     * get_question_target_db_column
443
-     *
444
-     * @param string $QSG_IDs csv list of $QSG IDs
445
-     * @return array|bool
446
-     * @throws \EE_Error
447
-     */
448
-    public function get_questions_in_groups($QSG_IDs = '')
449
-    {
450
-        if (empty($QSG_IDs)) {
451
-            EE_Error::add_error(
452
-                esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
453
-                __FILE__,
454
-                __FUNCTION__,
455
-                __LINE__
456
-            );
457
-            return false;
458
-        }
459
-        return EE_Registry::instance()->load_model('Question')->get_all(
460
-            array(
461
-                array(
462
-                    'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
463
-                    'QST_deleted'           => false,
464
-                    'QST_admin_only'        => is_admin(),
465
-                ),
466
-                'order_by' => 'QST_order',
467
-            )
468
-        );
469
-    }
470
-
471
-
472
-
473
-    /**
474
-     * get_options_for_question
475
-     *
476
-     * @param string $QST_IDs csv list of $QST IDs
477
-     * @return array|bool
478
-     * @throws \EE_Error
479
-     */
480
-    public function get_options_for_question($QST_IDs)
481
-    {
482
-        if (empty($QST_IDs)) {
483
-            EE_Error::add_error(
484
-                esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
485
-                __FILE__,
486
-                __FUNCTION__,
487
-                __LINE__
488
-            );
489
-            return false;
490
-        }
491
-        return EE_Registry::instance()->load_model('Question_Option')->get_all(
492
-            array(
493
-                array(
494
-                    'Question.QST_ID' => array('IN', $QST_IDs),
495
-                    'QSO_deleted'     => false,
496
-                ),
497
-                'order_by' => 'QSO_ID',
498
-            )
499
-        );
500
-    }
501
-
502
-
503
-
504
-
505
-
506
-
507
-
508
-    /**
509
-     * Gets all events that are published
510
-     * and have event start time earlier than now and an event end time later than now
511
-     *
512
-     * @param  array $query_params An array of query params to further filter on
513
-     *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
514
-     * @param bool   $count        whether to return the count or not (default FALSE)
515
-     * @return EE_Event[]|int
516
-     * @throws \EE_Error
517
-     */
518
-    public function get_active_events($query_params, $count = false)
519
-    {
520
-        if (array_key_exists(0, $query_params)) {
521
-            $where_params = $query_params[0];
522
-            unset($query_params[0]);
523
-        } else {
524
-            $where_params = array();
525
-        }
526
-        // if we have count make sure we don't include group by
527
-        if ($count && isset($query_params['group_by'])) {
528
-            unset($query_params['group_by']);
529
-        }
530
-        // let's add specific query_params for active_events
531
-        // keep in mind this will override any sent status in the query AND any date queries.
532
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
533
-        // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
534
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
535
-            $where_params['Datetime.DTT_EVT_start******'] = array(
536
-                '<',
537
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
538
-            );
539
-        } else {
540
-            $where_params['Datetime.DTT_EVT_start'] = array(
541
-                '<',
542
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
543
-            );
544
-        }
545
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
546
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
547
-                '>',
548
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
549
-            );
550
-        } else {
551
-            $where_params['Datetime.DTT_EVT_end'] = array(
552
-                '>',
553
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
554
-            );
555
-        }
556
-        $query_params[0] = $where_params;
557
-        // don't use $query_params with count()
558
-        // because we don't want to include additional query clauses like "GROUP BY"
559
-        return $count
560
-            ? $this->count(array($where_params), 'EVT_ID', true)
561
-            : $this->get_all($query_params);
562
-    }
563
-
564
-
565
-
566
-    /**
567
-     * get all events that are published and have an event start time later than now
568
-     *
569
-     * @param  array $query_params An array of query params to further filter on
570
-     *                             (Note that status and DTT_EVT_start will be overridden)
571
-     * @param bool   $count        whether to return the count or not (default FALSE)
572
-     * @return EE_Event[]|int
573
-     * @throws \EE_Error
574
-     */
575
-    public function get_upcoming_events($query_params, $count = false)
576
-    {
577
-        if (array_key_exists(0, $query_params)) {
578
-            $where_params = $query_params[0];
579
-            unset($query_params[0]);
580
-        } else {
581
-            $where_params = array();
582
-        }
583
-        // if we have count make sure we don't include group by
584
-        if ($count && isset($query_params['group_by'])) {
585
-            unset($query_params['group_by']);
586
-        }
587
-        // let's add specific query_params for active_events
588
-        // keep in mind this will override any sent status in the query AND any date queries.
589
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
590
-        // if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
591
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
592
-            $where_params['Datetime.DTT_EVT_start*****'] = array(
593
-                '>',
594
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
595
-            );
596
-        } else {
597
-            $where_params['Datetime.DTT_EVT_start'] = array(
598
-                '>',
599
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
600
-            );
601
-        }
602
-        $query_params[0] = $where_params;
603
-        // don't use $query_params with count()
604
-        // because we don't want to include additional query clauses like "GROUP BY"
605
-        return $count
606
-            ? $this->count(array($where_params), 'EVT_ID', true)
607
-            : $this->get_all($query_params);
608
-    }
609
-
610
-
611
-
612
-    /**
613
-     * Gets all events that are published
614
-     * and have an event end time later than now
615
-     *
616
-     * @param  array $query_params An array of query params to further filter on
617
-     *                             (note that status and DTT_EVT_end will be overridden)
618
-     * @param bool   $count        whether to return the count or not (default FALSE)
619
-     * @return EE_Event[]|int
620
-     * @throws \EE_Error
621
-     */
622
-    public function get_active_and_upcoming_events($query_params, $count = false)
623
-    {
624
-        if (array_key_exists(0, $query_params)) {
625
-            $where_params = $query_params[0];
626
-            unset($query_params[0]);
627
-        } else {
628
-            $where_params = array();
629
-        }
630
-        // if we have count make sure we don't include group by
631
-        if ($count && isset($query_params['group_by'])) {
632
-            unset($query_params['group_by']);
633
-        }
634
-        // let's add specific query_params for active_events
635
-        // keep in mind this will override any sent status in the query AND any date queries.
636
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
637
-        // add where params for DTT_EVT_end
638
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
639
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
640
-                '>',
641
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
642
-            );
643
-        } else {
644
-            $where_params['Datetime.DTT_EVT_end'] = array(
645
-                '>',
646
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
647
-            );
648
-        }
649
-        $query_params[0] = $where_params;
650
-        // don't use $query_params with count()
651
-        // because we don't want to include additional query clauses like "GROUP BY"
652
-        return $count
653
-            ? $this->count(array($where_params), 'EVT_ID', true)
654
-            : $this->get_all($query_params);
655
-    }
656
-
657
-
658
-
659
-    /**
660
-     * This only returns events that are expired.
661
-     * They may still be published but all their datetimes have expired.
662
-     *
663
-     * @param  array $query_params An array of query params to further filter on
664
-     *                             (note that status and DTT_EVT_end will be overridden)
665
-     * @param bool   $count        whether to return the count or not (default FALSE)
666
-     * @return EE_Event[]|int
667
-     * @throws \EE_Error
668
-     */
669
-    public function get_expired_events($query_params, $count = false)
670
-    {
671
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
672
-        // if we have count make sure we don't include group by
673
-        if ($count && isset($query_params['group_by'])) {
674
-            unset($query_params['group_by']);
675
-        }
676
-        // let's add specific query_params for active_events
677
-        // keep in mind this will override any sent status in the query AND any date queries.
678
-        if (isset($where_params['status'])) {
679
-            unset($where_params['status']);
680
-        }
681
-        $exclude_query = $query_params;
682
-        if (isset($exclude_query[0])) {
683
-            unset($exclude_query[0]);
684
-        }
685
-        $exclude_query[0] = array(
686
-            'Datetime.DTT_EVT_end' => array(
687
-                '>',
688
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
689
-            ),
690
-        );
691
-        // first get all events that have datetimes where its not expired.
692
-        $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
693
-        $event_ids = array_keys($event_ids);
694
-        // if we have any additional query_params, let's add them to the 'AND' condition
695
-        $and_condition = array(
696
-            'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
697
-            'EVT_ID'               => array('NOT IN', $event_ids),
698
-        );
699
-        if (isset($where_params['OR'])) {
700
-            $and_condition['OR'] = $where_params['OR'];
701
-            unset($where_params['OR']);
702
-        }
703
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
704
-            $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
705
-            unset($where_params['Datetime.DTT_EVT_end']);
706
-        }
707
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
708
-            $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
709
-            unset($where_params['Datetime.DTT_EVT_start']);
710
-        }
711
-        // merge remaining $where params with the and conditions.
712
-        $where_params['AND'] = array_merge($and_condition, $where_params);
713
-        $query_params[0] = $where_params;
714
-        // don't use $query_params with count()
715
-        // because we don't want to include additional query clauses like "GROUP BY"
716
-        return $count
717
-            ? $this->count(array($where_params), 'EVT_ID', true)
718
-            : $this->get_all($query_params);
719
-    }
720
-
721
-
722
-
723
-    /**
724
-     * This basically just returns the events that do not have the publish status.
725
-     *
726
-     * @param  array   $query_params An array of query params to further filter on
727
-     *                               (note that status will be overwritten)
728
-     * @param  boolean $count        whether to return the count or not (default FALSE)
729
-     * @return EE_Event[]|int
730
-     * @throws \EE_Error
731
-     */
732
-    public function get_inactive_events($query_params, $count = false)
733
-    {
734
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
735
-        // let's add in specific query_params for inactive events.
736
-        if (isset($where_params['status'])) {
737
-            unset($where_params['status']);
738
-        }
739
-        // if we have count make sure we don't include group by
740
-        if ($count && isset($query_params['group_by'])) {
741
-            unset($query_params['group_by']);
742
-        }
743
-        // if we have any additional query_params, let's add them to the 'AND' condition
744
-        $where_params['AND']['status'] = array('!=', 'publish');
745
-        if (isset($where_params['OR'])) {
746
-            $where_params['AND']['OR'] = $where_params['OR'];
747
-            unset($where_params['OR']);
748
-        }
749
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
750
-            $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
751
-            unset($where_params['Datetime.DTT_EVT_end']);
752
-        }
753
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
754
-            $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
755
-            unset($where_params['Datetime.DTT_EVT_start']);
756
-        }
757
-        $query_params[0] = $where_params;
758
-        // don't use $query_params with count()
759
-        // because we don't want to include additional query clauses like "GROUP BY"
760
-        return $count
761
-            ? $this->count(array($where_params), 'EVT_ID', true)
762
-            : $this->get_all($query_params);
763
-    }
764
-
765
-
766
-
767
-    /**
768
-     * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
769
-     * because we don't want to override any existing global default prices but instead insert NEW prices that get
770
-     * attached to the event. See parent for param descriptions
771
-     *
772
-     * @param        $id_or_obj
773
-     * @param        $other_model_id_or_obj
774
-     * @param string $relationName
775
-     * @param array  $where_query
776
-     * @return EE_Base_Class
777
-     * @throws EE_Error
778
-     */
779
-    public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
780
-    {
781
-        if ($relationName === 'Price') {
782
-            // let's get the PRC object for the given ID to make sure that we aren't dealing with a default
783
-            $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
784
-            // if EVT_ID = 0, then this is a default
785
-            if ((int) $prc_chk->get('EVT_ID') === 0) {
786
-                // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
787
-                $prc_chk->set('PRC_ID', 0);
788
-            }
789
-            // run parent
790
-            return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
791
-        }
792
-        // otherwise carry on as normal
793
-        return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
794
-    }
795
-
796
-
797
-
798
-    /******************** DEPRECATED METHODS ********************/
799
-
800
-
801
-
802
-    /**
803
-     * _get_question_target_db_column
804
-     *
805
-     * @deprecated as of 4.8.32.rc.001. Instead consider using
806
-     *             EE_Registration_Custom_Questions_Form located in
807
-     *             admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
808
-     * @access     public
809
-     * @param    EE_Registration $registration (so existing answers for registration are included)
810
-     * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
811
-     *                                         registration).
812
-     * @throws EE_Error
813
-     * @return    array
814
-     */
815
-    public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
816
-    {
817
-        if (empty($EVT_ID)) {
818
-            throw new EE_Error(__(
819
-                'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
820
-                'event_espresso'
821
-            ));
822
-        }
823
-        $questions = array();
824
-        // get all question groups for event
825
-        $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
826
-        if (! empty($qgs)) {
827
-            foreach ($qgs as $qg) {
828
-                $qsts = $qg->questions();
829
-                $questions[ $qg->ID() ] = $qg->model_field_array();
830
-                $questions[ $qg->ID() ]['QSG_questions'] = array();
831
-                foreach ($qsts as $qst) {
832
-                    if ($qst->is_system_question()) {
833
-                        continue;
834
-                    }
835
-                    $answer = EEM_Answer::instance()->get_one(array(
836
-                        array(
837
-                            'QST_ID' => $qst->ID(),
838
-                            'REG_ID' => $registration->ID(),
839
-                        ),
840
-                    ));
841
-                    $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
842
-                    $qst_name = $qstn_id = $qst->ID();
843
-                    $ans_id = $answer->ID();
844
-                    $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
845
-                    $input_name = '';
846
-                    $input_id = sanitize_key($qst->display_text());
847
-                    $input_class = '';
848
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
849
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
850
-                                                                                           . $input_name
851
-                                                                                           . $qst_name;
852
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
853
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
854
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
855
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
856
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
857
-                    // leave responses as-is, don't convert stuff into html entities please!
858
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
859
-                    if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
860
-                        $QSOs = $qst->options(true, $answer->value());
861
-                        if (is_array($QSOs)) {
862
-                            foreach ($QSOs as $QSO_ID => $QSO) {
863
-                                $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
864
-                            }
865
-                        }
866
-                    }
867
-                }
868
-            }
869
-        }
870
-        return $questions;
871
-    }
872
-
873
-
874
-    /**
875
-     * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
876
-     *                             or an stdClass where each property is the name of a column,
877
-     * @return EE_Base_Class
878
-     * @throws \EE_Error
879
-     */
880
-    public function instantiate_class_from_array_or_object($cols_n_values)
881
-    {
882
-        $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
883
-        if ($classInstance instanceof EE_Event) {
884
-            // events have their timezone defined in the DB, so use it immediately
885
-            $this->set_timezone($classInstance->get_timezone());
886
-        }
887
-        return $classInstance;
888
-    }
16
+	/**
17
+	 * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
18
+	 * event
19
+	 */
20
+	const sold_out = 'sold_out';
21
+
22
+	/**
23
+	 * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
24
+	 * date)
25
+	 */
26
+	const postponed = 'postponed';
27
+
28
+	/**
29
+	 * constant used by status(), indicating that the event will no longer occur
30
+	 */
31
+	const cancelled = 'cancelled';
32
+
33
+
34
+	/**
35
+	 * @var string
36
+	 */
37
+	protected static $_default_reg_status;
38
+
39
+
40
+	/**
41
+	 * This is the default for the additional limit field.
42
+	 * @var int
43
+	 */
44
+	protected static $_default_additional_limit = 10;
45
+
46
+
47
+	/**
48
+	 * private instance of the Event object
49
+	 *
50
+	 * @var EEM_Event
51
+	 */
52
+	protected static $_instance;
53
+
54
+
55
+
56
+
57
+	/**
58
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
59
+	 *
60
+	 * @param string $timezone
61
+	 * @throws \EE_Error
62
+	 */
63
+	protected function __construct($timezone = null)
64
+	{
65
+		EE_Registry::instance()->load_model('Registration');
66
+		$this->singular_item = esc_html__('Event', 'event_espresso');
67
+		$this->plural_item = esc_html__('Events', 'event_espresso');
68
+		// to remove Cancelled events from the frontend, copy the following filter to your functions.php file
69
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
70
+		// to remove Postponed events from the frontend, copy the following filter to your functions.php file
71
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
72
+		// to remove Sold Out events from the frontend, copy the following filter to your functions.php file
73
+		//  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
74
+		$this->_custom_stati = apply_filters(
75
+			'AFEE__EEM_Event__construct___custom_stati',
76
+			array(
77
+				EEM_Event::cancelled => array(
78
+					'label'  => esc_html__('Cancelled', 'event_espresso'),
79
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
80
+				),
81
+				EEM_Event::postponed => array(
82
+					'label'  => esc_html__('Postponed', 'event_espresso'),
83
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
84
+				),
85
+				EEM_Event::sold_out  => array(
86
+					'label'  => esc_html__('Sold Out', 'event_espresso'),
87
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
88
+				),
89
+			)
90
+		);
91
+		self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
92
+			: self::$_default_reg_status;
93
+		$this->_tables = array(
94
+			'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
95
+			'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
96
+		);
97
+		$this->_fields = array(
98
+			'Event_CPT'  => array(
99
+				'EVT_ID'         => new EE_Primary_Key_Int_Field(
100
+					'ID',
101
+					esc_html__('Post ID for Event', 'event_espresso')
102
+				),
103
+				'EVT_name'       => new EE_Plain_Text_Field(
104
+					'post_title',
105
+					esc_html__('Event Name', 'event_espresso'),
106
+					false,
107
+					''
108
+				),
109
+				'EVT_desc'       => new EE_Post_Content_Field(
110
+					'post_content',
111
+					esc_html__('Event Description', 'event_espresso'),
112
+					false,
113
+					''
114
+				),
115
+				'EVT_slug'       => new EE_Slug_Field(
116
+					'post_name',
117
+					esc_html__('Event Slug', 'event_espresso'),
118
+					false,
119
+					''
120
+				),
121
+				'EVT_created'    => new EE_Datetime_Field(
122
+					'post_date',
123
+					esc_html__('Date/Time Event Created', 'event_espresso'),
124
+					false,
125
+					EE_Datetime_Field::now
126
+				),
127
+				'EVT_short_desc' => new EE_Simple_HTML_Field(
128
+					'post_excerpt',
129
+					esc_html__('Event Short Description', 'event_espresso'),
130
+					false,
131
+					''
132
+				),
133
+				'EVT_modified'   => new EE_Datetime_Field(
134
+					'post_modified',
135
+					esc_html__('Date/Time Event Modified', 'event_espresso'),
136
+					false,
137
+					EE_Datetime_Field::now
138
+				),
139
+				'EVT_wp_user'    => new EE_WP_User_Field(
140
+					'post_author',
141
+					esc_html__('Event Creator ID', 'event_espresso'),
142
+					false
143
+				),
144
+				'parent'         => new EE_Integer_Field(
145
+					'post_parent',
146
+					esc_html__('Event Parent ID', 'event_espresso'),
147
+					false,
148
+					0
149
+				),
150
+				'EVT_order'      => new EE_Integer_Field(
151
+					'menu_order',
152
+					esc_html__('Event Menu Order', 'event_espresso'),
153
+					false,
154
+					1
155
+				),
156
+				'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
157
+				// EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
158
+				'status'         => new EE_WP_Post_Status_Field(
159
+					'post_status',
160
+					esc_html__('Event Status', 'event_espresso'),
161
+					false,
162
+					'draft',
163
+					$this->_custom_stati
164
+				),
165
+			),
166
+			'Event_Meta' => array(
167
+				'EVTM_ID'                         => new EE_DB_Only_Float_Field(
168
+					'EVTM_ID',
169
+					esc_html__('Event Meta Row ID', 'event_espresso'),
170
+					false
171
+				),
172
+				'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
173
+					'EVT_ID',
174
+					esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
175
+					false
176
+				),
177
+				'EVT_display_desc'                => new EE_Boolean_Field(
178
+					'EVT_display_desc',
179
+					esc_html__('Display Description Flag', 'event_espresso'),
180
+					false,
181
+					1
182
+				),
183
+				'EVT_display_ticket_selector'     => new EE_Boolean_Field(
184
+					'EVT_display_ticket_selector',
185
+					esc_html__('Display Ticket Selector Flag', 'event_espresso'),
186
+					false,
187
+					1
188
+				),
189
+				'EVT_visible_on'                  => new EE_Datetime_Field(
190
+					'EVT_visible_on',
191
+					esc_html__('Event Visible Date', 'event_espresso'),
192
+					true,
193
+					EE_Datetime_Field::now
194
+				),
195
+				'EVT_additional_limit'            => new EE_Integer_Field(
196
+					'EVT_additional_limit',
197
+					esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
198
+					true,
199
+					self::$_default_additional_limit
200
+				),
201
+				'EVT_default_registration_status' => new EE_Enum_Text_Field(
202
+					'EVT_default_registration_status',
203
+					esc_html__('Default Registration Status on this Event', 'event_espresso'),
204
+					false,
205
+					EEM_Event::$_default_reg_status,
206
+					EEM_Registration::reg_status_array()
207
+				),
208
+				'EVT_member_only'                 => new EE_Boolean_Field(
209
+					'EVT_member_only',
210
+					esc_html__('Member-Only Event Flag', 'event_espresso'),
211
+					false,
212
+					false
213
+				),
214
+				'EVT_phone'                       => new EE_Plain_Text_Field(
215
+					'EVT_phone',
216
+					esc_html__('Event Phone Number', 'event_espresso'),
217
+					false,
218
+					''
219
+				),
220
+				'EVT_allow_overflow'              => new EE_Boolean_Field(
221
+					'EVT_allow_overflow',
222
+					esc_html__('Allow Overflow on Event', 'event_espresso'),
223
+					false,
224
+					false
225
+				),
226
+				'EVT_timezone_string'             => new EE_Plain_Text_Field(
227
+					'EVT_timezone_string',
228
+					esc_html__('Timezone (name) for Event times', 'event_espresso'),
229
+					false,
230
+					''
231
+				),
232
+				'EVT_external_URL'                => new EE_Plain_Text_Field(
233
+					'EVT_external_URL',
234
+					esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
235
+					true
236
+				),
237
+				'EVT_donations'                   => new EE_Boolean_Field(
238
+					'EVT_donations',
239
+					esc_html__('Accept Donations?', 'event_espresso'),
240
+					false,
241
+					false
242
+				),
243
+			),
244
+		);
245
+		$this->_model_relations = array(
246
+			'Registration'           => new EE_Has_Many_Relation(),
247
+			'Datetime'               => new EE_Has_Many_Relation(),
248
+			'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
249
+			'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
250
+			'Term_Relationship'      => new EE_Has_Many_Relation(),
251
+			'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
252
+			'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
253
+			'Attendee'               => new EE_HABTM_Relation('Registration'),
254
+			'WP_User'                => new EE_Belongs_To_Relation(),
255
+		);
256
+		// this model is generally available for reading
257
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
258
+		parent::__construct($timezone);
259
+	}
260
+
261
+
262
+
263
+	/**
264
+	 * @param string $default_reg_status
265
+	 */
266
+	public static function set_default_reg_status($default_reg_status)
267
+	{
268
+		self::$_default_reg_status = $default_reg_status;
269
+		// if EEM_Event has already been instantiated,
270
+		// then we need to reset the `EVT_default_reg_status` field to use the new default.
271
+		if (self::$_instance instanceof EEM_Event) {
272
+			$default_reg_status = new EE_Enum_Text_Field(
273
+				'EVT_default_registration_status',
274
+				esc_html__('Default Registration Status on this Event', 'event_espresso'),
275
+				false,
276
+				$default_reg_status,
277
+				EEM_Registration::reg_status_array()
278
+			);
279
+			$default_reg_status->_construct_finalize(
280
+				'Event_Meta',
281
+				'EVT_default_registration_status',
282
+				'EEM_Event'
283
+			);
284
+			self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
285
+		}
286
+	}
287
+
288
+
289
+	/**
290
+	 * Used to override the default for the additional limit field.
291
+	 * @param $additional_limit
292
+	 */
293
+	public static function set_default_additional_limit($additional_limit)
294
+	{
295
+		self::$_default_additional_limit = (int) $additional_limit;
296
+		if (self::$_instance instanceof EEM_Event) {
297
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
298
+				'EVT_additional_limit',
299
+				__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
300
+				true,
301
+				self::$_default_additional_limit
302
+			);
303
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
304
+				'Event_Meta',
305
+				'EVT_additional_limit',
306
+				'EEM_Event'
307
+			);
308
+		}
309
+	}
310
+
311
+
312
+	/**
313
+	 * Return what is currently set as the default additional limit for the event.
314
+	 * @return int
315
+	 */
316
+	public static function get_default_additional_limit()
317
+	{
318
+		return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
319
+	}
320
+
321
+
322
+	/**
323
+	 * get_question_groups
324
+	 *
325
+	 * @return array
326
+	 * @throws \EE_Error
327
+	 */
328
+	public function get_all_question_groups()
329
+	{
330
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
331
+			array(
332
+				array('QSG_deleted' => false),
333
+				'order_by' => array('QSG_order' => 'ASC'),
334
+			)
335
+		);
336
+	}
337
+
338
+
339
+
340
+	/**
341
+	 * get_question_groups
342
+	 *
343
+	 * @param int $EVT_ID
344
+	 * @return array|bool
345
+	 * @throws \EE_Error
346
+	 */
347
+	public function get_all_event_question_groups($EVT_ID = 0)
348
+	{
349
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
350
+			EE_Error::add_error(
351
+				esc_html__(
352
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
353
+					'event_espresso'
354
+				),
355
+				__FILE__,
356
+				__FUNCTION__,
357
+				__LINE__
358
+			);
359
+			return false;
360
+		}
361
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
362
+			array(
363
+				array('EVT_ID' => $EVT_ID),
364
+			)
365
+		);
366
+	}
367
+
368
+
369
+
370
+	/**
371
+	 * get_question_groups
372
+	 *
373
+	 * @param int     $EVT_ID
374
+	 * @param boolean $for_primary_attendee
375
+	 * @return array|bool
376
+	 * @throws \EE_Error
377
+	 */
378
+	public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
379
+	{
380
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
381
+			EE_Error::add_error(
382
+				esc_html__(
383
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
384
+					'event_espresso'
385
+				),
386
+				__FILE__,
387
+				__FUNCTION__,
388
+				__LINE__
389
+			);
390
+			return false;
391
+		}
392
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
393
+			array(
394
+				array(
395
+					'EVT_ID'      => $EVT_ID,
396
+					'EQG_primary' => $for_primary_attendee,
397
+				),
398
+			)
399
+		);
400
+	}
401
+
402
+
403
+
404
+	/**
405
+	 * get_question_groups
406
+	 *
407
+	 * @param int             $EVT_ID
408
+	 * @param EE_Registration $registration
409
+	 * @return array|bool
410
+	 * @throws \EE_Error
411
+	 */
412
+	public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
413
+	{
414
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
415
+			EE_Error::add_error(
416
+				esc_html__(
417
+					'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
418
+					'event_espresso'
419
+				),
420
+				__FILE__,
421
+				__FUNCTION__,
422
+				__LINE__
423
+			);
424
+			return false;
425
+		}
426
+		$where_params = array(
427
+			'Event_Question_Group.EVT_ID'      => $EVT_ID,
428
+			'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false,
429
+			'QSG_deleted'                      => false,
430
+		);
431
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
432
+			array(
433
+				$where_params,
434
+				'order_by' => array('QSG_order' => 'ASC'),
435
+			)
436
+		);
437
+	}
438
+
439
+
440
+
441
+	/**
442
+	 * get_question_target_db_column
443
+	 *
444
+	 * @param string $QSG_IDs csv list of $QSG IDs
445
+	 * @return array|bool
446
+	 * @throws \EE_Error
447
+	 */
448
+	public function get_questions_in_groups($QSG_IDs = '')
449
+	{
450
+		if (empty($QSG_IDs)) {
451
+			EE_Error::add_error(
452
+				esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
453
+				__FILE__,
454
+				__FUNCTION__,
455
+				__LINE__
456
+			);
457
+			return false;
458
+		}
459
+		return EE_Registry::instance()->load_model('Question')->get_all(
460
+			array(
461
+				array(
462
+					'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
463
+					'QST_deleted'           => false,
464
+					'QST_admin_only'        => is_admin(),
465
+				),
466
+				'order_by' => 'QST_order',
467
+			)
468
+		);
469
+	}
470
+
471
+
472
+
473
+	/**
474
+	 * get_options_for_question
475
+	 *
476
+	 * @param string $QST_IDs csv list of $QST IDs
477
+	 * @return array|bool
478
+	 * @throws \EE_Error
479
+	 */
480
+	public function get_options_for_question($QST_IDs)
481
+	{
482
+		if (empty($QST_IDs)) {
483
+			EE_Error::add_error(
484
+				esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
485
+				__FILE__,
486
+				__FUNCTION__,
487
+				__LINE__
488
+			);
489
+			return false;
490
+		}
491
+		return EE_Registry::instance()->load_model('Question_Option')->get_all(
492
+			array(
493
+				array(
494
+					'Question.QST_ID' => array('IN', $QST_IDs),
495
+					'QSO_deleted'     => false,
496
+				),
497
+				'order_by' => 'QSO_ID',
498
+			)
499
+		);
500
+	}
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+	/**
509
+	 * Gets all events that are published
510
+	 * and have event start time earlier than now and an event end time later than now
511
+	 *
512
+	 * @param  array $query_params An array of query params to further filter on
513
+	 *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
514
+	 * @param bool   $count        whether to return the count or not (default FALSE)
515
+	 * @return EE_Event[]|int
516
+	 * @throws \EE_Error
517
+	 */
518
+	public function get_active_events($query_params, $count = false)
519
+	{
520
+		if (array_key_exists(0, $query_params)) {
521
+			$where_params = $query_params[0];
522
+			unset($query_params[0]);
523
+		} else {
524
+			$where_params = array();
525
+		}
526
+		// if we have count make sure we don't include group by
527
+		if ($count && isset($query_params['group_by'])) {
528
+			unset($query_params['group_by']);
529
+		}
530
+		// let's add specific query_params for active_events
531
+		// keep in mind this will override any sent status in the query AND any date queries.
532
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
533
+		// if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
534
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
535
+			$where_params['Datetime.DTT_EVT_start******'] = array(
536
+				'<',
537
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
538
+			);
539
+		} else {
540
+			$where_params['Datetime.DTT_EVT_start'] = array(
541
+				'<',
542
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
543
+			);
544
+		}
545
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
546
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
547
+				'>',
548
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
549
+			);
550
+		} else {
551
+			$where_params['Datetime.DTT_EVT_end'] = array(
552
+				'>',
553
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
554
+			);
555
+		}
556
+		$query_params[0] = $where_params;
557
+		// don't use $query_params with count()
558
+		// because we don't want to include additional query clauses like "GROUP BY"
559
+		return $count
560
+			? $this->count(array($where_params), 'EVT_ID', true)
561
+			: $this->get_all($query_params);
562
+	}
563
+
564
+
565
+
566
+	/**
567
+	 * get all events that are published and have an event start time later than now
568
+	 *
569
+	 * @param  array $query_params An array of query params to further filter on
570
+	 *                             (Note that status and DTT_EVT_start will be overridden)
571
+	 * @param bool   $count        whether to return the count or not (default FALSE)
572
+	 * @return EE_Event[]|int
573
+	 * @throws \EE_Error
574
+	 */
575
+	public function get_upcoming_events($query_params, $count = false)
576
+	{
577
+		if (array_key_exists(0, $query_params)) {
578
+			$where_params = $query_params[0];
579
+			unset($query_params[0]);
580
+		} else {
581
+			$where_params = array();
582
+		}
583
+		// if we have count make sure we don't include group by
584
+		if ($count && isset($query_params['group_by'])) {
585
+			unset($query_params['group_by']);
586
+		}
587
+		// let's add specific query_params for active_events
588
+		// keep in mind this will override any sent status in the query AND any date queries.
589
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
590
+		// if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
591
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
592
+			$where_params['Datetime.DTT_EVT_start*****'] = array(
593
+				'>',
594
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
595
+			);
596
+		} else {
597
+			$where_params['Datetime.DTT_EVT_start'] = array(
598
+				'>',
599
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
600
+			);
601
+		}
602
+		$query_params[0] = $where_params;
603
+		// don't use $query_params with count()
604
+		// because we don't want to include additional query clauses like "GROUP BY"
605
+		return $count
606
+			? $this->count(array($where_params), 'EVT_ID', true)
607
+			: $this->get_all($query_params);
608
+	}
609
+
610
+
611
+
612
+	/**
613
+	 * Gets all events that are published
614
+	 * and have an event end time later than now
615
+	 *
616
+	 * @param  array $query_params An array of query params to further filter on
617
+	 *                             (note that status and DTT_EVT_end will be overridden)
618
+	 * @param bool   $count        whether to return the count or not (default FALSE)
619
+	 * @return EE_Event[]|int
620
+	 * @throws \EE_Error
621
+	 */
622
+	public function get_active_and_upcoming_events($query_params, $count = false)
623
+	{
624
+		if (array_key_exists(0, $query_params)) {
625
+			$where_params = $query_params[0];
626
+			unset($query_params[0]);
627
+		} else {
628
+			$where_params = array();
629
+		}
630
+		// if we have count make sure we don't include group by
631
+		if ($count && isset($query_params['group_by'])) {
632
+			unset($query_params['group_by']);
633
+		}
634
+		// let's add specific query_params for active_events
635
+		// keep in mind this will override any sent status in the query AND any date queries.
636
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
637
+		// add where params for DTT_EVT_end
638
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
639
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
640
+				'>',
641
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
642
+			);
643
+		} else {
644
+			$where_params['Datetime.DTT_EVT_end'] = array(
645
+				'>',
646
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
647
+			);
648
+		}
649
+		$query_params[0] = $where_params;
650
+		// don't use $query_params with count()
651
+		// because we don't want to include additional query clauses like "GROUP BY"
652
+		return $count
653
+			? $this->count(array($where_params), 'EVT_ID', true)
654
+			: $this->get_all($query_params);
655
+	}
656
+
657
+
658
+
659
+	/**
660
+	 * This only returns events that are expired.
661
+	 * They may still be published but all their datetimes have expired.
662
+	 *
663
+	 * @param  array $query_params An array of query params to further filter on
664
+	 *                             (note that status and DTT_EVT_end will be overridden)
665
+	 * @param bool   $count        whether to return the count or not (default FALSE)
666
+	 * @return EE_Event[]|int
667
+	 * @throws \EE_Error
668
+	 */
669
+	public function get_expired_events($query_params, $count = false)
670
+	{
671
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
672
+		// if we have count make sure we don't include group by
673
+		if ($count && isset($query_params['group_by'])) {
674
+			unset($query_params['group_by']);
675
+		}
676
+		// let's add specific query_params for active_events
677
+		// keep in mind this will override any sent status in the query AND any date queries.
678
+		if (isset($where_params['status'])) {
679
+			unset($where_params['status']);
680
+		}
681
+		$exclude_query = $query_params;
682
+		if (isset($exclude_query[0])) {
683
+			unset($exclude_query[0]);
684
+		}
685
+		$exclude_query[0] = array(
686
+			'Datetime.DTT_EVT_end' => array(
687
+				'>',
688
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
689
+			),
690
+		);
691
+		// first get all events that have datetimes where its not expired.
692
+		$event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
693
+		$event_ids = array_keys($event_ids);
694
+		// if we have any additional query_params, let's add them to the 'AND' condition
695
+		$and_condition = array(
696
+			'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
697
+			'EVT_ID'               => array('NOT IN', $event_ids),
698
+		);
699
+		if (isset($where_params['OR'])) {
700
+			$and_condition['OR'] = $where_params['OR'];
701
+			unset($where_params['OR']);
702
+		}
703
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
704
+			$and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
705
+			unset($where_params['Datetime.DTT_EVT_end']);
706
+		}
707
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
708
+			$and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
709
+			unset($where_params['Datetime.DTT_EVT_start']);
710
+		}
711
+		// merge remaining $where params with the and conditions.
712
+		$where_params['AND'] = array_merge($and_condition, $where_params);
713
+		$query_params[0] = $where_params;
714
+		// don't use $query_params with count()
715
+		// because we don't want to include additional query clauses like "GROUP BY"
716
+		return $count
717
+			? $this->count(array($where_params), 'EVT_ID', true)
718
+			: $this->get_all($query_params);
719
+	}
720
+
721
+
722
+
723
+	/**
724
+	 * This basically just returns the events that do not have the publish status.
725
+	 *
726
+	 * @param  array   $query_params An array of query params to further filter on
727
+	 *                               (note that status will be overwritten)
728
+	 * @param  boolean $count        whether to return the count or not (default FALSE)
729
+	 * @return EE_Event[]|int
730
+	 * @throws \EE_Error
731
+	 */
732
+	public function get_inactive_events($query_params, $count = false)
733
+	{
734
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
735
+		// let's add in specific query_params for inactive events.
736
+		if (isset($where_params['status'])) {
737
+			unset($where_params['status']);
738
+		}
739
+		// if we have count make sure we don't include group by
740
+		if ($count && isset($query_params['group_by'])) {
741
+			unset($query_params['group_by']);
742
+		}
743
+		// if we have any additional query_params, let's add them to the 'AND' condition
744
+		$where_params['AND']['status'] = array('!=', 'publish');
745
+		if (isset($where_params['OR'])) {
746
+			$where_params['AND']['OR'] = $where_params['OR'];
747
+			unset($where_params['OR']);
748
+		}
749
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
750
+			$where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
751
+			unset($where_params['Datetime.DTT_EVT_end']);
752
+		}
753
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
754
+			$where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
755
+			unset($where_params['Datetime.DTT_EVT_start']);
756
+		}
757
+		$query_params[0] = $where_params;
758
+		// don't use $query_params with count()
759
+		// because we don't want to include additional query clauses like "GROUP BY"
760
+		return $count
761
+			? $this->count(array($where_params), 'EVT_ID', true)
762
+			: $this->get_all($query_params);
763
+	}
764
+
765
+
766
+
767
+	/**
768
+	 * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
769
+	 * because we don't want to override any existing global default prices but instead insert NEW prices that get
770
+	 * attached to the event. See parent for param descriptions
771
+	 *
772
+	 * @param        $id_or_obj
773
+	 * @param        $other_model_id_or_obj
774
+	 * @param string $relationName
775
+	 * @param array  $where_query
776
+	 * @return EE_Base_Class
777
+	 * @throws EE_Error
778
+	 */
779
+	public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
780
+	{
781
+		if ($relationName === 'Price') {
782
+			// let's get the PRC object for the given ID to make sure that we aren't dealing with a default
783
+			$prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
784
+			// if EVT_ID = 0, then this is a default
785
+			if ((int) $prc_chk->get('EVT_ID') === 0) {
786
+				// let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
787
+				$prc_chk->set('PRC_ID', 0);
788
+			}
789
+			// run parent
790
+			return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
791
+		}
792
+		// otherwise carry on as normal
793
+		return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
794
+	}
795
+
796
+
797
+
798
+	/******************** DEPRECATED METHODS ********************/
799
+
800
+
801
+
802
+	/**
803
+	 * _get_question_target_db_column
804
+	 *
805
+	 * @deprecated as of 4.8.32.rc.001. Instead consider using
806
+	 *             EE_Registration_Custom_Questions_Form located in
807
+	 *             admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
808
+	 * @access     public
809
+	 * @param    EE_Registration $registration (so existing answers for registration are included)
810
+	 * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
811
+	 *                                         registration).
812
+	 * @throws EE_Error
813
+	 * @return    array
814
+	 */
815
+	public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
816
+	{
817
+		if (empty($EVT_ID)) {
818
+			throw new EE_Error(__(
819
+				'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
820
+				'event_espresso'
821
+			));
822
+		}
823
+		$questions = array();
824
+		// get all question groups for event
825
+		$qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
826
+		if (! empty($qgs)) {
827
+			foreach ($qgs as $qg) {
828
+				$qsts = $qg->questions();
829
+				$questions[ $qg->ID() ] = $qg->model_field_array();
830
+				$questions[ $qg->ID() ]['QSG_questions'] = array();
831
+				foreach ($qsts as $qst) {
832
+					if ($qst->is_system_question()) {
833
+						continue;
834
+					}
835
+					$answer = EEM_Answer::instance()->get_one(array(
836
+						array(
837
+							'QST_ID' => $qst->ID(),
838
+							'REG_ID' => $registration->ID(),
839
+						),
840
+					));
841
+					$answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
842
+					$qst_name = $qstn_id = $qst->ID();
843
+					$ans_id = $answer->ID();
844
+					$qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
845
+					$input_name = '';
846
+					$input_id = sanitize_key($qst->display_text());
847
+					$input_class = '';
848
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
849
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
850
+																						   . $input_name
851
+																						   . $qst_name;
852
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
853
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
854
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
855
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
856
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
857
+					// leave responses as-is, don't convert stuff into html entities please!
858
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
859
+					if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
860
+						$QSOs = $qst->options(true, $answer->value());
861
+						if (is_array($QSOs)) {
862
+							foreach ($QSOs as $QSO_ID => $QSO) {
863
+								$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
864
+							}
865
+						}
866
+					}
867
+				}
868
+			}
869
+		}
870
+		return $questions;
871
+	}
872
+
873
+
874
+	/**
875
+	 * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
876
+	 *                             or an stdClass where each property is the name of a column,
877
+	 * @return EE_Base_Class
878
+	 * @throws \EE_Error
879
+	 */
880
+	public function instantiate_class_from_array_or_object($cols_n_values)
881
+	{
882
+		$classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
883
+		if ($classInstance instanceof EE_Event) {
884
+			// events have their timezone defined in the DB, so use it immediately
885
+			$this->set_timezone($classInstance->get_timezone());
886
+		}
887
+		return $classInstance;
888
+	}
889 889
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
             'WP_User'                => new EE_Belongs_To_Relation(),
255 255
         );
256 256
         // this model is generally available for reading
257
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
257
+        $this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Public();
258 258
         parent::__construct($timezone);
259 259
     }
260 260
 
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
      */
347 347
     public function get_all_event_question_groups($EVT_ID = 0)
348 348
     {
349
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
349
+        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
350 350
             EE_Error::add_error(
351 351
                 esc_html__(
352 352
                     'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
@@ -377,7 +377,7 @@  discard block
 block discarded – undo
377 377
      */
378 378
     public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
379 379
     {
380
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
380
+        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
381 381
             EE_Error::add_error(
382 382
                 esc_html__(
383 383
                     'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
@@ -411,7 +411,7 @@  discard block
 block discarded – undo
411 411
      */
412 412
     public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
413 413
     {
414
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
414
+        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
415 415
             EE_Error::add_error(
416 416
                 esc_html__(
417 417
                     'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
@@ -823,11 +823,11 @@  discard block
 block discarded – undo
823 823
         $questions = array();
824 824
         // get all question groups for event
825 825
         $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
826
-        if (! empty($qgs)) {
826
+        if ( ! empty($qgs)) {
827 827
             foreach ($qgs as $qg) {
828 828
                 $qsts = $qg->questions();
829
-                $questions[ $qg->ID() ] = $qg->model_field_array();
830
-                $questions[ $qg->ID() ]['QSG_questions'] = array();
829
+                $questions[$qg->ID()] = $qg->model_field_array();
830
+                $questions[$qg->ID()]['QSG_questions'] = array();
831 831
                 foreach ($qsts as $qst) {
832 832
                     if ($qst->is_system_question()) {
833 833
                         continue;
@@ -841,26 +841,26 @@  discard block
 block discarded – undo
841 841
                     $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
842 842
                     $qst_name = $qstn_id = $qst->ID();
843 843
                     $ans_id = $answer->ID();
844
-                    $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
844
+                    $qst_name = ! empty($ans_id) ? '['.$qst_name.']['.$ans_id.']' : '['.$qst_name.']';
845 845
                     $input_name = '';
846 846
                     $input_id = sanitize_key($qst->display_text());
847 847
                     $input_class = '';
848
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
849
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
848
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()] = $qst->model_field_array();
849
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_name'] = 'qstn'
850 850
                                                                                            . $input_name
851 851
                                                                                            . $qst_name;
852
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
853
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
854
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
855
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
856
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
852
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_id'] = $input_id.'-'.$qstn_id;
853
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_class'] = $input_class;
854
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_options'] = array();
855
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['qst_obj'] = $qst;
856
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['ans_obj'] = $answer;
857 857
                     // leave responses as-is, don't convert stuff into html entities please!
858
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
858
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['htmlentities'] = false;
859 859
                     if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
860 860
                         $QSOs = $qst->options(true, $answer->value());
861 861
                         if (is_array($QSOs)) {
862 862
                             foreach ($QSOs as $QSO_ID => $QSO) {
863
-                                $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
863
+                                $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_options'][$QSO_ID] = $QSO->model_field_array();
864 864
                             }
865 865
                         }
866 866
                     }
Please login to merge, or discard this patch.
events/help_tabs/events_default_settings_max_tickets.help_tab.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <p>
2 2
     <?php esc_html_e(
3
-        'Use this to control what the default will be for maximum tickets on an order when creating a new event.',
4
-        'event_espresso'
5
-    ); ?>
3
+		'Use this to control what the default will be for maximum tickets on an order when creating a new event.',
4
+		'event_espresso'
5
+	); ?>
6 6
 </p>
7 7
\ No newline at end of file
Please login to merge, or discard this patch.
core/services/notices/ConvertNoticesToEeErrors.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@
 block discarded – undo
43 43
             $error_string = esc_html__('The following errors occurred:', 'event_espresso');
44 44
             foreach ($notices->getError() as $notice) {
45 45
                 if ($this->getThrowExceptions()) {
46
-                    $error_string .= '<br />' . $notice->message();
46
+                    $error_string .= '<br />'.$notice->message();
47 47
                 } else {
48 48
                     EE_Error::add_error(
49 49
                         $notice->message(),
Please login to merge, or discard this patch.
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -19,56 +19,56 @@
 block discarded – undo
19 19
 class ConvertNoticesToEeErrors extends NoticeConverter
20 20
 {
21 21
 
22
-    /**
23
-     * Converts Notice objects into EE_Error notifications
24
-     *
25
-     * @param NoticesContainerInterface $notices
26
-     * @throws EE_Error
27
-     */
28
-    public function process(NoticesContainerInterface $notices)
29
-    {
30
-        $this->setNotices($notices);
31
-        $notices = $this->getNotices();
32
-        if ($notices->hasAttention()) {
33
-            foreach ($notices->getAttention() as $notice) {
34
-                EE_Error::add_attention(
35
-                    $notice->message(),
36
-                    $notice->file(),
37
-                    $notice->func(),
38
-                    $notice->line()
39
-                );
40
-            }
41
-        }
42
-        if ($notices->hasError()) {
43
-            $error_string = esc_html__('The following errors occurred:', 'event_espresso');
44
-            foreach ($notices->getError() as $notice) {
45
-                if ($this->getThrowExceptions()) {
46
-                    $error_string .= '<br />' . $notice->message();
47
-                } else {
48
-                    EE_Error::add_error(
49
-                        $notice->message(),
50
-                        $notice->file(),
51
-                        $notice->func(),
52
-                        $notice->line()
53
-                    );
54
-                }
55
-            }
56
-            if ($this->getThrowExceptions()) {
57
-                throw new EE_Error($error_string);
58
-            }
59
-        }
60
-        if ($notices->hasSuccess()) {
61
-            foreach ($notices->getSuccess() as $notice) {
62
-                EE_Error::add_success(
63
-                    $notice->message(),
64
-                    $notice->file(),
65
-                    $notice->func(),
66
-                    $notice->line()
67
-                );
68
-            }
69
-        }
70
-        $this->clearNotices();
71
-    }
22
+	/**
23
+	 * Converts Notice objects into EE_Error notifications
24
+	 *
25
+	 * @param NoticesContainerInterface $notices
26
+	 * @throws EE_Error
27
+	 */
28
+	public function process(NoticesContainerInterface $notices)
29
+	{
30
+		$this->setNotices($notices);
31
+		$notices = $this->getNotices();
32
+		if ($notices->hasAttention()) {
33
+			foreach ($notices->getAttention() as $notice) {
34
+				EE_Error::add_attention(
35
+					$notice->message(),
36
+					$notice->file(),
37
+					$notice->func(),
38
+					$notice->line()
39
+				);
40
+			}
41
+		}
42
+		if ($notices->hasError()) {
43
+			$error_string = esc_html__('The following errors occurred:', 'event_espresso');
44
+			foreach ($notices->getError() as $notice) {
45
+				if ($this->getThrowExceptions()) {
46
+					$error_string .= '<br />' . $notice->message();
47
+				} else {
48
+					EE_Error::add_error(
49
+						$notice->message(),
50
+						$notice->file(),
51
+						$notice->func(),
52
+						$notice->line()
53
+					);
54
+				}
55
+			}
56
+			if ($this->getThrowExceptions()) {
57
+				throw new EE_Error($error_string);
58
+			}
59
+		}
60
+		if ($notices->hasSuccess()) {
61
+			foreach ($notices->getSuccess() as $notice) {
62
+				EE_Error::add_success(
63
+					$notice->message(),
64
+					$notice->file(),
65
+					$notice->func(),
66
+					$notice->line()
67
+				);
68
+			}
69
+		}
70
+		$this->clearNotices();
71
+	}
72 72
 
73 73
 
74 74
 }
Please login to merge, or discard this patch.